The Perl CD Bookshelf, v4.0

Perl in a Nutshell, 2nd Edition
By By Nathan Patwardhan, Ellen Siever and Stephen Spainhour
Perl Cookbook, 2nd Edition
By Tom Christiansen and Nathan Torkington
Learning Perl, 3rd Edition
By Randal L. Schwartz and Tom Phoenix
Programming Perl, 3rd Edition
By Larry Wall, Tom Christiansen, and Jon Orwant
Learning Perl Objects, References and Modules
By Randal L. Schwartz, with Tom Phoenix
Mastering Regular Expressions, 2nd Edition by Jeffrey Friedl — in Adobe PDF format

Bonus Content!
Related Articles from the O'Reilly Network

Master Index
Copyright
Credits

The Perl CD Bookshelf, Version 4.0, is Copyright © 2004 by O'Reilly & Associates, Inc. All rights reserved.
Questions, comments, and suggestions to bookquestions@oreilly.com.

This product is printed with 100% recycled electrons.


Table of Contents

Copyright Page
Preface

Part I: Getting Started
Chapter 1: Introduction to Perl
Chapter 2: Installing Perl

Part II: Language Basics
Chapter 3: The Perl Executable
Chapter 4: The Perl Language
Chapter 5: Function Reference
Chapter 6: Debugging

Part III: Modules
Chapter 7: Packages, Modules, and Objects
Chapter 8: Standard Modules

Part IV: CGI
Chapter 9: CGI Overview
Chapter 10: The CGI.pm Module
Chapter 11: Web Server Programming with mod_perl

Part V: Databases
Chapter 12: Databases and Perl

Part VI: XML and SOAP
Chapter 13: XML and Perl
Chapter 14: SOAP

Part VII: Network Programming
Chapter 15: Sockets
Chapter 16: Email Connectivity
Chapter 17: Usenet News
Chapter 18: FTP
Chapter 19: Lightweight Directory Access with Net::LDAP

Part VIII: LWP
Chapter 20: The LWP Library

Part IX: Perl/Tk
Chapter 21: Perl/Tk

Part X: Win32
Chapter 22: Win32 Modules and Extensions
Chapter 23: OLE Automation
Chapter 24: ODBC Extension for Win32

Index
Colophon

Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


(Perl in a Nutshell, 2nd Edition)

 Java and XSLT
Previous Next

Copyright © 2002, 1999 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com). For more information contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com.

Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The association between the image of a camel and the topic of Perl is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Preface

Perl is a programming language that is useful. By this, we mean that people don't learn Perl just because they think they should, they learn Perl because they want to get something done.

This book is for Perl programmers who need to get things done. It's for readers who have dabbled a little in Perl and want a single reference for all their needs. This book is part reference, part guide to the world of Perl. We cover the language itself, but also the Perl modules that are most popular—modules for CGI, database manipulation, XML processing, network programming, graphical interfaces, and Win32 integration.

In this second edition of the book, we added several new chapters, included some topics that we neglected in the first edition and new technologies that have emerged, and updated the material to Perl 5.8.

0.1. How This Book Is Organized

This book has 10 parts, as follows:

Part I, "Getting Started"
Chapter 1, "Introduction to Perl" gets you oriented to Perl and the Perl community.

Chapter 2, "Installing Perl" gives you some pointers on installing Perl and its modules on your machine. This chapter introduces you to the CPAN archive and discusses using the CPAN module to retrieve the latest versions of Perl modules.

Part II, "Language Basics"
Chapter 3, "The Perl Executable" is about using the perl program itself. It covers environment variables, command-line options, and the differences in executing the Unix and Win32 versions of Perl.

Chapter 4, "The Perl Language" is the turbo-charged tutorial/reference to the Perl language. If you've never programmed before, then you might need a tutorial that goes more slowly. But if you have some experience with other programming languages, this chapter should teach you enough to start writing Perl programs.

Chapter 5, "Function Reference" is a reference chapter for each of the built-in functions of Perl.

Chapter 6, "Debugging" is about using the Perl debugger to help locate the rare errors in your programs.

Part III, "Modules"
Chapter 7, "Packages, Modules, and Objects" gives a quick introduction to Perl packages, Perl modules, and object-oriented programming in Perl.

Chapter 8, "Standard Modules" is a reference to each of the modules included in the standard Perl distribution.

Part IV, "CGI"
Chapter 9, "CGI Overview" is a brief introduction to the concepts behind CGI programming.

Chapter 10, "The CGI.pm Module" covers the very popular CGI.pm module, which is deemed essential by many CGI programmers.

Chapter 11, "Web Server Programmingwith mod_perl" is about mod_perl, the Apache module that can be used to significantly improve CGI performance and allows you to embed Perl code into the Apache server itself.

Part V, "Databases"
Chapter 12, "Databases and Perl" gives a brief introduction to DBM databases in Perl and provides a reference to DBI, the Database Independence package that gives you a consistent interface to many different database packages.

Part VI, "XML and SOAP"
Chapter 13, "XML and Perl" covers the modules for XML processing with Perl.

Chapter 14, "SOAP" gives an introduction to SOAP and web services in general, and to the SOAP::Lite module for SOAP programming with Perl.

Part VII, "Network Programming"
Chapter 15, "Sockets" explains socket programming and how to use the IO:Socket module.

Chapter 16, "Email Connectivity" covers the Net::SMTP and Net::POP3 modules for sending and reading email, and the Mail modules for manipulating email messages.

Chapter 17, "Usenet News" explains the NNTP protocol and the Net::NNTP module for reading and posting Usenet news, and the News::Newsrc module for managing .newsrc files.

Chapter 18, "FTP" explains the FTP protocol, the Net::FTP module for transferring files by FTP, and the Net::Netrc module for managing .netrc files.

Chapter 19, "Lightweight Directory Access with Net::LDAP" covers the Net::LDAP module for using LDAP directory services within Perl applications.

Part VIII, "LWP"
Chapter 20, "The LWP Library" covers the most commonly used parts of the huge LWP library of modules for HTTP transactions.

Part IX, "Perl/Tk"
Chapter 21, "Perl/Tk" is a reference to the Tk extension to Perl, which creates graphical user interfaces from within a Perl program.

Part X, "Win32"
Chapter 22, "Win32 Modules and Extensions" talks about the many Perl modules for working with the Win32 operating systems.

Chapter 23, "OLE Automation" covers the Win32::OLE modules for OLE automation.

Chapter 24, "ODBC Extension for Win32" covers the Win32::ODBC module.

Previous | Home | Next
Copyright Page | Book Index | 0.2. Conventions in This Book
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.2. Conventions in This Book

Italics
Used for filenames, program names, URLs, command-line options, email addresses, and to introduce new terms.

Constant Width
Used for code snippets, method and function names, text that should be typed literally, variables, constants, mail headers, and configuration directives.

Constant Width Italic
Used for replaceable items in code examples and syntax lines.

TIP: This icon indicates a note relating to the nearby text.

WARNING: This icon indicates a warning relating to the nearby text.

Previous | Home | Next
0. Preface | Book Index | 0.3. How to Contact Us
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.3. How to Contact Us

We have tested and verified the information in this book to the best of our ability, but you may find that features have changed (or even that we have made mistakes!). Please let us know about any errors you find, as well as your suggestions for future editions, by writing to:

O'Reilly & Associates, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
(800) 998-9938 (in the United States or Canada)
(707) 829-0515 (international or local)
(707) 829-0104 (fax)

There is a web page for this book, which lists errata, examples, and any additional information. You can access this page at:

http://www.oreilly.com/catalog/perlnut2/

To ask technical questions or comment on the book, send email to:

bookquestions@oreilly.com

For more information about books, conferences, Resource Centers, and the O'Reilly Network, see the O'Reilly web site at:

http://www.oreilly.com

Previous | Home | Next
0.2. Conventions in This Book | Book Index | 0.4. Acknowledgments for the First Edition
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.4. Acknowledgments for the First Edition

Many thanks to everyone who helped out on this book. Thanks to Larry Wall, Randal Schwartz, Tom Christiansen, and Sriram Srinivasan for their excellent books on Perl. Some material in this book is adapted from theirs; for that, we are very grateful.

Thanks also to all the reviewers of this book, who include Randal Schwartz, Tom Christiansen, Graham Barr, Clinton Wong, and Erik Olson. Without their help, this book wouldn't be nearly as helpful as it is.

We'd like to thank Linda Mui, our editor, and Val Quercia, who kept us on track, for all their support.

Previous | Home | Next
0.3. How to Contact Us | Book Index | 0.5. Acknowledgments for the Second Edition
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.5. Acknowledgments for the Second Edition

The second edition of this book was managed solely by Nathan Patwardhan. Thanks, Nate, for finishing this book under a difficult schedule and not complaining too much about being forced to edit files in the write-only format we call Docbook.

We'd also like to thank the technical reviewers for this edition: Jon Orwant, Brian Jepson, Sean Burke, David Blank-Edelman, Jason McIntosh, and Brand Hilton, all of whom gleefully agreed to review chapters of this book with little time and without much reward! Thanks to each of you for your help.

Finally, Nathan would like to thank the following people for their support: the Patwardhan, Kiebzak, and Powers families; Tabor Wells and Kendall Libby for making system administration more fun than a barrel of monkeys; Christopher Smith for the hilarious conversations and interest in working with tech pubs; David "Ira" Schwartz, Ph.D. for his significant contribution to my learning of C and Unix way back when; Julie Wasserman for introducing me to the metrics of customer satisfaction; and to the late Frank Willison for making a truly significant contribution to my life.

Previous | Home | Next
0.4. Acknowledgments for the First Edition | Book Index | I. Getting Started
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part I. Getting Started

Chapter 1, "Introduction to Perl"

Chapter 2, "Installing Perl"

Previous | Home | Next
0.5. Acknowledgments for the Second Edition | Book Index | 1. Introduction to Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 1. Introduction to Perl

Contents:

What's Perl Good For?
Perl Development
Which Platforms Support Perl?
Perl Resources

Computer languages differ not so much in what they make possible, but in what they make easy. Perl is designed to make the easy jobs easy, without making the hard jobs impossible. Perl makes it easy to manipulate numbers, text, files, directories, computers, networks, and programs. It also makes it easy to develop, modify, and debug your own programs portably, on any modern operating system.

Perl is especially popular with systems programmers and web developers, but it also appeals to a much broader audience. Originally designed for text processing, it has grown into a sophisticated, general-purpose programming language with a rich software development environment complete with debuggers, profilers, cross-referencers, compilers, interpreters, libraries, syntax-directed editors, and all the rest of the trappings of a "real" programming language.

There are many reasons for Perl's success. For starters, Perl is freely available and freely redistributable. But that's not enough to explain the Perl phenomenon, since many other freeware packages fail to thrive. Perl is not just free; it's also fun. People feel like they can be creative in Perl, because they have freedom of expression.

Perl is both a very simple language and a very rich language. It's a simple language in that the types and structures are simple to use and understand, and it borrows heavily from other languages you may already be familiar with. You don't have to know everything there is to know about Perl before you can write useful programs.

However, Perl is also a rich language, and there is much to learn about it. That's the price of making hard things possible. Although it will take some time for you to absorb all that Perl can do, somewhere down the line you will be glad that you have access to the extensive capabilities of Perl.

1.1. What's Perl Good For?

Perl has the advantage of being easy to learn if you just want to write simple scripts—thus its appeal to the ever-impatient system administrator and the deadline-driven CGI developer. However, as you become more ambitious, Perl lets you act on those ambitions. Chapter 2, "Installing Perl" covers how to get and install Perl, and Chapter 3, "The Perl Executable" through Chapter 6, "Debugging" cover the basics of the Perl language, its functions, and how to use the Perl debugger.

On top of the Perl language itself, however, are the Perl modules. You can think of modules as add-ons to the Perl language that allow you to streamline tasks by providing a consistent API. Perl itself is fun to use, but the modules lend Perl even more flexibility and enormous power. Furthermore, anyone can write and distribute a Perl module. Some modules are deemed important enough or popular enough to be distributed with Perl itself, but very few are actually written by the core Perl developers themselves. Chapter 7, "Packages, Modules, and Objects" introduces you to Perl modules, and Chapter 8, "Standard Modules" covers the standard modules that are distributed with Perl itself.

The most popular Perl module is CGI.pm, which gives a simple interface to developing common gateway interface (CGI) applications in Perl. While Perl itself is indispensable for many different tasks, its text-manipulation features make it perfect for CGI development on the Web. In fact, the resurgence of Perl over the past few years must be credited to its popularity as a CGI language. Chapter 10, "The CGI.pm Module" and Chapter 11, "Web Server Programmingwith mod_perl" talk about using Perl for CGI, including mod_perl, which merges Perl into the Apache web server.

Database interconnectivity is one of the most important functions of any programming language today, and Perl is no exception. DBI is a suite of modules that provide a consistent database-independent interface for Perl. Chapter 12, "Databases and Perl" covers both DBI and DBM (the more primitive but surprisingly effective database interface built directly into Perl).

The eXtensible Markup Language (XML) is quickly becoming the de facto way to store electronic information of any kind. Chapter 13, "XML and Perl" covers the modules designed for Perl and XML processing, and Chapter 14, "SOAP" covers using Perl for managing web services with the XML-based protocol SOAP.

The Internet doesn't start and stop at CGI. Network programming is another of Perl's strengths, with a robust sockets interface and several modules for writing clients and servers for all sorts of Internet services—not only the Web, but also email, news, FTP, LDAP, etc. Chapter 15, "Sockets" through Chapter 19, "Lightweight Directory Access with Net::LDAP" cover the modules for developing fully functional Internet applications in Perl.

The World Wide Web, of course, is the "killer app" of the Internet. LWP is a library of modules devoted to web programming. Chapter 20, "The LWP Library" covers the LWP library.

Perl programs are traditionally command line-based, but the Perl/Tk extension can provide Perl programs with graphical user interfaces, for both Unix and Microsoft Windows. Chapter 21, "Perl/Tk" gives a complete reference to Perl/Tk.

Finally, although Perl is primarily developed for Unix, recent releases of Perl for Windows 95 and Windows NT are gaining popularity, both for CGI and system administration tasks. Chapter 21, "Perl/Tk" through Chapter 24, "ODBC Extension for Win32" cover the Win32 modules for Perl.

As you may have noticed, Section 1.1, "What's Perl Good For?" has sneakily become a description of the contents of this book. This book aims at being a general-purpose reference to all things Perl.

Previous | Home | Next
I. Getting Started | Book Index | 1.2. Perl Development
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.2. Perl Development

Software doesn't grow on trees. Perl is free because of the donated efforts of several generous people who have devoted large chunks of their spare time to the development, maintenance, and evangelism of Perl.

Perl itself was created by Larry Wall, in an effort to produce reports for a bug-reporting system. Larry designed a new scripting language for this purpose and then released it to the Internet, thinking that someone else might find it useful. In the spirit of freeware, other people suggested improvements and even ways to implement them, and Perl transformed from a cute scripting language into a robust programming language.

Today, Larry does little actual development himself, but helps to guide several other selfless individuals in the continued development and design of the language. Currently, a team of porters are working (with Larry's guidance) on a complete rewrite of the language from the ground up, which is expected to yield a 21st-century version of the language in form and features. This rewrite will be released as Perl Version 6. At the time of this writing, progress on Perl 6 is steady but still a long way from completion.

This second edition of Perl in a Nutshell covers Perl 5.8.

Previous | Home | Next
1. Introduction to Perl | Book Index | 1.3. Which Platforms Support Perl?
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.3. Which Platforms Support Perl?

While Perl was developed on Unix and is closely entwined with Unix culture, it also has a strong following on the Windows and Macintosh platforms. Perl gives Windows 95, Windows NT, Macintosh, and even VMS users the opportunity to take advantage of the scripting power that Unix users take for granted.

Most Unix machines will have Perl already installed, since it's one of the first things a Unix system administrator will build for a new machine (and is in fact distributed with the operating system on some versions of Unix, such as Linux and FreeBSD). For Windows NT, Windows 95, and Macintosh, there are binary distributions of Perl that you can download for free. See Chapter 2, "Installing Perl" for information on installing Perl.

Although there is some history of other platforms not being treated seriously by the Perl community, Perl is becoming increasingly friendly to non-Unix platforms. The Win32 ports of Perl are quite stable, and as of Perl 5.8, are integrated wholly with core Perl.

Previous | Home | Next
1.2. Perl Development | Book Index | 1.4. Perl Resources
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.4. Perl Resources

Paradoxically, the way in which Perl helps you the most has almost nothing to do with Perl itself, and everything to do with the people who use Perl. While people start using Perl because they need it, they continue using Perl because they love it.

The result is that the Perl community is one of the most helpful in the world, with CPAN—the Comprehensive Perl Archive Network—as one example. When Perl programmers aren't writing their own programs, they spend their time helping others write theirs. They discuss common problems and help devise solutions. They develop utilities and modules for Perl and give them away to the world at large.

1.4.1. The comp.lang.perl.* Newsgroups

The central meeting place for Perl aficionados is Usenet. If you're not familiar with Usenet, it's a collection of special-interest groups (called newsgroups) on the Internet. For most anyone using a modern browser, Usenet access is as simple as a selecting a menu option on the browser. Perl programmers should consider subscribing to the following newsgroups:

comp.lang.perl.announce
A moderated newsgroup with announcements about new utilities or products related to Perl

comp.lang.perl.misc
The general-purpose newsgroup devoted to non-CGI-related Perl programming questions

comp.lang.perl.moderated
A moderated newsgroup intended to be a forum for more controlled, restrained discussions about Perl

comp.lang.perl.modules
A newsgroup devoted to using and developing Perl modules

comp.lang.perl.tk
A newsgroup concentrating on Perl/Tk, the graphical extension to Perl

comp.infosystems.www.authoring.cgi
A newsgroup for CGI questions in general, but mostly for Perl-related questions

At some point, it seems like every Perl programmer subscribes to comp.lang.perl.misc. You may eventually abandon it if the discussion becomes too detailed, too belligerent, or too bizarre for your taste. But you'll likely find yourself coming back from time to time, either to ask a question or just to check out the latest buzz.

One bit of advice, however: before posting questions to comp.lang.perl.misc (or any newsgroup, for that matter), you should read the group for a few days and read the FAQ (see Section 1.4.2, "Frequently Asked Questions Lists (FAQs)"). The comp.lang.perl.* newsgroups are a wonderful resource if you have an interesting or unusual question, but no one can save you if you ask something that's covered in the FAQ.

By the way, if you're a first-time poster to comp.lang.perl.misc, you shouldn't be surprised if you receive an email message listing various resources on Perl that you may not know about. This is done via an "auto-faq" service, which scans all postings and sends this helpful email to anyone who hasn't posted earlier.

1.4.2. Frequently Asked Questions Lists (FAQs)

A FAQ is a Frequently Asked Questions list, with answers. FAQs are traditionally associated with Usenet newsgroups, but the term has since been adopted by web sites, technical support departments, and even health care pamphlets. In general, FAQs are written and maintained on a volunteer basis by dedicated (and generous) members of the community. The Perl FAQ is maintained by Tom Christiansen and Nathan Torkington.

The Perl FAQ was created to minimize traffic on the comp.lang.perl.misc newsgroup when it became clear that the same questions were being asked over and over again. However, the FAQ has transcended into a general-purpose starting point for learning anything about Perl.

The FAQ is distributed in several different formats, including HTML, PostScript, and plain ASCII text. The main FAQ source is located at http://www.perl.com/pub/q/faqs. You can also find it at http://perlfaq.cpan.org/, and the latest version of the FAQ is posted on a semi-regular basis on comp.lang.perl.misc.

In addition to the general Perl FAQ, there are also several niche FAQs that are Perl-related. They are:

Perl CGI Programming FAQ
http://www.perl.com/CPAN-local/doc/FAQs/cgi/perl-cgi-faq.html

Perl/Tk FAQ
http://w4.lns.cornell.edu/~pvhp/ptk/ptkTOC.html

Perl for Win32 FAQ
http://www.ActiveState.com/support/faqs/win32/

Perl for the Mac FAQ
http://www.perl.com/CPAN/doc/FAQs/mac/MacPerlFAQ.html

By no means should you consider this to be an exhaustive list. Also check out appropriate mailing lists (see Section 1.4.3, "Mailing Lists"); you'll find that many mailing lists also maintain their own FAQs.

1.4.3. Mailing Lists

Several mailing lists are focused on more specialized aspects of Perl. Like Usenet newsgroups, mailing lists are discussion groups, but the discussion takes place over email. In general, mailing lists aren't as convenient as newsgroups, since a few hundred mail messages a day about Perl can become intrusive to any but the most obsessive Perl hackers. However, because mailing lists tend to have much smaller and more focused distributions, you'll find that they can sometimes be much more interesting and helpful than newsgroups.

There are tons of mailing lists for Perl users and developers alike. Some are specific to a particular module or distribution, such as the mailing lists for users of CGI.pm, LWP, DBI, or mod_perl. Other mailing lists discuss using Perl on non-Unix platforms such as Windows, Macintosh or VMS. Still more mailing lists are devoted to the development and advocacy of Perl in general.

For a list of Perl-related mailing lists, refer to the Perl Mailing List Database (lists.cpan.org) or to the list maintained by the Perl Mongers at http://www.perl.org/support/mailing_lists.html.

Many of these mailing lists maintain a "digest" version, which means that instead of receiving individual email messages all day long, you receive a few "digests" of the messages on a regular basis. Digests of a mailing list might be preferable to the minute-by-minute onslaught of email throughout the day, depending on how involved you are in the discussion.

1.4.4. CPAN

The Comprehensive Perl Archive Network (CPAN) is a repository of Perl modules and scripts submitted by Perl programs worldwide. It is by far the most valuable resource for Perl programmers, so if you haven't browsed through CPAN, go there now, and expect to stay a while. There are many mirrored CPAN sites around the world, but the preferred entry point is www.cpan.org.

1.4.5. www.perl.com

There are countless web pages devoted to Perl, but probably the most useful entry site to Perl resources is www.perl.com. Formerly maintained by Tom Christiansen, www.perl.com is now maintained by O'Reilly & Associates (the publisher of this book). From www.perl.com, you can access Perl documentation, news, software, FAQs, articles, and (of course) Perl itself.

1.4.6. Perl Mongers (www.perl.org)

The Perl Mongers is a nonprofit Perl advocacy organization that exists to provide services to Perl user groups and to take the place of the now defunct Perl Institute. If you live in a major city (in the United States or abroad), it's likely that a Perl Mongers group exists in your area. You can find out more about the Perl Mongers by checkout out the main site at www.perl.org or a description of user group services at www.pm.org.

If you're curious about the location of a Perl Mongers group, you should take a look at http://www.pm.org/groups/index.html.

1.4.7. The Perl Journal

The Perl Journal, published by CMP, is a quarterly publication with articles and news about Perl.

If you're interested in reading past TPJ articles, some highlights are being collated into book form (or, more specifically, three-book form) and should be available by the time you read this paragraph: Perl Programming: Best of The Perl Journal (O'Reilly).

1.4.8. Perl Conferences

For years, Usenix has devoted tracks of its conferences to Perl. However, today there are not just one but multiple conferences that focus on Perl.

In 1997, O'Reilly & Associates began hosting The Perl Conference (TPC), typically held during the third week of July in a major California city. In recent years, The Perl Conference has merged with a more general conference for open source technologies, but the Perl track is by far the best attended. For more information, go to http://conferences.oreilly.com/.

In 1999, a nonprofit organization called YAS (Yet Another Society) started sponsoring a more grassroots, less corporate conference called YAPC (Yet Another Perl Conference), typically held twice a year in university settings. YAPC::America::North is held in the United States or Canada in June, and YAPC::Europe is held in a major European city in September. For more information, go to http://www.yapc.org/.

1.4.9. Books

There are many books written on Perl. In fact, the current popularity of Perl is often credited to the original publication of Programming Perl, also known as "The Camel" (because of the animal on its cover), by Larry Wall and Randal Schwartz.[1] The Camel is also published by O'Reilly & Associates. The Camel isn't the best place to start if you're just learning Perl from scratch, but it's essential if you want to really understand Perl and not just dabble in it.

[1]The third and most recent edition of Programming Perl is written by Larry Wall, Tom Christiansen, and Jon Orwant.

Other Perl books published by O'Reilly & Associates are Learning Perl ("The Llama"), Advanced Perl Programming, Perl Cookbook, Mastering Regular Expressions, Learning Perl on Win32 Systems, Mastering Perl/Tk, Perl for System Administration, Perl for Web Site Management, Mastering Algorithms with Perl, Programming the Perl DBI, Perl and XML, and CGI Programming with Perl.

There are also books from other publishers, of course. Standouts include Object-Oriented Perl and Elements of Programming with Perl, both published by Manning Press, and Effective Perl Programming and Network Programming with Perl, published by Addison-Wesley Longman.

Previous | Home | Next
1.3. Which Platforms Support Perl? | Book Index | 2. Installing Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 2. Installing Perl

Contents:

The CPAN Architecture
How Is CPAN Organized?
Installing Perl
Getting and Installing Modules
Documentation

Some of the best things in life are free. So is Perl. Although bundled Perl distributions are frequently available on CD-ROM, perhaps installed as a core part of your operating system, most people download Perl from an online archive. CPAN, the Comprehensive Perl Archive Network, is the main distribution point for all things Perl.Whether you are looking for Perl itself, for a module, or for documentation about Perl, CPAN (http://www.cpan.org/) is the place to go. The ongoing development and enhancement of Perl is very much a cooperative effort, and CPAN is the place where the work of many individuals comes together.

2.1. The CPAN Architecture

CPAN represents the development interests of a cross-section of the Perl community. It contains Perl utilities, modules, documentation, and (of course) the Perl distribution itself. CPAN was created by Jarkko Hietaniemi and Andreas König.

The home for CPAN is http://www.cpan.org/, but CPAN is also mirrored on many other sites around the globe. This ensures that anyone with an Internet connection can have reliable access to CPAN's contents at any time. Since the structure of all CPAN sites is the same, a user searching for the current version of Perl can be sure that the stable.tar.gz file is the same on every site.

If you want to use anonymous FTP, the following machines should have the Perl source code plus a copy of the CPAN mirror list:

ftp.perl.com

ftp.cs.colorado.edu

ftp.cise.ufl.edu

ftp.funet.fi

ftp.cs.ruu.nl

The location of the top directory of the CPAN mirror differs on these machines, so look around once you get there. It's often something like /pub/perl/CPAN.

Previous | Home | Next
1.4. Perl Resources | Book Index | 2.2. How Is CPAN Organized?
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.2. How Is CPAN Organized?

CPAN materials are grouped into categories, including Perl modules, distributions, documentation, announcements, ports, scripts, and contributing authors. Each category is linked to related categories. For example, links to a graphing module written by an author appear in both the module and the author areas.

Since CPAN provides the same offerings worldwide, the directory structure has been standardized; files are located in the same place in the directory hierarchy at all CPAN sites. All CPAN sites use CPAN as the root directory, from which the user can select a specific Perl item. From the CPAN directory, you have the following choices:

Item | Description
CPAN.html | CPAN info page; some general information about CPAN
ENDINGS | Description of the file extensions, such as .tar, .gz, and .zip
MIRRORED BY | A list of sites mirroring CPAN
MIRRORING.FROM | A list of sites mirrored by CPAN
README | A brief description of what you'll find on CPAN
README.html | An HTML-formatted version of the README file
RECENT | Recent additions to the CPAN site
RECENT.html | An HTML-formatted list of recent additions
ROADMAP | What you'll find on CPAN and where
ROADMAP.html | An HTML-formatted version of ROADMAP
SITES | An exhaustive list of CPAN sites
SITES.html | An HTML-formatted version of SITES
authors | A list of CPAN authors
clpa | An archive of comp.land.perl.announce
disclaimer.html | Before you call your lawyer, read these details about CPAN content
doc | Various Perl documentation, FAQs, etc.
index.html | CPAN starting point in you prefer to browse CPAN from the web instead of FTP
indices | Everything that is indexed
misc | Miscellaneous Perl stuff such as Larry Wall quotes and gifts
modules | Modules for Perl Version 5
other-archives | Other things yet uncategorized
ports | Various Perl ports
scripts | Various scripts appearing in Perl books
src | The Perl sources from various versions

While most people who want to use Perl for Win32 should use ActivePerl from www.activestate.com, if you want to roll your own, you can get the current Perl source kit from the src directory and click on stable.tar.gz (or stable.zip, if you're building under Win32). If you want to stand on the cutting edge of Perl development, you should download devel.tar.gz (or devel.zip, if you're building under Win32). For ports to other systems, click on ports. The modules link is the one you want if you're looking for a Perl module. From there, you can get a full list of the modules or access the modules directly by author, by CPAN category, or by module name. (Section 2.4, "Getting and Installing Modules" later in this chapter talks about installing modules.) Click on doc for Perl documentation, FAQs, etc.

Previous | Home | Next
2. Installing Perl | Book Index | 2.3. Installing Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.3. Installing Perl

Most likely, your system administrator is responsible for installing and upgrading Perl. But if you are the system administrator, or you want to install Perl on your own system, sooner or later you will find yourself installing a new version of Perl.

TIP: If you run Perl and plan on upgrading to the latest distribution, be aware that pre-5.005 Perl extensions are not compatible with 5.6 and later. This means that you must rebuild and reinstall any dynamically loaded extensions you built under Perl distributions earlier than 5.005. If you're building under a Unix variant that's running Perl 5.005, choose the Configure option for 5.005 compatibility.

Specific installation instructions come in the README and INSTALL files of the Perl distribution kit. If you don't already have the Perl distribution, you can download it from CPAN—the latest Unix distribution is in stable.tar.gz. The information in this section is an overview of the installation process. The gory details are in the INSTALL file, which you should look at before starting, especially if you haven't done an installation before. Note that operating systems other than Unix may have special instructions; if so, follow those instructions instead of what's in this section or in INSTALL. Look for a file named README.xxx, in which xxx represents your operating-system type.

In addition to Perl itself, the standard distribution includes a set of core modules that are automatically installed with Perl. See Section 2.4, "Getting and Installing Modules" later in this chapter to learn how to install modules that are not bundled with Perl; Chapter 8, "Standard Modules" describes the standard modules in some detail.

2.3.1. Installing on Unix

Typically, the Perl kit will be packed as either a tar file or a set of shar (shell archive) scripts; in either case, the file will be in a compressed format. If you got your version of Perl directly from CPAN, it is probably in "tar-gzipped" format; tar and gzip are popular Unix data-archiving formats. In any case, once you've downloaded the distribution, you need to uncompress and unpack it. The filename indicates the kind of compression that was used. A .Z extension indicates you need to uncompress the file first, while a .gz extension indicates you need to gunzip the file. You then unpack the file as appropriate, read the README and INSTALL files, and run a massive shell script called Configure, which tries to figure out everything about your system and creates the file Config.pm to store the information. After this is done, you do a series of "makes" to find header file dependencies, to compile Perl (and a2p, which translates awk scripts to Perl), to run regression tests, and to install Perl in your system directories.

If you opt to build your own Perl under Win32, you will find that the Perl source kit is also shipped in zip format, which you can easily extract with pkunzip or Winzip (www.winzip.com).

If you're building Perl under Unix, it is likely that your architecture and development environment is supported by Configure. You shouldn't have any problems with the build process or running the test suite. One common problem is not making sure that Perl is linked against all the libraries it needs to build correctly. Also, you should say "yes" when Configure asks if you want dynamic loading, if your system supports it. Otherwise, you won't be able to install modules that use XS, which provides an interface between Perl and C.

If you are running Linux, and you've installed Perl from a tarball (or rpm package), you should make sure everything is there; one way to do that is to check the Config.pm file. If MakeMaker is not correctly installed, you might need to build Perl yourself.

It's possible you'll get a compiled (binary) copy of Perl, rather than the source. In that case, make sure you get suidperl,[2] a2p, s2p, and the Perl library routines. Install these files in the directories that your version was compiled for. Note that binary distributions of Perl are made available because they're handy, not because you are restricted from getting the source and compiling it yourself. The people who give you the binary distribution ought to provide you with some form of access to the source, if only a pointer to where they got the source. See the Copying file in the distribution for more information.

[2]Be care ful with suidperl. Most people do not understand the complexities and pitfalls of suidperl. Also, it will likely be deprecated after the Perl 5.8 release.

2.3.1.1. Perl examples

The Perl source distribution comes with some sample scripts in the eg/ subdirectory. Feel free to browse among them and use them. They are not installed automatically, however, so you need to copy them to the appropriate directory and possibly fix the #! line to point to the right interpreter.

The files in the t/ and lib/ subdirectories, although arcane in spots, can also serve as examples.

2.3.1.2. Patches

Since Perl is constantly being honed and improved, patches are sometimes made available through CPAN. Your distribution is likely to have had most of the patches applied already—run perl -v to check the patch level of your distribution. Patches are sent out with complete instructions on how to apply them using patch, which is available from the GNU project.

2.3.2. Installing on Win32

You need to obtain and install a copy of Perl yourself, unless you have had the good fortune of having either a system administrator install Perl on your system or access to a set of development tools to compile the Perl distribution.

The official precompiled Perl distribution for Win32 is ActivePerl, which is developed by ActiveState Tool Corporation (www.activestate.com). You'll find that ActivePerl is quite complete, down to the availability of such modules as Win32 and mod_perl.

When Perl 5.005 was released, Perl developers could build their own Perl for Win32 from the same source kit that their Unix counterparts used. In addition, the Perl build mechanism for Win32 began to support more than just commercial development toolkits, such as Microsoft's Visual C++. A Perl developer who wanted to build the Perl source kit with a free development toolkit could build Perl with Cygwin (www.cygnus.com), a Unix layer on top of Win32, or Mingw32 (www.mingw.org) with dmake, a set of Win32 runtime libraries that provide a Unix emulation under native Win32.

TIP: Unless there's something specific that you gain by building your own Perl for Win32, then you should use the Activestate build, ActivePerl.

2.3.2.1. ActivePerl

The canonical source for the ActivePerl distribution at the time of this writing is at http://aspn.activestate.com/ASPN/Downloads/ActivePerl/. Included in the distribution are:

Perl for Win32
Binary for the core Perl distribution

Perl for ISAPI
IIS plug-in for use with ISAPI-compliant web servers

PerlScript
ActiveX scripting engine

Perl Package Manager
Manager for Perl modules and extensions

The ActivePerl binary comes as a self-extracting executable that uses the standard Win32 InstallShield setup wizard to guide you through the installation process. By default, Perl is installed into the directory C:\Perl\version, in which version is the current version number (e.g., 5.005). (For information on customizing your installation, see the Win32 FAQ on the ActiveState web site.) The installation also associates the file extension .pl with Perl and adds the directory into which you installed Perl to your PATH environment variable.

If you want to install ActivePerl, you can do so by running the MSI archive that's shipped by ActiveState. If the MSI archive is not associated with the MSI application, you need to obtain InstMsi.exe from the downloads section at www.microsoft.com.

If you don't (or can't) install MSI on your system, ActiveState has made available a Perl installer that doesn't use MSI, but be aware that this installer doesn't have a corresponding de-installer.

2.3.2.2. Standard Perl distribution

The standard Perl distribution is available from CPAN, where you'll find binary and source distributions for the current version of Perl. The source distributions come as .tar.gz files, which you can extract using a utility that supports gzip files, tar files, and long filenames. Ports of both GNU gzip and tar are available for the various Win32 platforms, or you can use a graphical zip archive program such as WinZip. Make sure you preserve the directory structure when you unpack the distribution.

To install from the source, you need the Microsoft Visual C++ compiler, the Borland C++ compiler, or Mingw32 with EGCS gcc-2.95.X. If you're using Cygwin32, do not try to build Perl in the win32 subdirectory. Instead, you should run Configure in the src directory as you would when building under a Unix platform. You also need a make utility. Microsoft Visual C++ comes with nmake, or you can use dmake.[3]

[3]See the README.win32 file for information on obtaining Mingw32 and a Win32 dmake port.

Once you have the distribution, start by reading the file README.win32. Next, edit the file Makefile in the win32 subdirectory of the distribution and make sure that you're happy with the values for the install drive and directory. Then execute the following commands from the win32 subdirectory of the distribution to build, test, and install the distribution. This example assumes that you have the proper environment variables (LIB, INCLUDE, etc.) set up for your compiler and that nmake is your make program.

C:\> nmake         Build all of Perl
C:\> nmake test    Test your distribution
C:\> nmake install Install to target directory, as specified in the Makefile
TIP: If you're running Mingw32, you'll use dmake, since nmake is part of commercial development suites—such as Microsoft Visual C++—and is not available separately.

Assuming everything is now built correctly, you just need to add the bin subdirectory of the installation target directory to your path or to your operating environment under Microsoft server platforms such as Windows NT. For example, if you installed the Perl distribution to C:\Perl, you'll want to add the directory containing perl.exe (e.g., C:\Perl\bin) to your path.

Finally, you should restart your machine so the environment changes take effect, and you're ready to go. This is of particular importance if you're running Perl under Windows 95, 98, or ME.

WARNING: Windows 95/98 users can expect significantly different functionality from their Perl distribution than Windows NT users. For various reasons, some of the Win32 modules don't work on Windows 95/98. The functionality required to implement them may be missing on Windows 95/98, or bugs in Windows 95 may prevent them from working correctly.

Previous | Home | Next
2.2. How Is CPAN Organized? | Book Index | 2.4. Getting and Installing Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.4. Getting and Installing Modules

As you'll see when you look at the lists of modules and their authors on CPAN, many users have made their modules freely available. If you find an interesting problem and are thinking of writing a module to solve it, check the modules directory on CPAN first to see if there is a module there that you can use. The chances are good that there is a module that does what you need, or perhaps one that you can extend, rather than starting from scratch.[4]

[4]If you are interested in writing and contributing modules, there are several good starting points for learning to do so—see the perlmodlib manpage, the "Perl 5 Module List," and the "Perl Authors Upload Server" (http://www.perl.com/CPAN/modules/04pause.html).

Before you download a module, you might also check your system to see if it's already installed. The following command searches the libraries in the @INC array and prints the names of all modules it finds:

find `perl -e 'print "@INC"'` -name '*.pm' -print

2.4.1. Locating Modules

If you start from the modules directory on CPAN, you'll see that the modules are categorized into three subdirectories:

by-authors       Modules by author's registered CPAN name
by-category      Modules by subject matter (see below)
by-module        Modules by namespace (i.e., MIME)

If you know what module you want, you can go directly to it by clicking on the by-module entry. If you are looking for a module in a particular category, you can find it in the by-category subdirectory. If you know the author, click on by-author. However, if you aren't familiar with the categories and want to find a module that performs a certain task, you might want to get the file 00modlist.long.html, also in the modules directory. This file is the "Perl 5 Modules List." It contains a list of all the modules, by category, with a brief description of the purpose of each module and a link to the author's CPAN directory for downloading.

Here is a list of the Perl Module categories, plus two for modules that don't fit anywhere else:

02_Perl_Core_Modules
03_Development_Support
04_Operating_System_Interfaces
05_Networking_Devices_IPC
06_Data_Type_Utilities
07_Database_Interface
08_User_Interfaces
09_Language_Interfaces
10_File_Names_Systems_Locking
11_String_Lang_Text_Proc
12_Opt_Arg_Param_Proc
13_Internationalization_Locale
14_Security_and_Encryption
15_World_Wide_Web_HTML_HTTP_CGI
16_Server_and_Daemon_Utilities
17_Archiving_and_Compression
18_Images_Pixmaps_Bitmaps
19_Mail_and_Usenet_News
20_Control_Flow_Utilities
21_File_Handle_Input_Output
22_Microsoft_Windows_Modules
23_Miscellaneous_Modules
24_Commercial_Software_Interfaces
99_Not_In_Modulelist
99_Not_Yet_In_Modulelist

If you are in the by-categories subdirectory and have selected an area from which you'd like to download a module, you'll find a list of the files in the directory. tar files have a .tar.gz extension, and README files have a .readme extension. You'll generally find a README file for each module; take a look at it before you decide to download the file.

Here's a sample directory listing from category 14, under the MD5 directory:

Digest-MD5-2.09.readme
Digest-MD5-2.09.tar.gz
GAAS
GARY
MD5-1.5.3.readme
MD5-1.5.3.tar.gz
MD5-1.6.readme
MD5-1.6.tar.gz
MD5-1.7.readme
MD5-1.7.tar.gz
NWINT

You'll notice that multiple versions are sometimes listed—for example, the MD5 module has Versions 1.5.3 through 1.7 available. Generally, this is to facilitate the transition to a new version of the module.

Select the .readme file of the most current archive and review its contents carefully. README files often give special instructions about building the module; they warn you about other modules needed for proper functioning and if the module can't be built under certain versions of Perl. If you're satisfied with what you read, download the file.

2.4.2. Module Installation

If you're running the standard distribution of Perl, on either a Unix or Win32 system, and you want to install a module, this section explains how to do it. If you are running the ActiveState Win32 port, you can follow the instructions covered in this section, unless you're running on a system without a development toolkit; if this is the case, see the next section.

Before installing modules, you should understand at least a little about make. make is a command designed to automate compilations; it guarantees that programs are compiled with the correct options and are linked to the current version of program modules and libraries. But it's not just for programmers—make is useful for any situation in which there are dependencies among a group of related files.

make uses a file known as a Makefile, which is a text file that describes the dependencies and contains instructions that tell make what to do. A Perl programmer who writes a module creates a file called Makefile.PL that comes with the module when you download it. Makefile.PL is a Perl script that uses another module, ExtUtils::MakeMaker (generally referred to as simply MakeMaker), to generate a Makefile specific to that module on your system.

Before you can actually install the module, you need to decide where it should go. Modules can be installed either globally, for everyone to use, or locally, for your own use. Most system administrators install popular software, including Perl modules, to be globally available. In that case, the modules are generally installed in a branch of the lib directory with the rest of the Perl libraries.

If you have root privileges or write access to the locations where Perl modules are installed on your system, you can proceed by moving the downloaded module file to the correct directory and running gunzip and tar to unpack it. Then cd to the module directory and check any README or INSTALL files, check the MANIFEST file to be sure everything is there. If all is well, you can run the following to complete the installation:

% perl Makefile.PL
% make
% make test
% make install

If you're on a Win32 platform and are using Mingw32, do the following:

C:\modulename-version> perl Makefile.PL
C:\modulename-version> dmake
C:\modulename-version> dmake test
C:\modulename-version> dmake install

It's possible that you'll need to customize Makefile.PL before running it. If so, see the discussion of ExtUtils::MakeMaker in Chapter 8, "Standard Modules". Or, if you know the MakeMaker options that you'd like to add to Makefile.PL, you can add these options on the command line. A typical scenario would be on a system where you've installed a precompiled version of Perl, and the CC and LD options in Config.pm don't match your programming environment; thus, Perl modules won't build correctly. To solve this problem, you can do the following:

% perl Makefile.PL CC=gcc LD=gcc

If you are going to install the module locally (for example, if you don't have permission to install globally or you want to test it locally before installing it for general use), you need to pass a PREFIX argument to Perl when you run Makefile.PL to generate the Makefile. This argument tells MakeMaker to use the directory following PREFIX as the base directory when installing the module.

For example, to install a module in the directory /home/mydir/Perl/Modules, the PREFIX argument would look like this:

% perl Makefile.PL PREFIX=/home/mydir/Perl/Modules

Then follow the remaining steps, as above:

% make
% make test
% make install

The module is now available, but when you write Perl code to use the module, there's another detail to take care of. Since Perl looks in system-wide directories as specified in the special array @INC, it won't find local modules unless you tell it where they are. Instead, you'll receive an error message such as the following:

Can't locate <ModuleName>.pm in @INC.
BEGIN failed--compilation aborted.

Thus, if you installed the module in /home/mydir/Perl/Modules, you need to tell Perl to look in that location with the command use lib 'path':

#!/usr/local/bin/perl -w
use lib '/home/mydir/Perl/Modules';
use ModuleName;

2.4.3. Installing Modules with ActiveState Perl

Prior to Perl 5.005, ActiveState's Perl for Win32 did not support MakeMaker. If you are running Perl 5.004 (or earlier), you should upgrade because the absense of MakeMaker prevents you from installing and using most current Perl modules. While some modules can be installed manually, this is not suggested, since it's likely that something will be forgotten, and the module won't work correctly! You should follow all module documentation to determine which installation technique is the proper one, so that everything will be okay.

With 5.6 and later, you can use MakeMaker to install the modules, or you can use the Perl Package Manager that comes with ActivePerl.

2.4.3.1. Using MakeMaker

To install a module using MakeMaker, follow the procedure described earlier for installing when you are running the standard distribution, replacing make with nmake or dmake as appropriate.

2.4.3.2. Using the Perl Package Manager

The Perl Package Manager (PPM) provides a command-line interface for obtaining and installing Perl modules and extensions. To run PPM, connect to CPAN and type:

perl ppm.pl

The PPM prompt appears, and you can begin to enter PPM commands. The available commands are:

help [command]
Prints the list of commands and what they do, or help for a particular command.

install packages
Installs the specified packages.

quit
Leaves PPM.

remove packages
Removes the specified packages from the system.

search
Searches for information about available packages.

set
Sets or displays current options.

verify
Verifies that your current installation is up-to-date.

2.4.4. Installing Modules with the CPAN Module

If you are just getting and installing one or a few modules, it's not a big problem to download the module's tarball and run through the build process manually. But if you don't want to cope with the brute-force approach when dealing with large module installations (such as LWP and the CPAN bundle), there is an easier way—you can use the CPAN module. The CPAN module (CPAN.pm) can be used interactively from the command line to locate, download, and install Perl modules and their dependencies, or to identify modules and authors. CPAN.pm was designed to automate the installation of Perl modules; it includes searching capabilities and the ability to retrieve files from one or more of the mirrored CPAN sites and unpack them in a dedicated directory.

To run the CPAN module interactively, enter:

% perl -MCPAN -e shell

The first time you use the CPAN module, it takes you through a series of setup questions and writes CPAN::Config if you run the above as root or your administrative user. If the above is run as a user who does not have administrative permissions, CPAN.pm determines who you are and writes MyConfig.pm in a subdirectory of your home directory (defaults to ~/.cpan/CPAN/MyConfig.pm). After that, whenever you use the CPAN module for downloading other modules, it uses the .cpan directory as the general build and cache directory, saved as cpan_home in the configuration file. If ReadLine support is available (i.e., Term::ReadKey and Term::ReadLine are installed), you can use command history and command completion as you enter commands.

When the module runs and is ready for commands to be entered, you'll see the prompt:

cpan>

You can then enter h to get a brief help message, or just start entering commands. The commands are all methods in the CPAN::Shell package. For commands that can operate on modules, bundles, authors, or distributions, CPAN.pm treats arguments containing a slash (/) as distributions, arguments beginning with Bundle:: as bundles, and everything else as modules or authors. The following is a listing of the interactive CPAN commands.

?
?

Displays brief help message. Same as h command.

!
! perl-code

evals a Perl command.

a
a [authorlist]

Searches for CPAN authors. Arguments can be strings that must be matched exactly or regular expressions, which must be enclosed in slashes and are matched in case-insensitive fashion. With no arguments, it returns a list of all authors, by CPAN ID. With arguments, it returns a list of authors if there is more than one that matches the criteria, or it returns additional information if a single author is returned. String and regular expression arguments can be combined in the same command.

cpan> a /^nv/ LWALL
Author          NVPAT (Nathan V. Patwardhan)
Author          LWALL (Larry Wall. Author of Perl. Busy man.)
cpan> a /^nv/
Author id = NVPAT
    EMAIL        nvp@ora.com
    FULLNAME     Nathan V. Patwardhan
autobundle
autobundle [bundlelist]

Writes a bundle file containing a list of all modules that are both available from CPAN and currently installed within @INC. The file is written to the Bundle subdirectory of cpan_home with a name that contains the current date and a counter—for example, Snapshot_1998_04_27_00.pm. You can use this file as input to the install command to install the latest versions of all the modules on your system:

perl -MCPAN -e 'install Bundle::Snapshot_1998_04_27_00'
b
b [bundlelist]

Searches for CPAN bundles. Arguments are the same as for the a command, except they specify bundles. With a single argument, b displays details about the bundle; with multiple arguments, it displays a list.

clean
clean [arglist]

Does a make clean in the distribution file's directory. arglistcan include one or more modules, bundles, distributions, or one of the values r or u to reinstall or uninstall.

d
d [distriblist]

Displays information about module distributions for the distribution(s) specified in distriblist. Arguments are the same as for the a command. Displays details for a single argument, or a list if the output consists of multiple distributions.

force
force method [arglist]

Takes as a first argument the method to invoke, which can be one of make, test, or install, and executes the command from scratch for each argument in arglist. The arguments may be modules or distributions.

Be warned that force also allows you to install modules that have failed some or all of the module tests. If installing modules that have failed their tests bothers you, then you shouldn't use force.

h
h

Displays brief help message. Same as ?.

i
i [arglist]

Displays information about the arguments specified in arglist, which can be an author, module, bundle, or distribution. Arguments and output are the same as for a.

install
install [arglist]

Installs the arguments specified in arglist, which can be modules or distributions. Implies test. For a distribution, install is run unconditionally. For a module, CPAN.pm checks to see if the module is up-to-date, and if so, prints a message to that effect and does not do the install. Otherwise, it finds and processes the distribution that contains the module.

look
look arg

Takes one argument, which is a module or distribution, gets and untars the distribution file if necessary, changes to the appropriate directory, and opens a subshell process in that directory.

m
m [arglist]

Displays information about modules. Arguments are the same as for the a command. Displays details for a single module, or a list if there is more than one in the output.

make
make [arglist]

Unconditionally runs a make on each argument in arglist, which can be a module or a distribution. For a module, CPAN.pm finds and processes the distribution that contains the module.

o
o type [option] [value]

Sets and queries options. Takes the following arguments:

type
Type of options to set or query. The possible values are:

debug
Debugging options. Prints CPAN module options for debugging the package.

conf
Configuration options. Lists or sets values for CPAN module configuration variables kept in the hash %CPAN::Config. These configuration variables are:

Variable

Content

build_cache

Size of cache for directories to build modules

build_dir

Locally accessible directory to build modules

index_expire

Number of days before refetching index files

cpan_home

Local directory reserved for this package

gzip

Location of external program gzip

inactivity_timeout

Breaks an interactive Makefile.PL after inactivity_timeout seconds of inactivity (set to 0 to never break)

inhibit_startup_message

If true, does not print startup message

keep_source

If set, keeps source in local directory

keep_source_where

Where to keep source

make

Location of external make program

make_arg

Arguments to always pass to make

make_install_arg

Same as make_arg for make install

makepl_arg

Arguments to always pass to perl Makefile.PL

pager

Location of external more program (or other pager)

tar

Location of external tar program

unzip

Location of external unzip program

urllist

Arrayref to nearby CPAN sites (or equivalent locations, such as CD-ROM)

cache_metadata

Uses serializer to cache metadata

prerequisites_policy

Sets behavior for handling module dependencies; options are follow, automatically, ask, and ignore

scan_cache

Controls the cache-scanning behavior; options are atstart and never

wait_list

An arrayref that contains the wait server(s) to try

option
The CPAN module configuration option or options; used with conf. Can be one or more scalar or list options from the table above.

value
Value to be set for a configuration option. The possibilities for o conf are:

o conf scalaropt
Prints current value of scalar option

o conf scalaropt value
Sets scalar option to value

o conf listopt
Prints current value of list option in MakeMaker format

o conf listopt [shift|pop]
Shifts or pops the array in listoptvariable

o conf listopt [unshift|push|splice] list
Works like the corresponding Perl functions to modify the array in listopt based on list

o conf commit
Wites CPAN::Config with updated options

q
q

Quits the CPAN module shell subroutine.

r
r

Recommendations for reinstallation. With no argument, lists all distributions that are out-of-date. With an argument, tells you whether that module or distribution is out-of-date.

readme
readme arglist

Finds and displays the README file for modules or distributions in arglist.

recompile
recompile

Runs full make/test/install cycle over all installed dynamically loadable modules with force in effect. Useful for completing a network installation on systems after the first installation, in which the CPAN module would otherwise declare the modules already up-to-date.

reload
reload arg

Reloads index files or re-eval s CPAN.pm itself. arg may be:

cpan
Re-eval s CPAN.pm.

index
Reloads index of files.

test
test

Runs the make test command.

u
u

Lists all uninstalled distributions.

Previous | Home | Next
2.3. Installing Perl | Book Index | 2.5. Documentation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.5. Documentation

Perl documentation is written in a language known as pod (plain old documentation). Pod is a set of simple tags that can be processed to produce documentation in the style of Unix manpages. There are also several utility programs available that process pod text and generate output in different formats. Pod tags can be intermixed with Perl commands or can be saved in a separate file, which usually has a .pod extension. The pod tags and the utility programs that are included in the Perl distribution are described in Chapter 4, "The Perl Language".

2.5.1. Installing the Documentation

On Unix, the standard Perl installation procedure generates manpages for the Perl documentation from their pod format, although your system administrator might also choose to install the documentation as HTML files. You can also use this procedure to generate manpages for CPAN modules when you install them. You might need to modify your MANPATH environment variable to include the path to the Perl manpages, but then you should be able to read the documentation with the man command. In addition, Perl comes with its own command, perldoc, which formats the pod documentation and displays it. perldoc is particularly useful for reading module documentation, which might not be installed as manpages; you can also use it for reading the core Perl documentation.

The ActiveState Win32 port comes with documentation in HTML format; you can find it in the /docs subdirectory of the distribution. Documentation specific to ActiveState's Perl for Win32 is installed in the /docs/Perl-Win32 subdirectory.

2.5.2. The Perl Manpages

Perl comes with lots of online documentation. To make life easier, the manpages are divided into separate sections so you don't have to wade through hundreds of pages of text to find what you are looking for. You can read them with either the man command or perldoc. Run man perl or perldoc perl to read the top-level page. This page in turn directs you to more specific pages. Or, if you know which page you want, you can go directly there by using:

% man perlvar
or:
% perldoc perlvar

The following table lists the sections in a logical order for reading through them:

Section | Description
perl | Overview (the top level)
perldelta | Changes since previous version
perlfaq | Frequently asked questions
perltoc | Table of contents for Perl documentation
perldata | Data structures
perlsyn | Syntax
perlop | Operators and precedence
perlre | Regular expressions
perlrun | Execution and options
perlfunc | Built-in functions
perlvar | Predefined variables
perlsub | Subroutines
perlmod | How modules work
perlmodlib | How to write and use modules
perlmodinstall | How to install modules from CPAN
perlform | Formats
perllocale | Locale support
perlref | References
perldsc | Data structures introduction
perllol | Data structures: lists of lists
perltoot | OO tutorial
perlobj | Objects
perltie | Objects hidden behind simple variables
perlbot | OO tricks and examples
perlipc | Interprocess communication
perldebug | Debugging
perldiag | Diagnostic messages
perlsec | Security
perltrap | Traps for the unwary
perlport | Portability guide
perlstyle | Style guide
perlpod | Plain old documentation
perlbook | Book information
perlembed | Embedding Perl in your C or C++ application
perlapio | Internal I/O abstraction interface
perlxs | XS application programming interface
perlxstut | XS tutorial
perlguts | Internal functions for those doing extensions
perlcall | Calling conventions from C
perlhist | History records
perlreftut | Perl references short introduction
perlrequick | Perl regular expressions quick start
perllexwarn | Perl warnings and their control
perldebtut | Perl debugging tutorial
perlopentut | Perl open( ) tutorial
perlretut | Perl regular expressions tutorial
perlboot | Perl OO tutorial for beginners
perltootc | Perl OO tutorial, part 2
perlfork | Perl fork( ) information
perlnumber | Perl number semantics
perlthrtut | Perl threads tutorial
perlunicode | Perl unicode support
perlebcdic | Considerations for running Perl on EBCDIC platforms
perlnewmod | Perl modules: preparing a new module for distribution
perlfaq1 | General questions about Perl
perlfaq2 | Obtaining and learning about Perl
perlfaq3 | Programming tools
perlfaq4 | Data manipulation
perlfaq5 | Files and formats
perlfaq6 | Regexes
perlfaq7 | Perl language issues
perlfaq8 | System interaction
perlfaq9 | Networking
perlcompile | Perl compiler suite intro
perldebguts | Perl debugging guts and tips
perlclib | Internal replacements for standard C library functions
perlutil | Utilities packaged with the Perl distribution
perlfilter | Perl source filters
perldbmfilter | Perl DBM filters
perlapi | Perl API listing (autogenerated)
perlintern | Perl internal functions (autogenerated)
perltodo | Perl things to do
perlhack | Perl hackers guide
perl5005delta | Perl changes in Version 5.005
perl5004delta | Perl changes in Version 5.004
perlaix | Perl notes for AIX
perlamiga | Perl notes for Amiga
perlbs2000 | Perl notes for POSIX-BC BS2000
perlcygwin | Perl notes for Cygwin
perldos | Perl notes for DOS
perlepoc | Perl notes for EPOC
perlhpux | Perl notes for HP-UX
perlmachten | Perl notes for Power MachTen
perlmacos | Perl notes for Mac OS (Classic)
perlmpeix | Perl notes for MPE/iX
perlos2 | Perl notes for OS/2
perlos390 | Perl notes for OS/390
perlsolaris | Perl notes for Solaris
perlvmesa | Perl notes for VM/ESA
perlvms | Perl notes for VMS
perlvos | Perl notes for Stratus VOS
perlwin32 | Perl notes for Windows
perl561delta.pod | What's new in Perl v5.6.x (added in 5.8)
perl56delta.pod | What's new in Perl v5.6.0 (added in 5.8)
perl570delta.pod | What's new in Perl v5.7.0 (added in 5.8)
perl571delta.pod | What's new in Perl v5.7.1 (added in 5.8)
perl572delta.pod | What's new in Perl v5.7.2 (added in 5.8)
perlapollo.pod | Perl on Apollo DomainOS (added in 5.8)
perlbeos.pod | Perl on BeOS (added in 5.8)
perlce.pod | Perl on Windows CE (added in 5.8)
perldgux.pod | Perl on DG/UX (added in 5.8)
perlhurd.pod | Perl on GNU Hurd (added in 5.8)
perlintro.pod | A brief introduction and overview of Perl (added in 5.8)
perliol.pod | C API for Perl's implementation of I/O in Layers (added in 5.8)
perlmint.pod | Perl on Atari MiNT (added in 5.8)
perlmodstyle.pod | Perl module style guide (added in 5.8)
perlnetware.pod | Perl on Netware 5.x (added in 5.8)
perlothrtut.pod | Old tutorial on threads in Perl (added in 5.8)
perlpacktut.pod | Tutorial on pack and unpack
perlplan9.pod | Perl on Plan-9 (added in 5.8)
perlpodspec.pod | Plain Old Documentation; format specification and notes (added in 5.8)
perlqnx.pod | Perl on QNX (added in 5.8)
perltooc.pod | Tom's OO Tutorial for Class Data in Perl (added in 5.8)
perltru64.pod | Perl Version 5 on Tru64 systems (added in 5.8)
perluniintro.pod | Perl Unicode introduction (added in 5.8)
perluts.pod | Perl under UTS (added in 5.8)

Previous | Home | Next
2.4. Getting and Installing Modules | Book Index | II. Language Basics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part II. Language Basics

Chapter 3, "The Perl Executable"

Chapter 4, "The Perl Language"

Chapter 5, "Function Reference"

Chapter 6, "Debugging"

Previous | Home | Next
2.5. Documentation | Book Index | 3. The Perl Executable
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 3. The Perl Executable

Contents:

Command Processing
Command-Line Options
Environment Variables
The Perl Compiler
Threads

The perl executable is normally installed in /usr/bin or /usr/local/bin on your machine. Some people often refer to perl as the Perl interpreter, but this isn't strictly correct, as you'll learn shortly.

Every Perl program must be passed through the Perl executable to be executed. The first line in many Perl programs is something like:

#!/usr/bin/perl

For Unix systems, this #! (hash-bang or shebang) line tells the shell to look for the /usr/bin/perl program and pass the rest of the file to that /usr/bin/perl for execution. Sometimes, you'll see different pathnames to the Perl executable, such as /usr/local/bin/perl. You might see perl5 or perl6 instead of perl on sites that still depend on older versions of Perl.

Often, you'll see command-line options tacked on the end of perl, such as the notorious -w switch, which produces warning messages. But almost all Perl programs on Unix start with some variation of #!/usr/bin/perl.

If you get a mysterious "Command not found" error on a Perl program, it's often because the path to the Perl executable is wrong. When you download Perl programs off the Internet, copy them from one machine to another, or copy them out of a book (like this one!). The first thing you should do is make sure that the #! line points to the location of the Perl executable on your system. If you're on a Win32 platform, where the shebang path is used only to check for Perl switches, you should make sure that you run pl2bat.bat on the program so you can run it directly from the command line.

So what does the Perl executable do? It compiles the program internally into a parse tree and executes it immediately. Because the program is not compiled and executed in separate steps, Perl is commonly known as an interpreted language, but this is not quite true.[5]

[5]Unlike strictly compiled languages, the compiled form of a Perl program is not stored as a separate file. However, Versions 5.6 and later give you the option of using a standalone Perl compiler that creates bytecode to be executed separately. We'll say more about the compiler later in this chapter.

So do you call something a Perl "script" or a Perl "program"? Typically, the word "program" is used to describe something that needs to be compiled into assembler or bytecode before executing, as in the C language. The word "script" is used to describe something that runs through an executable on your system, such as the Bourne shell. For Perl, you can use either phrase and only offend those Perl programmers who care about semantics more than you do.

What does all this mean for you? When you write a Perl program, you can just give it a correct #! line at the top of the script, make it executable with chmod +x, and run it. For 95% of Perl programmers in this world, that's all they care about.

3.1. Command Processing

In addition to specifying a #! line, you can specify a short script directly on the command line. Here are some of the possible ways to run Perl:

  • Issue the perl command, writing your script line by line via -e switches on the command line:

    perl -e 'print "Hello, world\n"'    # Unix
perl -e "print \"Hello, world\n\""  # Win32 or Unix
perl -e "print qq[Hello, world\n]"  # Also Win32

  • Issue the perl command, passing Perl the name of your script as the first parameter (after any switches):

    perl testpgm

  • On Unix systems that support the #! notation, specify the Perl command on the #! line, make your script executable, and invoke it from the shell (as described above).

  • Pass your script to Perl via standard input. For example, under Unix:

    echo "print 'Hello, world'" | perl -
% perl
print "Hello, world\n";
^D

  • On Win32 systems, you can associate an extension (e.g., .plx) with a file type and double-click on the icon for a Perl script with that file type. Or, as mentioned earlier, do this:

    (open a "DOS" window)
C:\> (edit your Perl program in your favorite editor)
C:\> pl2bat yourprog.plx
C:\> .\yourprog.bat
(program output here)

    If you are using the ActiveState version of Win32 Perl, the installer normally prompts you to create the association.

  • On Win32 systems, if you double-click on the icon for the Perl executable, you'll find yourself in a command-prompt window with a blinking cursor. You can enter your Perl commands, indicating the end of your input with Ctrl-Z, and Perl will compile and execute your script.

Perl parses the input file from the beginning, unless you've specified the -x switch (see Section 3.2, "Command-Line Options" later in this chapter). If there is a #! line, it is always examined for switches as the line is being parsed. Thus, switches behave consistently regardless of how Perl was invoked.

After locating your script, Perl compiles the entire script into an internal form. If there are any compilation errors, execution of the script is not attempted. If the script is syntactically correct, it is executed. If the script runs off the end without hitting an exit or die operator, an implicit exit(0) is provided to indicate successful completion.

Previous | Home | Next
II. Language Basics | Book Index | 3.2. Command-Line Options
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.2. Command-Line Options

Perl expects any command-line options, also known as switches or flags, to come first on the command line. The next item is usually the name of the script, followed by any additional arguments (often filenames) to be passed into the script. Some of these additional arguments may be switches, but if so, they must be processed by the script, since Perl gives up parsing switches as soon as it sees either a non-switch item or the special -- switch that terminates switch processing.

A single-character switch with no argument may be combined (bundled) with the switch that follows it, if any. For example:

#!/usr/bin/perl -spi.bak

is the same as:

#!/usr/bin/perl -s -p -i.bak

Perl recognizes the switches listed in Table 3-1.

Table 3-1. Perl switches

Switch

Function

--

Terminates switch processing, even if the next argument starts with a minus. It has no other effect.

-0[octnum]

Specifies the record separator ($/) as an octal number. If octnum is not present, the null character is the separator. Other switches may precede or follow the octal number.

-a

Turns on autosplit mode when used with -n or -p. An implicit split of the @F array is inserted as the first command inside the implicit while loop produced by -n or -p. The default field delimiter is whitespace; a different field delimiter may be specified using -F.

-c

Causes Perl to check the syntax of the script and exit without executing it. More or less equivalent to having exit(0) as the first statement in your program.

-d

Runs the script under the Perl debugger. See Chapter 6, "Debugging".

-d:foo

Runs the script under the control of a debugging or tracing module installed in the Perl library as Devel::foo. For example, -d:DProf executes the script using the Devel::DProf profiler. See also the section on DProf in Chapter 6, "Debugging".

-Dnumber

-Dlist

Sets debugging flags. (This works only if debugging was compiled into the version of Perl you are running.) You may specify either a number that is the sum of the bits you want, or a list of letters. To watch how Perl executes your script, for instance, use -D14 or -Dslt. Another useful value is -D1024 (-Dx), which lists your compiled syntax tree. And -D512 (-Dr) displays compiled regular expressions. The numeric value of the flags is available internally as the special variable $^D. Here are the assigned bit values:

Bit

Letter

Meaning

1

p

Tokenizing and parsing

2

s

Stack snapshots

4

l

Label stack processing

8

t

Trace execution

16

o

Object method lookup

32

c

String/numeric conversions

64

P

Print preprocessor command for -P

128

m

Memory allocation

256

f

Format processing

512

r

Regular expression processing

1,024

x

Syntax tree dump

2,048

u

Tainting checks

4,096

L

Memory leaks (not supported anymore)

8,192

H

Hash dump; usurps values

16,384

X

Scratchpad allocation

32,768

D

Cleaning up

-e commandline

May be used to enter one or more lines of script. If -e is used, Perl does not look for the name of a script in the argument list. Multiple -e commands may be given to build up a multiline script. (Make sure to use semicolons where you would in a normal program.)

-Fpattern

Specifies the pattern to split on if -a is also in effect. The pattern may be surrounded by //, '', or ""; otherwise it is put in single quotes. As of Perl 5.8, the -F option is recognized on the #! line.

-h

Prints a summary of Perl's command-line options.

-i[extension]

Specifies that files processed by the <> construct are to be edited in-place. Perl does this by renaming the input file, opening the output file by the original name, and selecting that output file as the default for print statements. The extension, if supplied, is added to the name of the old file to make a backup copy. If no extension is supplied, no backup is made.

-I[directory]

Directories specified by -I are prepended to @INC, which holds the search path for modules. If -P is also specified, to invoke the C preprocessor, -I tells the preprocessor where to search for include files. By default, it searches /usr/include and /usr/lib/perl.

-l[octnum]

Enables automatic line-end processing. This switch has two effects. First, when it's used with -n or -p, it causes the line terminator to be automatically chomp ed. Second, it sets $\ to the value of octnum so any print statements will have a line terminator of ASCII value octnum added back on. If octnum is omitted, $\ is set to the current value of $/, which is typically a newline. So, to trim lines to 80 columns, say this:

perl -lpe 'substr($_, 80) = ""'

-m[-]module

-M[-]module

-M[-]'module ...'

-[mM][-]modulearg[,arg]...

-mmodule

Executes use module before executing your script.

-Mmodule

Executes use module before executing your script. The command is formed by interpolation, so you can use quotes to add extra code after the module name—for example, -M'module qw(foo bar)'. If the first character after the -M or -m is a minus (-), then the use is replaced with no.

You can also say -m module=foo,bar or -Mmodule= foo,bar as a shortcut for -M'module qw(foo bar)'. This avoids the need to use quotes when importing symbols. The actual code generated by -Mmodule=foo,bar is:

use module split(/,/, q{foo,bar})

The = form removes the distinction between -m and -M.

-n

Causes Perl to assume the following loop around your script, which makes it iterate over filename arguments:

LINE:
while (<>) {
   ...      # Your script goes here

By default, the lines are not printed. (See -p to have lines printed.) BEGIN and END blocks may be used to capture control before or after the implicit loop.

-p

Causes Perl to assume the following loop around your script, which makes it iterate over filename arguments:

LINE:
while (<>) {
    ...     # Your script goes here
} continue {
    print;

The lines are printed automatically. To suppress printing, use the -n switch. If both are specified, the -p switch overrides -n. BEGIN and END blocks may be used to capture control before or after the implicit loop.

-P

Causes your script to run through the C preprocessor before compilation by Perl. (Since both comments and cpp directives begin with the # character, you should avoid starting comments with any words recognized by the C preprocessor, such as if, else, or define.)

-s

Enables some rudimentary parsing of switches on the command line after the script name but before any filename arguments or the -- switch terminator. Any switch found there is removed from @ARGV, and a variable of the same name as the switch is set in the Perl script. No switch bundling is allowed, since multicharacter switches are allowed. As of Perl 5.8, -s is recognized on the #! line.

-S

Makes Perl use the PATH environment variable to search for the script (unless the name of the script starts with a slash). Typically, this is used to emulate #! startup on machines that don't support #!.

-t

Forces "taint" checks to be turned on, but warning will be issued instead of fatal errors. Warnings can be controlled with no warnings qw (taint). Designed for use in development only; -T is preferred for production code. New in 5.8.

-T

Forces "taint" checks to be turned on. Ordinarily, these checks are done only when running setuid or setgid. It's a good idea to turn them on explicitly for programs run on another user's behalf, such as CGI programs.

-u

Causes Perl to dump core after compiling your script. You can take this core dump and turn it into an executable file by using the undump program (not supplied). This speeds startup at the expense of some disk space (which you can minimize by stripping the executable). If you want to execute a portion of your script before dumping, use Perl's dump operator instead. Note: availability of undump is platform-specific; it may not be available for a specific port of Perl.

-U

Allows Perl to do unsafe operations. Currently, the only "unsafe"operations are the unlinking of directories while running as superuser and running setuid programs with fatal taint checks turned into warnings.

-v

Prints the version and patch level of your Perl executable.

-V

Prints a summary of the major Perl configuration values and the current value of @INC.

-V:name

Prints the value of the named configuration variable to STDOUT.

-w

Prints warnings about identifiers that are mentioned only once and scalar variables that are used before being set. Also warns about redefined subroutines and references to undefined filehandles or to filehandles opened as read-only that you are attempting to write on. Warns you if you use a non-number as though it was a number, if you use an array as though it was a scalar, if your subroutines recurse more than 100 levels deep, etc.

-x[directory]

Tells Perl to extract a script that is embedded in a message by looking for the first line that starts with #! and contains the string "perl". Any meaningful switches on that line after the word "perl" are applied. If a directory name is specified, Perl switches to that directory before running the script. The script must be terminated with _ _END_ _ or _ _DATA_ _ if there is trailing text to be ignored. (The script can process any or all of the trailing text via the DATA filehandle if desired.)

Previous | Home | Next
3. The Perl Executable | Book Index | 3.3. Environment Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.3. Environment Variables

Environment variables are used to set user preferences. Individual Perl modules or programs are always free to define their own environment variables, and there is also a set of special environment variables used in the CGI environment (see Chapter 9, "CGI Overview").

Perl uses the following environment variables:

HOME
Used if chdir has no argument.

LOGDIR
Used if chdir has no argument and HOME is not set.

PATH
Used in executing subprocesses and in finding the script if -S is used.

PATHEXT
On Win32 systems, if you want to avoid typing the extension every time you execute a Perl script, you can set the PATHEXT environment variable so that it includes Perl scripts. For example:

C:\> set PATHEXT=%PATHEXT%;.PLX

This setting lets you type:

C:\> myscript

without including the file extension. Be careful when setting PATHEXT permanently—it also includes executable file types such as .com, .exe, .bat, and .cmd. If you inadvertently lose those extensions, you'll have difficulty invoking applications and script files.

PERL5LIB
A colon-separated list of directories in which to look for Perl library files before looking in the standard library and the current directory. If PERL5LIB is not defined, PERLLIB is used. When running taint checks, neither variable is used. The script should instead say:

use lib "/my/directory";
PERL5OPT
Command-line options (switches). Switches in this variable are taken as if they were on every Perl command line. Only the -[DIMUdmw] switches are allowed. When running taint checks, this variable is ignored.

PERLLIB
A colon-separated list of directories in which to look for Perl library files before looking in the standard library and the current directory. If PERL5LIB is defined, PERLLIB is not used.

PERL5DB
The command used to load the debugger code. The default is:

BEGIN { require 'perl5db.pl' }
PERL5SHELL
On Win32 systems, may be set to an alternative shell for Perl to use internally to execute "backtick" commands or the system function.

PERL_DEBUG_MSTATS
Relevant only if your Perl executable was built with -DDEBUGGING_MSTATS. If set, causes memory statistics to be dumped after execution. If set to an integer greater than 1, it also causes memory statistics to be dumped after compilation.

PERL_DESTRUCT_LEVEL
Relevant only if your Perl executable was built with -DDEBUGGING. Controls the behavior of global destruction of objects and other references.

Perl also has environment variables that control how Perl handles data specific to particular natural languages. See the perllocale manpage.

Previous | Home | Next
3.2. Command-Line Options | Book Index | 3.4. The Perl Compiler
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.4. The Perl Compiler

Starting with Perl 5.005, the Perl compiler became part of the standard Perl distribution. You'll find that with Perl 5.6 and later, the Perl compiler has become far more stable. The compiler allows you to distribute Perl programs in binary form, which enables easy packaging of Perl-based programs without relying on the source machine to have the correct version of Perl and the correct modules installed. After the initial compilation, running a compiled program should be faster because it doesn't have to be recompiled each time it's run. However, you shouldn't expect that the compiled code itself will run faster than the original Perl source or that the executable will be smaller—in reality, the executable file is likely to be significantly bigger.

This initial release of the compiler is still considered to be a beta version. It's distributed as an extension module, B, that comes with the following backends:

Bytecode
Translates a script into platform-independent Perl bytecode.

C
Translates a Perl script into C code.

CC
Translates a Perl script into optimized C code.

Deparse
Regenerates Perl source code from a compiled program.

Lint
Extends the Perl -w option. Named after the Unix Lint program-checker.

Showlex
Shows lexical variables used in functions or files.

Xref
Creates a cross-reference listing for a program.

Once you've generated the C code with either the C or the CC backend, you run the cc_harness program to compile it into an executable. There is also a byteperl interpreter that lets you run the code you've generated with the Bytecode backend.

Here's an example that takes a simple "Hello world" program and uses the CC backend to generate C code:

% perl -MO=CC,-ohi.c hi.pl
hi.pl syntax OK
% perl cc_harness -O2 -ohi hi.c
# You may have to provide the full path of where cc_harness lives
gcc -B/usr/ccs/bin/ -D_REENTRANT -DDEBUGGING -I/usr/local/include
-I/usr/local/lib/perl5/sun4-solaris-thread/5.00466/CORE -O2 -ohi hi.c
-L/usr/local/lib /usr/local/lib/perl5/sun4-solaris-thread/5.00466/CORE/libperl.a
-lsocket -lnsl -lgdbm -ldl -lm -lposix4 -lpthread -lc -lcrypt
% hi
Hi there, world!

The compiler also comes with a frontend, perlcc. You can use it to compile code into a standalone executable or compile a module (a .pm file) into a shared object (an .so file) that can be included in a Perl program via use. For example:

% perlcc a.p         # Compiles into the executable 'a'
% perlcc A.pm        # Compiles into A.so

The following options can be used with perlcc:

-argv arguments
Used with -run or -e. Passes the string arguments to the executable as @ARGV.

-C c_code_name
Gives the name c_code_name to the generated C code that will be compiled. Valid only if you are compiling one file on the command line.

-e perl_line_to_execute
Works like perl -e to compile "one-liners." The default is to compile and run the code. With -o, it saves the resulting executable.

-gen
Creates the intermediate C code but doesn't compile the results; does an implicit -sav.

-I include_directories
Adds directories inside include_directories to the compilation command.

-L library_directories
Adds directories in library_directories to the compilation command.

-log logname
Opens a log file (for append) for saving text from a compile command.

-mod
Tells perlcc to compile the files given at the command line as modules. Usually used with module files that don't end with .pm.

-o executable_name
Gives the name executable_name to the executable that will be compiled. Only valid if compiling one file on the command line.

-prog
Tells perlcc to compile the files given at the command line as programs. Usually used with program files that don't end with a .p, .pl, or .bat extension.

-regex rename_regex
Provides the rule rename_regex for creating executable filenames, in which rename_regex is a Perl regular expression.

-run
Immediately runs the generated Perl code. Note that the rest of @ARGV is interpreted as arguments to the program being compiled.

-sav
Tells Perl to save the intermediate C code.

-verbose verbose_level
Compiles verbosely, setting verbose_level to control the degree of verbosity. verbose_level can be given as either a sum of bits or a list of letters. Values are listed in the following table.

Bit

Letter

Action

1

g

Code generation errors to STDERR.

2

a

Compilation errors to STDERR.

4

t

Descriptive text to STDERR.

8

f

Code generation errors to file. Requires -log.

16

c

Compilation errors to file. Requires -log.

32

d

Descriptive text to file. Requires -log.

With -log, the default level is 63; otherwise the default level is 7.

There are two environment variables that you can set for perlcc: PERL_SCRIPT_EXT and PERL_MODULE_EXT. These can be used to modify the default extensions that perlcc recognizes for programs and modules. The variables take colon-separated Perl regular expressions.

The modules that comprise the compiler are described in Chapter 8, "Standard Modules". Also see the documentation that comes with the compiler, which includes more complete information on installing and using it.

Previous | Home | Next
3.3. Environment Variables | Book Index | 3.5. Threads
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.5. Threads

Perl 5.6 and later also include native multithreading capability, which is distributed with Perl as a set of modules. The threads modules have improved since the 5.005 release, but should still be considered an experimental feature and aren't automatically compiled in with Perl.

WARNING: Pay close attention to Configure when you build Perl so that you don't include threads support if you don't want it.

You might want to build a separate version of Perl with threads enabled, if you'd like to test the threads feature under your platform.

Chapter 8, "Standard Modules" describes the individual thread modules. For information on using threads, refer to the perlthrtut manpage (included with more recent distributions of Perl).

Previous | Home | Next
3.4. The Perl Compiler | Book Index | 4. The Perl Language
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 4. The Perl Language

Contents:

Program Structure
Data Types and Variables
Statements
Special Variables
Operators
Regular Expressions
Subroutines
References and Complex Data Structures
Filehandles
Signals
Unicode
Formats
Pod

This chapter is a quick and merciless guide to the Perl language itself. If you're trying to learn Perl from scratch and would prefer to be taught rather than to have things thrown at you, then you might be better off with Learning Perl, 3rd Edition by Randal L. Schwartz and Tom Phoenix. However, if you already know some other programming languages and just want to learn the particulars of Perl, this chapter is for you. Sit tight, and forgive us for being terse—we have a lot of ground to cover.

If you want a more complete discussion of the Perl language and its idiosyncrasies (and we mean complete), see Programming Perl, 3rd Edition by Larry Wall, Tom Christiansen, and Jon Orwant.

4.1. Program Structure

Perl is a particularly forgiving language, as far as program layout goes. There are no rules about indentation, newlines, etc. Most lines end with semicolons, but not everything has to. Most things don't have to be declared, except for a couple of things that do. Here are the bare essentials:

Whitespace
Whitespace is required only between items that would otherwise be confused as a single term. All types of whitespace—spaces, tabs, newlines, etc.—are equivalent in this context. A comment counts as whitespace. Different types of whitespace are distinguishable within quoted strings, formats, and certain line-oriented forms of quoting. For example, in a quoted string, a newline, a space, and a tab are interpreted as unique characters.

Semicolons
Every simple statement must end with a semicolon. Compound statements contain brace-delimited blocks of other statements and do not require terminating semicolons after the ending brace. A final simple statement in a block also does not require a semicolon.

Declarations
Only subroutines and report formats need to be explicitly declared. All other user-created objects are automatically created with a null or 0 value unless they are defined by some explicit operation such as assignment. The -w command-line switch will warn you about using undefined values.

You may force yourself to declare your variables by including the use strict pragma in your programs (see Chapter 8, "Standard Modules" for more information on pragmas and strict in particular). This causes an error if you do not explicitly declare your variables.

Comments and documentation
Comments within a program are indicated by a pound sign (#). Everything following a pound sign to the end of the line is interpreted as a comment.

Lines starting with = are interpreted as the start of a section of embedded documentation (pod), and all subsequent lines until the next =cut are ignored by the compiler. See Section 4.12, "Formats" later in this chapter for more information on pod format.

Previous | Home | Next
3.5. Threads | Book Index | 4.2. Data Types and Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.2. Data Types and Variables

Perl has three basic data types: scalars, arrays, and hashes.

Scalars are essentially simple variables. They are preceded by a dollar sign ($). A scalar is either a number, a string, or a reference. (A reference is a scalar that points to another piece of data. References are discussed later in this chapter.) If you provide a string in which a number is expected or vice versa, Perl automatically converts the operand using fairly intuitive rules.

Arrays are ordered lists of scalars accessed with a numeric subscript (subscripts start at 0). They are preceded by an "at" sign (@).

Hashes are unordered sets of key/value pairs accessed with the keys as subscripts. They are preceded by a percent sign (%).

4.2.1. Numbers

Perl stores numbers internally as either signed integers or double-precision, floating-point values. Numeric literals are specified by any of the following floating-point or integer formats:

12345
Integer

-54321
Negative integer

12345.67
Floating point

6.02E23
Scientific notation

0xffff
Hexadecimal

0377
Octal

4_294_967_296
Underline for legibility

Since Perl uses the comma as a list separator, you cannot use a comma for improving the legibility of a large number. To improve legibility, Perl allows you to use an underscore character instead. The underscore works only within literal numbers specified in your program, not in strings functioning as numbers or in data read from somewhere else. Similarly, the leading 0x for hex and 0 for octal work only for literals. The automatic conversion of a string to a number does not recognize these prefixes—you must do an explicit conversion.

Be aware that in Perl 5.8, there are many changes in how Perl deals with integers and floating-point numbers. Regardless of how your system handles numbers and conversion between characters and numbers, Perl 5.8 works around system deficiencies to force more accurate number handling. Furthermore, whereas prior to 5.8 Perl used floating-point numbers exclusively in math operations, Perl 5.8 now uses and stores integers in numeric conversions and in arithmetic operations.

4.2.2. String Interpolation

Strings are sequences of characters. String literals are usually delimited by either single (') or double (") quotes. Double-quoted string literals are subject to backslash and variable interpolation, and single-quoted strings are not (except for \' and \\, used to put single quotes and backslashes into single-quoted strings). You can embed newlines directly in your strings.

Table 4-1 lists all the backslashed or escape characters that can be used in double-quoted strings.

Table 4-1. Double-quoted string representations

Code | Meaning
\n | Newline
\r | Carriage return
\t | Horizontal tab
\f | Form feed
\b | Backspace
\a | Alert (bell)
\e | ESC character
\033 | ESC in octal
\x7f | DEL in hexadecimal
\cC | Ctrl-C
\\ | Backslash
\" | Double quote
\u | Force next character to uppercase
\l | Force next character to lowercase
\U | Force all following characters to uppercase
\L | Force all following characters to lowercase
\Q | Backslash all following non-alphanumeric characters
\E | End \U, \L, or \Q

Table 4-2 lists alternative quoting schemes that can be used in Perl. These are useful in diminishing the number of commas and quotes you may have to type, and they allow you not to worry about escaping characters such as backslashes when there are many instances in your data. The generic forms allow you to use any non-alphanumeric, non-whitespace characters as delimiters in place of the slash (/). If the delimiters are single quotes, no variable interpolation is done on the pattern. Parentheses, brackets, braces, and angle brackets can be used as delimiters in their standard opening and closing pairs.

Table 4-2. Quoting syntax in Perl

Customary | Generic | Meaning | Interpolation
'' | q// | Literal | No
"" | qq// | Literal | Yes
'' | qx// | Command | Yes
( ) | qw// | Word list | No
( ) | qr// | Pattern | Yes
// | m// | Pattern match | Yes
s/// | s/// | Substitution | Yes
y/// | tr/// | Translation | No

4.2.3. Here Documents

A line-oriented form of quoting is based on the Unix shell "here-document" syntax. Following a <<, you specify a string to terminate the quoted material, and all lines following the current line down to the terminating string are the value of the item. This is of particular importance if you're trying to print something like HTML that would be cleaner to print as a chunk instead of as individual lines. For example:

#!/usr/local/bin/perl -w

my $Price = 'right';

print <<"EOF";
The price is $Price.
EOF

The terminating string does not have to be quoted. For example, the previous example could have been written as:

#!/usr/local/bin/perl -w

my $Price = 'right';

print <<EOF;
The price is $Price.
EOF

You can assign here documents to a string:

my $assign_this_heredoc =<< "EOS";
This string is assigned to $whatever.
EOS

You can use a here document to execute commands:

#!/usr/local/bin/perl -w

print <<`CMD`;
ls -l
CMD

You can stack here documents:

#!/usr/local/bin/perl -w

print <<"joe", <<"momma"; # You can stack them
I said foo.
joe
I said bar.
momma

One caveat about here documents: you may have noticed in each of these examples that the quoted text is always left-justified. That's because any whitespace used for indentation will be included in the string. For example:

#!/usr/local/bin/perl -w

print <<"    INDENTED";
    Same old, same old.
    INDENTED

Although you can use a trick of including whitespace in the terminating tag to keep it indented (as we did here), the string itself will have the whitespace embedded—in this case, it will be Same old, same old..

4.2.4. Lists

A list is an ordered group of scalar values. A literal list can be composed as a comma-separated list of values contained in parentheses, for example:

(1,2,3)                  # Array of three values 1, 2, and 3
("one","two","three")    # Array of three values "one", "two", and "three"

The generic form of list creation uses the quoting operator qw// to contain a list of values separated by whitespace:

qw/snap crackle pop/

With the quoting operators, you're not limited to // when you use one of the operators. You can use just about any character you want. The following is exactly the same as the example above:

qw!snap crackle pop!

It's important that you remember not to use any delimiters except whitespace with qw//. If you do, these delimiters will be handled as list members:

@foods = qw/fish, beef, lettuce, cat, apple/; # EL WRONG-O!
foreach (@foods) {
    print $_; # Prints fish and then a literal comma, etc.
}

4.2.5. Variables

A variable always begins with the character that identifies its type: $, @, or %. Most of the variable names you create can begin with a letter or underscore, followed by any combination of letters, digits, or underscores, up to 255 characters in length. Upper- and lowercase letters are distinct. Variable names that begin with a digit can contain only digits, and variable names that begin with a character other than an alphanumeric or underscore can contain only that character. The latter forms are usually predefined variables in Perl, so it is best to name your variables beginning with a letter or underscore.

Variables have the undef value before they are first assigned or when they become "empty." For scalar variables, undef evaluates to 0 when used as a number, and a zero-length, empty string ("") when used as a string.

Simple variable assignment uses the assignment operator (=) with the appropriate data. For example:

$age = 26;                # Assigns 26 to $age
@date = (8, 24, 70);      # Assigns the three-element list to @date
%fruit = ('apples', 3, 'oranges', 6);
 # Assigns the list elements to %fruit in key/value pairs

Scalar variables are always named with an initial $, even when referring to a scalar value that is part of an array or hash.

Every variable type has its own namespace. You can, without fear of conflict, use the same name for a scalar variable, an array, or a hash (or, for that matter, a filehandle, a subroutine name, or a label). This means that $foo and @foo are two different variables. It also means that $foo[1] is an element of @foo, not a part of $foo.

4.2.5.1. Arrays

An array is a variable that stores an ordered list of scalar values. Arrays are preceded by an "at" sign (@).

@numbers = (1,2,3);        # Set the array @numbers to (1,2,3)

To refer to a single element of an array, use the dollar sign ($) with the variable name (it's a scalar), followed by the index of the element in square brackets (the subscript operator). Array elements are numbered starting at 0. Negative indexes count backwards from the last element in the list (i.e., -1 refers to the last element of the list). For example, in this list:

@date = (8, 24, 70);

$date[2] is the value of the third element, 70.

4.2.5.2. Hashes

A hash is a set of key/value pairs. Hashes are preceded by a percent sign (%). To refer to a single element of a hash, you use the hash variable name followed by the "key" associated with the value in braces. For example, the hash:

%fruit = ('apples', 3, 'oranges', 6);

has two values (in key/value pairs). If you want to get the value associated with the key apples, you use $fruit{'apples'}.

It is often more readable to use the => operator in defining key/value pairs. The => operator is similar to a comma, but it's more visually distinctive and quotes any bare identifiers to the left of it:

%fruit = (
    apples  => 3,
    oranges => 6
);

4.2.6. Scalar and List Contexts

Every operation that you invoke in a Perl script is evaluated in a specific context, and how that operation behaves may depend on the context it is being called in. There are two major contexts: scalar and list. All operators know which context they are in, and some return lists in contexts wanting a list and scalars in contexts wanting a scalar. For example, the localtime function returns a nine-element list in list context:

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( );

But in a scalar context, localtime returns the number of seconds since January 1, 1970:

$now = localtime( );

Statements that look confusing are easy to evaluate by identifying the proper context. For example, assigning what is commonly a list literal to a scalar variable:

$a = (2, 4, 6, 8);

gives $a the value 8. The context forces the right side to evaluate to a scalar, and the action of the comma operator in the expression (in the scalar context) returns the value farthest to the right.

Another type of statement that might be confusing is the evaluation of an array or hash variable as a scalar. For example:

$b = @c;

When an array variable is evaluated as a scalar, the number of elements in the array is returned. This type of evaluation is useful for finding the number of elements in an array. The special $#array form of an array value returns the index of the last member of the list (one less than the number of elements).

If necessary, you can force a scalar context in the middle of a list by using the scalar function.

4.2.7. Declarations and Scope

In Perl, only subroutines and formats require explicit declaration. Variables (and similar constructs) are automatically created when they are first assigned.

Variable declaration comes into play when you need to limit the scope of a variable's use. You can do this in two ways:

Dynamic scoping
Creates temporary objects within a scope. Dynamically scoped constructs are visible globally, but take action only within their defined scopes. Dynamic scoping applies to variables declared with local.

Lexical scoping
Creates private constructs that are visible only within their scopes. The most frequently seen form of lexically scoped declaration is the declaration of my variables.

Therefore, we can say that a local variable is dynamically scoped, whereas a my variable is lexically scoped. Dynamically scoped variables are visible to functions called from within the block in which they are declared. Lexically scoped variables, on the other hand, are totally hidden from the outside world, including any called subroutines, unless they are declared within the same scope. See Section 4.7, "Subroutines" later in this chapter for further discussion.

Previous | Home | Next
4. The Perl Language | Book Index | 4.3. Statements
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.3. Statements

A simple statement is an expression evaluated for its side effects. Every simple statement must end in a semicolon, unless it is the final statement in a block.

A sequence of statements that defines a scope is called a block. Generally, a block is delimited by braces, or { }. Compound statements are built out of expressions and blocks. A conditional expression is evaluated to determine whether a statement block will be executed. Compound statements are defined in terms of blocks, not statements, which means that braces are required.

Any block can be given a label. Labels are identifiers that follow the variable-naming rules (i.e., they begin with a letter or underscore and can contain alphanumerics and underscores). They are placed just before the block and are followed by a colon, such as SOMELABEL here:

SOMELABEL: {
  ...statements...
  }

By convention, labels are all uppercase, so as not to conflict with reserved words. Labels are used with the loop control commands next, last, and redo to alter the flow of execution in your programs.

4.3.1. Conditionals and Loops

The if and unless statements execute blocks of code depending on whether a condition is met. These statements take the following forms:

if (expression) {block} else {block}

unless (expression) {block} else {block}

if (expression1) {block}
elsif (expression2) {block}
  ...
elsif (lastexpression) {block}
else {block}

4.3.1.1. while loops

The while statement repeatedly executes a block as long as its conditional expression is true. For example:

while (<INFILE>) {
    chomp;
    print OUTFILE, "$_\n";
}

This loop reads each line from the file opened with the filehandle INFILE and prints them to the OUTFILE filehandle. The loop will cease when it encounters an end-of-file.

If the word while is replaced by the word until, the sense of the test is reversed. The conditional is still tested before the first iteration, though.

The while statement has an optional extra block on the end called a continue block. This block is executed before every successive iteration of the loop, even if the main while block is exited early by the loop control command next. However, the continue block is not executed if the main block is exited by a last statement. The continue block is always executed before the conditional is reevaluated.

4.3.1.2. for loops

The for loop has three semicolon-separated expressions within its parentheses. These three expressions function respectively as the initialization, the condition, and the reinitialization expressions of the loop. The for loop can be defined in terms of the corresponding while loop:

for ($i = 1; $i < 10; $i++) {
    ...
}

This is the same as:

$i = 1;
while ($i < 10) {
    ...
}
continue {
    $i++;
}

4.3.1.3. foreach loops

The foreach loop iterates over a list value and sets the control variable (var) to be each element of the list in turn:

foreach var (list) {
    ...
}

Like the while statement, the foreach statement can also take a continue block.

4.3.1.4. Modifiers

Any simple statement may be followed by a single modifier that gives the statement a conditional or looping mechanism. This syntax provides a simpler and often more elegant method than using the corresponding compound statements. These modifiers are:

statement if EXPR;
statement unless EXPR;
statement while EXPR;
statement until EXPR;

For example:

$i = $num if ($num < 50); # $i will be less than 50
$j = $cnt unless ($cnt < 100); # $j will equal 100 or greater
$lines++ while <FILE>;
print "$_\n" until /The end/;

The conditional is evaluated first with the while and until modifiers except when applied to ado {} statement, in which case the block executes once before the conditional is evaluated. For example:

do {
    $line = <STDIN>;
    ...
} until $line eq ".\n";

For more information on do, see Chapter 5, "Function Reference".

4.3.1.5. Loop control

You can put a label on a loop to give it a name. The loop's label identifies the loop for the loop-control commands next, last, and redo:

LINE: while (<SCRIPT>) {
    print;
    next LINE if /^#/;      # Discard comments
    }

The syntax for the loop-control commands is:

last label
next label
redo label

If the label is omitted, the loop-control command refers to the innermost enclosing loop.

The last command is like the break statement in C (as used in loops); it immediately exits the loop in question. The continue block, if any, is not executed.

The next command is like the continue statement in C; it skips the rest of the current iteration and starts the next iteration of the loop. If there is a continue block on the loop, it is always executed just before the conditional is reevaluated.

The redo command restarts the loop block without evaluating the conditional again. The continue block, if any, is not executed.

4.3.1.6. goto

Perl supports a goto command. There are three forms: goto label, goto expr, and goto &name. In general, you shouldn't need to use goto, which you'll conclude if you do a search for goto in the comp.lang.perl.misc archives on groups.google.com.

The goto label form finds the statement labeled with label and resumes execution there. It may not be used to go inside any construct that requires initialization, such as a subroutine or a foreach loop.

The goto expr form expects the expression to return a label name.

The goto &name form substitutes a call to the named subroutine for the currently running subroutine.

Previous | Home | Next
4.2. Data Types and Variables | Book Index | 4.4. Special Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.4. Special Variables

Some variables have a predefined, special meaning in Perl. They use punctuation characters after the usual variable indicator ($, @, or %), such as $_. The explicit, long-form names are the variables' equivalents when you use the English module by including use English; at the top of your program.

4.4.1. Global Special Variables

The most common special variable is $_, which contains the default input and pattern-searching string. For example:

foreach ('hickory','dickory','doc') {
        print;
}

The first time the loop is executed, "hickory" is printed. The second time around, "dickory" is printed, and the third time, "doc" is printed. That's because in each iteration of the loop, the current string is placed in $_ and is used by default by print. Here are the places where Perl will assume $_, even if you don't specify it:

  • Various unary functions, including functions such as ord and int, as well as the all file tests (-f, -d), except for -t, which defaults to STDIN.

  • Various list functions such as print and unlink.

  • The pattern-matching operations m//, s///, and tr/// when used without an =~ operator.

  • The default iterator variable in a foreach loop if no other variable is supplied.

  • The implicit iterator variable in the grep and map functions.

  • The default place to put an input record when a line-input operation's result is tested by itself as the sole criterion of a while test (i.e., <filehandle>). Note that outside of a while test, this does not happen.

The following is a complete listing of global special variables:

$_
$ARG
The default input and pattern-searching space.

$.
$INPUT_LINE_NUMBER
$NR
The current input line number of the last filehandle that was read. An explicit close on the filehandle resets the line number.

$/
$INPUT_RECORD_SEPARATOR
$RS
The input record separator; newline by default. If set to the null string, it treats blank lines as delimiters.

$,
$OUTPUT_FIELD_SEPARATOR
$OFS
The output field separator for the print operator.

$\
$OUTPUT_RECORD_SEPARATOR
$ORS
The output record separator for the print operator.

$
$LIST_SEPARATOR
Like $, except that it applies to list values interpolated into a double-quoted string (or similar interpreted string). Default is a space.

$;
$SUBSCRIPT_SEPARATOR
$SUBSEP
The subscript separator for multidimensional array emulation. Default is \034.

$^L
$FORMAT_FORMFEED
What a format outputs to perform a formfeed. Default is \f.

$:
$FORMAT_LINE_BREAK_CHARACTERS
The current set of characters after which a string may be broken to fill continuation fields (starting with ^) in a format. Default is \n".

$^A
$ACCUMULATOR
The current value of the write accumulator for format lines.

$#
$OFMT
Contains the output format for printed numbers (deprecated).

$?
$CHILD_ERROR
The status returned by the last pipe close, backtick ('') command, or system operator.

$!
$OS_ERROR
$ERRNO
If used in a numeric context, yields the current value of the errno variable, identifying the last system call error. If used in a string context, yields the corresponding system error string.

$@
$EVAL_ERROR
The Perl syntax error message from the last eval command.

$$
$PROCESS_ID
$PID
The pid of the Perl process running this script.

$<
$REAL_USER_ID
$UID
The real user ID (uid) of this process.

$>
$EFFECTIVE_USER_ID
$EUID
The effective uid of this process.

$(
$REAL_GROUP_ID
$GID
The real group ID (gid) of this process.

$)
$EFFECTIVE_GROUP_ID
$EGID
The effective gid of this process.

$0
$PROGRAM_NAME
Contains the name of the file containing the Perl script being executed.

$[
The index of the first element in an array and of the first character in a substring. Default is 0.

$]
$PERL_VERSION
Returns the version plus patch level divided by 1,000.

$^D
$DEBUGGING
The current value of the debugging flags.

$^E
$EXTENDED_OS_ERROR
Extended error message on some platforms.

$^F
$SYSTEM_FD_MAX
The maximum system file descriptor, ordinarily 2.

$^H
Contains internal compiler hints enabled by certain pragmatic modules.

$^I
$INPLACE_EDIT
The current value of the inplace-edit extension. Use undef to disable inplace editing.

$^M
The contents of $M can be used as an emergency memory pool in case Perl die s with an out-of-memory error. Use of $M requires a special compilation of Perl. See the INSTALL document for more information.

$^O
$OSNAME
Contains the name of the operating system for which the current Perl binary was compiled.

$^P
$PERLDB
The internal flag that the debugger clears so that it doesn't debug itself.

$^T
$BASETIME
The time at which the script began running, in seconds since the epoch.

$^W
$WARNING
The current value of the warning switch, either true or false.

$^X
$EXECUTABLE_NAME
The name that the Perl binary itself was executed as. As of Perl 5.8, Perl asks the operating system instead of using C's argv[0].

$ARGV
Contains the name of the current file when reading from <ARGV>.

4.4.2. Global Special Arrays and Hashes
@ARGV
The array containing the command-line arguments intended for the script.

@INC
The array containing the list of places to look for Perl scripts to be evaluated by the do, require, or use constructs.

@F
The array into which the input lines are split when the -a command-line switch is given.

%INC
The hash containing entries for the filename of each file that has been included via do or require.

%ENV
The hash containing your current environment.

%SIG
The hash used to set signal handlers for various signals.

4.4.3. Global Special Filehandles
ARGV
The special filehandle that iterates over command-line filenames in @ARGV. Usually written as the null filehandle in <>.

STDERR
The special filehandle for standard error in any package.

STDIN
The special filehandle for standard input in any package.

STDOUT
The special filehandle for standard output in any package.

DATA
The special filehandle that refers to anything following the _ _END_ _ token in the file containing the script. Or the special filehandle for anything following the _ _DATA_ _ token in a required file, as long as you're reading data in the same package _ _DATA_ _ was found in.

_ (underscore)
The special filehandle used to cache the information from the last stat, lstat, or file test operator.

4.4.4. Global Special Constants
_ _END_ _
Indicates the logical end of your program. Any following text is ignored, but may be read via the DATA filehandle.

_ _FILE_ _
Represents the filename at the point in your program where it's used. Not interpolated into strings.

_ _LINE_ _
Represents the current line number. Not interpolated into strings.

_ _PACKAGE_ _
Represents the current package name at compile time, or undefined if there is no current package. Not interpolated into strings.

4.4.5. Regular Expression Special Variables

For more information on regular expressions, see Section 4.6, "Regular Expressions" later in this chapter.

$digit
Contains the text matched by the corresponding set of parentheses in the last pattern matched. For example, $1 matches whatever was contained in the first set of parentheses in the previous regular expression.

$&
$MATCH
The string matched by the last successful pattern match.

$'
$PREMATCH
The string preceding whatever was matched by the last successful pattern match.

$'
$POSTMATCH
The string following whatever was matched by the last successful pattern match.

$+
$LAST_PAREN_MATCH
The last bracket matched by the last search pattern. This is useful if you don't know which of a set of alternative patterns was matched. For example:

/Version: (.*)|Revision: (.*)/ && ($rev = $+);
$^N
The string matched by the most recently closed group. This is most useful inside (?{ . . . }) blocks for examining matched text. If you have multiple matches denoted by parentheses, $^N can be used in lieu of $1, $2, $3, etc., so you don't have to manually count the number of sets of parentheses that denote your matches. For example:

#!/usr/local/bin/perl -w

$words = "person|here";
$words =~ /(\w+)\|(\w+)/;
print $^N;   # Prints 'here'

4.4.6. Filehandle Special Variables

Most of these variables apply only when using formats. See Section 4.11, "Unicode" later in this chapter.

$|
$OUTPUT_AUTOFLUSH
If set to nonzero, forces an fflush(3) after every write or print on the currently selected output channel.

$%
$FORMAT_PAGE_NUMBER
The current page number of the currently selected output channel.

$=
$FORMAT_LINES_PER_PAGE
The current page length (printable lines) of the currently selected output channel. Default is 60.

$-
$FORMAT_LINES_LEFT
The number of lines left on the page of the currently selected output channel.

$~
$FORMAT_NAME
The name of the current report format for the currently selected output channel. Default is the name of the filehandle.

$^
$FORMAT_TOP_NAME
The name of the current top-of-page format for the currently selected output channel. Default is the name of the filehandle with _TOP appended.

Previous | Home | Next
4.3. Statements | Book Index | 4.5. Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.5. Operators

Table 4-3 lists all the Perl operators from highest to lowest precedence and indicates their associativity.

Table 4-3. Perl associativity and operators, listed by precedence

Associativity | Operators
Left | Terms and list operators (leftward)
Left | -> (method call, dereference)
Nonassociative | ++ -- (autoincrement, autodecrement)
Right | ** (exponentiation)
Right | ! ~ \ and unary + and - (logical not, bit-not, reference, unary plus, unary minus)
Left | =~ !~ (matches, doesn't match)
Left | * / % x (multiply, divide, modulus, string replicate)
Left | + - . (addition, subtraction, string concatenation)
Left | << >> (left bit-shift, right bit-shift)
Nonassociative | Named unary operators and file-test operators
Nonassociative | < > <= >= lt gt le ge (less than, greater than, less than or equal to, greater than or equal to, and their string equivalents)
Nonassociative | == != <=> eq ne cmp (equal to, not equal to, signed comparison, and their string equivalents)
Left | & (bit-and)
Left | | ^ (bit-or, bit-xor)
Left | && (logical AND)
Left | || (logical OR)
Nonassociative | .. ... (range)
Right | ?: (ternary conditional)
Right | = += -= *= and so on (assignment operators)
Left | , => (comma, arrow comma)
Nonassociative | List operators (rightward)
Right | not (logical not)
Left | and (logical and)
Left | or xor (logical or, xor)

You can clarify your expressions by using parentheses to group any part of an expression. Anything in parentheses will be evaluated as a single unit within a larger expression.

With very few exceptions, Perl operators act upon scalar values only, not upon list values.

Terms that take highest precedence in Perl include variables, quote and quotelike operators, any expression in parentheses, and any function with arguments in parentheses.

A list operator is a function that can take a list of values as its argument. List operators take highest precedence when considering what's to the left of them. They have considerably lower precedence when looking to their right, which is the expected result.

Also parsed as high-precedence terms are the do{} and eval{} constructs, as well as subroutine and method calls, the anonymous array and hash composers ([] and {}), and the anonymous subroutine composer sub{}.

A unary operator is a function that takes a single scalar value as its argument. Unary operators have a lower precedence than list operators because they expect and take only one value.

4.5.1. The Arrow Operator

The arrow operator is a dereference operator. It can be used for references to arrays, hashes, code references, or for calling methods on objects. See the discussion of references in Chapter 7, "Packages, Modules, and Objects".

4.5.2. Unary Operators

Unary ! performs logical negation, that is, "not." The not operator is a lower-precedence version of !.

Unary - performs arithmetic negation if the operand is numeric. If the operand is an identifier, then a string consisting of a minus sign concatenated with the identifier is returned. Otherwise, if the string starts with a plus or minus, a string starting with the opposite sign is returned.

Unary ~ performs bitwise negation, that is, one's complement. For example, on a 32-bit machine, ~0xFF is 0xFFFFFF00. If the argument to ~ is a string instead of a number, a string of identical length is returned, but with all the bits of the string complemented.

Unary + has no semantic effect whatsoever, even on strings. It is syntactically useful for separating a function name from a parenthesized expression that would otherwise be interpreted as the complete list of function arguments.

Unary \ creates a reference to whatever follows it (see Section 4.8, "References and Complex Data Structures" later in this chapter). Do not confuse this behavior with the behavior of the backslash within a string. The \ operator may also be used on a parenthesized list value in a list context, in which case it returns references to each element of the list.

4.5.3. Arithmetic Operators

Binary ** is the exponentiation operator. Note that it binds even more tightly than unary minus, so -2**4 is -(2**4), not (-2)**4. Also note that ** has right associativity, so:

$e = 2 ** 3 ** 4;

evaluates to 2 to the 81st power, not 8 to the 4th power.

The * (multiply) and / (divide) operators work exactly as you might expect, multiplying or dividing their two operands. Division is done in floating-point mode, unless integer mode in enabled (via use integer).

The % (modulus) operator converts its operands to integers before finding the remainder according to integer division. For the same operation in floating-point mode, you may prefer to use the fmod( ) function from the POSIX module (see Chapter 8, "Standard Modules").

4.5.4. Comparison Operators

Comparison operators can be categorized into relational and equality operators.

4.5.4.1. Relational operators

Perl has two classes of relational operators. One class operates on numeric values, and the other operates on string values. String comparisons are based on the ASCII collating sequence. Relational operators are nonassociative, so $a < $b < $c is a syntax error.

Numeric | String | Meaning
> | gt | Greater than
>= | ge | Greater than or equal to
< | lt | Less than
<= | le | Less than or equal to

4.5.4.2. Equality operators

The equal and not-equal operators return 1 for true and "" for false (just as the relational operators do). The <=> and cmp operators return -1 if the left operand is less than the right operand, 0 if they are equal, and +1 if the left operand is greater than the right.

Numeric | String | Meaning
== | eq | Equal to
!= | ne | Not equal to
<=> | cmp | Comparison, with signed result

4.5.5. Autoincrement and Autodecrement

If placed before a variable, the ++ and -- operators increment or decrement the variable before returning the value. If placed after, they increment or decrement the variable after returning the value.

4.5.6. Assignment Operators

Perl recognizes the following operators for assigning a value to a variable:

=    **=    +=    *=    &=    <<=    &&=
-=    /=    |=    >>=   ||=    .=     %=
^=    x=

Each operator requires a variable on the left side and an expression on the right side. For the simple assignment operator, =, the value of the expression is stored in the designated variable. For the other operators, Perl evaluates the expression:

$var OP= $value

as if it was written:

$var = $var OP $value

except that $var is evaluated only once. For example:

$a += 2;    # Same as $a = $a + 2

4.5.7. Pattern Match Operators

Binary =~ binds a scalar expression to a pattern match, substitution, or translation. These operations search or modify the string $_ by default.

Binary !~ is just like =~ except the return value is negated in the logical sense. The following expressions are functionally equivalent:

$string !~ /pattern/
not $string =~ /pattern/

see Section 4.6, "Regular Expressions" later in this chapter.

4.5.8. File Test Operators

A file test operator is a unary operator that tests a filename or a filehandle.

Operator | Meaning
-r | File is readable by effective uid/gid
-w | File is writable by effective uid/gid
-x | File is executable by effective uid/gid
-o | File is owned by effective uid
-R | File is readable by real uid/gid
-W | File is writable by real uid/gid
-X | File is executable by real uid/gid
-O | File is owned by real uid
-e | File exists
-z | File has zero size
-s | File has nonzero size (returns size)
-f | File is a plain file
-d | File is a directory
-l | File is a symbolic link
-p | File is a named pipe (FIFO)
-S | File is a socket
-b | File is a block special file
-c | File is a character special file
-t | Filehandle is opened to a tty
-u | File has setuid bit set
-g | File has setgid bit set
-k | File has sticky bit set
-T | File is a text file
-B | File is a binary file (opposite of -T)
-M | Age of file (at startup) in days since modification
-A | Age of file (at startup) in days since last access
-C | Age of file (at startup) in days since inode change

4.5.9. Logical Operators

Perl provides the && (logical AND) and || (logical OR) operators. They evaluate from left to right testing the truth of the statement.

Example | Name | Result
$a && $b | And | $a if $a is false, $b otherwise
$a || $b | Or | $a if $a is true, $b otherwise

For example, an oft-appearing idiom in Perl programs is:

open(FILE, "somefile") || die "Cannot open somefile: $!\n";

In this case, Perl first evaluates the open function. If the value is true (because somefile was successfully opened), the execution of the die function is unnecessary and is skipped.

Perl also provides lower-precedence and and or operators that are more readable.

4.5.10. Bitwise Operators

Perl has bitwise AND, OR, and XOR (exclusive OR) operators: &, |, and ^. These operators work differently on numeric values than they do on strings. If either operand is a number, then both operands are converted to integers, and the bitwise operation is performed between the two integers. If both operands are strings, these operators do bitwise operations between corresponding bits from the two strings.

4.5.11. Miscellaneous Operators

The following operators don't fit into any of the previous categories.

4.5.11.1. Range operator

The .. range operator is really two different operators depending on the context. In a list context, it returns a list of values counting (by ones) from the left value to the right value.

In a scalar context, .. returns a Boolean value. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, after which the range operator becomes false again. The right operand is not evaluated while the operator is in the false state, and the left operand is not evaluated while the operator is in the true state.

The alternate version of this operator, ..., does not test the right operand immediately when the operator becomes true; it waits until the next evaluation.

4.5.11.2. Conditional operator

Ternary ?: is the conditional operator. It works like an if-then-else statement but can safely be embedded within other operations and functions:

test_expr ? if_true_expr : if_false_expr

If the test_expr is true, only the if_true_expr is evaluated. Otherwise, only the if_false_expr is evaluated. Either way, the value of the evaluated expression becomes the value of the entire expression.

4.5.11.3. Comma operator

In a list context, , is the list argument separator and inserts both its arguments into the list. In scalar context, , evaluates its left argument, throws that value away, then evaluates its right argument and returns that value.

The => operator is mostly just a synonym for the comma operator. It's useful for documenting arguments that come in pairs. It also forces any identifier to the left of it to be interpreted as a string.

4.5.11.4. String operator

The concatenation operator . is used to add strings together:

print 'abc' . 'def';        # Prints abcdef
print $a . $b;              # Concatenates the string values of $a and $b

Binary x is the string repetition operator. In scalar context, it returns a concatenated string consisting of the left operand repeated the number of times specified by the right operand:

print '-' x 80;                           # Prints row of dashes
print "\t" x ($tab/8), ' ' x ($tab%8);    # Tabs over

In list context, if the left operand is a list in parentheses, the x works as a list replicator rather than a string replicator. This is useful for initializing all the elements of an array of indeterminate length to the same value:

@ones = (1) x 80;           # A list of 80 1s
@ones = (5) x @ones;        # Set all elements to 5
Previous | Home | Next
4.4. Special Variables | Book Index | 4.6. Regular Expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.6. Regular Expressions

Regular expressions are used several ways in Perl. They're used in conditionals to determine whether a string matches a particular pattern. They're also used to find patterns in strings and replace the match with something else.

The ordinary pattern match operator looks like /pattern/. It matches against the $_ variable by default. If the pattern is found in the string, the operator returns true (1); if there is no match, a false value ("") is returned.

The substitution operator looks like s/pattern/replace/. This operator searches $_ by default. If it finds the specified pattern, it is replaced with the string in replace. If pattern is not matched, nothing happens.

You may specify a variable other than $_ with the =~ binding operator (or the negated !~ binding operator, which returns true if the pattern is not matched). For example:

$text =~ /sampo/;

4.6.1. Pattern-Matching Operators

The following list defines Perl's pattern-matching operators. Some of the operators have alternative "quoting" schemes and have a set of modifiers that can be placed directly after the operators to affect the match operation in some way.

m/pattern/gimosxe
Searches a string for a pattern match. Modifiers are:

Modifier

Meaning

g

Match globally, i.e., find all occurrences.

i

Do case-insensitive pattern matching.

m

Treat string as multiple lines.

o

Compile pattern only once.

s

Treat string as single line.

x

Use extended regular expressions.

If / is the delimiter, then the initial m is optional. With m, you can use any pair of non-alphanumeric, non-whitespace characters as delimiters.

?pattern?
This operator is just like the m/pattern/ search, except it matches only once.

qr/pattern/imosx
Creates a precompiled regular expression from pattern, which can be passed around in variables and interpolated into other regular expressions. The modifiers are the same as those for m// above.

s/pattern/replacement/egimosx
Searches a string for pattern and replaces any match with the replacement text. Returns the number of substitutions made, which can be more than one with the /g modifier. Otherwise, it returns false (0). If no string is specified via the =~ or !~ operator, the $_ variable is searched and modified. Modifiers are:

Modifier

Meaning

e

Evaluate the right side as an expression.

g

Replace globally, i.e., all occurrences.

cg

Continue search after g failed. No longer supported for s/// as of Perl 5.8.

i

Do case-insensitive pattern matching.

m

Treat string as multiple lines.

o

Compile pattern only once.

s

Treat string as single line.

x

Use extended regular expressions.

Any non-alphanumeric, non-whitespace delimiter may replace the slashes. If single quotes are used, no interpretation is done on the replacement string (the /e modifier overrides this, however).

tr/pattern1/pattern2/cds
y/pattern1/pattern2/cds
This operator scans a string character by character and replaces all occurrences of the characters found in pattern1 with the corresponding character in pattern2. It returns the number of characters replaced or deleted. If no string is specified via the =~ or !~ operator, the $_ string is translated. Modifiers are:

Modifier

Meaning

c

Complement pattern1.

d

Delete found but unreplaced characters.

s

Squash duplicate replaced characters.

4.6.2. Regular Expression Syntax

The simplest kind of regular expression is a literal string. More complicated patterns involve the use of metacharacters to describe all the different choices and variations that you want to build into a pattern. Metacharacters don't match themselves, but describe something else. The metacharacters are:

Metacharacter | Meaning
\ | Escapes the character(s) immediately following it
. | Matches any single character except a newline (unless /s is used)
^ | Matches at the beginning of the string (or line, if /m is used)
$ | Matches at the end of the string (or line, if /m is used)
* | Matches the preceding element 0 or more times
+ | Matches the preceding element 1 or more times
? | Matches the preceding element 0 or 1 times
{...} | Specifies a range of occurrences for the element preceding it
[...] | Matches any one of the class of characters contained within the brackets
(...) | Groups regular expressions
| | Matches either the expression preceding or following it

The . (single dot) is a wildcard character. When used in a regular expression, it can match any single character. The exception is the newline character (\n), except when you use the /s modifier on the pattern match operator. This modifier treats the string to be matched against as a single "long" string with embedded newlines.

The ^ and $ metacharacters are used as anchors in a regular expression. The ^ matches the beginning of a line. This character should appear only at the beginning of an expression to match the beginning of the line. The exception to this is when the /m (multiline) modifier is used, in which case it will match at the beginning of the string and after every newline (except the last, if there is one). Otherwise, ^ will match itself, unescaped, anywhere in a pattern, except if it is the first character in a bracketed character class, in which case it negates the class.

Similarly, $ will match the end of a line (just before a newline character) only if it is at the end of a pattern, unless /m is used, in which case it matches just before every newline and at the end of a string. You need to escape $ to match a literal dollar sign in all cases, because if $ isn't at the end of a pattern (or placed right before a ) or ]), Perl will attempt to do variable interpretation. The same holds true for the @ sign, which Perl will interpret as an array variable start unless it is backslashed.

The *, +, and ? metacharacters are called quantifiers. They specify the number of times to match something. They act on the element immediately preceding them, which could be a single character (including the .), a grouped expression in parentheses, or a character class. The {...} construct is a generalized modifier. You can put two numbers separated by a comma within the braces to specify minimum and maximum numbers that the preceding element can match.

Parentheses are used to group characters or expressions. They also have the side effect of remembering what they matched so you can recall and reuse patterns with a special group of variables.

The | is the alternation operator in regular expressions. It matches either what's on its left side or right side. It does not affect only single characters. For example:

/you|me|him|her/

looks for any of the four words. You should use parentheses to provide boundaries for alternation:

/And(y|rew)/

This will match either "Andy" or "Andrew".

4.6.3. Escaped Sequences

The following table lists the backslashed representations of characters that you can use in regular expressions:

Code | Matches
\a | Alarm (beep)
\n | Newline
\r | Carriage return
\t | Tab
\f | Formfeed
\e | Escape
\038 | Any octal ASCII value
\x7f | Any hexadecimal ASCII value
\x{263a} | A wide hexadecimal value
\c x | Control-x
\N{name} | A named character

4.6.4. Character Classes

The [...] construct is used to list a set of characters (a character class) of which one will match. Brackets are often used when capitalization is uncertain in a match:

/[tT]here/

A dash (-) may be used to indicate a range of characters in a character class:

/[a-zA-Z]/;  # Match any single letter
/[0-9]/;     # Match any single digit

To put a literal dash in the list you must use a backslash before it (\-).

By placing a ^ as the first element in the brackets, you create a negated character class, i.e., it matches any character not in the list. For example:

/[^A-Z]/;    # Matches any character other than an uppercase letter

Some common character classes have their own predefined escape sequences for your programming convenience:

Code | Matches
\d | A digit, same as [0-9]
\D | A nondigit, same as [^0-9]
\w | A word character (alphanumeric), same as [a-zA-Z_0-9]
\W | A non-word character, [^a-zA-Z_0-9]
\s | A whitespace character, same as [ \t\n\r\f]
\S | A non-whitespace character, [^ \t\n\r\f]
\C | Match a character (byte)
\pP | Match P-named (Unicode) property
\PP | Match non-P
\X | Match extended unicode sequence

While Perl implements lc() and uc( ), which you can use for testing the proper case of words or characters, you can do the same with escape sequences:

Code | Matches
\l | Lowercase until next character
\u | Uppercase until next character
\L | Lowercase until \E
\U | Uppercase until \E
\Q | Disable pattern metacharacters until \E
\E | End case modification

These elements match any single element in (or not in) their class. A \w matches only one character of a word. Using a modifier, you can match a whole word, for example, with \w+. The abbreviated classes may also be used within brackets as elements of other character classes.

4.6.5. Anchors

Anchors don't match any characters; they match places within a string. The two most common anchors are ^ and $, which match the beginning and end of a line, respectively. The following table lists the anchoring patterns used to match certain boundaries in regular expressions:

Assertion | Meaning
^ | Matches at the beginning of the string (or line, if /m is used)
$ | Matches at the end of the string (or line, if /m is used)
\b | Matches at word boundary (between \w and \W)
\B | Matches except at word boundary
\A | Matches at the beginning of the string
\Z | Matches at the end of the string or before a newline
\z | Matches only at the end of the string
\G | Matches where previous m//g left off
\c | Suppresses resetting of search position when used with \g. Without \c, search pattern is reset to the beginning of the string.

The $ and \Z assertions can match not only at the end of the string, but also one character earlier than that, if the last character of the string is a newline.

4.6.6. Quantifiers

Quantifiers are used to specify the number of instances of the previous element that can match. For instance, you could say "match any number of a's, including none" (a*), or "match between 5 and 10 instances of the word 'owie' ((owie){5,10})".

Quantifiers, by nature, are greedy. That is, the way the Perl regular expression "engine" works is that it will look for the biggest match possible (the farthest to the right) unless you tell it not to. Say you are searching a string that reads:

a whatever foo, b whatever foo

and you want to find a and foo with something in between. You might use:

/a.*foo/

A . followed by a * looks for any character, any number of times, until foo is found. But since Perl will look as far to the right as possible to find foo, the first instance of foo is swallowed up by the greedy .* expression.

Therefore, all the quantifiers have a notation that allows for minimal matching, so they are nongreedy. This notation uses a question mark immediately following the quantifier to force Perl to look for the earliest available match (farthest to the left). The following table lists the regular expression quantifiers and their nongreedy forms:

Maximal | Minimal | Allowed range
{n,m} | {n,m}? | Must occur at least n times but no more than m times
{n,} | {n,}? | Must occur at least n times
{n} | {n}? | Must match exactly n times
* | *? | 0 or more times (same as {0,})
+ | +? | 1 or more times (same as {1,})
? | ?? | 0 or 1 time (same as {0,1})

4.6.7. Pattern Match Variables

Parentheses not only group elements in a regular expression, they also remember the patterns they match. Every match from a parenthesized element is saved to a special, read-only variable indicated by a number. You can recall and reuse a match by using these variables.

Within a pattern, each parenthesized element saves its match to a numbered variable, in order starting with 1. You can recall these matches within the expression by using \1, \2, and so on.

Outside of the matching pattern, the matched variables are recalled with the usual dollar sign, i.e., $1, $2, etc. The dollar sign notation should be used in the replacement expression of a substitution and anywhere else you might want to use the variables in your program. For example, to implement "i before e, except after c":

s/([^c])ei/$1ie/g;

The backreferencing variables are:

$+
Returns the last parenthesized pattern match

$&
Returns the entire matched string

$'
Returns everything before the matched string

$'
Returns everything after the matched string

Backreferencing with these variables will slow down your program noticeably for all regular expressions.

4.6.8. Extended Regular Expressions

Perl defines an extended syntax for regular expressions. The syntax is a pair of parentheses with a question mark as the first thing within the parentheses. The character after the question mark gives the function of the extension. The extensions are:

(?#text)
A comment. The text is ignored.

(?:...)
(?imsx-imsx:...)
This groups things like (...) but doesn't make backreferences.

(?=...)
A zero-width positive lookahead assertion. For example, /\w+(?=\t)/ matches a word followed by a tab, without including the tab in $&.

(?!...)
A zero-width negative lookahead assertion. For example, /foo(?!bar)/ matches any occurrence of foo that isn't followed by bar.

(?<...)
A zero-width positive lookbehind assertion. For example, /(?<bad)boy/ matches the word boy that follows bad, without including bad in $&. This works only for fixed-width lookbehind.

(?{code})
An experimental regular expression feature to evaluate any embedded Perl code. This evaluation always succeeds, and code is not interpolated.

(?<!=...)
A zero-width negative lookbehind assertion. For example, /(?<!=bad)boy/ matches any occurrence of boy that doesn't follow bad. This works only for fixed-width lookbehind.

(?>...)
Matches the substring that the standalone pattern would match if anchored at the given position.

(?(condition)yes-pattern|no-pattern)
(?(condition)yes-pattern)
Matches a pattern determined by a condition. condition should be either an integer, which is true if the pair of parentheses corresponding to the integer has matched, or a lookahead, lookbehind, or evaluate, zero-width assertion. no-pattern will be used to match if the condition was not meant, but it is also optional.

(?imsx-imsx)
One or more embedded pattern-match modifiers. Modifiers are switched off if they follow a - (dash). The modifiers are defined as follows:

Modifier

Meaning

i

Do case-insensitive pattern matching.

m

Treat string as multiple lines.

s

Treat string as single line.

x

Use extended regular expressions.

Previous | Home | Next
4.5. Operators | Book Index | 4.7. Subroutines
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.7. Subroutines

Subroutines are declared using one of these forms:

sub name {block}
sub name (proto) {block}

Prototypes allow you to put constraints on the arguments you provide to your subroutines.

You can also create anonymous subroutines at runtime, which will be available for use through a reference:

$subref = sub {block};

4.7.1. Calling Subroutines

The ampersand (&) is the identifier used to call subroutines. Most of the time, however, subroutines can be used in an expression just like built-in functions. To call subroutines directly:

name(args);        # & is optional with parentheses
name args;         # Parens optional if predeclared/imported
&name;             # Passes current @_ to subroutine

To call subroutines indirectly (by name or by reference):

&$subref(args);    # & is not optional on indirect call
&$subref;          # Passes current @_ to subroutine

4.7.2. Passing Arguments

All arguments to a subroutine are passed as a single, flat list of scalars, and return values are returned the same way. Any arrays or hashes passed in these lists will have their values interpolated into the flattened list.

Any arguments passed to a subroutine come in as the array @_.

You may use the explicit return statement to return a value and leave the subroutine at any point.

4.7.3. Passing References

If you want to pass more than one array or hash into or out of a function and maintain their integrity, you should pass references as arguments. The simplest way to do this is to take your named variables and put a backslash in front of them in the argument list:

@returnlist = ref_conversion(\@temps1, \@temps2, \@temps3);

This sends references to the three arrays to the subroutine (and saves you the step of creating your own named references to send to the function). The references to the arrays are passed to the subroutine as the three-member @_ array. The subroutine will have to dereference the arguments so that the data values may be used.

Returning references is a simple matter of returning scalars that are references. This way, you can return distinct hashes and arrays.

4.7.4. Private and Local Variables

Any variables you use in the function that aren't declared private are global variables. In subroutines, you'll often want to use variables that won't be used anywhere else in your program, and you don't want them taking up memory when the subroutine is not being executed. You also might not want to alter variables in subroutines that might have the same name as global variables.

The my function declares variables that are lexically scoped within the subroutine. Lexically scoped variables are private variables that exist only within the block or subroutine in which they are declared. Outside of their scope, they are invisible and can't be altered in any way.

To scope multiple variables at once, use a list in parentheses. You can also assign a variable in a my statement:

my @list = (44, 55, 66);
my $cd = "orb";

Dynamic variables are visible to other subroutines called from within their scope, are defined with local, and are not private variables but global variables with temporary values. When a subroutine is executed, the global value is hidden away, and the local value is used. Once the scope is exited, the original global value is used. Most of the time, you will want to use my to localize parameters in a subroutine.

4.7.5. Prototypes

Prototypes allow you to design your subroutines to take arguments with constraints on the number of parameters and types of data. To declare a function with prototypes, use the prototype symbols in the declaration line like this:

sub addem ($$) {
...
}

In this case, the function expects two scalar arguments. The following table gives the various prototype symbols:

Symbol | Meaning
$ | Scalar
@ | List
% | Hash
& | Anonymous subroutine
* | Typeglob

A backslash placed before one of these symbols forces the argument to be that exact variable type. For instance, a function that requires a hash variable would be declared like this:

sub hashfunc (\%);

Unbackslashed @ or % symbols act exactly alike and will eat up all remaining arguments, forcing list context. Likewise, a $ forces scalar context on an argument, so taking an array or hash variable for that parameter would probably yield unwanted results.

A semicolon separates mandatory arguments from optional arguments. For example:

sub newsplit (\@$;$);

requires two arguments: an array variable and a scalar. The third scalar is optional. Placing a semicolon before @ and % is not necessary since lists can be null.

A typeglob prototype symbol (*) will always turn its argument into a reference to a symbol table entry. It is most often used for filehandles.

Previous | Home | Next
4.6. Regular Expressions | Book Index | 4.8. References and Complex Data Structures
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.8. References and Complex Data Structures

A Perl reference is a fundamental data type that "points" to another piece of data or code. A reference knows the location of the information and the type of data stored there.

A reference is a scalar and can be used anywhere a scalar can be used. Any array element or hash value can contain a reference (a hash key cannot contain a reference), which is how nested data structures are built in Perl. You can construct lists containing references to other lists, which can contain references to hashes, and so on.

4.8.1. Creating References

You can create a reference to an existing variable or subroutine by prefixing it with a backslash:

$a = "fondue";
@alist = ("pitt", "hanks", "cage", "cruise");
%song = ("mother" => "crying", "brother" => "dying");
sub freaky_friday { s/mother/daughter/ }
# Create references
$ra = \$a;
$ralist = \@alist;
$rsong = \%song;
$rsub = \&freaky_friday; # '&' required for subroutine names

References to scalar constants are created similarly:

$pi = \3.14159;
$myname = \"Charlie";

Note that all references are prefixed by a $, even if they refer to an array or hash. All references are scalars; thus, you can copy a reference to another scalar or even reference another reference:

$aref = \@names;
$bref = $aref;            # Both refer to @names
$cref = \$aref;           # $cref is a reference to $aref

Because arrays and hashes are collections of scalars, you can create references to individual elements by prefixing their names with backslashes:

$star = \$alist[2];       # Refers to third element of @alist
$action = \$song{mother}; # Refers to the 'mother' value of %song

4.8.1.1. Referencing anonymous data

It is also possible to take references to literal data not stored in a variable. This data is called anonymous because it is not bound to any named variable.

To create a reference to a scalar constant, simply backslash the literal string or number.

To create a reference to an anonymous array, place the list of values in square brackets:

$shortbread = [ "flour", "butter", "eggs", "sugar" ];

This creates a reference to an array, but the array is available only through the reference $shortbread.

A reference to an anonymous hash uses braces around the list of elements:

$cast =  { host     => "Space Ghost",
           musician => "Zorak",
           director => "Moltar" };

4.8.2. Dereferencing

Dereferencing returns the value a reference points to. The general method of dereferencing uses the reference variable substituted for the regular name part of a variable. If $r is a reference, then $$r, @$r, or %$r retrieve the value that is referred to, depending on whether $r is pointing to a scalar, array, or hash. A reference can be used in all the places where an ordinary data type can be used.

When a reference is accidentally evaluated as a plain scalar, it returns a string that indicates the type of data it points to and the memory address of the data.

If you just want to know the type of data that is being referenced, use ref, which returns one of the following strings if its argument is a reference. Otherwise, it returns false.

SCALAR
ARRAY
HASH
CODE
GLOB
REF

4.8.2.1. Arrow dereferencing

References to arrays, hashes, and subroutines can be dereferenced using the -> operator. This operator dereferences the expression to its left, which must resolve to an array or hash and accesses the element represented by the subscripted expression on its right. For example, these three statements are equivalent:

$$arrayref[0] = "man";
${$arrayref}[0] = "man";
$arrayref->[0] = "man";

The first statement dereferences $arrayref first and finds the first element of that array. The second uses braces to clarify this procedure. The third statement uses the arrow notation to do the same thing.

The arrow dereferencing notation can be used only to access a single scalar value. You cannot use arrow operators in expressions that return either slices or whole arrays or hashes.

Previous | Home | Next
4.7. Subroutines | Book Index | 4.9. Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.9. Filehandles

A filehandle is the name for an I/O connection between your Perl process and the operating system. Filehandle names are like label names but use their own namespace. Like label names, the convention is to use all uppercase letters for filehandle names.

Every Perl program has three filehandles that are automatically opened: STDIN, STDOUT, and STDERR. By default, the print and write functions write to STDOUT. Additional filehandles are created using the open function:

open (DATA, "numbers.txt");

DATA is the new filehandle that is attached to the external file, which is now opened for reading. You can open filehandles for reading, writing, and appending to external files and devices. To open a file for writing, prefix the filename with a greater-than sign:

open(OUT, ">outfile");

To open a file for appending, prefix the filename with two greater-than signs:

open(LOGFILE, ">>error_log");

The open function returns true if the file is successfully opened, and false if it failed to open. Opening a file can fail for any number of reasons, e.g., a file does not exist, is write-protected, or you don't have permission for a file or directory. However, a filehandle that has not been successfully opened can still be read from (giving you an immediate EOF) or written to with no noticeable effects.

You should always check the result of open immediately and report an error if the operation does not succeed. The warn function can report an error to standard error if something goes wrong, and die can terminate your program and tell you what went wrong. For example:

open(LOGFILE, "/usr/httpd/error_log")
        || warn "Could not open /usr/httpd/error_log.\n";
open(DATA, ">/tmp/data") || die "Could not create /tmp/data\n.";

Once the file is opened, you can access the data using the diamond operator, <filehandle>. This is the line-input operator. When used on a filehandle in a scalar context, it returns a line from a filehandle as a string. Each time it is called, it returns the next line from the filehandle until it reaches the end-of-file. The operator keeps track of the line it is on in the file, unless the filehandle is closed and reopened, which resets the operator to the top-of-file.

For example, the following prints any line containing the word "secret.html" from the LOGFILE filehandle:

while (<LOGFILE>) {
        print "$_\n" if /secret\.html/;
}

In a list context, the line-input operator returns a list in which each line is an element. The empty <> operator reads from the ARGV filehandle, which reads the array of filenames from the Perl command line. If @ARGV is empty, the operator resorts to standard input.

A number of functions send output to a filehandle. The filehandle must already be opened for writing, of course. In the previous example, print wrote to the STDOUT filehandle, even though it wasn't specified. Without a filehandle, print defaults to the currently selected output filehandle, which will be STDOUT until you open and select another one in your program. See the select function (filehandle version) for more information.

If your program involves more than a couple of open filehandles, you should specify the filehandles for all of your I/O functions to be safe:

print LOGFILE "======= Generated report $date ======="

To close a filehandle, use the close function. Filehandles are also closed when the program exits.

4.9.1. Perl 5.8 and PerlIO

Perl 5.8 does I/O via PerlIO instead of through your system's I/O (STDIO). By implementing open( ) with PerlIO, the default behavior of open is changed to support a three-argument format. For example:

open($fh, '>:utf-8', $filename)
    or die("...");   # Open $filename and support utf-8

In this example, the filehandle is marked with utf-8 (or utf8 for EBCDIC users) to accept Perl's internal Unicode encoding.

The PerlIO layers are:

unix
Low-level read/write

stdio
Standard I/O

perlio
Portable implementation of buffering

crlf
Win32

Also in Perl 5.8, you are no longer required to name a filehandle in open( ) because Perl will handle the filehandles internally:

open($fh, ...) or ...

You can also use anonymous temporary files with the new form of open( ):

open($fh, ">", undef) or ...

Pipes can also be used with a multiple-argument form of open. The following code is roughly equivalent to the Unix command 'ls -al':

open($fh, "-|", 'ls -al', '/users') or ...
Previous | Home | Next
4.8. References and Complex Data Structures | Book Index | 4.10. Signals
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.10. Signals

Perl supports many facilities for Interprocess Communication (IPC), including signals and sockets. Regardless of which IPC form you use with Perl, you'll almost always tangle with signals.

Signals can be generated from any source, including key sequences on your keyboard, an event on your system, or from a failed program.

For quite some time, Perl has used a simple signal handling module, in which %SIG was populated with keys that represented the signal handlers your system supported. You'd invoke one of these handlers when Perl came across $SIG{'whatever_signal_here'}. In fact, even in Perl 5.8, the %SIG interface is the same, but the behavior of signals is entirely different. More on this shortly.

For signals to be useful, they must be trapped and dealt with. However, you shouldn't try to do too much when you trap a signal. Generally, you should only generate a warning and deal with the condition that caused the error. In a way, Perl's %SIG keeps you from doing too much. %SIG works like this:

$SIG{I_GOT_THIS_SIGNAL} = \&now_call_this_sub_to_handle_it;
sub now_call_this_sub_to_handle it {
    ...
}

If you need to know which signals Perl is aware of, do a 'kill -l' on a Unix system, or use Config.pm:

#!/usr/local/bin/perl -w

use Config;

print "Perl knows about the following signals:\n";
print $Config{sig_name_init}, "\n";

Here's a simple snippet that lets you know if someone sent you a HUP signal:

$SIG{HUP} = \&hic_hup;
sub hic_hup {
    my $signal = shift;
    # Don't die for now.  Just warn us.
    warn "Somebody sent me a SIG${signal}\n";
}

Often, the type of signal you encounter in your Perl program will dictate how you should handle it. For example, you should assign 'IGNORE' to the 'CHLD' signal on many Unix platforms to reduce the possibility of creating zombie processes. Other signals, such as KILL and STOP, cannot and should not be ignored so easily. For this purpose, Perl lets you use a local( ) statement, which lets you temporarily ignore a signal:

sub kill_handler {
    local $SIG{KILL} = 'IGNORE'; # Inherited by all functions here
    i_will_settle_for_denial();
}

sub i_will_settle_for_denial {
    # KILL ignored for now.  Go in peace.
}

Unix allows you to kill processes with negative process IDs by sending a signal zero. If you have a program that starts itself and several children, use 'kill -PARENT_PID' to kill the parent and all of the children processes. But obviously, if you send a HUP to the parent, you don't want the parent to die. You can avoid this with Perl and signals:

sub be_nice_to_your_parents {
    local($SIG{HUP}) = 'IGNORE';
     kill('HUP', -$$);    # This pid and its kids
}

Naturally, you don't have to do anything fancy with signal handlers. You can simply die if the given $SIG{NAME} won't cause negative effects on your system if you mishandle it:

$SIG{INT} = sub {
    die "\nYou've interrupted me for one last time!\n"
};

Keep in mind that it's not all fun and games with Perl and signals. If you don't know how your system's C library and its signals implementation behave, or if you haven't read the instructions before firing your BB gun, you'll shoot your eye out. We guarantee it!

As of Perl 5.8, you can probably be a little more confident in Perl's ability to handle even a bad system-specific signals implementation. In the old days, when men were men and eyeless men were everywhere, a bad signals implementation at both a system and Perl level, or a signal cropping up at the wrong time, could corrupt Perl's internal state. Thankfully, Perl 5.8 and later will postpone signal handling until it's safe to proceed. This means that while the signals interface doesn't change, even if your program catches a signal at a specific place, Perl 5.8 and later will finish whatever they are doing when the signal is encountered.

Finally, signals aren't limited to coping with the behaviors of processes. You can also trap alarm signals for Perl functions and system calls alike if your Perl code lives in an eval( ) block. For example, let's say you want to ping a host, your-host.your.domain, and you want the ping process to timeout in a reasonable amount of time if your-host.your.domain isn't available. You can use alarm( ) inside of eval( ), like so:

#!/usr/local/bin/perl -w

my $to_ping = 'your-host.your.domain';
my $a_secs = 5;

eval {
    local $SIG{ALRM} = sub { die "no dice for $to_ping" };
    alarm $a_secs;
    system("/usr/sbin/ping", $to_ping);
    alarm 0;
};

if ($@ and $@ !~ /no dice for $to_ping/) { die }

Note that you may have to wait for the ping command itself to timeout. While alarm occurs after $a_secs, you won't see the "no dice for . . . " message until system( ) (or qx( )) is complete. This is not the case for Perl functions such as flock( ), open( ), etc.

Previous | Home | Next
4.9. Filehandles | Book Index | 4.11. Unicode
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.11. Unicode

Unicode provides a unique number for every character, regardless of the computing platform, program, or programming language. This is particularly important because without a standard such as Unicode, computers would continue to use different encoding classes for characters, many of which would conflict if character classes were used together.

Unicode support was introduced to Perl with Perl 5.6. Although it is still not completely adherent in the Unicode spec, Unicode support has matured significantly under Perl 5.8. You can now use Unicode reliably with file I/O and with regular expressions. With regular expressions, the pattern will adapt to the data and will automatically switch to the correct Unicode character scheme.

Perl's Unicode implementation falls into the following categories:

I/O
There is currently no way in Perl to mark data that's read from or written to a file as being of type Unicode (utf8). Future versions of Perl will support such a feature.

Regular expressions
The determination whether to match Unicode characters is made when the pattern is compiled, based on whether the pattern contains Unicode characters and not when matching happens at runtime. This will be changed to match Unicode characters at runtime.

use utf8
The utf8 module is still needed to enable a few Unicode features. The utf8 pragma, as implemented by the utf8 module, implements tables used for Unicode support. You must load the utf8 pragma explicitly to enable recognition of UTF-8 encoded literals and identifiers in the source text.

Byte and character semantics
As of 5.6.0, Perl uses logically wide characters to represent strings internally. This internal representation uses the UTF-8 encoding. Future versions of Perl will work with characters rather than bytes. This was a purposeful decision made so Perl 5.6 could transition from byte semantics to character semantics in programs. Perl will make the decision to switch to character semantics if it finds that the input data has characters on which it can safely operate with UTF-8. You can disable character semantics by using the bytes pragma, as explained in Chapter 8, "Standard Modules". Character semantics have the following effects:

  • Strings and patterns may contain characters that have an ordinal value larger than 255.

  • Identifiers within a Perl program may contain Unicode alphanumeric characters.

  • Regular expressions match characters and not bytes.

  • Character classes in regular expressions match characters and not bytes.

  • Named Unicode properties and block ranges may be used as character classes with the \p and \P constructs.

  • \X matches any extended Unicode sequence.

  • tr// matches characters instead of bytes.

  • Case translation operators use the Unicode case translation tables when provided character input.

  • Most operators that deal with positions or lengths in a string switch to using character positions.

  • pack( ) and unpack( ) do not change.

  • Bit operators work on characters.

  • scalar reverse( ) reverses characters and not bytes.

Previous | Home | Next
4.10. Signals | Book Index | 4.12. Formats
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.12. Formats

Formats are a mechanism for generating formatted reports for outputting data and are defined with the format keyword. The general form looks like:

format name =
 ...template lines...
 ...argument line...
.

Most of your format names will be the same as the filehandle names for which they are used. The default format for a filehandle is the one with the same name.

The format definition is like a subroutine definition. It doesn't contain immediately executed code and can therefore be placed anywhere in the file with the rest of the program; they are commonly placed near the end of the file with subroutine definitions. To output to a format, use the write function instead of print.

The template lines contain literal text and fieldholders. Fieldholders contain symbols that describe the size and positioning of the area on the line where data is output. An argument line immediately follows a template line that contains the fields to be replaced by data. The argument line is a list of variables (or expressions), separated by commas, that fill the fields in the previous line in the order they are listed.

Here's an example of a template line with two fieldholders and the argument line that follows:

Hello, my name is @<<<<<<<<<< and I'm @<< years old.
$name, $age

The fieldholders are @<<<<<<<<<< and @<<, which specify left-justified text fields with 11 and 3 characters, respectively.

Most fieldholders start with @. The characters following @ indicate the type of field, while the number of characters (including @) indicate the field width. The following fieldholder characters determine the positioning of text fields:

<<<< (left angle brackets)
A left-justified field; if the value is shorter than the field width, it will be padded on the right with spaces.

>>>> (right angle brackets)
A right-justified field; if the value is too short, it will be padded on the left with spaces.

|||| (vertical bars)
A centered field; if the value is too short, it will be padded on both sides with spaces, enough on each side to center the value within the field.

Another kind of fieldholder is a fixed-precision numeric field. This field also begins with @, and is followed by one or more hashmarks (###) with an optional dot (indicating a decimal point). For example:

format MONEY =
Assets: @#####.## Liabilities: @#####.## Net: @#####.##
$assets, $liabilities, $assets-$liabilities
.

The multiline fieldholder allows you to include a value that may have many lines of information. This fieldholder is denoted by @* on a line by itself. The next line defines the value that will be substituted into the field, which in this case may be an expression that results in a value that contains many newlines.

Another kind of fieldholder is a filled field. This fieldholder allows you to create a filled paragraph, breaking the text into conveniently sized lines at word boundaries, wrapping the lines as needed. A filled field is denoted by replacing the @ marker in a text fieldholder with a caret (^<<<, for example). The corresponding value for a filled field (on the following line of the format) must be a scalar variable containing text, rather than an expression that returns a scalar value. When Perl is filling the filled field, it takes the value of the variable and removes as many words as will fit in the field. Subsequent calls for the variable in a filled field will continue where the last one left off.

If the variable's contents are exhausted before the number of fields, you will simply end up with blank lines. You can suppress blank lines by placing a tilde (~) on the line. Any line that contains a tilde character is not output if the line would have otherwise printed blank (i.e., just whitespace). The tilde itself always prints as a blank and can be placed anywhere a space could have been placed in the line.

If the text in the variable is longer than what can be filled in the fields, output continues only until the fields run out. The shortcut to get the string to print until it ends is to use two consecutive tildes (~~) on a line. This causes the line to repeat automatically until the result is a completely blank line (which will be suppressed).

Default values for format parameters all relate to the format of the currently selected filehandle. The currently selected filehandle starts out as STDOUT, which makes it easy to print things on the standard output. However, you can change the currently selected filehandle with the select function, which takes a single filehandle (or a scalar variable containing the name of a filehandle) as an argument. Once the currently selected filehandle is changed, it affects all future operations that depend on the currently selected filehandle.

Previous | Home | Next
4.11. Unicode | Book Index | 4.13. Pod
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.13. Pod

Pod is a simple, but surprisingly capable, text formatter that uses tags to tell a translator how to format the text. The tags serve several purposes:

  • They tell the formatter how to lay out text on the page.

  • They provide font and cross-reference information.

  • They start and stop parsing of code.

The last item is indicative of one of pod's most useful features—that it can be intermixed with Perl code. While it can be difficult to force yourself to go back and write documentation for your code after the fact, with Perl you can simply intermingle the documentation with the code, and do it all at once. It also lets you use the same text as both code documentation and user documentation.

A pod translator reads a file paragraph by paragraph, ignoring text that isn't pod, and converting it to the proper format. Paragraphs are separated by blank lines (not just by newlines). The various translators recognize three kinds of paragraphs:

Command
Commands begin with =, followed immediately by the command identifier:

=cut

They can also be followed by text:

=head2 Second-level head

A blank line signals the end of the command.

Text
A paragraph consisting of a block of text, generally filled and possibly justified, depending on the translator. For example, a command such as =head2 will probably be followed with a text paragraph:

=head2 Pod

Pod is a simple, but surprisingly capable, text formatter that uses
tags to tell a translator how to format the text.
Verbatim
A paragraph that is to be reproduced as is, with no filling or justification. To create a verbatim paragraph, indent each line of text with at least one space:

Don't fill this paragraph. It's supposed
to look exactly like this on the page.
There are blanks at the beginning of each line.

4.13.1. Paragraph Tags

The following paragraph tags are recognized as valid pod commands.

=back
=back

Moves left margin back to where it was before the last =over. Ends the innermost =over/=back block of indented text. If there are multiple levels of indent, one =back is needed for each level.

=begin
=begin format

Starts a block of text that will be passed directly to a particular formatter rather than being treated as pod. For example:

=begin html

A =begin/=end block is like =for except that it doesn't necessarily apply to a single paragraph.

=cut
=cut

Indicates the end of pod text. Tells the compiler that there isn't anymore pod (for now) and to start compiling again.

=end
=end

Ends a =begin block. Tells the translator to treat what follows as pod again.

=for
=for format

Indicates a format change, for the next paragraph only.

=head1
=head1 text

text following the tag is formatted as a top-level heading. Generally all uppercase.

=head2
=head2 text

text following the tag is formatted as a second-level heading.

=item
=item text

Starts a list. Lists should always be inside an over/back block. Many translators use the value of text on the first =item to determine the type of list:

=item *
Bulleted list. An asterisk (*) is commonly used for the bullet, but can be replaced with any other single character. Followed by a blank line and then the text of the bulleted item:

=item *

This is the text of the bullet.
=item n
Numbered list. Replace n with 1 on the first item, 2 on the second, and so on. Pod does not automatically generate the numbers.

=item text
Definition list. Formats text as the term and the following paragraph as the body of the list item. For example:

=item <HTML>

Indicates the beginning of an HTML file

The exact appearance of the output depends on the translator you use, but it will look pretty much like this:

<HTML>
    Indicates the beginning of an HTML file
=over
=over n

Specifies the beginning of a list, in which n indicates the depth of the indent. For example, =over 4 will indent four spaces. Another =over before a =back creates nested lists. The =over tag should be followed by at least one =item.

=pod
=pod

Indicates the beginning of pod text. A translator starts to pay attention when it sees this tag, and the compiler ignores everything from there to the next =cut.

4.13.2. Interior Sequences

In addition to the paragraph tags, pod has a set of tags that apply within text, either in a paragraph or a command. These interior sequences are:

Sequence |  | Function
B<text> |  | Makes text bold, usually for switches and programs
C<code> |  | Literal code
E<escape> |  | Named character:
 | E<gt> | Literal >
 | E<lt> | Literal <
 | E<html> | Non-numeric HTML entity
 | E<n> | Character number n, usually an ASCII character
F<file> |  | Filename
I<text> |  | Italicize text, usually for emphasis or variables
L<name> |  | Link (cross-reference) to name:
 | L<name> | Manpage
 | L<name/ident> | Item in a manpage
 | L<name/"sec"> | Section in another manpage
 | L<"sec"> | Section in this manpage; quotes are optional
 | L</"sec"> | Same as L<"sec">
S<text> |  | text has non-breaking spaces
X<index> |  | Index entry
Z<> |  | Zero-width character

4.13.3. Pod Utilities

As mentioned earlier, a number of utility programs have been written to convert files from pod to a variety of output formats. Some of the utilities are described here, particularly those that are part of the Perl distribution. Other programs are available on CPAN.

perldoc
perldoc [options] docname

Formats and displays Perl pod documentation. Extracts the documentation from pod format and displays it. For all options except -f, docname is the name of the manpage, module, or program containing pod to be displayed. For -f, it's the name of a built-in Perl function to be displayed.

Options

-f function
Formats and displays documentation for the specified Perl function.

-h
Displays help message.

-l
Displays full path to the module.

-m
Displays entire module, both code and pod text, without formatting the pod.

-t
Displays using text formatter instead of nroff. Faster, but output is less fancy.

-u
Unformatted. Finds and displays the document without formatting it.

-v
Verbose. Describes search for the file, showing directories searched and where file was found.

perldoc applies switches found in the PERLDOC environment variable before those from the command line. It searches directories specified by the PERL5LIB, PERLLIB (if PERL5LIB isn't defined), and PATH environment variables.

pod2fm
pod2fm [options] file

Translates pod to FrameMaker format.

Options

-book [bookname]
If set, creates FrameMaker book file. If not specified, bookname defaults to perl; filename extension is .book in either case.

-[no]doc
Whether to convert a MIF-format .doc output file to binary FrameMaker format. Default is -doc.

-format type
Which format to copy from the template document specified with the -template option. Type can be a comma-separated list, and -format can also be specified more than once. Legal types are:

Type

Description

all

All types (the default)

Character

Character formats

Paragraph

Paragraph formats

Page

Master page layouts

Reference

Reference page layouts

Table

Table formats

Variables

Variable definitions

Math

Math definitions

Cross

Cross-reference definitions

Color

Color definitions

Conditional

Conditional text definitions

Break

Preserves page breaks; controls how the other types are used

Other

Preserves other format changes; controls how the other types are used

-[no]index
Whether to generate an index. Defaults to -noindex.

-[no]lock
Whether to lock file as read-only so you can use hypertext marker feature. Defaults to -nolock.

-[no]mmlonly
Whether to stop execution after generating the MML version of the file. Default is -nommlonly.

-[no]open
Whether to try to open the book after creating it; requires the -book option.

-template document
Specifies a template document for pod2fm copies a format for use in formatting the output. document is the path to the template document.

-[no]toc
Whether to generate a table of contents. Defaults to -notoc.

pod2html
pod2html [options] inputfile

Translates files from pod to HTML format. Wrapper around the standard module Pod::Html; see Chapter 8, "Standard Modules" for the options, which are passed to Pod::Html as arguments.

pod2latex
pod2latex inputfile

Translates files from pod to LaTeX format. Writes output to a file with .tex extension.

pod2man
pod2man [options] inputfile

Translates pod directives in file inputfile to Unix manpage format. Converts pod-tagged text to nroff source that can be viewed by the man command, or troff for typesetting.

Options

--center=string
Sets centered header to string. Defaults to "User Contributed Perl Documentation" unless -\-official flag is set, in which case it defaults to "Perl Programmers Reference Guide."

--date=string
Sets left-hand footer string to date.

--fixed=font
Specifies the fixed-width font to use for code examples.

--lax
If set, ignores missing sections.

--official
If set, uses default header as shown for -\-center above.

--release=rel
Sets centered footer. Defaults to current Perl release.

--section=manext
Sets manpage section for nroff .TH macro. Default is 3 (functions) if filename ends in .pm; otherwise 1 (user commands).

pod2text
pod2text < input

Translates pod to text and displays it. A wrapper around the Pod::Text module.

Options

--help
Displays help information.

--htmlroot=name
Sets base URL for the HTML files to name.

--index
Generates index at top of the HTML file (default).

--infile=name
Converts pod file name. Default is to take input from STDIN.

--libpods=name:...:name
List of page names (e.g., "perlfunc") that contain linkable =item s.

--outfile=name
Creates HTML file name. Default is to send output to STDOUT.

--podroot=name
Uses name as base directory for finding library pods.

--podpath=name:...:name
Lists podroot subdirectories with pod files whose HTML-converted forms can be linked to in cross-references.

--netscape
Uses Netscape HTML directives when applicable.

--noindex
Does not generate index at top of the HTML file.

--nonetscape
Does not use Netscape HTML directives (default).

--norecurse
Does not recurse into subdirectories specified in podpath.

--recurse
Recurses into subdirectories specified in podpath (default).

--title=title
Specifies title for the resulting HTML file.

--verbose
Displays progress messages.

Previous | Home | Next
4.12. Formats | Book Index | 5. Function Reference
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 5. Function Reference

Contents:

Perl Functions by Category
Perl Functions in Alphabetical Order

This chapter gives a brief description of Perl's built-in functions. Each description gives the syntax of the function, with the types and order of its arguments.

Required arguments are shown in italics, separated by commas. If an argument must be a specific variable type, that variable's identifier will be used (e.g., a percent sign for a hash, %hash). Optional arguments are placed in brackets. Do not use the brackets in function calls unless you really want to use an anonymous hash reference.

There are different ways to use a built-in function. For starters, any argument that requires a scalar value can be made up of any expression that returns one. For example, you can obtain the square root of the first value in an array:

$root = sqrt (shift @numbers);

shift removes the first element of @numbers and returns it to be used by sqrt.

Many functions take a list of scalars for arguments. Any array variable or other expression that returns a list can be used for all or part of the arguments. For example:

chmod (split /,/ FILELIST>); # An expression returns a list
chmod 0755, @executables;    # Array used for part of arguments

In the first line, the split expression reads a string from a filehandle and splits it into a list. The list provides proper arguments for chmod. The second line uses an array that contains a list of filenames for chmod to act upon.

Parentheses are not required around a function's arguments. However, without parentheses, functions are viewed as operators in an expression (the same is true of predeclared subroutines). If you use a function in a complex expression, you may want to use parentheses for clarity. See Chapter 4, "The Perl Language" for more about precedence in Perl expressions.

5.1. Perl Functions by Category

Here are Perl's functions and function-like keywords, arranged by category. Note that some functions appear in more than one category.

Scalar manipulation
chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q//, qq//, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///

Regular expressions and pattern matching
m//, pos, qr//, quotemeta, s///, split, study

Numeric functions
abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand

Array processing
pop, push, shift, splice, unshift

List processing
grep, join, map, qw//, reverse, sort, unpack

Hash processing
delete, each, exists, keys, values

Input and output
binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir, rewinddir, seek, seekdir, select, syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write

Fixed-length data and records
pack, read, syscall, sysread, syswrite, unpack, vec

Filehandles, files, and directories
chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, stat, symlink, sysopen, umask, unlink, utime

Flow of program control
caller, continue, die, do, dump, eval, exit, goto, last, next, redo, return, sub, wantarray

Scoping
caller, import, local, my, package, use

Miscellaneous
defined, dump, eval, formline, local, my, prototype, reset, scalar, undef, wantarray

Processes and process groups
alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe, qx//, setpgrp, setpriority, sleep, system, times, wait, waitpid

Library modules
do, import, no, package, require, use

Classes and objects
bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use

Low-level socket access
accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket, socketpair

System V interprocess communication
msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop, shmctl, shmget, shmread, shmwrite

Fetching user and group information
endgrent, endhostent, endnetent, endpwent, getgrent, getgrgid, getgrnam, get-login, getpwent, getpwnam, getpwuid, setgrent, setpwent

Fetching network information
endprotoent, endservent, gethostbyaddr, gethostbyname, gethostent, getnet-byaddr, getnetbyname, getnetent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, sethostent, setnet-ent, setprotoent, setservent

Time
gmtime, localtime, time, times

Previous | Home | Next
4.13. Pod | Book Index | 5.2 Perl Functions in Alphabetical Order
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.2. Perl Functions in Alphabetical Order

abs
abs value
Returns the absolute value of its argument (or $_ if omitted).

accept
accept newsocket, genericsocket
Readies a server process to accept socket connections from clients. Execution is suspended until a connection is made, at which time the newsocket filehandle is opened and attached to the newly made connection. The function returns the connected address if the call succeeds or false otherwise (and it puts the error code into $!). genericsocket must be a filehandle already opened via the socket function and bound to one of the server's network addresses.

alarm
alarm n
Sends a SIGALRM signal to the executing Perl program after n seconds. On some older systems, alarms go off "at the top of the second," so, for instance, an alarm 1 may go off anywhere between 0 to 1 seconds from now, depending on when in the current second it is. An alarm 2 may go off anywhere from 1 to 2 seconds from now. And so on.

Each call disables the previous timer, and an argument of 0 may be supplied to cancel the previous timer without starting a new one. The return value is the number of seconds remaining on the previous timer.

atan2
atan2 y, x
Returns the arctangent of y/xin the range - Figure 5.4 to Figure 5.4. A quick way to get an approximate value of Figure 5.4 is to say:

$pi = atan2(1,1) * 4;

For the tangent operation, you may use the POSIX::tan( ) function, or use the familiar relation:

sub tan { sin($_[0]) / cos($_[0]) }
bind
bind socket, address
Attaches an address to an already opened socket specified by the socket filehandle. The function returns true for success, false otherwise (and puts the error code into $!). address should be a packed address of the proper type for the socket.

binmode
binmode filehandle
Arranges for the file to be treated in binary mode on operating systems that distinguish between binary and text files. It should be called after open but before any I/O is done on the filehandle. The only way to reset binary mode on a filehandle is to reopen the file.

binmode has no effect under Unix, Plan9, or other systems that use a single \n (newline) character as a line delimiter. On systems such as Win32 or MS-DOS, binmode is needed to prevent the translation of the line delimiter characters to and from \n.

bless
bless $ref, [classname]
Looks up the item pointed to by reference ref and tells the item that it is now an object in the classname package—or the current package if no class name is specified. It returns the reference for convenience, since a bless is often the last thing in a constructor function. (Always use the two-argument version if the constructor doing the blessing might be inherited by a derived class. In such cases, the class you want to bless your object into will normally be found as the first argument to the constructor in question.)

caller
caller [n]
Returns information about the stack of current subroutine calls. Without an argument, it returns the package name in a scalar context; in a list context, it returns the package name, filename, and line number from which the currently executing subroutine was called:

($package, $filename, $line) = caller;

With an argument it evaluates n as the number of stack frames to go back before the current one. It also reports some additional information that the debugger uses to print a stack trace:

$i = 0;
while (($pack, $file, $line, $subname, $hasargs,
        $wantarray, $evaltext, $is_require) = caller($i++)) {
    ...
}

Furthermore, when called from within the DB package, caller returns more detailed information: it sets the list variable @DB::args as the argument passed in the given stack frame.

chdir
chdir dirname
Changes the working directory to dirname, if possible. If dirname is omitted, it changes to the home directory. The function returns 1 upon success, 0 otherwise (and puts the error code into $!).

chmod
chmod mode, filelist
Changes the permissions of a list of files. The first argument must be the permissions mode given in its octal number representation. The function returns the number of files successfully changed. For example:

$cnt = chmod 0755, 'file1', 'file2';

will set $cnt to 0, 1, or 2, depending on how many files got changed (in the sense that the operation succeeded, not in the sense that the bits were different afterward).

chomp
chomp $var
chomp @list
Removes any line-ending characters of a string in $var, or each string in @list, that correspond to the current value of $/ (not just any last character, as chop does). chomp returns the number of characters deleted. If $/ is empty (in paragraph mode), chomp removes all newlines from the selected string (or strings, if chomping a list). If no argument is given, the function chomps the $_ variable.

chop
chop $var
chop @list
Chops off the last character of a string contained in the variable $var (or strings in each element of a @list) and returns the character chopped. The chop operator is used primarily to remove the newline from the end of an input record but is more efficient than s/\n$//. If no argument is given, the function chops the $_ variable.

chown
chown uid, gid, files
Changes the owner and group of a list of files. The first two arguments must be the numerical uid and gid, in that order. The function returns the number of files successfully changed.

On most systems, you are not allowed to change the ownership of the file unless you're the superuser, although you should be able to change the group to any of your secondary groups. On insecure systems, these restrictions may be relaxed, but this is not a portable assumption.

chr
chr number
Returns the character represented by number in the character set. For example, chr(65) is "A" in ASCII.

chroot
chroot dirname
Changes the root directory for the current process to dirname—the starting point for pathnames beginning with /. This directory is inherited across exec calls and by all subprocesses. There is no way to undo a chroot. Only the superuser can use this function.

close
close filehandle
Closes the file, socket, or pipe associated with the given filehandle. You don't have to close filehandle if you are immediately going to do another open on it, since the next open will close it for you. However, an explicit close on an input file resets the line counter ($.), while the implicit close done by open does not. Closing a pipe will wait for the process executing on the pipe to complete and will prevent the script from exiting before the pipeline is finished. Also, closing a pipe explicitly puts the status value of the command executing on the pipe into $?.

filehandle may be an expression with a value that gives a real filehandle name. It may also be a reference to a filehandle object returned by some of the object-oriented I/O packages.

closedir
closedir dirhandle
Closes a directory associated with the given directory handle opened by opendir.

connect
connect socket, address
Initiates a connection with another process that is waiting at an accept on the filehandle socket. The function returns true for success, false otherwise (and puts the error code into $!). address is a packed network address of the proper type for socket.

To disconnect a socket, use either close or shutdown.

cos
cos num
Returns the cosine of num (expressed in radians). For the inverse cosine operation, you may use the POSIX::acos( ) function, or use this relation:

sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
crypt
crypt string, salt
Used by the passwd function on Unix systems to produce a unique 13-character string (stored in the system's password file) from the first 8 characters of the given string and the 2-character salt. The Perl function operates the same way and returns a 13-character string with the first 2 characters as the salt. crypt uses a modified version of the Data Encryption Standard, which produces a one-way encryption; the resulting string cannot be decrypted to determine the original string. crypt can be used to check that a password is correct by comparing the string from the function to the string found in /etc/passwd (if you have permission to do this):

if (crypt ($guess, $pass) eq $pass) {
       # guess is correct
   }

The variable $pass is the password string from the password file. crypt merely uses the first two characters from this string for the saltargument.

dbmclose
dbmclose %hash
Breaks the binding between a DBM file and a hash.

This function is actually just a call to untie with the proper arguments, but is provided for backward compatibility with older versions of Perl.

dbmopen
dbmopen %hash, dbname, mode
Binds a DBM file (dbname) to a hash (%hash). dbnameis the name of the database without the .dir or .pag extension. Note that while not deprecated, dbmopen has basically been superseded by tie( ). If the database does not exist, and a valid mode is specified, the database is created with the permissions specified by mode (as modified by the umask). To prevent creation of the database if it doesn't exist, you may specify a mode of undef, and the function will return a false value if it can't find an existing database. If your system supports only the older DBM functions, you may have only one dbmopen in your program.

Values assigned to the hash prior to the dbmopen are not accessible. If you don't have write access to the DBM file, you can only read the hash variables, not set them.

This function is actually just a call to tie with the proper arguments, but is provided for backward compatibility with older versions of Perl.

defined
defined expr
Returns a Boolean value saying whether the scalar value resulting from expr has a real value. If no argument is given, defined checks $_.

A scalar that contains no valid string, numeric, or reference value is known as the undefined value, or undef. Many operations return the undefined value under exceptional conditions, such as end-of-file, uninitialized variable, system error, and so on. This function allows you to distinguish between an undefined null string and a defined null string when you're using operators that might return a real null string.

You can use defined to see if a subroutine exists, that is, if the subroutine definition has been successfully parsed. However, using defined on an array or a hash is not guaranteed to produce intuitive results and should be avoided.

delete
delete $hash{key}
delete @hash{@keys}
Deletes the specified key or keys and associated values from the specified hash. (It doesn't delete a file. See unlink for that.) Deleting from $ENV{} modifies the environment. Deleting from a hash that is bound to a (writable) DBM file deletes the entry from the DBM file.

For normal hashes, the delete function returns the value (not the key) that was deleted, but this behavior is not guaranteed for tied hashes, such as those bound to DBM files. To test whether a hash element has been deleted, use exists.

die
die message
Prints message to the standard error output and exits the Perl program with a nonzero exit status. message can be a list value, like the arguments to print, from which the elements are concatenated into a single string for output. If message does not end with a newline (\n), the current script filename, line number, and input line number (if any) are appended to the message with a newline. With no argument, the function outputs the string Died as its default.

die exits the programs with the current value of the $! variable, which contains the text describing the most recent operating system error value. This value can be used in the message to describe what the problem may have been.

die behaves differently inside an eval statement. It places the error message in the $@ variable and aborts the eval, which returns an undefined value. This use of die can raise runtime exceptions that can be caught at a higher level of the program.

do
do {block}
Executes the sequence of commands in the block and returns the value of the last expression evaluated. When modified by a loop modifier, Perl executes the blockonce before testing the loop condition. (On other statements, the loop modifiers test the conditional first.)

dump
dump label
During program execution, causes an immediate core dump after code previous to it has already been executed. Primarily, this is so that you can use the undump program to turn your core dump into an executable binary after having initialized all your variables at the beginning of the program. Please note that you shouldn't use dump( ) or undump( ) with the availability of the Perl Compiler (B modules) as part of your Perl distribution. In addition, you're unlikely to have success with dump or undump on most modern Unix systems (that support dynamic loading from libdl). dump arranges for the revived binary, when run, to begin by executing a goto label (with all the restrictions that goto suffers). Think of the operation as a goto with an intervening core dump and reincarnation. If label is omitted, the function arranges for the program to restart from the top. Note that any files opened at the time of the dump will no longer be open when the program is reincarnated. See also the -u command-line switch.

As of Perl 5.8, dump is now largely obsolete, partly because it's difficult to convert a core file into an executable, and because the real compiler backends for generating portable bytecode and compilable C code have superseded it. That's why you should now invoke it as "CORE::dump( )" if you don't want to be warned against a possible typo.

The undump program is not available on all systems and may not be compatible with specific ports of Perl.

each
each %hash
Returns a two-element list consisting of the key and value for the next element of a hash. With successive calls to each, you can iterate over the entire hash. Entries are returned in an indeterminate order. When the hash is entirely read, a null list is returned. The next call to each after that will start a new iteration. The iterator can be reset either by reading all the elements from the hash or by calling the keys function in scalar context. You must not add elements to the hash while iterating over it, although you are permitted to use delete. In a scalar context, each returns only the key.

There is a single iterator for each hash, shared by all each, keys, and values function calls in the program. This means that after a keys or values call, the next each call will start again from the beginning.

endgrent
endgrent
Closes the groups file (usually /etc/group on Unix systems) if open. Not implemented on Win32 systems.

endhostent
endhostent
Closes the hosts file (usually /etc/hosts on Unix systems) if open. Not implemented on Win32 systems.

endnetent
endnetent
Closes the networks file (usually /etc/networks on Unix systems) if open. Not implemented on Win32 systems.

endprotoent
endprotoent
Closes the prototypes file (usually /etc/prototypes on Unix systems) if open. Not implemented on Win32 systems.

endpwent
endpwent
Closes the password file (/etc/passwd or equivalent on Unix systems) if open. Not implemented on Win32 systems.

endservent
endservent
Closes the services file (usually /etc/services on Unix systems) if open. Not implemented on Win32 systems.

eof
eof filehandle
eof( )
Returns true if the next read on filehandle will return end-of-file, or if filehandle is not open. filehandle may be an expression with a value that gives the real filehandle name. An eof without an argument returns the end-of-file status for the last file read. Empty parentheses ( ) may be used in connection with the combined files listed on the command line. That is, inside a while (<>) loop, eof( ) will detect the end of only the last of a group of files. Use eof(ARGV) or eof (without parentheses) to test each file in a while (<>) loop. For example, the following code inserts dashes just before the last line of the last file:

while (<>) {
    if (eof( )) {
        print "-" x 30, "\n";
    }
    print;
}
eval
eval string
eval {block}
Evaluates the expression or code in its argument at runtime as a separate Perl program within the context of the larger script. Any variable settings remain afterward, as do any subroutine or format definitions. The code of the eval is treated as a block, so any locally scoped variables declared within the eval last only until the eval is done. (See also local and my.) The value returned from an eval is the value of the last expression evaluated. Like subroutines, you may also use the return function to return a value and exit the eval.

With eval string, the contents of string are compiled and executed at runtime. For example:

$a = 3, $b = 4;
$c = '$a * $b';
print (eval "$c"); # Prints 12

The string form of eval is useful for executing strings produced at runtime from standard or other dynamic input sources. If the string produces an error, either from syntax or at runtime, the eval exits with the undefined value and places the error in $@. If string is omitted, the operator evaluates $_.

The block form of eval is used in Perl programs to handle runtime errors (exceptions). The code in block is compiled only once during the compilation of the main program. If there is a syntax error in the block, it will produce an error at compile time. If the code in block produces a runtime error (or if a die statement is encountered), the eval exits, and the error is placed in $@. For example, the following code can be used to trap a divide-by-zero error at runtime:

eval {
      $a = 10; $b = 0;
      $c = $a / $b;     # Causes runtime error
                        # Trapped by eval
     };
print $@;               # Prints "Illegal division by 0 at
                        # try.pl line 3"

As with any code in a block, a final semicolon is not required.

exec
exec command
Terminates the currently running Perl script and executes the program named in command. The Perl program does not resume after the exec unless the exec cannot be run and produces an error. Unlike system, the executed command is not forked off into a child process. An exec completely replaces the script in its current process.

command may be a scalar containing a string with the name of the program to run and any arguments. This string is checked for shell metacharacters, and if there are any, passes the string to /bin/sh/ -c for parsing. Otherwise, the string is read as a program command, bypassing any shell processing. The first word of the string is used as the program name, with any remaining words used as arguments.

command may also be a list value in which the first element is parsed as the program name and remaining elements as arguments. For example:

exec 'echo', 'Your arguments are: ', @ARGV;

The exec function is not implemented for Perl on Win32 platforms.

exists
exists $hash{$key}
Returns true if the specified hash key exists, even if the corresponding value is undefined.

exit
exit status
Exits the current Perl process immediately with that value given by status. This could be the entire Perl script you are running or only a child process created by fork. Here's a fragment that lets a user exit the program by typing x or X:

$ans = <STDIN>;
exit 0 if $ans =~ /^[Xx]/;

If status is omitted, the function exits with 0. You shouldn't use exit to abort a subroutine if there's any chance that someone might want to trap whatever error happened. Use die instead, which can be trapped by an eval.

exp
exp num
Returns e to the power of num. If num is omitted, it gives exp($_). To do general exponentiation, use the ** operator.

fcntl
fcntl filehandle, function, arg
Calls the file control function (with the function-specific arg) to use on the file or device opened with filehandle. fcntl calls Unix's fcntl function (not available on Win32 platforms). If the function is not implemented, the program exits with a fatal error. fcntl sets file descriptors for a filehandle. This built-in command is usable when you use the Fcntl module in the standard distribution:

use Fcntl;

This module imports the correct functiondefinitions. See the description of the Fcntl module in Chapter 8, "Standard Modules".

The return value of fcntl (and ioctl) is as follows:

System call returns | Perl returns
-1 | Undefined value
0 | String "0 but true"
Anything else | That number

Thus Perl returns true on success and false on failure, yet you can still easily determine the actual value returned by the operating system.

fileno
fileno filehandle
Returns the file descriptor for a filehandle. (A file descriptor is a small integer, unlike the filehandle, which is a symbol.) It returns undef if the handle is not open. It's useful for constructing bitmaps for select and for passing to certain obscure system calls if syscall is implemented. It's also useful for double-checking that the open function gave you the file descriptor you wanted.

flock
flock filehandle, operation
Establishes or removes a lock on a file opened with filehandle. This function calls one of the Unix functions flock, lockf, or the locking capabilities of fcntl, whichever your system supports. If none of these functions exist on your system, flock will produce a fatal error.

operation is the type of locking function to perform. The number by each operation name is the argument that Perl's flock takes by default. You may also use the operation names if you explicitly import them from the Fcntl module with use Fcntl ":flock".

LOCK_SH (1)">LOCK_SH (1)
Establishes a shared lock on the file (read lock).

LOCK_EX (2)">LOCK_EX (2)
Establishes an exclusive lock on the file (write lock).

LOCK_UN (8)">LOCK_UN (8)
Removes a lock from the file.

LOCK_NB (4)">LOCK_NB (4)
Prevents flock from blocking while trying to establish a lock with LOCK_SH or LOCK_EX and instructs it to return immediately. LOCK_NB must be ored with the other operation as an expression for the operation argument, i.e., (LOCK_EX | LOCK_NB).

fork
fork
Spawns a child process that executes the code immediately following the fork call until the process is terminated (usually with an exit). The child process runs parallel to the parent process and shares all the parent's variables and open filehandles. The function returns the child pid to the parent process and 0 to the child process on success. If it fails, it returns the undefined value to the parent process, and no child process is created. If you fork your child processes, you'll have to wait on their zombies when they die. The fork function is unlikely to be implemented on any operating system not resembling Unix, unless it purports POSIX compliance.

formline
formline picture, variables
Internal function used by formats, although you may also call it. It formats a list of values (variables) according to the contents of picture, placing the output into the format output accumulator, $^A. When a write is done, the contents of $^A are written to a filehandle, but you can also read $^A yourself and set $^A back to "". Note that a format typically does one formline per line of form, but the formline function itself doesn't care how many newlines are embedded in the picture. This means that the ~ and ~~ tokens will treat the entire picture as a single line. Thus, you may need to use multiple formlines to implement a single-record format, such as the format compiler.

Be careful if you put double quotes around the picture, since an @ character may be taken to mean the beginning of an array name. formline always returns true. See Chapter 4, "The Perl Language" for more information.

getc
getc filehandle
Returns the next byte from the input file attached to filehandle. At end-of-file, it returns a null string. If filehandle is omitted, the function reads from STDIN. This operator is very slow, but is occasionally useful for single-character input from the keyboard.

getgrent
getgrent
Returns the next entry from the systems group file (usually /etc/group on Unix systems) starting from the top. Returns null when end-of-file is reached. The return value from getgrent in list context is:

($name, $passwd, $gid, $members)

in which $members contains a space-separated list of the login names of the members of the group. In scalar context, getgrent returns only the group name.

getgrgid
getgrgid gid
Retrieves a group file (/etc/group) entry by group number gid. The return value in list context is:

($name, $passwd, $gid, $members)

in which $members contains a space-separated list of the login names of the members of the group. If you want to do this repeatedly, consider caching the data in a hash using getgrent. In scalar context, getgrgid returns only the group name.

getgrnam
getgrnam name
Retrieves a group file entry by the group name name. The return value in list context is:

($name, $passwd, $gid, $members)

in which $members contains a space-separated list of the login names of the members of the group. In scalar context, getgrnam returns only the numeric group ID.

gethostbyaddr
gethostbyaddr address, [addrtype]
Retrieves the hostname (and alternate addresses) of a packed binary network address. (addrtype indicates the type of address given. Since gethostbyaddr is used almost solely for Internet IP addresses, addrtype is not needed.) The return value in list context is:

($name, $aliases, $addrtype, $length, @addrs)

in which @addrs is a list of packed binary addresses. In the Internet domain, each address is four bytes long and can be unpacked by something like:

($a, $b, $c, $d) = unpack('C4', $addrs[0]);

In scalar context, gethostbyaddr returns only the hostname.

gethostbyname
gethostbyname name
Retrieves the address (and other names) of a network hostname. The return value in list context is:

($name, $aliases, $addrtype, $length, @addrs)

in which @addrs is a list of raw addresses. In scalar context, gethostbyname returns only the host address.

gethostent
gethostent
Retrieves the next entry from your system's network hosts file (usually /etc/hosts on Unix). The return value from gethostent is:

($name, $aliases, $addrtype, $length, @addrs)

in which @addrs is a list of raw addresses. Scripts that use this function should not be considered portable.

getlogin
getlogin
Returns the current login from /etc/utmp (Unix systems only), if any. If null, use getpwuid. For example:

$login = getlogin || getpwuid($<) || "Intruder!!";
getnetbyaddr
getnetbyaddr address, [addrtype]
Retrieves the network name or names of the given network address. (addrtype indicates the type of address. Often, this function is used for IP addresses, in which the type is not needed.) The return value in list context is:

($name, $aliases, $addrtype, $net)

In scalar context, getnetbyaddr returns only the network name.

getnetbyname
getnetbyname name
Retrieves the network address of a network name. The return value in list context is:

($name, $aliases, $addrtype, $net)

In scalar context, getnetbyname returns only the network address.

getnetent
getnetent
Retrieves the next line from your /etc/networks file, or system equivalent. The return value in list context is:

($name, $aliases, $addrtype, $net)

In scalar context, getnetent returns only the network name.

getpeername
getpeername socket
Returns the packed socket address of the other end of the socket connection. For example:

use Socket;
$hersockaddr = getpeername SOCK;
($port, $heraddr) = unpack_sockaddr_in($hersockaddr);
$herhostname = gethostbyaddr($heraddr, AF_INET);
$herstraddr = inet_ntoa($heraddr);
getpgrp
getpgrp pid
Returns the current process group for the specified process ID (pid). Use a pid of 0 for the current process. Invoking getpgrp will produce a fatal error if used on a machine that doesn't implement the getpgrp system call. If pid is omitted, the function returns the process group of the current process (the same as using a pid of 0). On systems implementing this operator with the POSIX getpgrp(2) system call, pid must be omitted or, if supplied, must be 0.

getppid
getppid
Returns the process ID of the parent process. On a typical Unix system, if your parent process ID changes to 1, your parent process has died, and you've been adopted by the init program.

getpriority
getpriority type, id
Returns the current priority for a process, a process group, or a user. type indicates which of these three process types to return. (The type identifiers are system-specific. Consult the manpage for getpriority.) The id gives the specific ID of the corresponding process type in type: a process ID, a process-group ID, or a user ID. The value 0 in who gives the priority for the current process, process group, or user.

The priority will be an integer value. Lower values indicate higher priority (negative values may be returned on some systems). Invoking getpriority will produce a fatal error if used on a machine that doesn't implement the getpriority system call.

getprotobyname
getprotobyname name
Translates a protocol name to its corresponding number. The return value in list context is:

($name, $aliases, $protocol_number)

In scalar context, getprotobyname returns only the protocol number.

getprotobynumber
getprotobynumber number
Translates a protocol number to its corresponding name. The return value in list context is:

($name, $aliases, $protocol_number)

In scalar context, getprotobynumber returns only the protocol name.

getprotoent
getprotoent
Retrieves the next line from the /etc/protocols file (on some Unix systems). Returns null at the end of the file. The return value from getprotoent is:

($name, $aliases, $protocol_number)

In scalar context, getprotoent returns only the protocol name.

getpwent
getpwent
Retrieves the next line from the /etc/passwd file (or its equivalent coming from another server). Returns null at the end of the file. The return value in list context is:

($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell)

Some machines may use the quota and comment fields for other purposes, but the remaining fields will always be the same. To set up a hash for translating login names to uids, do this:

while (($name, $passwd, $uid) = getpwent) {
    $uid{$name} = $uid;
}

In scalar context, getpwent returns only the username.

getpwnam
getpwnam name
Retrieves the passwd file entry of a user name. The return value in list context is:

($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell)

If you want to do this repeatedly, consider caching the data in a hash using getpwent.

In scalar context, getpwnam returns only the numeric user ID.

getpwuid
getpwuid uid
Retrieves the passwd file entry with the user ID uid. The return value in list context is:

($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell)

If you want to do this repeatedly, consider slurping the data into a hash using getpwent.

In scalar context, getpwuid returns the username.

getservbyname
getservbyname name, proto
Translates a service (port) name to its corresponding port number. proto is a protocol name such as tcp. The return value in list context is:

($name, $aliases, $port_number, $protocol_name)

In scalar context, getservbyname returns only the service port number.

getservbyport
getservbyport port, proto
Translates a service (port) number to its corresponding names. proto is a protocol name such as tcp. The return value in list context is:

($name, $aliases, $port_number, $protocol_name)

In scalar context, getservbyport returns only the service port name.

getservent
getservent
Retrieves the next listing from the /etc/services file or its equivalent. Returns null at the end of the file. The return value in list context is:

($name, $aliases, $port_number, $protocol_name)

In scalar context, getservent returns only the service port name.

getsockname
getsockname socket
Returns the packed socket address of this end of the socket connection.

getsockopt
getsockopt socket, level, optname
Returns the value of the socket option optname, or the undefined value if there is an error. level identifies the protocol level used by socket. Options vary for different protocols. See also setsockopt.

glob
glob expr
Performs filename expansion (globbing) on expr, returning the next successive name on each call. If expr is omitted, $_ is globbed instead. This is the internal function implementing the <*> operator, except that it may be easier to type this way.

The glob function is not related to the Perl notion of typeglobs, other than that they both use a * to represent multiple items.

gmtime
gmtime expr
Converts a time string as returned by the time function to a nine-element list with the time correct for Greenwich Mean Time zone (a.k.a. GMT, UTC, etc.). Typically used as follows:

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
        gmtime(time);

All list elements are numeric and come straight out of a C language struct tm. In particular, this means that $mon has the range 0..11, $wday has the range 0..6, and the year has had 1,900 subtracted from it. (You can remember which elements are 0-based because you're always using these as subscripts into 0-based arrays containing month and day names.) If expr is omitted, it does gmtime(time). For example, to print the current month in London:

$london_month = (qw(Jan Feb Mar Apr May Jun
        Jul Aug Sep Oct Nov Dec))[(gmtime)[4]];

The Perl library module Time::Local contains a subroutine, timegm( ), that can convert in the opposite direction.

In scalar context, gmtime returns a ctime(3)-like string based on the GMT time value.

goto
goto label
goto &name
Finds the statement labeled with label (or an expression that evaluates to a label) and resumes execution there. It may not be used to go into any construct that requires initialization, such as a subroutine or a foreach loop. It also can't be used to go into a construct that is optimized away. It can be used to go almost anywhere else within the dynamic scope, including out of subroutines, but for that purpose, it's usually better to use another construct, such as last or die.

goto &name substitutes a call to the named subroutine for the currently running subroutine. This is used by AUTOLOAD subroutines that wish to load another subroutine and pretend that this subroutine—and not the original one—had been called in the first place (except that any modifications to @_ in the original subroutine are propagated to the replacement subroutine). After the goto, not even caller will be able to tell that the original routine was called first.

grep
grep expr, list
grep {block} list
Evaluates expr or blockin a Boolean context for each element of list, temporarily setting $_ to each element in turn. In list context, it returns a list of those elements for which the expression is true. Mostly used like Unix grep, in which expr is a search pattern, and list elements that match are returned. In scalar context, grep returns the number of times the expression was true.

For example, presuming @all_lines contains lines of code, this example weeds out comment lines:

@code_lines = grep !/^#/, @all_lines;
hex
hex hexnum
Converts a hexadecimal string hexnum into its equivalent decimal value. If hexnum is omitted, it interprets $_. The following code sets $number to 4,294,906,560:

$number = hex("ffff12c0");

To do the inverse function, use:

sprintf "%lx", $number;   # That's a letter 'l', not a one
index
index string, substr, [start]
Returns the position of the first occurrence of substr in string. The start, if specified, specifies the position to start looking in the string. Positions are integer numbers based at 0. If the substring is not found, the index function returns -1.

int
int num
Returns the integer portion of num. If num is omitted, the function uses $_.

ioctl
ioctl filehandle, function, arg
Calls the ioctl Unix system call to perform function (with the function-specific arg) on the file or device opened with filehandle. See fcntl for a description of return values.

join
join char, list
Joins the separate strings of list into a single string with fields separated by the value of char and returns the string. For example:

$_ = join ':', $login,$passwd,$uid,$gid,$gcos,$home,$shell;

To do the opposite, see split. To join things together into fixed-position fields, see pack.

keys
keys %hash
Returns a list consisting of all the keys of the named hash. The keys are returned in an apparently random order, but it is the same order that either the values or each function produces (assuming that the hash has not been modified between calls).

In scalar context, keys returns the number of elements of the hash (and resets the each iterator).

keys can be used as an lvalue to increase the number of hash buckets allocated for the hash:

keys %hash = 200;
kill
kill sig, processes
Sends a signal, sig, to a list of processes. You may use a signal name in quotes (without a SIG on the front). This function returns the number of processes successfully signaled. If the signal is negative, the function kills process groups instead of processes.

last
last label
Immediately exits the loop identified by label. If label is omitted, the command refers to the innermost enclosing loop.

lc
lc string
Returns a lowercase version of string (or $_, if omitted). This is the internal function implementing the \L escape in double-quoted strings.

lcfirst
lcfirst string
Returns a version of string (or $_, if omitted) with the first character lowercased. This is the internal function implementing the \l escape in double-quoted strings.

length
length val
Returns the length in bytes of the scalar value val. If val is omitted, the function returns the length of $_.

Do not try to use length to find the size of an array or hash. Use scalar @array for the size of an array, and scalar keys %hashfor the size of a hash.

link
link oldfile, newfile
Creates a Unix hard link from a new filename, newfile, to an existing file, oldfile, on the same filesystem. The function returns 1 for success, 0 otherwise (and puts the error code into $!). This function is unlikely to be implemented on non-Unix systems. See also symlink.

listen
listen socket, queuesize
Tells the operating system that you are ready to accept connections on socket and sets the number of waiting connections to queuesize. If the queue is full, clients trying to connect to the socket will be refused connection.

local
local vars
Declares one or more global variables vars to have temporary values within the innermost enclosing block, subroutine, eval, or file. The new value is initially undef for scalars and ( ) for arrays and hashes. If more than one variable is listed, the list must be placed in parentheses, because the operator binds more tightly than a comma. All the listed variables must be legal lvalues, that is, something you can assign to. This operator works by saving the current values of those variables on a hidden stack and restoring them upon exiting the block, subroutine, eval, or file.

Subroutines called within the scope of a local variable will see the localized inner value of the variable. The technical term for this process is "dynamic scoping." Use my for true private variables.

localtime
localtime val
Converts the value returned by time to a nine-element list with the time corrected for the local time zone. It's typically used as follows:

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
        localtime(time);

All list elements are numeric. The element $mon (month) has the range 0..11, and $wday (weekday) has the range 0..6. The year has had 1,900 subtracted from it. (You can remember which elements are 0-based because you're always using them as subscripts into 0-based arrays containing month and day names.) If val is omitted, it does localtime(time). For example, to get the name of the current day of the week:

$thisday = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[(localtime)[6]];

The Perl library module Time::Local contains a subroutine, timelocal( ), that can convert in the opposite direction.

In scalar context, localtime returns a ctime(3)-like string based on the localtime value.

log
log num
Returns logarithm (base e) of num. If num is omitted, the function uses $_.

lstat
lstat file
Like stat, returns information on file, except that if file is a symbolic link, lstat returns information about the link; stat returns information about the file pointed to by the link. (If symbolic links are unimplemented on your system, a normal stat is done instead.)

map
map {block} list
map expr, list
Evaluates the block or exprfor each element of list (locally setting $_ to each element) and returns the list value composed of the results of each evaluation. It evaluates block or exprin a list context, so each element of listmay produce zero, one, or more elements in the returned value. These are all flattened into one list. For instance:

@words = map { split ' ' } @lines;

splits a list of lines into a list of words. Often, though, there is a one-to-one mapping between input values and output values:

@chars = map chr, @nums;

This statement translates a list of numbers to the corresponding characters.

mkdir
mkdir filename, mode
Creates the directory specified by filename, with permissions specified by the numeric mode(as modified by the current umask). If it succeeds, it returns 1; otherwise, it returns 0 and sets $! (from the value of errno).

msgctl
msgctl id, cmd, arg
Calls the msgctl system call, which is used to perform different control operations on IPC message queues. (See the msgctl documentation on your system for details.) If cmd is &IPC_STAT, then argmust be a variable that will hold the returned msqid_ds structure. The return values work like those of fnctl: the undefined value for error, 0 but true for zero, or the actual return value otherwise. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "msg.ph";

This function is available only on machines supporting System V IPC.

msgget
msgget key, flags
Calls the System V IPC msgget system call. See the msgget documentation on your system for details. The function returns the message queue ID, or the undefined value if there is an error. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "msg.ph";

This function is available only on machines supporting System V IPC.

msgrcv
msgrcv id, var, size, type, flags
Calls the System V IPC msgrcv system call to receive a message from message queue id into variable var with a maximum message size of size. When a message is received, the message type will be the first thing in var, and the maximum length of var is sizeplus the size of the message type. The function returns true if successful, or false if there is an error. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "msg.ph";

This function is available only on machines supporting System V IPC.

msgsnd
msgsnd id, msg, flags
Calls the System V IPC msgsnd system call to send the message msg to the message queue id. msg must begin with the long integer message type. You can create a message like this:

$msg = pack "L a*", $type, $text_of_message;

The function returns true if successful, or false if there is an error. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "msg.ph";

This function is available only on machines supporting System V IPC.

my
my vars
Declares one or more private variables to exist only within the innermost enclosing block, subroutine, eval, or file. The new value is initially undef for scalars and ( ) for arrays and hashes. If more than one variable is listed, the list must be placed in parentheses, because the operator binds more tightly than a comma. Only simple scalars or complete arrays and hashes may be declared this way. The variable name may not be package-qualified, because package variables are all global, and private variables are not related to any package.

Unlike local, this operator has nothing to do with global variables, other than hiding any other variable of the same name from view within its scope. (A global variable can always be accessed through its package-qualified form or a symbolic reference, however.) A private variable is not visible until the statement after its declaration. Subroutines called from within the scope of such a private variable cannot see the private variable unless the subroutine is also textually declared within the scope of the variable.

next
next label
Immediately jumps to the next iteration of the loop identified by label or the innermost enclosing loop, if there is no argument. If there is a continue block, it will be executed immediately after the next, before the loop is reiterated.

no
no Module list
Effectively "undoes" the use function. Used to deactivate pragmas (compiler directives) for sections of your program. For instance:

no strict 'refs'

allows soft references to the end of the block scope if:

use strict 'refs'

was previously invoked.

oct
oct ostring
Interprets ostring as an octal string and returns the equivalent decimal value. (If ostringhappens to start with 0x, it is interpreted as a hex string instead.) The following will handle decimal, octal, and hex in the standard notation:

$val = oct $val if $val =~ /^0/;

If ostring is omitted, the function interprets $_. To perform the inverse function on octal numbers, use:

$oct_string = sprintf "%lo", $number;
open
open filehandle, filename

open filehandle, mode, filename

open filehandle, mode, expr, list (new in 5.8)

open filehandle, mode, reference (new in 5.8)
Opens the file given by filename and associates it with filehandle. If filehandle is omitted, the scalar variable of the same name as the filehandle must contain the filename. (And you must also be careful to use or die after the statement rather than || die, because the precedence of || is higher than list operators such as open.)

If filename is preceded by either < or nothing, the file is opened for input (read-only). If filename is preceded by >, the file is opened for output. If the file doesn't exist, it will be created; if the file exists, it will be overwritten with output using >. Preceding the filename with >> opens an output file for appending. For both read and write access, use a + before < or >.

If you choose to use the three-or-more-arguments form of open, you can use separate mode and filename arguments, such as open($fh, $mode, $filename), in which $moderepresents an open mode or pipe. For example:

my $mode = '+<';
my $filename = 'whatever.txt';
open(FH, $mode, $filename)
    or die("can't open $filename: $!");

As covered in Chapter 4, "The Perl Language", you can build Perl 5.8 and newer with PerlIO support, which offers additional features for your system's I/O (STDIO). This allows you to do neat things, such as specify utf-8 as your default encoding for all of your I/O, or set your default line endings with 'crlf'. In addition, you can select piping to or extracting information from an external program with '|-' and '-|', respectively. For example:

my $prog = "webster overworked";
open($fh, '-|', $prog)
    or die("can't open pipe to '$prog': $!");

or, similarly:

my @prog_info = qw(/usr/contrib/bin/webster overworked);
open($fh, '-|', @prog_info)
    or die(...);

A filehandle may also be attached to a process by using a piped command. If the filename begins with |, the filename is interpreted as a command to which output is to be piped. If the filename ends with a |, the filename is interpreted as a command that pipes input to you. You may not have an open command that pipes both in and out.

Any pipe command containing shell metacharacters is passed to the shell for execution; otherwise, it is executed directly by Perl. The filename - refers to STDIN, and > refers to STDOUT. open returns nonzero upon success, the undefined value otherwise. If the open involved a pipe, the return value happens to be the process ID of the subprocess.

opendir
opendir dirhandle, directory
Opens a directory for processing by readdir, telldir, seekdir, rewinddir, and closedir. The function returns true if successful. Directory handles have their own namespace separate from filehandles.

ord
ord expr
Returns the numeric ASCII value of the first character of expr. If expr is omitted, it uses $_. The return value is always unsigned. If you want a signed value, use unpack('c', expr). If you want all the characters of the string converted to a list of numbers, use unpack('C*', expr) instead.

our
our vars
Declares the listed variables to be valid globals within the enclosing block, file, or eval. vars must be in parentheses if more than one value is used. our( ) has the same scoping rules as a "my" declaration but does not create a local variable. Variables that you create with our( ) will be visible across its lexical scope and may cross package boundaries. Unlike use vars, our( ) is not package scoped; the package in which the variable is entered is determined at the point of declaration, not at the time of use. This means the following behavior holds:

package Foo;
                our $bar;           # Declares $Foo::bar for rest of lexical scope
                $bar = 20;

                package Bar;
                print $bar;         # Prints 20

You my use multiple our declarations in the same lexical scope if they are in different packages. If they are in the same package, Perl will emit warnings if you have asked for them:

use warnings;
                package Foo;
                our $bar;           # Declares $Foo::bar for rest of lexical scope
                $bar = 20;

                package Bar;
                our $bar = 30;      # Declares $Bar::bar for rest of lexical scope
                print $bar;         # Prints 30
                our $bar;           # Emits warning
pack
pack template, list
Takes a list of values and packs it into a binary structure, returning the string containing the structure. templateis a sequence of characters that give the order and type of values, as follows:

Character | Meaning
@ | Null-fill to absolute position.
( | Start of a ( ) group.
a | An ASCII string, will be null padded.
A | An ASCII string, will be space padded.
b | A bit string, low-to-high order (such as vec( )).
B | A bit string, high-to-low order.
c | A signed char value.
C | An unsigned char value.
d | A double-precision float in the native format.
D | A long double-precision float in the native format. Long doubles are avai able only if your system supports long double values and if Perl has been compiled to support these values. Causes a fatal error otherwise. New in 5.8.
f | A single-precision float in the native format.
F | A floating-point value in the native format, i.e., a Perl internal floating-point value (NV). New in 5.8.
h | A hexadecimal string, low nybble first.
H | A hexadecimal string, high nybble first.
i | A signed integer value.
I | An unsigned integer value.
l | A signed long value.
j | A signed integer value, i.e., a Perl internal integer (IV). New in 5.8.
J | An unsigned integer value, i.e., a Perl internal unsigned integer (UV). New in 5.8.
L | An unsigned long value.
n | A short in "network" (big-endian) order.
N | A long in "network" (big-endian) order.
p | A pointer to a string.
P | A pointer to a structure (fixed-length string).
q | A signed quad (64-bit) value. New in 5.8.
Q | An unsigned quad value. Quads are available only if your system supports 64-bit integer values and if Perl has been compiled to support these values. Causes a fatal error otherwise. New in 5.8.
s | A signed short value.
S | An unsigned short value.
v | A short in "VAX" (little-endian) order.
V | A long in "VAX" (little-endian) order.
u | A uuencoded string.
U | A Unicode character number. Encodes to UTF-8 internally (or UTF-EBCDIC in EBCDIC platforms). New in 5.8.
w | A BER compressed integer.
x | A null byte.
X | Back up a byte.
Z | A null terminated (ASCII) string. Will be null padded. New in 5.8.
Each character may optionally be followed by a number that gives a repeat count. Together the character and the repeat count make a field specifier. Field specifiers may be separated by whitespace, which will be ignored. With all types except a and A, the pack function will gobble up that many values from the list. Specifying * for the repeat count means to use however many items are left. The a and A types gobble just one value, but pack it as a string of length count, padding with nulls or spaces as necessary. (When unpacking, A strips trailing spaces and nulls, but a does not.) Real numbers (floats and doubles) are in the native machine format only; due to the multiplicity of floating formats, and the lack of a standard network representation, no facility for interchange has been made.

Generally, the same template may also be used in the unpack function. If you want to join variable length fields with a delimiter, use the join function.

package
package namespace
Declares that the rest of the innermost enclosing block, subroutine, eval, or file belongs to the indicated namespace. (The scope of a package declaration is thus the same as the scope of a local or my declaration.) All subsequent references to unqualified global identifiers will be resolved by looking them up in the declared packages symbol table. A package declaration affects only global variables—including those you've used local on—but not lexical variables created with my.

Using package without an argument is possible, but since its semantics are unclear, package; has been depracated in Perl 5.8. If you intend to disallow variables that aren't fully qualified, use strict; instead.

Typically, you put a package declaration as the first thing in a file that will be included by the require or use operator, but you can put one anywhere that a statement would be legal. When defining a class or a module file, it is customary to name the package the same name as the file, to avoid confusion. (It's also customary to name such packages beginning with a capital letter, because lowercase modules are, by convention, interpreted as pragmas.)

pipe
pipe readhandle, writehandle
Opens a pair of connected pipes. This call is almost always used right before a fork, after which the pipes reader should close writehandle, and the writer should close readhandle. (Otherwise, the pipe won't indicate end-of-file to the reader when the writer closes it.) Note that if you set up a loop of piped processes, deadlock can occur unless you are very careful. In addition, note that Perl's pipes use standard I/O buffering, so you may need to set $| on your writehandle to flush after each output command, depending on the application. See select filehandle.

pop
pop @array
Treats an array like a stack, popping and returning the last value of the array and shortening the array by one element. If array is omitted, the function pops @ARGV (in the main program) or @_ (in subroutines).

If there are no elements in the array, pop returns the undefined value. See also push and shift. If you want to pop more than one element, use splice.

pos
pos $scalar
Returns the location in scalar where the last m//g search over scalarleft off. It returns the offset of the character after the last one matched. This is the offset where the next m//g search on that string will start. Remember that the offset of the beginning of the string is 0. For example:

$grafitto = "fee fie foe foo";
while ($grafitto =~ m/e/g) {
    print pos $grafitto, "\n";
}

prints 2, 3, 7, and 11, the offsets of each of the characters following an "e". The pos function may be assigned a value to tell the next m//g where to start.

print
print [filehandle] list
Prints a string or a comma-separated list of strings to the specified filehandle. If no filehandle is given, the function prints to the currently open filehandle (STDOUT initially). The function returns 1 if successful, 0 otherwise. filehandlemay be a scalar variable name (unsubscripted), in which case the variable contains either the name of the actual filehandle or a reference to a filehandle object from one of the object-oriented filehandle packages. filehandle may also be a block that returns either kind of value:

print { $OK ? "STDOUT" : "STDERR" } "stuff\n";
print { $iohandle[$i] } "stuff\n";

If list is also omitted, $_ is printed. Note that because print takes a list, anything in the list is evaluated in list context.

printf
printf [filehandle] format, list
Prints a formatted string of the elements in list to filehandle or, if omitted, the currently selected output filehandle. This is similar to the C library's printf and fprintf functions, except that the * field width specifier is not supported. The function is exactly equivalent to:

print filehandle sprintf(format, list);

printf and sprintf use the same format syntax, but sprintf returns only a string; it doesn't print to a filehandle. The format string contains text with embedded field specifiers into which the elements of list are substituted in order, one per field. Field specifiers follow the form:

%m.nx

A percent sign begins each field, and x is the type of field. The optional m gives the minimum field width for appropriate field types (negative m left-justifies). The .n gives the precision for a specific field type, such as the number of digits after a decimal point for floating-point numbers, the maximum length for a string, and the minimum length for an integer.

Field specifiers (x) may be the following:

Code | Meaning
% | Percent sign
c | Character
d | Decimal integer
e | Exponential format floating-point number
E | Exponential format floating-point number with uppercase E
f | Fixed-point format floating-point number
g | Floating-point number, in either exponential or fixed decimal notation
G | Like g with uppercase E (if applicable)
ld | Long decimal integer
lo | Long octal integer
lu | Long unsigned decimal integer
lx | Long hexadecimal integer
o | Octal integer
s | String
u | Unsigned decimal integer
x | Hexadecimal integer
X | Hexadecimal integer with uppercase letters
p | The Perl value's address in hexadecimal
n | Special value that stores the number of characters output so far into the next variable in the parameter list
prototype
prototype function
Returns the prototype of a function as a string, or undef if the function has no prototype. function is the name of the function or a reference to it.

push
push @array, list
Pushes the elements of list onto the end of array. The length of array increases by the length of list. The function returns this new length. See also pop and unshift.

q/string/
q/string/
qq/string/
qx/string/
qw/strings/
Generalized forms of quoting. q// is equivalent to using single quotes (literal, no variable interpolation). qq// is equivalent to double quotes (literal, interpolated). qx// is equivalent to using backticks for commands (interpolated). And qw// is equivalent to splitting a single-quoted string on whitespace.

quotemeta
quotemeta expr
Returns the value of expr (or $_ if not specified) with all non-alphanumeric characters backslashed. This is the internal function implementing the \Q escape in interpolative contexts (including double-quoted strings, backticks, and patterns).

rand
rand num
Returns a random fractional number between 0 and the value of num. (numshould be positive.) If num is omitted, the function returns a value between 0 and 1 (including 0, but excluding 1). See also srand.

To get an integral value, combine this with int, as in:

$roll = int(rand 6) + 1;       # $roll is now an integer between 1 and 6
read
read filehandle, $var, length, [offset]
Attempts to read length bytes of data into variable var from the specified filehandle. The function returns the number of bytes actually read, or 0 at end-of-file. It returns the undefined value on error. var will grow or shrink to the length actually read. The offset, if specified, says where in the variable to start putting bytes, so that you can do a read into the middle of a string.

To copy data from the filehandle FROM into the filehandle TO, you could say:

while (read FROM, $buf, 16384) {
    print TO $buf;
}

Note that the opposite of read is simply print, which already knows the length of the string you want to write and can write a string of any length.

Perl's read function is actually implemented in terms of standard I/O's fread function, so the actual read system call may read more than length bytes to fill the input buffer, and fread may do more than one system read to fill the buffer. To gain greater control, specify the real system call using sysread.

readdir
readdir dirhandle
Reads directory entries from a directory handle opened by opendir. In scalar context, this function returns the next directory entry, if any; otherwise, it returns an undefined value. In list context, it returns all the rest of the entries in the directory, which will of course be a null list if there are none.

readline
readline *filehandle
Reads a line or lines from the specified filehandle. (A typeglob of the filehandle name should be supplied.) Returns one line per call in a scalar context. Returns a list of all lines until the end-of-file in list context.

readlink
readlink name
Returns the name of a file pointed to by the symbolic link name. nameshould evaluate to a filename, the last component of which is a symbolic link. If it is not a symbolic link, or if symbolic links are not implemented, or if a system error occurs, the undefined value is returned, and you should check the error code in $!. If name is omitted, the function uses $_.

readpipe
readpipe cmd
Executes cmd as a system command and returns the collected standard output of the command. In a scalar context, the output is returned as a single, possibly multiline, string. In list context, a list of output lines is returned.

recv
recv socket, $var, len, flags
Receives a message on a socket. It attempts to receive len bytes of data into variable var from the specified socket filehandle. The function returns the address of the sender, or the undefined value if there's an error. varwill grow or shrink to the length actually read. The function takes the same flags as the recv(2) system call.

redo
redo [label]
Restarts a loop block identified by label without reevaluating the conditional. The continue block, if any, is not executed. If the label is omitted, the command refers to the innermost enclosing loop.

ref
ref $var
Returns a string indicating the type of the object referenced if var is a reference; returns the null string otherwise. Built-in types include:

REF
SCALAR
ARRAY
HASH
CODE
GLOB

If the referenced object has been blessed into a package, that package name is returned instead. You can think of ref as a "typeof" operator.

rename
rename oldname, newname
Changes the name of a file from oldname to newname. It returns 1 for success, 0 otherwise (and puts the error code into $!). It will not work across filesystem boundaries. If there is already a file named newname, it will be destroyed.

require
require filename
require num
require package
Asserts a dependency of some kind depending on its argument. (If an argument is not supplied, $_ is used.)

If the argument is a string filename, this function includes and executes the Perl code found in the separate file of that name. This is similar to performing an eval on the contents of the file, except that require checks to see that the library file has not been included already. The function also knows how to search the include path stored in the @INC array.

If requires argument is a number num, the version number of the currently executing Perl binary (as known by $]) is compared to num. If it is smaller, execution is immediately aborted. Thus, a script that requires Perl version 5.003 can have as its first line:

require 5.003;

and earlier versions of Perl will abort.

If require's argument is a package name, require assumes an automatic .pm suffix, making it easy to load standard modules. This is like use, except that it happens at runtime, not compile time, and the import routine is not called.

reset
reset expr
Used at the top of a loop or in a continue block at the end of a loop to clear global variables or reset ?? searches so they work again. expr is a list of single characters (hyphens are allowed for ranges). All scalar variables, arrays, and hashes beginning with one of those letters are reset to their pristine state. If expr is omitted, one-match searches (?PATTERN?) are reset to match again. The function resets variables or searches for the current package only. It always returns 1.

Lexical variables (created by my) are not affected. Use of reset is vaguely deprecated.

return
return expr
Returns from a subroutine (or eval) with the value of expr. (In the absence of an explicit return, the value of the last expression evaluated is returned.) Use of return outside of a subroutine or eval will result in a fatal error.

The supplied expression will be evaluated in the context of the subroutine invocation. That is, if the subroutine was called in a scalar context, expr is also evaluated in scalar context. If the subroutine was invoked in a list context, then expr is also evaluated in list context and can return a list value. A return with no argument returns the undefined value in scalar context and a null list in list context. The context of the subroutine call can be determined from within the subroutine by using the (misnamed) wantarray function.

reverse
reverse list
Returns a list value consisting of the elements of listin the opposite order. This is fairly efficient because it just swaps the pointers around. In scalar context, the function concatenates all the elements of list together and returns the reverse of this character by character.

rewinddir
rewinddir dirhandle
Sets the current position to the beginning of the directory for the readdir routine on dirhandle. The function may not be available on all machines that support readdir.

rindex
rindex str, substr, [position]
Works just like index except that it returns the position of the last occurrence of substr in str (a reverse index). The function returns -1 if not found. position, if specified, is the rightmost position that may be returned, i.e., how far in the string the function can search.

rmdir
rmdir name
Deletes the directory specified by name if it is empty. If it succeeds, it returns 1; otherwise, it returns 0 and puts the error code into $!. If name is omitted, the function uses $_.

scalar
scalar expr
Forces an expression expr to be evaluated in scalar context.

seek
seek filehandle, offset, whence
Positions the file pointer for filehandle, just like the fseek(3) call of standard I/O. The first position in a file is at offset 0, not offset 1, and offsets refer to byte positions, not line numbers. The function returns 1 upon success, 0 otherwise. For handiness, the function can calculate offsets from various file positions for you. The value of whence specifies which of three file positions your offset is relative to: 0, the beginning of the file; 1, the current position in the file; or 2, the end of the file. offset may be negative for a whence of 1 or 2.

seekdir
seekdir dirhandle, pos
Sets the current position for the readdir routine on dirhandle. posmust be a value returned by telldir. This function has the same caveats about possible directory compaction as the corresponding system library routine.

select
select filehandle
Returns the currently selected output filehandle, and if filehandle is supplied, sets that as the current default filehandle for output. This has two effects. First, a write or a print without a filehandle argument will default to this filehandle. Second, special variables related to output will refer to this output filehandle.

select
select rbits, wbits, ebits, timeout
The four-argument select operator is totally unrelated to the previously described select operator. This operator is for discovering which (if any) of your file descriptors are ready to do input or output, or to report an exceptional condition. It calls the select(2) system call with the bitmasks you've specified, which you can construct using fileno and vec, like this:

$rbits = $wbits = $ebits = "";
vec($rbits, fileno(STDIN), 1) = 1;
vec($wbits, fileno(STDOUT), 1) = 1;
$ein = $rin | $win;

The select call blocks until one or more file descriptors is ready for reading, writing, or reporting an error condition. timeout is given in seconds and tells select how long to wait.

semctl
semctl id, semnum, cmd, arg
Calls the System V IPC system call semctl(2). If cmd is &IPC_STAT or &GETALL, then argmust be a variable which will hold the returned semid_ds structure or semaphore value array. The function returns like ioctl: the undefined value for error, 0 but true for zero, or the actual return value otherwise. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "sem.ph";

This function is available only on machines supporting System V IPC.

semget
semget key, nsems, size, flags
Calls the System V IPC system call semget(2). The function returns the semaphore ID, or the undefined value if there is an error. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "sem.ph";

This function is available only on machines supporting System V IPC.

semop
semop key, opstring
Calls the System V IPC system call semop(2) to perform semaphore operations such as signaling and waiting. opstring must be a packed array of semop structures. You can make each semop structure by saying pack('s*', $semnum, $semop, $semflag). The number of semaphore operations is implied by the length of opstring. The function returns true if successful or false if there is an error. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "sem.ph";

This function is available only on machines supporting System V IPC.

send
send socket, msg, flags, [dest]
Sends a message msg on a socket. It takes the same flags as the system call of the same name (see send(2)). On unconnected sockets, you must specify a destination dest to send to, in which case send works like sendto(2). The function returns the number of bytes sent, or the undefined value if there is an error. On error, it puts the error code into $!.

Some non-Unix systems improperly treat sockets as different objects than ordinary file descriptors, which means that you must always use send and recv on sockets rather than the standard I/O operators.

sethostent
sethostent stayopen
Opens the hosts file (usually /etc/hosts on Unix systems) and resets the "current" selection to the top of the file. stayopen, if nonzero, keeps the file open across calls to other functions. Not implemented on Win32 systems.

setgrent
setgrent
Opens the groups file (usually /etc/group on Unix systems) and resets the top of the file as the starting point for any read and/or write functions on the file (with the proper permissions). This function will reset the getgrent function back to retrieve group entries from the start of the group file. Not implemented on Win32 systems.

setnetent
setnetent stayopen
Opens the networks file (usually /etc/group) and resets the "current" selection to the top of the file. stayopen, if nonzero, keeps the file open across calls to other functions. Not implemented on Win32 systems.

setpgrp
setpgrp pid, pgrp
Sets the current process group pgrp for the specified pid (use a pidof 0 for the current process). Invoking setpgrp will produce a fatal error if used on a machine that doesn't implement setpgrp(2). Some systems will ignore the arguments you provide and always do setpgrp(0, $$). Fortunately, those are the arguments you usually provide. (For better portability, use the setpgid( ) function in the POSIX module, or if you're really just trying to daemonize your script, consider the POSIX::setsid( ) function as well.)

setpriority
setpriority which, who, priority
Sets the current priority for a process, a process group, or a user. which must indicate one of these types: PRIO_PROCESS, PRIO_PGRP, or PRIO_USER. who, therefore, identifies the specific process, process group, or user with its ID. priority is an integer number that will be added to or subtracted from the current priority; the lower the number, the higher the priority. The interpretation of a given priority may vary from one operating system to the next. See setpriority on your system. Invoking setpriority will produce a fatal error if used on a machine that doesn't implement setpriority.

setprotoent
setprotoent stayopen
Opens the prototypes file (usually /etc/prototypes) and resets the "current" selection to the top of the file. stayopen, if nonzero, keeps the file open across calls to other functions. Not implemented on Win32 systems.

setpwent
setpwent
Opens the password file (usually /etc/passwd) and resets the top of the file as the starting point for any read and/or write functions on the file (with the proper permissions). This function will reset the getpwent function back to retrieve group entries from the start of the group file. Not implemented on Win32 systems.

setservent
setservent stayopen
Opens the services file (usually /etc/services) and resets the "current" selection to the top of the file. stayopen, if nonzero, keeps the file open across calls to other functions. Not implemented on Win32 systems.

setsockopt
setsockopt socket, level, optname, optval
Sets the socket option requested (optname) to the value optval. The function returns undefined if there is an error. optval may be specified as undef if you don't want to pass an argument. level specifies the protocol type used on the socket.

shift
shift @array
Removes the first value of @array and returns it, shortening the array by 1 and moving everything down. If there are no elements in the array, the function returns the undefined value. If @array is omitted, the function shifts @ARGV (in the main program), or @_ (in subroutines). See also unshift, push, and pop. shift and unshift functions do the same thing to the left end of an array that pop and push do to the right end.

shmctl
shmctl id, cmd, arg
Calls the System V IPC system call, shmctl(2), for performing operations on shared memory segments. If cmd is &IPC_STAT, then arg must be a variable that will hold the returned shmid_ds structure. The function returns like ioctl: the undefined value for error, "0 but true" for 0, or the actual return value otherwise. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "shm.ph";

This function is available only on machines supporting System V IPC.

shmget
shmget key, size, flags
Calls the System V IPC system call, shmget(2). The function returns the shared memory segment ID, or the undefined value if there is an error. On error, it puts the error code into $!. Before calling, you should say:

require "ipc.ph";
require "shm.ph";

This function is available only on machines supporting System V IPC.

shmread
shmread id, var, pos, size
Reads from the shared memory segment id starting at position pos for size size (by attaching to it, copying out, and detaching from it). var must be a variable that will hold the data read. The function returns true if successful or false if there is an error. On error, it puts the error code into $!. This function is available only on machines supporting System V IPC.

shmwrite
shmwrite id, string, pos, size
Writes to the shared memory segment ID starting at position pos for size size (by attaching to it, copying in, and detaching from it). If string is too long, only size bytes are used; if string is too short, nulls are written to fill out size bytes. The function returns true if successful or false if there is an error. On error, it puts the error code into $!. This function is available only on machines supporting System V IPC.

shutdown
shutdown socket, how
Shuts down a socket connection in the manner indicated by how. If how is 0, further receives are disallowed. If how is 1, further sends are disallowed. If how is 2, everything is disallowed.

This function will not shut down your system; you'll have to execute an external program to do that. See system.

sin
sin num
Returns the sine of num (expressed in radians). If num is omitted, it returns the sine of $_.

sleep
sleep n
Causes the script to sleep for n seconds, or forever if no argument is given. It may be interrupted by sending the process a SIGALRM. The function returns the number of seconds actually slept. On some systems, the function sleeps till the "top of the second." So, for instance, a sleep 1 may sleep anywhere from 0 to 1 second, depending on when in the current second you started sleeping.

socket
socket socket, domain, type, protocol
Opens a socket of the specified kind and attaches it to filehandle socket. domain, type, and protocol are specified the same as for socket(2). Before using this function, your program should contain the line:

use Socket;

This setting gives you the proper constants. The function returns true if successful.

socketpair
socketpair sock1, sock2, domain, type, prtcl
Creates an unnamed pair of sockets in the specified domain and of the specified type. domain, type, and protocol are specified the same as for socketpair(2). If socketpair is unimplemented, invoking this function yields a fatal error. The function returns true if successful.

This function is typically used just before a fork. One of the resulting processes should close sock1, and the other should close sock2. You can use these sockets bidirectionally, unlike the filehandles created by the pipe function.

sort
sort [code] list
Sorts a list and returns the sorted list value. By default (without a code argument), it sorts in standard string comparison order (undefined values sorting before defined null strings, which sort before everything else). code, if given, may be the name of a subroutine or a code block (anonymous subroutine) that defines its own comparison mechanism for sorting elements of list. The routine must return to the sort function an integer less than, equal to, or greater than 0, depending on how the elements of the list will be ordered. (The handy <=> and cmp operators can be used to perform three-way numeric and string comparisons.)

The normal calling code for subroutines is bypassed, with the following effects: the subroutine may not be a recursive subroutine, and the two elements to be compared are passed into the subroutine as $a and $b, not via @_. The variables $a and $b are passed by reference, so don't modify them in the subroutine.

Do not declare $a and $b as lexical variables (with my). They are package globals (though they're exempt from the usual restrictions on globals when you're using use strict). However, you do need to make sure your sort routine is in the same package, or else you must qualify $a and $b with the package name of the caller.

In versions preceding 5.005, Perl's sort is implemented in terms of C's qsort(3) function. Some qsort(3) versions will dump core if your sort subroutine provides inconsistent ordering of values. As of 5.005, however, this is no longer true.

splice
splice @array, pos, [n], [list]
Removes n number of elements from @array starting at position pos, replacing them with the elements of list, if provided. The function returns the elements removed from the array. The array grows or shrinks as necessary. If n is omitted, the function removes everything from posonward.

split
split /pattern/, string, [limit]
Scans a string for delimiters that match pattern and splits the string into a list of substrings, returning the resulting list value in list context, or the count of substrings in scalar context. The delimiters are determined by repeated pattern matching, using the regular expression given in pattern, so the delimiters may be of any size and need not be the same string on every match. If the pattern doesn't match at all, split returns the original string as a single substring. If it matches once, you get two substrings, and so on.

If limit is specified and is not negative, the function splits into no more than that many fields. If limit is negative, it is treated as if an arbitrarily large limit has been specified. If limit is omitted, trailing null fields are stripped from the result (which potential users of pop would do well to remember). If string is omitted, the function splits the $_ string. If patternis also omitted, the function splits on whitespace, /\s+/, after skipping any leading whitespace.

If the pattern contains parentheses, then the substring matched by each pair of parentheses is included in the resulting list, interspersed with the fields that are ordinarily returned. Here's a simple case:

split /([-,])/, "1-10,20";

This produces the list value:

(1, '-', 10, ',', 20)
sprintf
sprintf format, list
Returns a string formatted by the printf conventions. The format string contains text with embedded field specifiers into which the elements of list are substituted, one per field. Field specifiers are roughly of the form:

%m.nx

in which m and n are optional sizes with interpretation that depends on the type of field, and xis one of the following:

Code | Meaning
% | Percent sign
c | Character
d | Decimal integer
e | Exponential format floating-point number
E | Exponential format floating-point number with uppercase E
f | Fixed-point format floating-point number
g | Floating-point number, in either exponential or fixed decimal notation
G | Like g with uppercase E (if applicable)
ld | Long decimal integer
lo | Long octal integer
lu | Long unsigned decimal integer
lx | Long hexadecimal integer
o | Octal integer
s | String
u | Unsigned decimal integer
x | Hexadecimal integer
X | Hexadecimal integer with uppercase letters
p | The Perl value's address in hexadecimal
n | Special value that stores the number of characters output so far into the next variable in the parameter list.
m is typically the minimum length of the field (negative for left-justified), and nis precision for exponential formats and the maximum length for other formats. Padding is typically done with spaces for strings and zeroes for numbers. The * character as a length specifier is not supported.

sqrt
sqrt num
Returns the square root of num, or $_ if omitted. For other roots such as cube roots, you can use the ** operator to raise something to a fractional power.

srand
srand expr
Sets the random number seed for the rand operator so that rand can produce a different sequence each time you run your program. If expr is omitted, a default seed is used that is a mix of difficult-to-predict, system-dependent values. If you call rand and haven't called srand, rand calls srand with the default seed.

stat
stat file
Returns a 13-element list giving the statistics for a file, indicated by either a filehandle or an expression that gives its name. It's typically used as follows:

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
    $atime,$mtime,$ctime,$blksize,$blocks)
            = stat $filename;

Not all fields are supported on all filesystem types. Here are the meanings of the fields:

Field | Meaning
dev | Device number of filesystem
ino | Inode number
mode | File mode (type and permissions)
nlink | Number of (hard) links to the file
uid | Numeric user ID of file's owner
gid | Numeric group ID of file's owner
rdev | The device identifier (special files only)
size | Total size of file, in bytes
atime | Last access time since the epoch
mtime | Last modification time since the epoch
ctime | Inode change time (not creation time!) since the epoch
blksize | Preferred blocksize for file system I/O
blocks | Actual number of blocks allocated
$dev and $ino, taken together, uniquely identify a file. The $blksize and $blocks are likely defined only on BSD-derived filesystems. The $blocks field (if defined) is reported in 512-byte blocks. Note that $blocks*512 can differ greatly from $size for files containing unallocated blocks, or "holes," which aren't counted in $blocks.

If stat is passed the special filehandle consisting of an underline, no actual stat is done, but the current contents of the stat structure from the last stat or stat-based file test (the -x operators) is returned.

study
study scalar
This function takes extra time to study scalar($_ if unspecified) in anticipation of doing many pattern matches on the string before it is next modified. You may have only one study active at a time—if you study a different scalar, the first is "unstudied."

sub
sub name [proto] {block}
sub [proto] name
Declares and defines a subroutine. name is the name given to the subroutine; block is the code that will be executed when the subroutine is called. Without block, this statement declares only a subroutine, which must be defined at a later point in your program. proto is a sequence of symbols that places constraints on the arguments that the subroutine will receive. See Section 4.7, "Subroutines".

substr
substr string, pos, [n, replacement]
Extracts and returns a substring n characters long, starting at character position pos, from a given string. If pos is negative, the substring starts that far from the end of the string instead. If n is omitted, everything to the end of the string is returned. If n is negative, the length is calculated to leave that many characters off the end of the string.

You can use substr( ) as an lvalue—replacing the delimited substring with a new string—if string is given as an lvalue. You can also specify a replacement string in the fourth parameter to replace the substring. The original extracted substring is still returned.

symlink
symlink oldfile, newfile
Creates a new filename symbolically linked to the old filename. The function returns 1 for success, 0 otherwise. On systems that don't support symbolic links, it produces a fatal error at runtime. Be careful if you supply a relative symbolic link, since it will be interpreted relative to the location of the symbolic link itself, not your current working directory. See also link and readlink.

syscall
syscall list
Calls the system call specified as the first element of the list, passing the remaining elements as arguments to the system call. The function produces a fatal error if syscall(2) is unimplemented. The arguments are interpreted as follows: if a given argument is numeric, the argument is passed as a C integer. If not, a pointer to the string value is passed.

sysopen
sysopen filehandle, filename, mode, [perms]
Opens the file given by filename and associates it with filehandle. This function calls open(2) with the parameters filename, mode, and perms.

The possible values and flag bits of the mode parameter are system-dependent; they are available via the Fcntl library module. However, for historical reasons, some values are universal: 0 means read-only, 1 means write-only, and 2 means read/write.

If the file named by filename does not exist, and sysopen creates it (typically because mode includes the O_CREAT flag), then the value of perms specifies the permissions of the newly created file. If perms is omitted, the default value is 0666, which allows read and write for all. This default is reasonable. See umask.

The FileHandle module provides a more object-oriented approach to sysopen. See also open.

sysread
sysread filehandle, scalar, length, [offset]
Reads length bytes of data into variable scalar from the specified filehandle. The function returns the number of bytes actually read, or 0 at end-of-file. It returns the undefined value on error. scalar will grow or shrink to the length actually read. The offset, if specified, says where in the string to start putting the bytes so you can read into the middle of a string that's being used as a buffer. You should be prepared to handle the problems (such as interrupted system calls) that standard I/O normally handles for you.

sysseek
sysseek filehandle, offset, whence
A variant of seek( ) that sets and gets the file's system read/write position using the lseek(2) system call. It's the only reliable way to seek before a sysread( ) or syswrite( ). Returns the new position, or undef on failure. Arguments are the same as for seek.

system
system list
Executes any program on the system for you. It does exactly the same thing as exec list except that it does a fork first, and then, after the exec, it waits for the execed program to complete. That is, it runs the program for you and returns when it's done, unlike exec, which never returns (if it succeeds). Note that argument processing varies depending on the number of arguments, as described for exec. The return value is the exit status of the program as returned by the wait(2) call. To get the actual exit value, divide by 256. (The lower eight bits are set if the process died from a signal.) See exec.

syswrite
syswrite filehandle, scalar, length, [offset]
Writes length bytes of data from variable scalar to the specified filehandle. The function returns the number of bytes actually written, or the undefined value on error. You should be prepared to handle the problems that standard I/O normally handles for you, such as partial writes. The offset, if specified, says where in the string to start writing from, in case you're using the string as a buffer, for instance, or need to recover from a partial write.

Do not mix calls to print (or write) and syswrite on the same filehandle unless you really know what you're doing.

tell
tell filehandle
Returns the current file position (in bytes, 0-based) for filehandle. This value is typically fed to the seek function at a future time to get back to the current position. If filehandle is omitted, the function returns the position of the last file read. File positions are only meaningful on regular files. Devices, pipes, and sockets have no file position.

telldir
telldir dirhandle
Returns the current position of the readdir routines on a directory handle (dirhandle). This value may be given to seekdir to access a particular location in a directory. The function has the same caveats about possible directory compaction as the corresponding system library routine. This function may not be implemented everywhere that readdir is. Even if it is, no calculation may be done with the return value. It's just an opaque value, meaningful only to seekdir.

tie
tie variable, classname, list
Binds a variable to a package class, classname, that will provide the implementation for the variable. Any additional arguments (list) are passed to the "new" method of the class (meaning TIESCALAR, TIEARRAY, or TIEHASH). Typically, these are arguments that might be passed to the dbm_open(3) function of C, but this is package-dependent. The object returned by the "new" method is also returned by the tie function, which can be useful if you want to access other methods in classname. (The object can also be accessed through the tied function.)

A class implementing a hash should provide the following methods:

TIEHASH $class, LIST
DESTROY $self
FETCH $self, $key
STORE $self, $key, $value
DELETE $self, $key
EXISTS $self, $key
FIRSTKEY $self
NEXTKEY $self, $lastkey

A class implementing an ordinary array should provide the following methods:

TIEARRAY $classname, LIST
DESTROY $self
FETCH $self, $subscript
STORE $self, $subscript, $value

A class implementing a scalar should provide the following methods:

TIESCALAR $classname, LIST
DESTROY $self
FETCH $self,
STORE $self, $value

Unlike dbmopen, the tie function will not use or require a module for you—you need to do that explicitly yourself.

tied
tied variable
Returns a reference to the object underlying variable (the same value that was originally returned by the tie call that bound the variable to a package). It returns the undefined value if variable isn't tied to a package. So, for example, you can use:

ref tied %hash

to find out which package your hash is currently tied to.

time
time
Returns the number of non-leap seconds since January 1, 1970, UTC. The returned value is suitable for feeding to gmtime and localtime, for comparison with file modification and access times returned by stat, and for feeding to utime.

times
times
Returns a four-element list giving the user and system CPU times, in seconds (possibly fractional), for this process and for the children of this process:

($user, $system, $cuser, $csystem) = times;

For example, to time the execution speed of a section of Perl code:

$start = (times)[0];
...
$end = (times)[0];
printf "that took %.2f CPU seconds\n", $end - $start;
truncate
truncate file, length
Truncates a file (given as a filehandle or by name) to the specified length. The function produces a fatal error if truncate(2) or an equivalent isn't implemented on your system.

uc
uc string
Returns an uppercased version of string (or $_ if string is omitted). This is the internal function implementing the \U escape in double-quoted strings. POSIX setlocale(3) settings are respected.

ucfirst
ucfirst string
Returns a version of string (or $_ if string is omitted) with the first character uppercased. This is the internal function that implements the \u escape in double-quoted strings. POSIX setlocale(3) settings are respected.

umask
umask expr
Sets the umask for the process to expr and returns the old one. (The umask tells Unix which permission bits to disallow when creating a file.) If expr is omitted, the function merely returns the current umask. For example, to ensure that the "other" bits are turned on and that the "user" bits are turned off, try something like:

umask((umask( ) & 077) | 7);
undef
undef expr
Undefines the value of expr, which must be an lvalue. Use only on a scalar value, an entire array or hash, or a subroutine name (using the & prefix). Any storage associated with the object will be recovered for reuse (though not returned to the system, for most versions of Unix). The undef function will probably not do what you expect on most special variables. The function always returns the undefined value. This is useful because you can omit the expr, in which case nothing gets undefined, but you still get an undefined value that you could, for instance, return from a subroutine to indicate an error.

You may use undef as a placeholder on the left side of a list assignment, in which case the corresponding value from the right side is simply discarded. Apart from that, you may not use undef as an lvalue.

unlink
unlink list
Deletes a list of files. (Under Unix, it will remove a link to a file, but the file may still exist if another link references it.) If list is omitted, it unlinks the file given in $_. The function returns the number of files successfully deleted. Note that unlink will not delete directories unless you are the superuser and the -U flag is supplied to Perl. Even if these conditions are met, be warned that unlinking a directory can inflict serious damage on your filesystem. Use rmdir instead.

unpack
unpack template, string
Takes a string (string) representing a data structure and expands it into a list value, returning the list value. (unpack does the reverse of pack.) In a scalar context, it can be used to unpack a single value. The template has much the same format as the pack function—it specifies the order and type of the values to be unpacked. See pack for a more detailed description of template.

unshift
unshift @array, list
Prepends the elements of list to the front of the array and returns the new number of elements in the array.

untie
untie variable
Breaks the binding between a variable and a package. See tie.

use
use Module list
use version
use Module version list
If the first argument is a number, it is treated as a version number. If the version of Perl is less than version, an error message is printed and Perl exits. This provides a way to check the Perl version at compilation time instead of waiting for runtime.

If version appears between Module and list, then use calls the version method in class Module with version as an argument.

Otherwise, use imports some semantics into the current package from the named Module, generally by aliasing certain subroutine or variable names into your package. It is exactly equivalent to the following:

BEGIN { require Module; import Module list; }

The BEGIN forces the require and import to happen at compile time. The require makes sure that the module is loaded into memory if it hasn't been yet. The import is not a built-in function—it's just an ordinary static method call into the package named by Module that tells the module to import the list of features back into the current package. The module can implement its import method any way it likes, though most modules just choose to derive their import method via inheritance from the Exporter class defined in the Exporter module.

If you don't want your namespace altered, explicitly supply an empty list:

use Module ( );

This is exactly equivalent to the following:

BEGIN { require Module; }

Because this is a wide-open interface, pragmas (compiler directives) are also implemented this way. (See Chapter 8, "Standard Modules" for descriptions of the currently implemented pragmas.) These pseudomodules typically import semantics into the current block scope, unlike ordinary modules, which import symbols into the current package. (The latter are effective through the end of the file.)

There's a corresponding declaration, no, that "unimports" any meanings originally imported by use but have since become less important:

no integer;
no strict 'refs';
utime
utime atime, mtime, files
Changes the access time (atime) and modification time (mtime) on each file in a list of files. The first two elements must be the numerical access and modification times, in that order. The function returns the number of files successfully changed. The inode change time of each file is set to the current time. Here's an example of a utime command:

#!/usr/bin/perl
$now = time;
utime $now, $now, @ARGV;

To read the times from existing files, use stat.

values
values %hash
Returns a list consisting of all the values of the named hash. The values are returned in an apparently random order, but it is the same order that the keys or each function would produce on the same hash. To sort the hash by its values, see the example under keys. Note that using values on a hash bound to a very large DBM file will produce a very large list, causing you to have a very large process, and leaving you in a bind. You might prefer to use the each function, which will iterate over the hash entries one by one without reading them all into a single list.

vec
vec string, offset, bits
Treats a string as a vector of unsigned integers and returns the value of the element specified by offset and bits. The function may also be assigned to, which causes the element to be modified. The purpose of the function is to provide compact storage of lists of small integers. The integers may be very small—vectors can hold numbers that are as small as one bit, resulting in a bitstring.

The offset specifies the number of elements to skip over to find the one you want. bits is the number of bits per element in the vector, so each element can contain an unsigned integer in the range 0..(2**bits)-1. bits must be one of 1, 2, 4, 8, 16, or 32. As many elements as possible are packed into each byte, and the ordering is such that vec($vectorstring,0,1) is guaranteed to go into the lowest bit of the first byte of the string. To find the position of the byte in which an element will be placed, you have to multiply the offset by the number of elements per byte. When bits is 1, there are eight elements per byte. When bits is 2, there are four elements per byte. When bits is 4, there are two elements (called nybbles) per byte. And so on.

Regardless of whether your system is big-endian or little-endian, vec($foo, 0, 8) always refers to the first byte of string $foo. See select for examples of bitmaps generated with vec.

Vectors created with vec can also be manipulated with the logical operators |, &, ^, and ~, which will assume a bit vector operation is desired when the operands are strings. A bit vector (bits == 1) can be translated to or from a string of 1s and 0s by supplying a b* template to unpack or pack. Similarly, a vector of nybbles (bits == 4) can be translated with an h* template.

wait
wait
Waits for a child process to terminate and returns the pid of the deceased process, or -1 if there are no child processes. The status is returned in $?. If you get zombie child processes, you are probably calling either this function or waitpid. A common strategy to avoid such zombies is:

$SIG{CHLD} = sub { wait };

If you expected a child and didn't find it, you probably had a call to system, a close on a pipe, or backticks between the fork and the wait. These constructs also do a wait(2) and may have harvested your child process. Use waitpid to avoid this problem.

waitpid
waitpid pid, flags
Waits for a particular child process pid to terminate and returns the pid when the process is dead, or -1 if there are no child processes or if the flags specify nonblocking and the process isn't dead yet. The status of the dead process is returned in $?. To get valid flag values, do the following:

use POSIX "sys_wait_h";

On systems that implement neither the waitpid(2) nor the wait4(2) system call, flags may be specified only as 0. In other words, you can wait for a specific pid, but you can't do it in nonblocking mode.

wantarray
wantarray
Returns true if the context of the currently executing subroutine is looking for a list value. The function returns false if the context is looking for a scalar. May also return undef if a subroutine's return value will not be used at all.

warn
warn msg
Produces a message on STDERR just like die, but doesn't try to exit or throw an exception. For example:

warn "Debug enabled" if $debug;

If the message supplied is null, the message "Something's wrong" is used. As with die, a message not ending with a newline will have file and line number information automatically appended. The warn operator is unrelated to the -w switch.

write
write filehandle
Writes a formatted record (possibly multiline) to the specified filehandle, using the format associated with that filehandle (see Section 4.11, "Unicode"). By default, the format for a filehandle is the one having the same name as the filehandle.

If filehandle is unspecified, output goes to the current default output filehandle, which starts as STDOUT but may be changed by the select operator. If the filehandle is an expression, then the expression is evaluated to determine the actual filehandle at runtime.

Note that write is not the opposite of read. Use print for simple string output. If you want to bypass standard I/O, see syswrite.

Previous | Home | Next
5. Function Reference | Book Index | 6. Debugging
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 6. Debugging

Contents:

The Perl Debugger
Debugger Commands
Using the Debugger
Customizing the Debugger
The Perl Profiler
The perlbug Program

Of course everyone writes perfect code on the first try, but on those rare occasions when something goes wrong, and you're having trouble with your Perl script, there are several things you can do:

  • Run the script with the -w switch, which prints warnings about possible problems in your code.

  • Use the Perl debugger.

  • Use another debugger, or a profiler such as the Devel::DProf module.

The major focus of this chapter is the Perl debugger, which provides an interactive Perl environment. The chapter also describes the DProf module and the dprofpp program that comes with it; together they can provide you with a profile of your Perl script. If you've ever used any debugger, and you understand concepts such as breakpoints and backtraces, you'll have no trouble learning to use the Perl debugger. Even if you haven't used another debugger, the command descriptions and some experimenting should get you going.

6.1. The Perl Debugger

To run your script under the Perl source debugger, invoke Perl with the -d switch:

perl -d myprogram

This works like an interactive Perl environment, prompting for debugger commands that let you examine source code, set breakpoints, get stack backtraces, change the values of variables, etc. If your program takes any switches or arguments, you must include them in the command:

perl -d myprogram myinput

In Perl, the debugger is not a separate program as it is in the typical compiled environment. Instead, the -d flag tells the compiler to insert source information into the parse trees it's about to hand off to the interpreter. This means your code must compile correctly for the debugger to work on it—the debugger won't run until you have fixed all compiler errors.

After your code has compiled, and the debugger has started up, the program halts right before the first runtime executable statement (see Section 6.3, "Using the Debugger" regarding compile time statements) and waits for you to enter a debugger command. Whenever the debugger halts and shows you a line of code, it always displays the line it's about to execute, rather than the one it has just executed.

Any command not recognized by the debugger is directly executed as Perl code in the current package. To be recognized by the debugger, the command must start at the beginning of the line; otherwise, the debugger assumes it's for Perl.

Previous | Home | Next
5. Function Reference | Book Index | 6.2. Debugger Commands
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.2. Debugger Commands

The debugger understands the following commands.

-
-

Lists the previous few lines.

.
.

Returns debugger pointer to the last-executed line and prints it out.

/pattern/
/pattern/

Searches forward for pattern; final / is optional.

?pattern?
?pattern?

Searches backward for pattern; final ? is optional.

<
< [command]

Sets a Perl command to run before every debugger prompt. A multiline command may be entered by backslashing the newlines. With no command, the list of actions is reset.

<<

<< [command]

Adds to the list of Perl commands to run before each debugger prompt.

<CR>
<CR>

Repeats last n or s command.

>
> [command]

Sets a Perl command to run after the prompt when you've just given a command to return to executing the script. A multiline command may be entered by backslashing the newlines.

>>
>> [command]

Adds to the list of Perl commands to run after each debugger prompt.

{
{ [commandline]

Sets a debugger command to run before each prompt.

{{
{{ [commandline]

Adds to the list of debugger commands to run before each prompt.

!
! [number]

Reruns a previous command (defaults to the last command executed).

!
! -number

Reruns numberth-to-last command.

!
! pattern

Reruns last command that started with pattern. See O recallCommand.

!!
!! cmd

Runs cmd in a subprocess (which reads from DB::IN and writes to DB::OUT). See O shellBang.

|
| dbcmd

Runs specified debugger command, piping DB::OUT to $ENV{PAGER}.

||
|| dbcmd

Same as |dbcmd, but DB::OUT is temporarily select ed as well. Often used with commands that would otherwise produce long output, such as:

|V main
=
= [alias value]

Defines a command alias. If alias and valueare omitted, lists all current aliases.

A
A

Deletes all installed actions.

a
a [line] command

Sets an action to be done before the line is executed. The following steps are taken:

  • Checks for a breakpoint at this line

  • Prints the line if necessary

  • Performs any actions associated with the line

  • Prompts the user if at a breakpoint or in single-step mode

  • Evaluates the line

For example, the following prints the value of $foo (and DB FOUND) every time line 53 is passed:

a 53 print "DB FOUND $foo\n"
b
b [line] [condition]

Sets a breakpoint at line, which must begin an executable statement. If line is omitted, sets a breakpoint on the line that is about to be executed. condition, if given, is evaluated each time the statement is reached, and a breakpoint is taken if condition is true:

b 237 $x > 30
b 33 /pattern/i
b
b subname [condition]

Sets a (possibly conditional) breakpoint at the first line of the named subroutine.

b
b load filename

Sets a breakpoint on requireing the given file.

b
b postpone subname [condition]

Sets a (possibly conditional) breakpoint at the first line of subroutine subname after it has been compiled.

b
b compile subname

Stops after the subroutine has been compiled.

c
c [line | sub]

Continues, optionally inserting a one-time-only breakpoint at the specified line or subroutine.

command
command

Executes command as a Perl statement. A semicolon is not needed at the end.

D
D

Deletes all installed breakpoints

d
d [line]

Deletes the breakpoint at the specified line. If line is omitted, deletes the breakpoint on the line that is about to be executed..

f
f filename

Switches to viewing a different file.

H
H [-number]

Displays last number commands. If number is omitted, it lists all previous commands. Only commands longer than one character are listed.

h
h [command]

Prints a help message, listing the available debugger commands.

If you supply another debugger command as an argument to the h command, it prints out the description for just that command. The command h h produces a more compact help listing designed to fit on one screen.

L
L

Lists all breakpoints and actions for the current file.

l
l [linespec]

If linespec is omitted, lists the next few lines. Otherwise, lists the lines specified by linespec, which can be one of the following:

line
Lists the single line line

min+incr
Lists incr+1 lines starting at min

min-max
Lists lines min through max

subname
Lists the first few lines from subroutine subname.

Also see the w and - commands.

m
m expr

evals the expression in array context and prints methods callable on the first element of the result.

m
m class

Prints methods callable via the given class.

n
n

Next. Passes over subroutine calls and executes the next statement at this level.

O
O [opt[="val"]] [opt'val'] [opt?]

Sets or queries option values. If omitted, val defaults to 1. opt? displays the value of option opt. opt can be abbreviated to the shortest unique string, and multiple options can be specified. The possible options are:

AutoTrace
Affects printing of messages at every possible breaking point.

frame
Enables printing of messages on entry and exit from subroutines.

inhibit_exit
Enables stepping off the end of the script.

maxTraceLen
Gives the maximum length of evals/args listed in the stack trace.

ornaments
Affects the appearance of the command line on the screen.

pager
Specifies the program to use for output of pager-piped commands (those beginning with a | character). Default value is $ENV{PAGER}.

PrintRet
Enables printing of return value after r command.

recallCommand, ShellBang
Specifies the characters used to recall previous commands or spawn a shell. By default, these are both set to !.

The following options affect what happens with the V, X, and x commands:

arrayDepth, hashDepth
Prints only to depth n ("" for all).

compactDump, veryCompact
Changes style of array and hash dumps.

DumpDBFiles
Dumps arrays holding debugged files.

DumpPackages
Dumps symbol tables of packages.

globPrint
Specifies whether to print contents of globs.

quote, HighBit, undefPrint
Changes style of string dump.

signalLevel, warnLevel, dieLevel
Specifies level of verbosity.

tkRunning
Runs Tk while prompting (with ReadLine).

During startup, debugger options are initialized from $ENV{PERLDB_OPTS}. You can set the additional initialization options TTY, noTTY, ReadLine, and NonStop there. See Section 6.4, "Customizing the Debugger" later in this chapter for more information.

p
p expr

Same as print DB::OUT expr in the current package. In particular, does not dump nested data structures and objects, unlike the x command. The DB::OUT handle is opened to /dev/tty (or perhaps an editor window) no matter where standard output may have been redirected to.

q
q or ^D

Quits the debugger.

R
R

Restarts the debugger. As much of your history is maintained across the sessions as possible, but some internal settings and command-line options may be lost.

r
r

Returns from current subroutine.

S
S [[!]pattern]

Lists subroutine names matching (or, if ! is specified, not matching) pattern. If pattern is omitted, lists all subroutines.

s
s [expr]

Single steps. Executes until it reaches the beginning of another statement, descending into subroutine calls. If an expression is supplied that includes a function call, the function is also single-stepped.

T
T

Produces a stack backtrace. For example:

DB<2> T
$ = main::infested called from file 'Ambulation.pm' line 10
@ = Ambulation::legs(1, 2, 3, 4) called from file
'camel_flea' line 7
$ = main::pests('bactrian', 4) called from file
'camel_flea' line 4

The lefthand character ($ or @) tells whether the function was called in a scalar or list context. The example shows three lines because it was three functions deep when the stack backtrace ran.

t
t

Toggles trace mode.

t
t expr

Traces through execution of expr.

v
v

Shows versions of loaded modules.

V
V [pkg [vars]]

Displays all (or some) variables in package pkg using a data pretty-printer (which displays keys and their values for hashes, makes control characters printable, prints nested data structures in a legible fashion, and so on). pkg defaults to the main package. Make sure you enter the identifiers without a type specifier such as $ or @, like this:

V DB filename line

In place of a variable name, you can use ~pattern or !pattern to print existing variables with names that either match or don't match the specified regular expression.

w
w [line]

Lists a window of a few lines around the given line, or lists the current line if line is omitted.

X
X [vars]

Same as V currentpackage[vars].

x
x expr

evals the expression in a list context and dumps out the result in a pretty-printed fashion. Unlike the print command above, prints nested data structures recursively.

Previous | Home | Next
6. Debugging | Book Index | 6.3. Using the Debugger
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.3. Using the Debugger

If you have any compile time executable statements (code within a BEGIN block or a use statement), they are not stopped by the debugger, although require s are.

The debugger prompt is something like this:

DB<8>

or even this:

DB<<17>>

The number in angle brackets is the command number. A csh-like history mechanism lets you access previous commands by number. For example, !17 repeats command number 17. The number of angle brackets indicates the depth of the debugger. You get more than one set of brackets, for example, if you're already at a breakpoint and print out the result of a function call that itself also has a breakpoint.

If you want to enter a multiline command, such as a subroutine definition with several statements, you can use a backslash to escape the newline that would normally end the debugger command:

DB<1> sub foo { \
cont:   print "fooline\n"; \
cont: }
DB<2> foo
fooline

You can maintain limited control over the Perl debugger from within your Perl script. You might do this, for example, to set an automatic breakpoint at a certain subroutine whenever a particular program is run under the debugger. Setting $DB::single to 1 causes execution to stop at the next statement, as though you'd used the debugger's s command. Setting $DB::single to 2 is equivalent to typing the n command, and the $DB::trace variable can be set to 1 to simulate the t command.

Once you are in the debugger, you can terminate the session by entering q or Ctrl-D at the prompt. You can also restart the debugger with R.

Previous | Home | Next
6.2. Debugger Commands | Book Index | 6.4. Customizing the Debugger
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.4. Customizing the Debugger

You can do some customizing by setting up a .perldb file with initialization code. When it starts up, the debugger reads and processes this file. For instance, you can set up aliases such as these:

$DB::alias{'len'}  = 's/^len(.*)/p length($1)/';
$DB::alias{'stop'} = 's/^stop (at|in)/b/';
$DB::alias{'ps'}   = 's/^ps\b/p scalar /';
$DB::alias{'quit'} = 's/^quit\b.*/exit/';

You can also use this file to set options and define a subroutine, &afterinit, to be executed after the debugger is initialized.

After the configuration file has been processed, the debugger consults the environment variable PERLDB_OPTS and parses its contents as arguments to the O opt=val debugger command.

While any options can be set in PERLDB_OPTS, the following options can only be specified at startup. If you want to set them in your configuration file, call &parse_options("opt=val").

TTY
The TTY to use for debugging I/O.

noTTY
If set, goes in NonStop mode. On an interrupt, if TTY is not set, it uses the value of noTTY or /tmp/perldbtty$$ to find the TTY using Term::Rendezvous. The current variant is to have the name of the TTY in this file.

ReadLine
If false, a dummy ReadLine is used so you can debug ReadLine applications.

NonStop
If true, no interaction is performed until an interrupt.

LineInfo
File or pipe to print line number information to. If it's a pipe, then a short, emacs-like message is used.

For example, if you create the following .perldb file:

&parse_options("NonStop=1 LineInfo=db.out");
sub afterinit { $trace = 1; }

your script will run without human intervention, putting trace information into the file db.out.

Previous | Home | Next
6.3. Using the Debugger | Book Index | 6.5. The Perl Profiler
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.5. The Perl Profiler

You can supply an alternative debugger for Perl to run by invoking your script with the -d:module switch. One of the most popular alternative debuggers for Perl is DProf, the Perl profiler. As of this writing, DProf is not included with the standard Perl distribution, but it is expected to be included soon.

Meanwhile, you can fetch the Devel::DProf module from CPAN. Once it has been properly installed on your system, you can use it to profile the Perl program in testpgm by typing:

perl -d:DProf testpgm

As your script runs, DProf gathers profile information. When the script terminates, the profiler dumps the gathered information to a file called tmon.out. A tool such as dprofpp, which is supplied with the Devel::DProf package, can be run to interpret the profile. If you run dprofpp against the tmon.out file created by DProf in the example above, you'll see something like the following:

% dprofpp tmon.out
Total Elapsed Time =    0.15 Seconds
  User+System Time =     0.1 Seconds
Exclusive Times
%Time Seconds     # Calls sec/call Name
 30.0   0.030          1   0.0300 Text::Wrap::CODE(0x175f08)
 20.0   0.020          1   0.0200 main::CODE(0xc7880)
 20.0   0.020          1   0.0200 main::CODE(0xfe480)
 10.0   0.010          1   0.0100 Text::Wrap::CODE(0x17151c)
 10.0   0.010         10   0.0010 Text::Tabs::expand
 0.00   0.000          1   0.0000 lib::CODE(0xfe5b8)
 0.00   0.000          3   0.0000 Exporter::export
 0.00   0.000          1   0.0000 Config::FETCH
 0.00   0.000          1   0.0000 lib::import
 0.00   0.000          1   0.0000 Text::Wrap::CODE(0x171438)
 0.00   0.000          3   0.0000 vars::import
 0.00   0.000          3   0.0000 Exporter::import
 0.00   0.000          2   0.0000 strict::import
 0.00   0.000          1   0.0000 Text::Wrap::CODE(0x171684)
 0.00   0.000          1   0.0000 lib::CODE(0xfe4d4)

The output shows the 15 subroutines that use the most time; you can then focus your efforts on those subroutines where tuning the code will have the greatest effect. This output is an example of running the dprofpp command with the default option set. The following are the options that are available:

-a
Sorts output alphabetically by subroutine name.

-E
Default. Displays all subroutine times exclusive of child subroutine times.

-F
Forces generation of fake exit timestamps if dprofpp reports that the profile is garbled. Useful only if dprofpp determines that the profile is garbled due to missing exit timestamps.

-I
Displays all subroutine times inclusive of child subroutine times.

-l
Sorts by number of calls to the subroutines.

-O cnt
Shows only cnt subroutines. The default is 15.

-p script
Profiles the given script and interprets its profile data, combining the usual two steps into one.

-Q
Used with -p, profiles the script and quits without interpreting the data.

-q
Does not display column headers.

-r
Displays elapsed real times.

-s
Displays system times only.

-T
Displays subroutine calls, but not subroutine statistics.

-t
Displays subroutine call tree, but not subroutine statistics. A subroutine called multiple times is shown only once, with a repeat count.

-U
Displays unsorted output.

-u
Displays user times only.

-V
Prints the dprofpp version number.

-v
Sorts by average time spent in subroutines during each call.

-z
Default. Sorts by amount of user and system time used, so that the first few lines should show which subroutines are using the most time.

Previous | Home | Next
6.4. Customizing the Debugger | Book Index | 6.6. The perlbug Program
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.6. The perlbug Program

As you develop and debug your own code, it's possible that you'll run into a bug in Perl itself. If you do, the best way to report it is with the perlbug program. perlbug is a Perl program designed to automate the process of reporting bugs in the Perl standard distribution and the standard modules. It works interactively, prompting you for the information needed and generating an email message addressed to perlbug@perl.com. (If the bug you found is in one of the nonstandard Perl ports, see the documentation for that port to find out how to report bugs.) When you run perlbug, it prompts you to include all relevant information, making it easier for the Perl developers to reproduce and track down the bug. If you come up with a patch to resolve the problem, include that too.

Don't use perlbug to get help debugging your code (for that, see the list of newsgroups and other resources in Chapter 1, "Introduction to Perl"). But if you believe you've found a bug in Perl itself, perlbug is the way to report it.

To run perlbug, simply enter the command with any options you want to include. For example:

% perlbug -t

The possible options are:

-a address
Email address to send report to. Default is perlbug@perl.com.

-b body
Body of report. If not included on the command line or in a file, you are given a chance to edit it.

-C
Don't send a copy to your Perl administrator.

-c address
Email address where copy should be sent. Default is your Perl administrator.

-d
Data mode. (The default if you redirect or pipe input.) Prints your configuration data, without mailing anything. Use with -v to get more complete data.

-e editor
Editor to use. Defaults to your default editor or to vi.

-f file
File containing prepared body of report.

-h
Prints help message.

-ok
Reports successful build on this system to Perl porters. Forces -S and -C; forces and supplies values for -s and -b. Use with -v to get more complete data. Only reports if this system is less than 60 days old.

-okay
Like -ok but will report on systems older than 60 days.

-r address
Return address. If not specified on the command line, perlbug prompts for it.

-S
Send without asking for confirmation.

-s subject
Subject to include. If not specified on command line, perlbug prompts for it.

-t
Test mode. Target address defaults to perlbug-test@perl.com.

-v
Verbose. Includes verbose configuration data in report.

Previous | Home | Next
6.5. The Perl Profiler | Book Index | III. Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part III. Modules

Chapter 7, "Packages, Modules, and Objects"

Chapter 8, "Standard Modules"

Previous | Home | Next
6.6. The perlbug Program | Book Index | 7. Packages, Modules, and Objects
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 7. Packages, Modules, and Objects

Contents:

Namespaces and Packages
Modules
Object-Oriented Perl
Object Syntax

Over the years, Perl has evolved from a utilitarian scripting tool into a sophisticated object-oriented programming language. Many people continue to use Perl just for simple scripts, and Perl will continue to make simple tasks easy. However, Perl can also make difficult tasks possible by writing reusable code and using object-oriented programming techniques.

This chapter explains what Perl modules are and how to use them in your programs. Modules are written to accomplish tasks that either aren't implemented by Perl's built-in functions, or that could be done better. We say modules are "reusable" because anyone who needs to accomplish the same task can use that module instead of writing the code from scratch. As you write more and more Perl code, you'll undoubtedly find yourself using many of the modules other Perl programmers have provided. You may also find yourself writing modules and making them available for others to use.

The remainder of this book describes a significant portion of the functionality that's present in publicly available Perl modules. You'll find that a number of standard or core modules are distributed with Perl; many of these modules are discussed in Chapter 8, "Standard Modules". Scores of other modules are available on CPAN, and virtually any task you'd like to accomplish in Perl is implemented in a module found there. For unbundled modules, you'll need to install the module on your system and integrate it into your program with the use function.

The use function is often the key to working with modules. For example, to bring the functionality of the popular CGI module into your program, you need to install the CGI.pm module (the .pm stands for Perl module) and put this line near the top of your program:

use CGI;

Now your program can use the many functions and variables made available by the CGI module.

Packages (from which modules are built) are also a mechanism by which Perl's object-oriented features are implemented. But object-oriented programming isn't for everyone, and there's nothing in packages that forces the programmer to work with the object-oriented paradigm.

7.1. Namespaces and Packages

A namespace does what it says: it stores names (or identifiers), including names of variables, subroutines, filehandles, and formats. Each namespace has its own symbol table, which is basically a hash with a key for each identifier.

The default namespace for programs is main, but you can define other namespaces and variables and use them in your program. Variables in different namespaces can even have the same name, but they are completely distinct from one another.

In Perl, a namespace is held in a package. By convention, package names start with a capital letter, and you should follow that convention when you create your own packages.

Each package starts with a package declaration. The package call takes one argument: the name of the package. Within the scope of a package declaration, all regular identifiers are created within that package (except for my variables).

From inside one package, you can refer to variables from another package by "qualifying" them with the package name. To do this, place the name of the package followed by two colons (::) before the identifier's name, e.g., $Package::varname.

If the package name is null, the main package is assumed. For example, $var and $::var are the same as $main::var.

Packages may be nested inside other packages. However, the package name must still be fully qualified. For example, if the package Province is declared inside the package Nation, a variable in the Province package is called as $Nation::Province::var. You cannot use a "relative" package name such as $Province::var within the Nation package for the same thing.

The default main namespace contains all other packages within it.

Previous | Home | Next
III. Modules | Book Index | 7.2. Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.2. Modules

A module is a package defined in a file with a name that is the same as the package's. Perl locates modules by searching the @INC array, which contains a list of library directories. Perl's use of @INC is roughly comparable to the Unix shell's use of the PATH environment variable to locate executable programs. @INC is defined when Perl is built and can be supplemented with the -I command-line option to Perl or with use lib within a program.

When you refer to ModuleName in your program, Perl searches in the directories listed in @INC for the module file ModuleName.pm and uses the first one it finds. When you refer to a module embedded in another package, such as ParentPackage::ModuleName, Perl looks for a ParentPackage/ subdirectory in the @INC path, and for a ModuleName.pm file in that subdirectory.

Every Perl installation includes a central lib directory. The actual pathname of this directory varies from system to system, but it's commonly /usr/lib/perl or /usr/local/lib/perl. Looking at the central lib directory for your Perl distribution, you'll see something like this:

% ls -aF /usr/local/lib/perl
./               I18N/            bigfloat.pl      less.pm
../              IO/              bigint.pl        lib.pm
AnyDBM_File.pm   IPC/             bigrat.pl        locale.pm
AutoLoader.pm    Math/            blib.pm          look.pl
AutoSplit.pm     Net/             cacheout.pl      man/
Benchmark.pm     Pod/             chat2.pl         newgetopt.pl
Bundle/          Search/          complete.pl      open2.pl
CGI/             SelectSaver.pm   constant.pm      open3.pl
CGI.pm           SelfLoader.pm    ctime.pl         perl5db.pl
CPAN/            Shell.pm         diagnostics.pm   pod/
CPAN.pm          Symbol.pm        dotsh.pl         pwd.pl
Carp.pm          Sys/             dumpvar.pl       shellwords.pl
        ...

When you request the AnyDBM_File module, it uses AnyDBM_File.pm. When you request the Math::Complex module, it looks for Math/Complex.pm.

A module can be included in your program with use or require. Both use and require read in a module file for use with your program.

require Module;

or:

use Module;

use can also take a list of strings naming entities that you want to import from the module. The list only has to include entities that are not automatically exported by the module. You don't have to provide this list if the module automatically exports all the entities you need.

use Module qw(const1 const2 func1 func2 func3);

The difference between use and require is that use pulls in the module at compile time. This means that functions such as func1 or func2can be used as predeclared list operators throughout the file. The require call does not necessarily load the module during compilation, so you must explicitly qualify its routines with the package name.

Previous | Home | Next
7. Packages, Modules, and Objects | Book Index | 7.3. Object-Oriented Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.3. Object-Oriented Perl

In Perl circles, modules and object-oriented programming are often spoken of in the same breath, but the connection is misleading. The implementation of modules in Perl is object-oriented, but that doesn't mean that the actual modules are objectified. Perl modules don't necessarily involve objects just because the Perl programmer has encapsulated their code in a module.

Generally, an object is an instance of a class. So in Perl terms, the object is created by calling a constructor, and will be used to create a new object and a reference to it. (Often, the constructor is named new, but Create is also used in Win32 classes.) This reference is a regular scalar variable, except that it refers to an underlying object that knows which class it belongs to. In your programs, you will use the reference to manipulate the object.

Methods are subroutines that expect an object reference as a first argument, such as:

sub in_class {
   my $class = shift; # object reference
   my ($this, $that) = @_; # params
}

Methods may be invoked like this:

PackageName->constructor(args)->method_name(args);

or:

$object = PackageName->constructor(args);
$object->method_name(args);

Objects have a specific set of available methods within their class, but they also inherit methods from their parent class, if they have one.

Objects are destroyed when the last reference to them goes away. You can control this capture before the object is destroyed with the DESTROY method. The DESTROY method should be defined somewhere in the class. You do not call DESTROY explicitly; it will be called at an appropriate time. Object references contained in the current object will be freed when the current object is freed. Most of the time, you won't need to explicitly destroy an object, but there are occasions when you should, such as when you are done with a socket object.

Previous | Home | Next
7.2. Modules | Book Index | 7.4. Object Syntax
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.4. Object Syntax

Perl uses two forms of syntax for invoking methods on objects. For both types of syntax, the object reference or class name is given as the first argument. A method that takes a class name is called a class method, and one that takes an object reference is called an instance method.

Class methods provide functionality for the entire class, not just for a single object that belongs to the class. Class methods expect a class name as their first argument. Following this explanation, a constructor is an example of a class method:

sub new {
   my $self = {};
   bless $self;
   return $self;
}

On the other hand, an instance method expects an object reference as its first argument. An instance method will shift the first argument and use this argument as a reference:

sub instance_method {
   my $self = shift;
   my($one, $two, $three) = @_;
   # do stuff
}

Here is an example of a constructor creating a new object and returning a reference:

$tri = Triangle::Right->new(side1 => 3, side2 => 4);

This example creates a new right-triangle object and references it with $tri. The parameters are given as a hash-style list. This is common for constructors, since they set initial parameters for an object that is probably just a hash. Now that we have an object, we can invoke a method on it. Suppose Triangle::Right defines a method, hypot, that returns the length of the hypotenuse for a given right-triangle object. It would be used like this:

$h = $tri->hypot;
print "The hypotenuse is: $h.\n";

In this particular example, there happens to be no additional arguments to the hypot method, but there could have been.

With the arrow (->) notation, the left side of the arrow must be an object reference or a class name, while the right side of the arrow must be a method defined for that object. Any arguments must follow the method inside of parentheses. For example:

$obj->method(args)
CLASS->method(args)

You have to use parentheses because this form can't be used as a list operator, although the first type of method syntax can.

The examples given above would look like this using the arrow syntax:

$tri = Triangle::Right->new(side1 => 3, side2 => 4);
$h = $tri->hypot( );
print "The hypotenuse is: $h.\n";

The arrow syntax provides a helpful visual relationship between the object and its method, but both forms of syntax do the same thing. Precedence for the arrow syntax is left-to-right, exactly the same as for the dereferencing operator. This allows you to chain together objects and methods if you want to simplify things. You just have to make sure you have an object to the left of the arrow and a method to the right:

%sides = (side1 => 3, side2 => 4);
$h = Triangle::Right->new(%sides)->hypot( );
print "The hypotenuse is: $h.\n";

In this example, you never assign a variable name to the right-triangle object; the reference is passed directly to the hypot method.

Previous | Home | Next
7.3. Object-Oriented Perl | Book Index | 8. Standard Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 8. Standard Modules

Contents:

AnyDBM_File
Attribute::Handlers
attributes
attrs
AutoLoader
AutoSplit
autouse
B
B::Asmdata
B::Assembler
B::Bblock
B::Bytecode
B::C
B::CC
B::Concise
B::Debug
B::Deparse
B::Disassembler
B::Lint
B::Showlex
B::Stackobj
B::Terse
B::Xref
base
Benchmark
bigint
bignum
bigrat
blib
bytes
ByteLoader
Carp
CGI
CGI::Apache
CGI::Carp
CGI::Cookie
CGI::Fast
CGI::Pretty
CGI::Push
CGI::Switch
charnames
Class::ISA
Class::Struct
Config
constant
CPAN
CPAN::FirstTime
CPAN::Nox
Cwd
Data::Dumper
DB
DB_File
Devel::DProf
Devel::PPPort
Devel::SelfStubber
diagnostics
Digest
Digest::MD5
DirHandle
Dumpvalue
DynaLoader
encoding
English
Env
Errno
Exporter
ExtUtils::Command
ExtUtils::Command::MM
ExtUtils::Constant
ExtUtils::Embed
ExtUtils::Install
ExtUtils::Installed
ExtUtils::Liblist
ExtUtils::MakeMaker
ExtUtils::Manifest
ExtUtils::Miniperl
ExtUtils::Mkbootstrap
ExtUtils::Mksymlists
ExtUtils::MM
ExtUtils::MM_Any
ExtUtils::MM_BeOS
ExtUtils::MM_DOS
ExtUtils::MM_NW5
ExtUtils::MM_OS2
ExtUtils::MM_Unix
ExtUtils::MM_UWIN
ExtUtils::MM_VMS
ExtUtils::MM_Win32
ExtUtils::MY
ExtUtils::Packlist
ExtUtils::testlib
Fatal
Fcntl
fields
File::Basename
File::CheckTree
File::Compare
File::Copy
File::DosGlob
File::Find
File::Path
File::Spec
File::Spec::Cygwin
File::Spec::Mac
File::Spec::OS2
File::Spec::Unix
File::Spec::VMS
File::Spec::Win32
File::stat
File::Temp
FileCache
FileHandle
Filter::Simple
Filter::Util::Call
FindBin
GDBM_File
Getopt::Long
Getopt::Std
Hash::Util
I18N::Collate
I18N::Langinfo
I18N::LangTags
I18N::LangTags::List
if
integer
IO
IO::File
IO::Handle
IO::Pipe
IO::Seekable
IO::Select
IO::Socket
IPC::Msg
IPC::Open2
IPC::Open3
IPC::Semaphore
IPC::SysV
less
lib
List::Util
locale
Math::BigFloat
Math::BigInt
Math::BigInt::Calc
Math::BigRat
Math::Complex
Math::Trig
MIME::Base64
MIME::QuotedPrint
NDBM_File
Net::Cmd
Net::Config
Net::Domain
Net::FTP
Net::hostent
Net::netent
Net::Netrc
Net::NNTP
Net::Ping
Net::POP3
Net::protoent
Net::servent
Net::SMTP
Net::Time
O
ODBM_File
Opcode
ops
overload
PerlIO
PerlIO::Scalar
PerlIO::Via
Pod::Functions
Pod::Html
Pod::ParseLink
Pod::Text
POSIX
re
Safe
Scalar::Util
SDBM_File
Search::Dict
SelectSaver
SelfLoader
Shell
sigtrap
Socket
sort
Storable
strict
subs
Switch
Symbol
Sys::Hostname
Sys::Syslog
Term::Cap
Term::Complete
Term::ReadLine
Test
Test::Builder
Test::Harness
Test::More
Test::Simple
Text::Abbrev
Text::Balanced
Text::ParseWords
Text::Soundex
Text::Tabs
Text::Wrap
Thread
Thread::Queue
Thread::Semaphore
Thread::Signal
Thread::Specific
Tie::Array, Tie::StdArray
Tie::File
Tie::Handle
Tie::Hash
Tie::Memoize
Tie::RefHash
Tie::Scalar
Tie::SubstrHash
Time::gmtime
Time::HiRes
Time::Local
Time::localtime
Time::tm
UNIVERSAL
User::grent
User::pwent
utf8
vars
vmsish
XS::Typemap

We've talked about the extent to which Perl benefits from user contributions. In fact, many contributed modules are so generally useful that they are now distributed with Perl itself. This chapter describes these "standard modules"; if you are running Perl 5.005, all these modules are already available to you. If you are running an earlier version of Perl, and you find that a module you want isn't on your system, or if you simply don't find what you need among the modules in this chapter, check CPAN for one that does what you want.

While this chapter primarily covers standard Perl modules called at execution time from your program, it also covers the "pragmatic" modules that affect the compilation phase. (A pragma is a compiler directive that provides hints to the compiler.) By convention, the names of the pragmatic modules are all lowercase, while the names of other modules begin with an uppercase letter and are of mixed case.

The Win32-specific modules are not included in this chapter, but are described in Chapter 19, "Lightweight Directory Access with Net::LDAP".

The following table provides a quick look at the standard modules and what they do:

Module | Function
AnyDBM_File | Provides framework for multiple DBMs
Attribute::Handlers | Simpler definition of attribute handlers (new in 5.8)
attributes | Sets or gets attributes of a subroutine
attrs | Sets or gets attributes of a subroutine (deprecated)
AutoLoader | Loads functions only on demand
AutoSplit | Splits a module for autoloading
autouse | Postpones loading modules until a function is used
B | Perl compiler and tools
base | Establishes IS-A relationship with base class at compile time
Benchmark | Checks and compares running times of code
bigint | Transparent big integer support for Perl (new in 5.8)
bignum | Transparent BigNumber support for Perl (new in 5.8)
bigrat | Transparent BigNumber/BigRational support for Perl (new in 5.8)
blib | Uses MakeMaker's uninstalled version of a package
bytes | Perl pragma to force byte semantics rather than character semantics
ByteLoader | Loads byte-compiled Perl code
Carp | Generates error messages
CGI | Simple Common Gateway Interface class
CGI::Apache | Sets up environment to use CGI with Perl-Apache API
CGI::Carp | CGI routines for writing to HTTPD (or other) error log
CGI::Cookie | CGI interface to Netscape (HTTP/1.1) cookies
CGI::Fast | CGI interface for FastCGI
CGI::Pretty | Module to produce nicely formatted HTML code
CGI::Push | Interface for server push operations
CGI::Switch | Tries multiple constructors and returns the first available CGI object
charnames | Defines character names for \N{named} string literal escape
Class::ISA | Reports the search path for a class's ISA tree (new in 5.8)
Class::Struct | Declares struct-like datatypes as Perl classes
Config | Accesses Perl configuration information
constant | Perl pragma to declare constants
CPAN | Queries, downloads, and builds Perl modules from CPAN sites
CPAN::FirstTime | Utility for CPAN::Config file initialization
CPAN::Nox | Wrapper around CPAN.pm without using any XS module
Cwd | Gets pathname of current working directory
Data::Dumper | Returns Perl data structures as strings
DB | Programmatic interface to the Perl debugging API
DB_File | Accesses Berkeley DB
Devel::DProf | Perl Code Profiler
Devel::PPPort | Module that assists with module porting between Perl versions
Devel::SelfStubber | Generates stubs for a self-loading module
diagnostics | Forces verbose warning diagnostics
Digest | Modules that calculate message digests (new in 5.8)
Digest::MD5 | Perl interface to the MD5 Algorithm (new in 5.8)
DirHandle | Supplies object methods for directory handles
Dumpvalue | Provides a screen dump of Perl data
DynaLoader | Automatic dynamic loading of Perl modules
encoding | Allows you to write your script in nonasii or nonutf8 (new in 5.8)
English | Uses English or awk names for punctuation variables
Env | Imports environment variables
Errno | System errno constants from errno.h include file
Exporter | Default import method for modules
ExtUtils::Command | Utilities to replace common Unix commands
ExtUtils::Command::MM | Commands that the MM's can use in Makefiles (new in 5.8)
ExtUtils::Constant | Generates XS code to import C header constants (new in 5.8)
ExtUtils::Embed | Utilities for embedding Perl in C/C++ applications
ExtUtils::Install | Installs files from here to there
ExtUtils::Installed | Inventory management of installed modules
ExtUtils::Liblist | Determines libraries to use and how to use them
ExtUtils::MakeMaker | Creates a Makefile for a Perl extension
ExtUtils::Manifest | Utilities to write and check a MANIFEST file
ExtUtils::Miniperl | Writes the C code for perlmain.c
ExtUtils::Mkbootstrap | Makes a bootstrap file for use by DynaLoader
ExtUtils::Mksymlists | Writes linker option files for dynamic extension
ExtUtils::MM | Operating system-adjusted ExtUtils::MakeMaker subclass (new in 5.8)
ExtUtils::MM_Any | Platform-agnostic MM methods (new in 5.8)
ExtUtils::MM_BeOS | Methods that override UN*X behavior in ExtUtils::MakeMaker (new in 5.8)
ExtUtils::MM_DOS | DOS-specific subclass of ExtUtils::MM_Unix (new in 5.8)
ExtUtils::MM_NW5 | Methods that override UN*X behavior in ExtUtils::MakeMaker (new in 5.8)
ExtUtils::MM_OS2 | Methods to override Unix behavior in ExtUtils::MakeMaker
ExtUtils::MM_Unix | Methods used by ExtUtils::MakeMaker
ExtUtils::MM_UWIN | U/WIN-specific subclass of ExtUtils::MM_Unix (new in 5.8)
ExtUtils::MM_VMS | Methods to override Unix behavior in ExtUtils::MakeMaker
ExtUtils::MM_Win32 | Methods to override Unix behavior in ExtUtils::MakeMaker
ExtUtils::MY | ExtUtils::MakeMaker subclass for customization (new in 5.8)
ExtUtils::Packlist | Manages .packlist files
ExtUtils::testlib | Adds blib/* directories to @INC
Fatal | Replaces functions with equivalents that succeed or die
Fcntl | Loads the C fcntl.h defines
fields | Perl pragma to provide compile time-verified class fields
File::Basename | Parses file specifications
File::CheckTree | Runs many tests on a collection of files
File::Compare | Compares files or filehandles
File::Copy | Copies files or filehandles
File::DosGlob | DOS-like globbing with enhancements
File::Find | Traverses a file tree
File::Path | Creates or removes a series of directories
File::Spec | Portably performs operations on filenames
File::Spec::Cygwin | Methods for Cygwin file specs (new in 5.8)
File::stat | By-name interface to Perl's built-in stat functions
File::Temp | Returns the name and handle of a temporary file safely
FileCache | Keeps more files open than the system permits
FileHandle | Supplies object methods for filehandles
Filter::Simple | Simplified source filtering (new in 5.8)
Filter::Util::Call | Perl Source Filter Utility Module (new in 5.8)
FindBin | Locates directory of original Perl script
GDBM_File | Tied access to GDBM library
Getopt::Long | Extended processing of command-line options
Getopt::Std | Processes single-character options with option clustering
Hash::Util | A selection of general utility hash subroutines (new in 5.8)
I18N::Collate | Compares 8-bit scalar data according to the current locale
I18N::Langinfo | Queries locale information (new in 5.8)
I18N::LangTags | Functions for dealing with RFC3066-style language tags (new in 5.8)
I18N::LangTags::List | Tags and names for human languages (new in 5.8)
if | Uses a Perl module if a condition holds (new in 5.8)
integer | Does arithmetic in integer instead of double
IO | Loads various I/O modules
IO::File | Supplies object methods for filehandles
IO::Handle | Supplies object methods for I/O handles
IO::Pipe | Supplies object methods for pipes
IO::Seekable | Supplies seek-based methods for I/O objects
IO::Select | Object-oriented interface to the select system call
IO::Socket | Object interface to socket communications
IPC::Msg | System V Msg IPC object class
IPC::Open2 | Opens a process for both reading and writing
IPC::Open3 | Opens a process for reading, writing, and error handling
IPC::Semaphore | System V Semaphore IPC object class
IPC::SysV | System V IPC constants
less | Perl pragma to request less of something from the compiler
lib | Manipulates @INC at compile time
List::Util | A selection of general utility list subroutines (new in 5.8)
locale | Perl pragma to use and avoid POSIX locales for built-in operations
Math::BigFloat | Arbitrary-length floating-point math package
Math::BigInt | Arbitrary-length integer math package
Math::BigInt::Calc | Pure Perl module to support Math::BigInt (new in 5.8)
Math::BigRat | Arbitrarily big rationals (new in 5.8)
Math::Complex | Complex numbers package
Math::Trig | Trigonometric functions
MIME::Base64 | Encoding and decoding of base64 strings (new in 5.8)
MIME::QuotedPrint | Encoding and decoding of quoted, printable strings (new in 5.8)
NDBM_File | Tied access to NDBM files
Net::Cmd | Network Command class (new in 5.8)
Net::Config | Local configuration data for libnet (new in 5.8)
Net::Domain | Attempts to evaluate the current host's Internet name and domain (new in 5.8)
Net::FTP | FTP Client class (new in 5.8)
Net::hostent | By-name interface to Perl's built-in gethost* functions
Net::netent | By-name interface to Perl's built-in getnet* functions
Net::Netrc | OO interface to user's netrc file (new in 5.8)
Net::NNTP | NNTP Client class (new in 5.8)
Net::Ping | Checks whether a host is online
Net::POP3 | Post Office Protocol 3 Client class (new in 5.8)
Net::protoent | By-name interface to Perl's built-in getproto* functions
Net::servent | By-name interface to Perl's built-in getserv* functions
Net::SMTP | Simple Mail Transfer Protocol Client class (new in 5.8)
Net::Time | Time and daytime network client interface (new in 5.8)
ODBM_File | Tied access to ODBM files
Opcode | Disables named opcodes when compiling Perl code
ops | Restricts unsafe operations when compiling
overload | Overloads Perl's mathematical operations
PerlIO | On-demand loader for PerlIO layers and root of PerlIO::* namespace (added in 5.8)
PerlIO::Scalar | Support module for in-memory I/O (new in 5.8)
PerlIO::Via | Helper class for PerlIO layers implemented in Perl (new in 5.8)
Pod::Functions | Used in converting from pod to HTML
Pod::Html | Module to convert pod files to HTML
Pod::ParseLink | Parses link-formatting code in POD documents (new in 5.8)
Pod::Text | Converts pod data to formatted ASCII text
POSIX | Perl interface to IEEE Std 1003.1
re | Perl pragma to alter regular expression behavior
Safe | Creates safe namespaces for evaluating Perl code
Scalar::Util | A selection of general-utility scalar subroutines (new in 5.8)
SDBM_File | Tied access to SDBM files
Search::Dict | Searches for key in dictionary file
SelectSaver | Saves and restores selected filehandle
SelfLoader | Loads functions only on demand
Shell | Runs shell commands transparently within Perl
sigtrap | Enables stack backtrace on unexpected signals
Socket | Loads the C socket.h defines and structure manipulators
sort | Perl pragma that controls sort behavior (new in 5.8)
Storable | Persistence for Perl data structures (new in 5.8)
strict | Restricts unsafe constructs
subs | Predeclares subroutine names
Switch | A switch statement for Perl (new in 5.8)
Symbol | Generates anonymous globs; qualifies variable names
Sys::Hostname | Tries every conceivable way to get hostname
Sys::Syslog | Perl interface to Unix syslog(3) calls
Term::Cap | Terminal capabilities interface
Term::Complete | Word completion module
Term::ReadLine | Interface to various ReadLine packages
Test | Framework for writing test scripts
Test::Builder | Backend for building text libraries (new in 5.8)
Test::Harness | Runs Perl standard test scripts with statistics
Test::More | Yet another framework for writing test scripts (new in 5.8)
Test::Simple | Basic utilities for writing tests (new in 5.8)
Text::Abbrev | Creates an abbreviation table from a list
Text::Balanced | Extracts delimited text sequences from strings (new in 5.8)
Text::ParseWords | Parses text into a list of tokens
Text::Soundex | The soundex algorithm described by Knuth
Text::Tabs | Expands and unexpands tabs
Text::Wrap | Wraps text into a paragraph
Thread | Multithreading support
Thread::Queue | Thread-safe queues
Thread::Semaphore | Thread-safe semaphores
Thread::Signal | Starts a thread that runs signal handlers reliably
Thread::Specific | Thread-specific keys
Tie::Array | Base class definitions for tied arrays
Tie::File | Accesses the lines of a disk file via a Perl array (new in 5.8)
Tie::Handle | Base class definitions for tied handles
Tie::Hash | Base class definitions for tied hashes
Tie::Memorize | Adds data to a hash when needed (new in 5.8)
Tie::RefHash | Uses references as hash keys
Tie::Scalar | Base class definitions for tied scalars
Tie::SubstrHash | Fixed table size, fixed key length hashing
Time::gmtime | By-name interface to Perl's built-in gmtime function
Time::HiRes | High-resolution alarm, sleep, gettimeofday, interval timers (new in 5.8)
Time::Local | Computes time from local and GMT time
Time::localtime | By-name interface to Perl's built-in localtime function
Time::tm | Internal object used by Time::gmtime and Time::localtime
UNIVERSAL | Base class for all classes (blessed references)
User::grent | By-name interface to Perl's built-in getgr* functions
User::pwent | By-name interface to Perl's built-in getpw* functions
utf8 | Perl pragma to enable/disable UTF-8 in source code
vars | Predeclares global variable names
vmsish | Perl pragma that controls VMS-specific language features (new in 5.8)
XS::Typemap | Module that tests the XS typemaps distributed with Perl (new in 5.8)

In the remainder of this chapter, the modules are arranged in alphabetical order for easy reference. For more detail about a module, use the perldoc command to read the manpage for that module (see Chapter 4, "The Perl Language" for information on perldoc).

8.1. AnyDBM_File

Provides a single Database Manager (DBM) interface regardless of the DBM implementation you use. The module inherits from the various DBM packages; by default, it inherits from NDBM_File. If it doesn't find NDBM_File, the default search order is: DB_File, GDBM_File, SDBM_File (which comes with Perl), and finally, ODBM_File. You can override this default order by redefining @ISA:

@AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File);

However, an explicit use takes priority over the @ISA ordering.

Perl's dbmopen function simply calls tie to bind a hash to AnyDBM_File. The effect is to bind the hash to one of the specific DBM classes that AnyDBM_File inherits from.

Previous | Home | Next
7.4. Object Syntax | Book Index | 8.2. Attribute::Handlers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.2. Attribute::Handlers

Implements a simpler definition of attribute handlers. When inherited by a package, Attribute::Handlers allows that package's class to define handler subroutines for specific attributes. When inherited by a package, these handlers will be called by the same names as the original attribute-handling subroutines. Attribute handlers will be called at one of the following compilation phases: BEGIN, CHECK, INIT, or END blocks. Note that Attribute::Handlers is shipped with the Perl source kit as of Version 5.8.

Handlers are defined as subroutines and named as the desired attribute. In the following example, the attribute is :ATTR, which lives in a subroutine that's called Nate1() in the HandlerBing class:

package HandlerBing;
use Attribute::Handlers;
sub Nate1 :ATTR {
    my(@attrs) = @_; # We simply want to test by dumping the attributes
    print "attributes: \n",
       join("\n", @attrs), "\n";
}
 # true.
1;

This stub for the HandlerBing class creates a handler for the attribute :Nate1. When you want to use this handler while within HandlerBing, you can do the following:

sub Nate2 :Nate1 {
    my (@stuff) = @_;
        print STDERR "in Nate2 ", join("\n", @stuff), "\n";
}

When you call Nate2, it invokes the Nate1 handler and passes the following elements into the @_ array:

0
The name of the package in which the handler was declared

1
A reference to the symbol table entry (a typeglob) that contains the subroutine

2
A reference to the subroutine

3
The name of the attribute itself

4
Any data associated with that attribute

5
The name of the compilation phase in which the handler was invoked

The same holds true for declaring any variables with the :Nate1 attribute within HandlerBing:

my $monica :Nate1;
my $phoebe :Nate1;

Attribute::Handlers also supports typed lexicals. This is a nice feature, since you can invoke a handler from a package that defines another one from whatever package you're in (or writing!). For example:

package MustNotSeeTV;
 my HandlerBring $whatever : Nate1;
 # true
1;

You can apply handlers only by type, if you wish. You can do this by passing a built-in type to :ATTR:

package ReRun;
 sub Tiresome :ATTR(HASH) { print "your reruns have become tiresome\n"; }
 # true
1;

In the above code, Tiresome is an attribute handler that applies only to HASH es. And certainly, you can declare separate handlers (of the same names) for the other types.

If you have problems passing certain data to a handler, such as now..later or laugh@you, you can use the RAWDATA type to pass this data cleanly:

sub RawLikeSushi : ATTR(RAWDATA) { ... do something ... }

Attribute::Handlers implements the following diagnostics (from the Attribute::Handlers manpage):

Bad attribute type: ATTR(%s)
An attribute handler was specified with an :ATTR(ref_type), but the type of referent it was defined to handle wasn't one of the five permitted: SCALAR, ARRAY, HASH, CODE, or ANY.

Attribute handler %s doesn't handle %s attributes
A handler for attributes of the specified name was defined, but not for the specified type of declaration. Typically encountered when trying to apply a VAR attribute handler to a subroutine, or a SCALAR attribute handler to another type of variable.

Declaration of %s attribute in %s package may clash with future reserved word
A handler for an attribute with an all-lowercase name was declared. An attribute with an all-lowercase name might mean something to Perl itself someday, even though most don't yet. Use a mixed-case attribute name instead.

Can't have two ATTR specifiers on one subroutine
You just can't, okay? Instead, put all the specifications together, separated by commas in a single ATTR(specifications).

Can't autotie a %s
You can declare autoties only for types SCALAR, ARRAY, and HASH. They're the only things (apart from typeglobs, which are not declarable) that Perl can tie.

Internal error: %s symbol went missing
Something is rotten in the state of the program. An attributed subroutine ceased to exist between the point where it was declared and the point where its attribute handler(s) would have been called.

Won't be able to apply an END handler
You tried to define an END handler for an attribute that is applied to a lexical variable. Since the variable may not be available during END, this will fail.

Previous | Home | Next
8. Standard Modules | Book Index | 8.3. attributes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.3. attributes

Replacement for attrs.pm that sets or gets the attributes of subroutines. Attributes are set at compile time. If an attribute is unrecognized, it will result in a fatal error. While the error is trappable, it will stop the compilation within an eval. You must be careful about naming your attributes; an attribute that's all lowercase and not a built-in attribute will result in a warning (unless you use warnings "reserved"). An example of attributes is:

sub foo : method ;
    use attributes ( );    # Optional, to get subroutine declarations
    my @attrlist = attributes::get(\&foo);

The built-in attributes are:

locked
Setting this attribute is meaningful only when the subroutine or method will be called by multiple threads. When set on a method subroutine (i.e., one marked with the method attribute), Perl ensures that any invocation of it implicitly locks its first argument before execution. When set on a non-method subroutine, Perl ensures that a lock is taken on the subroutine itself before execution. The semantics of the lock are exactly those of one explicitly taken with the "lock" operator immediately after the subroutine is entered.

method
Indicates that the referenced subroutine is a method. This has a meaning when taken together with the locked attribute. It also means that a subroutine so marked will not trigger the "Ambiguous call resolved as CORE::%s" warning.

lvalue
Indicates that the referenced subroutine is a valid lvalue and can be assigned to. The subroutine must return a modifiable value such as a scalar variable, as described in the perlsub manpage.

There are no built-in attributes for anything other than subroutines.

Previous | Home | Next
8.2. Attribute::Handlers | Book Index | 8.4. attrs
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.4. attrs

Sets or gets the attributes of subroutines. Attributes are set for a subroutine at compile time; therefore, setting an invalid attribute results in a compile-time error. Note that attrs has been deprecated. You should use the attributes form instead. During execution, when you call attrs::get on a subroutine reference or name, it returns the list of attributes that are set. Note that attrs::get is not exported. The old usage of attrs is as follows:

sub test {
    use attrs qw(locked method);
    ...
}
@a = attrs::get(\test);

You should use a form like the following instead:

sub test : locked method { }

You can read more about attributes in the next section.

The valid attributes are:

locked
Meaningful only when the subroutine or method will be called by multiple threads. When set on a subroutine that also has the method attribute set, invoking that subroutine implicitly locks its first argument before execution. On a non-method subroutine, a lock is taken on the subroutine itself before execution. The lock semantics are identical to one taken explicitly with the lock operator immediately after entering the subroutine.

method
The invoking subroutine is a method.

Previous | Home | Next
8.3. attributes | Book Index | 8.5. AutoLoader
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.5. AutoLoader

Delays the loading of functions until they are used. Each function is placed in a file that has the same name as the function, with an .al extension. The files are stored in a subdirectory of the auto/ directory that is named after the package. For example, the function GoodStuff::whatever is loaded from the file auto/GoodStuff/whatever.al. Should always be used and not require d.

A module using the AutoLoader has the special marker, _ _END_ _ prior to the declarations for the subroutine to be autoloaded. Any code before this marker is loaded and compiled when the module is used, but at the marker, Perl stops parsing the file.

Later, during execution, when a subroutine that isn't yet in memory is called, the AUTOLOAD function attempts to find it in a directory relative to the location of the module file. For example, if POSIX.pm is in the directory /usr/local/lib/perl5, then AutoLoader looks for POSIX subroutines in /usr/local/lib/perl5/auto/POSIX/*.al.

Previous | Home | Next
8.4. attrs | Book Index | 8.6. AutoSplit
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.6. AutoSplit

Splits a program or module into files that the AutoLoader can handle. It can be called from a program or from the command line:

# From a program
use AutoSplit;
autosplit_modules(@ARGV)

# From the command line
perl -MAutoSplit -e 'autosplit(FILE, DIR, KEEP, CHECK, MODTIME)' ...

# Another interface
perl -MAutoSplit -e 'autosplit_lib_modules(@ARGV)' ...

AutoSplit is used by MakeMaker as well as by the standard Perl libraries. It operates on a file, splitting off subroutines that come after the _ _END_ _ marker and storing them as described above for AutoLoader, creating any necessary directories along the way. AutoSplit has two functions.

autosplit
autosplit (file, dir, keep, check, modtime)

Splits the module into files. Each file is given the name of the subroutine it contains, with .al appended. autosplit also creates the file autosplit.ix, which serves as both a forward declaration of all package routines and as a timestamp showing when the hierarchy was last updated. Takes the following arguments:

file
Filename of program or module to be split.

dir
Name of directory hierarchy in which to store the split files.

keep
If false, preexisting .al files in the auto directory that are no longer part of the module are deleted.

check
If true, checks to be sure the module being split includes a use AutoLoader statement. If the statement is missing, autosplit doesn't process the module.

modtime
If true, splits the module only if it is newer than autosplit.ix.

autosplit_lib_modules
autosplit_lib_modules (@ARGV)

Takes a list of modules that are assumed to be in a lib subdirectory of the current directory, processes them as described above for autosplit, and stores the resulting file in the directory lib/auto. Used in building Perl.

Previous | Home | Next
8.5. AutoLoader | Book Index | 8.7. autouse
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.7. autouse

Pragma for postponing the loading of a module from compile time to execution time. The module isn't loaded until one of its subroutines is used; the subroutines all have to be exported by the module:

use autouse module => qw(sub1 [sub2 ...])

Use with care, since problems that might otherwise be found during compilation won't crop up until your program is already executing.

Previous | Home | Next
8.6. AutoSplit | Book Index | 8.8. B
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.8. B

The Perl compiler. To use the compiler, you don't need to use this module. See the O module, which is the user frontend to the compiler; see also the compiler section of Chapter 3, "The Perl Executable". The B module provides the classes for implementing backends for the compiler. If you plan to write a new backend, read the B manpage for the details of the module.

Previous | Home | Next
8.7. autouse | Book Index | 8.9. B::Asmdata
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.9. B::Asmdata

Contains autogenerated data about Perl ops; used to generate bytecode. Any changes made to this file will be lost.

Previous | Home | Next
8.8. B | Book Index | 8.10. B::Assembler
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.10. B::Assembler

Assembles Perl bytecode.

Previous | Home | Next
8.9. B::Asmdata | Book Index | 8.11. B::Bblock
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.11. B::Bblock

Walks the basic blocks of a program. Invoked as:

perl -MO=Bblock[,options] filename
Previous | Home | Next
8.10. B::Assembler | Book Index | 8.12. B::Bytecode
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.12. B::Bytecode

The bytecode backend for the Perl compiler. Takes Perl source code and generates platform-independent bytecode that can be run with the byteperl executable or can be loaded via the byteload_fh function in the B module. Compiling with the bytecode backend won't speed up execution of your program, but it may improve start-up time. Invoke as:

perl -MO=Bytecode[,options] program

in which program is the name of the Perl script to compile. Any non-option arguments are treated as the names of objects to be saved; the main program is assumed if there are no extra arguments. Possible options are:

--
Forces end of options.

-Dopts
Debug options, which can be concatenated or specified separately. Possible options are:

a
Tells the bytecode assembler to include assembler source in its output as bytecode comments

b
Prints debugging information about bytecompiler progress

C
Prints each CV from the final walk through the symbol tree

o
Prints each OP as it's processed

-fopt
Forces individual optimizations on or off. Preceding an optimization with no- turns that option off (e.g., no-compress-nullops). Possible values of opt are:

bypass-nullops
If op->op_next ever points to a NULLOP, replaces the op_next field with the first non-NULLOP in the path of execution.

compress-nullops
Fills in only the necessary fields of ops that have been optimized away by Perl's internal compiler.

omit-sequence-numbers
Leaves out the code to fill in the op_seq field for all ops that are used only by Perl's internal compiler.

strip-syntax-tree
Leaves out the code to fill in the internal syntax tree pointers. Use of this option breaks any goto label statements and prevents later recompiling or disassembling of the resulting program.

-m
Compiles as a module rather than as a standalone program.

-ofilename
Sends output to filename instead of STDOUT.

-O[n]
Sets the optimization level to n, in in which n is an integer. n defaults to 1. -O1 sets -fcompress-nullops -fomit-sequence-numbers, and -O6 adds -fstrip-syntax-tree.

-S
Outputs bytecode assembler source instead of assembling it into bytecode.

Previous | Home | Next
8.11. B::Bblock | Book Index | 8.13. B::C
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.13. B::C

The C backend for the Perl compiler. Generates C source code from Perl source; the generated code corresponds to Perl's internal structures for running the program. Compiling with the C backend won't speed up execution of your program, but it may improve start-up time. Invoke as:

perl -MO=C[,options] program

in which program is the name of the Perl script to compile. Any non-option arguments are treated as the names of objects to be saved; the main program is assumed if there are no extra arguments. Possible options are:

--
Forces end of options.

-Dopts
Debug options, which can be concatenated or specified separately. Possible options are:

A
Prints AV information on saving

c
Prints COPs as they are processed, including file and line number

C
Prints CV information on saving

M
Prints MAGIC information on saving

o
Prints each OP as it's processed

-fopt
Forces individual optimizations on or off. Possible values of opt are:

cog
Copy-on-grow. PVs are declared and initialized statically.

no-cog
No copy-on-grow.

-ofilename
Sends output to filename instead of to STDOUT.

-O[n]
Sets optimization level, in which n is an integer. n defaults to 1. Currently, values of 1 and higher set cog.

-uPackname
Forces apparently unused subroutines from package Packname to be compiled, letting programs use eval "foo( )" even if subroutine foo isn't seen to be used at compile time. You can specify multiple -u options.

-v
Compiles verbosely.

Previous | Home | Next
8.12. B::Bytecode | Book Index | 8.14. B::CC
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.14. B::CC

The CC backend for the Perl compiler. Generates optimized C source code that corresponds to your program's flow. The initial version included in Perl 5.005 actually includes few optimizations, but this will change. Programs compiled with this backend may start up and execute slightly faster. Invoke as:

perl -MO=C[,options] program

program is the name of the Perl script to compile. Any non-option arguments are treated as the names of objects to be saved; the main program is assumed if there are no extra arguments. Possible options are:

--
Forces end of options.

-Dopts
Debug options, which can be concatenated or specified separately. Possible options are:

l
Outputs the filename and line number of each original line of Perl code as it is processed

O
Outputs each OP as it is compiled

p
Outputs the contents of the shadow pad of lexicals as it is loaded for each sub or for the main program

q
Outputs the name of each fake PP function in the queue as it's about to be processed

r
Writes debugging output to STDERR instead of as comments in the C output

s
Outputs the contents of the shadow stack at each OP

t
Outputs timing information of the stages of compilation

-fopt
Forces individual optimizations on or off. Possible values of opt are:

freetmps-each-bblock
Runs FREETMPS at the end of each basic block instead of at the end of each statement. freetmps-each-loop and freetmps-each-bblock are mutually exclusive.

freetmps-each-loop
Runs FREETMPS at the end of each loop instead of at the end of each statement. freetmps-each-loop and freetmps-each-bblock are mutually exclusive.

omit-taint
Doesn't generate code for handling Perl's tainting mechanism.

-mModulename
Generates source for an XSUB module instead of for an executable.

-ofilename
Sends output to filename instead of to STDOUT.

-O[n]
Sets optimization level, in which n is an integer. n defaults to 1. Currently, -O1 sets -ffreetmps-each-bblock, and -O2 sets -ffreetmps-each-loop.

-uPackname
Forces apparently unused subroutines from package Packname to be compiled, permitting programs to use eval "foo( )" even if subroutine foo isn't seen to be used at compile time. You can specify multiple -u options.

-v
Compiles verbosely.

Previous | Home | Next
8.13. B::C | Book Index | 8.15. B::Concise
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.15. B::Concise

A module that walks the Perl syntax tree, printing concise info about the internal OPs of a Perl program's syntax tree. The format of the information displayed is customizable. Its function is similar to that of Perl's -Dx debugging flag or the B::Terse module, but it is more sophisticated and flexible. Invoke as:

perl -MO=Concise[,options] program

program is the name of the Perl script to compile. Any non-option arguments are treated as the names of objects to be saved; the main program is assumed if there are no extra arguments. Possible options are:

-basic
Prints OPs in the order they appear in the OP tree (a preorder traversal, starting at the root). Default.

-exec
Prints OPs in the order they would normally execute. For the majority of constructs, this is a postorder traversal of the tree, ending at the root.

-tree
Prints OPs in a text approximation of a tree, with the root of the tree at the left and "left-to-right" order of children transformed into "top-to-bottom". Unsuitable for large programs.

-compact
Uses a tree format in which the minimum amount of space is used for the lines connecting nodes (one character in most cases).

-loose
Uses a tree format that uses longer edges to separate OP nodes. Default.

-vt
Uses tree-connecting characters drawn from the VT100 line-drawing set.

-ascii
Draws the tree with standard ASCII characters such as + and |. Default.

-main
Includes the main program in the output, even if subroutines were also specified.

-basen
Prints OP sequence numbers in base n, with n <= 62. The default is 36.

-bigendian
Prints sequence numbers with the most significant digit first. Default.

-littleendian
Prints sequence numbers with the least significant digit first.

-concise
Uses the author's favorite set of formatting conventions. Default.

-terse
Uses formatting conventions that emulate the output of B::Terse.

-linenoise
Uses formatting conventions in which the name of each OP, rather than written out in full, is represented by a one- or two-character abbreviation.

-debug
Uses formatting conventions reminiscient of B::Debug.

-env
Uses formatting conventions read from the environment variables B_CONCISE_FORMAT, B_CONCISE_GOTO_FORMAT, and B_CONCISE_TREE_FORMAT.

Previous | Home | Next
8.14. B::CC | Book Index | 8.16. B::Debug
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.16. B::Debug

Walks the Perl syntax tree, printing debug information about ops. Invoke as:

perl -MO=Debug[,exec] filename

If exec is specified, walks in execution order rather than in syntax order.

Previous | Home | Next
8.15. B::Concise | Book Index | 8.17. B::Deparse
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.17. B::Deparse

Perl compiler backend that generates Perl source code from the internal compiled structure of a program. The output won't be exactly the same as the original program, but it will be close. Invoke as:

perl -MO=Deparse[,options] program

program is the name of the program that will be deparsed. The options are comma-separated and follow normal backend option conventions. The possible options are:

-l
Adds #line declarations to the output based on line and file locations of the original code.

-p
Prints parentheses wherever they are legal, not just where they are required. Useful for seeing how Perl is parsing your expressions.

-sletters
Provides style options for the output. In this initial release, the only style option provided is C, which "cuddles" else, elsif, and continue blocks so that, for example, you would get:

} else {

instead of:

}
  else {

The default is to not cuddle.

-uPackage
Deparses subroutines in package Package as well as the main program, subroutines called by the main program, and subroutines in the main program. Multiple -u arguments can be given, separated by commas.

Previous | Home | Next
8.16. B::Debug | Book Index | 8.18. B::Disassembler
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.18. B::Disassembler

Disassembles Perl bytecode.

Previous | Home | Next
8.17. B::Deparse | Book Index | 8.19. B::Lint
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.19. B::Lint

Provides program checking for Perl programs. Equivalent to running Perl with the -w option. Named after the Unix lint program for checking C programs. Invoked as:

perl -MO=Lint[,options] program

program is the name of the Perl program that will be checked. The options are separated by commas and follow normal backend option conventions. Most of the options are lint-check options, in which each option is a word specifying one lint check. Preceding an option with no- turns off that option. Options specified later override earlier options. There is also one non-lint-check option, -u. Here is the list of available options:

all
Turns all warnings on.

context
Warns whenever an array is used in implicit scalar context.

dollar-underscore
Warns whenever $_ is explicitly used anywhere or whenever it is used as the implicit argument of a print statement.

implicit-read
Warns whenever an operation implicitly reads a Perl special variable.

implicit-write
Warns whenever an operation implicitly writes to a Perl special variable.

none
Turns off all warnings.

private-names
Warns whenever any variable, subroutine, or method name lives in a non-current package but begins with an underscore ( _ ). Doesn't warn about an underscore as a single-character name, e.g., $_.

regexp-variables
Warns whenever one of the regular expression variables $', $&, or $' is used.

-u Package
Normally checks only the main program code and all subroutines defined in package main. -u lets you specify other packages to be checked.

undefined-subs
Warns whenever an undefined subroutine is invoked.

Previous | Home | Next
8.18. B::Disassembler | Book Index | 8.20. B::Showlex
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.20. B::Showlex

Shows lexical variables used in functions or files. Invoke as:

perl -MO=Showlex[,sub] filename

If sub is provided and is the name of a subroutine in file filename, B::Showlex prints the lexical variables used in that subroutine. Otherwise, it prints the file-scope lexicals in filename.

Previous | Home | Next
8.19. B::Lint | Book Index | 8.21. B::Stackobj
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.21. B::Stackobj

Serves as a helper module for the CC backend.

Previous | Home | Next
8.20. B::Showlex | Book Index | 8.22. B::Terse
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.22. B::Terse

Walks the Perl syntax tree, printing terse information about the ops. Invoke as:

perl -MO=Terse[,exec] filename

If exec is specified, walks the tree in execution order instead of syntax order.

Previous | Home | Next
8.21. B::Stackobj | Book Index | 8.23. B::Xref
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.23. B::Xref

Perl compiler backend that generates a cross-reference listing of variables, subroutines, and formats in a Perl program. Results are grouped by file, then subroutine, then package, then objects within the package with line numbers. The line numbers are given as a comma-separated list. A line number may be preceded by one of the following code letters:

Code | Meaning
% | Subroutine or method call
f | Format definition
i | Introduction, e.g., a lexical defined with my
s | Subroutine definition

Invoke B::Xref like this:

perl -MO=Xref[,options] program

program is the Perl program whose cross-reference you want. Options are separated by commas and follow normal backend option conventions. The possible options are:

-D
Specifies internal debug options. Most useful if specified with -r option. Debug options are:

O
Prints each operator as it's being processed, in the execution order of the program

t
Prints the object on the top of the stack as it is being tracked

-ofilename
Sends output to filename instead of to STDOUT.

-r
Produces raw output in machine-readable form for each definition or use of a variable, subroutine, or format.

Previous | Home | Next
8.22. B::Terse | Book Index | 8.24. base
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.24. base

Provides a shortcut for setting up @ISA. You can say:

use base qw(A B);

instead of:

BEGIN {
    require Foo;
    require Bar;
    push @ISA, qw(Foo Bar);
}
Previous | Home | Next
8.23. B::Xref | Book Index | 8.25. Benchmark
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.25. Benchmark

Provides routines for timing the execution of your code and formatting the results. Inherits only from the Exporter class. It has the following functions.

new
new Benchmark

Returns the current time. By getting the current time before and after running the code, you can calculate the time it takes the code to run.

clearallcache
clearallcache

Clears the entire cache. Exported on request.

clearcache
clearcache (count)

Clears the cached time for count rounds of the null loop. Exported on request.

debug
Benchmark->debug(flag)

Enables or disables debugging by setting the $Benchmark::Debug flag.

disablecache
disablecache

Disables use of the cache. Exported on request.

enablecache
enablecache

Resumes caching. Exported on request.

timediff
timediff (t1, t2)

Calculates the difference between two times and returns the difference as a Benchmark object suitable for passing to timestr. Always exported.

timeit
timeit (count, code)

Runs code and reports the time it took. Always exported. Takes the following arguments:

count
The number of times to run the loop

code
The code to run, specified as either a code reference or a string

timestr
timestr (timediff[, style[, format]])

Converts times to printable strings. Always exported. Takes the following arguments:

timediff
The object containing the times to be formatted.

style
The output format. The possible values of style are:

all
Shows all of the following times: wallclock, user, system, user time of children, and system time of children

auto
Like all, except that if the children times are both 0, it acts like noc

noc
Shows all except the two children times

nop
Shows only wallclock and the two children times

format
Indicates the printf(3)-style format specifier (without the leading %) to use for printing the times. The default is 5.2f.

timethese
timethese (count, \%codehashref[, style])

Times each of several pieces of code and reports the results separately. Always exported. Takes the following arguments:

count
The number of times to run the loop.

\%codehashref
Reference to a hash in which the keys are names and the values are either strings or code references; each key/value pair specifies a piece of code to run.

style
Determines the format of the output. See timestr for the possible values of style.

timethis
timethis (count, code[, title[, style]])

Runs a chunk of code several times. Always exported. Takes the following arguments:

count
The number of times to run the loop.

code
The code to run, specified as either a code reference or a string.

title
The title of the result; default is "timethis COUNT".

style
Determines the format of the output. See timestr for the possible values of style.

Previous | Home | Next
8.24. base | Book Index | 8.26. bigint
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.26. bigint

Provides big-integer support for Perl. Prior to 5.8, and for 32-bit architectures, Perl supported whatever numbers your platform supported. This wasn't always the best solution when dealing with large numbers. Thus, the integer-related math modules were born, including Math::BigInt and bigint. Math::BigInt and bigint override all of the core Perl math functions and still support large integers. As of Perl 5.8, bigint.pm is shipped with the Perl source kit.

For example:

#!/usr/local/bin/perl -w
use bigint;

my $num1 = 4;
my $num2 = 1024;
 print $num1 ** $num2, "\n";  # Prints a very large number
Previous | Home | Next
8.25. Benchmark | Book Index | 8.27. bignum
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.27. bignum

Supports whatever big numbers you give it, including large integers and floats. In addition, bignum lets you specify options for the accuracy and precision of numbers that you'll calculate with it.

For example:

#!/usr/local/bin/perl -w
use bignum;

my $num1 = 4;
my $num2 = 5;
my $mult = $num1 * $num2;

print sqrt($mult),"\n"; # Yup

For a number that would be large, you can use bignum's accuracy option, a, to set the number of places after the decimal:

perl -Mbignum=a,50 -le 'print sqrt(20), "\n";'

If you wish to use rounding with bignum, you can use the precision option, p, with a 0 or 1 value to round up a value:

perl -Mbignum=p,0 -le 'print sqrt(24), "\n";' # Gives 5

To enable tracing for bignum, use the t or trace options:

/usr/local/perl5.8-prerc1/bin/perl5.7.3 -Mbignum=p,0,t -le 'print sqrt(24)'
MBI import Math::BigInt::Trace :constant upgrade Math::BigFloat::Trace lib Calc
MBF import Math::BigFloat::Trace :constant downgrade Math::BigInt::Trace
MBI new '24' => '24' (Math::BigInt::Trace)
MBF new '24' => '24' (Math::BigFloat)
MBF new '4' => '4' (Math::BigFloat)
MBF new '1E-4' => '0' (Math::BigFloat)
MBI new '2' => '2' (Math::BigInt::Trace)
MBF new '2' => '2' (Math::BigInt::Trace)
MBI new '38' => '38' (Math::BigInt::Trace)
MBI new '38' => '38' (Math::BigInt::Trace)

The l, or lib, option lets you specify a different math library:

perl -Mbignum=l,new_math_lib -e 'print $this ** $that'

The v, or version, option shows you the version of all modules used by bignum and then exits.

Previous | Home | Next
8.26. bigint | Book Index | 8.28. bigrat
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.28. bigrat

Implements big rational support for Perl. For example, if you want to add the fractions 1/2 + 3/8, you can use bigrat to calculate the result and display it in fractional form: 7/8. Or in Perl terms:

#!/usr/local/bin/perl -w
use bigrat;

my $frac1 = 1/2;
my $frac2 = 3/8;
print $frac1 + $frac2, "\n"; # Prints 7/8

As of Perl 5.8, bigrat is shipped with the Perl source kit.

Previous | Home | Next
8.27. bignum | Book Index | 8.29. blib
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.29. blib

Pragma for testing programs against a package before the package has been installed. Given a directory path, blib starts looking for a blib directory structure in that directory; if it doesn't find one there, it works its way back up five levels. If no path is specified, it starts looking in the current directory.

blib is meant to be used from the command line:

perl -Mblib script [args...]
perl -Mblib=dir script [args...]

However, you can also call it from a Perl program:

use blib;
use blib 'dir';
Previous | Home | Next
8.28. bigrat | Book Index | 8.30. bytes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.30. bytes

The use bytes pragma disables character semantics for the rest of the lexical scope in which it appears. no bytes can reverse the effect of use bytes within the current lexical scope. Perl normally assumes character semantics in the presence of character data (i.e., data from a source marked as being of a particular character encoding). When use bytes is in effect, the encoding is temporarily ignored, and each string is treated as a series of bytes.

bytes is used as follows:

$x = chr(400);
    print "Length is ", length $x, "\n";     # "Length is 1"
    printf "Contents are %vd\n", $x;         # "Contents are 400"
    {
        use bytes;
        print "Length is ", length $x, "\n"; # "Length is 2"
        printf "Contents are %vd\n", $x;     # "Contents are 198.144"
    }
Previous | Home | Next
8.29. blib | Book Index | 8.31. ByteLoader
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.31. ByteLoader

ByteLoader is used to load byte-compiled Perl code. It uses the source filter mechanism to read the bytecode and insert it into the compiled code at the appropriate point. You will probably never interact with ByteLoader programatically.

Previous | Home | Next
8.30. bytes | Book Index | 8.32. Carp
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.32. Carp

Provides routines for generating error messages. Its subroutines generally report errors from the perspective of the calling program. It has the following functions.

carp
carp msg

Warns of an error; reports the error as having occurred in the calling routine, not in the routine that contains the carp.

Use Carp;
carp "text of error message";
cluck
cluck msg

Warns of errors and prints a stack backtrace; reports the error as having occurred in the calling routine. Not exported by default.

use Carp qw(cluck);
cluck "text of error message";
confess
confess msg

Dies and prints a stack backtrace. Reports the error as having occurred at the point where confess was called.

croak
croak msg

Dies and reports error as having occurred in the calling routine.

Previous | Home | Next
8.31. ByteLoader | Book Index | 8.33. CGI
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.33. CGI

The Common Gateway Interface (CGI) library permits object-oriented web form creation and processing. The CGI.pm module contains the bulk of functionality for CGI programming. Four subclasses provide interfaces to various server environments and additional features. They are described below. For complete information on how CGI works and a description of CGI.pm, see Chapter 9, "CGI Overview" and Chapter 10, "The CGI.pm Module".

Previous | Home | Next
8.32. Carp | Book Index | 8.34. CGI::Apache
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.34. CGI::Apache

Sets up the environment for using CGI.pm with the Perl-Apache API. The new constructor for this class creates an Apache::CGI class object that interfaces to the API.

Previous | Home | Next
8.33. CGI | Book Index | 8.35. CGI::Carp
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.35. CGI::Carp

Creates Carp-like CGI routines for writing error messages to the HTTPD or other error log. Exports functions for warn, die, carp, confess, and croak. The functions write timestamped error messages to your server log or other output that you specify. See Section 8.32, "Carp" for details on the Carp functions.

Two other functions are provided by this module. Neither are automatically exported, so you must explicitly import them in use:

use CGI::Carp qw(carpout fatalsToBrowser);
carpout
carpout \*fh

Sends error messages to the filehandle fh. You should provide a reference to the filehandle glob, although you can also just use the filehandle's name for this function.

fatalsToBrowser
fatalsToBrowser

When this routine is imported via use, fatal errors, such as those produced by die and confess, send error messages to the browser as well as the error log. A simple HTTP response is created with the error message, followed by a request to send mail to the web administrator.

Previous | Home | Next
8.34. CGI::Apache | Book Index | 8.36. CGI::Cookie
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.36. CGI::Cookie

Provides an interface to Netscape (HTTP/1.1) cookies that can be used in conjunction with CGI.pm or independently. To use CGI::Cookie, create a new cookie object with the constructor new. You can then send the cookie to the browser in one of the following ways:

  • From a CGI script, create a Set-Cookie field in the HTTP header for each cookie you want to send ($c is the cookie object):

    print "Set-Cookie: $c0";

  • With CGI.pm (see Chapter 10, "The CGI.pm Module"), use the header method with a -cookie argument:

    print header(-cookie=>$c);

  • Using mod_perl (see Chapter 11, "Web Server Programmingwith mod_perl"), use the request object's header_out method:

    $r->header_out('Set-Cookie',$c);

    The following methods are provided for CGI::Cookie.

new
$c = new CGI::Cookie(attribs)

Constructor. Creates a new cookie. Attributes are:

-domain = domain_name
Optional. Points to domain name or fully qualified hostname to which cookie will be returned. If missing, browser will return cookie only to the server that set it.

-expires = date
Optional expiration date in any of the date formats recognized by CGI.pm. If missing, cookie expires at the end of this browser session.

-name = name
Required. Scalar value with the cookie name.

-path = path
Optional. Points to a partial URL on the current server; cookies will be returned to any URL beginning with this path. Defaults to /.

-secure = boolean
Optional. If true, browser will return cookie only if a cryptographic protocol is in use.

-value = value
Required. The value of the cookie; can be a scalar, an array reference, or a hash reference.

as_string
$c->as_string

Turns internal representation of cookie into RFC-compliant text. Called internally by overloading the "" operator, or can be called directly.

domain
$c->domain(val)

Gets or sets the cookie's domain. With no parameter, gets the current value; otherwise, sets the new value.

expires
$c->expires(val)

Gets or sets the cookie's expiration date. With no parameter, gets the current expiration date; otherwise, sets the new value.

fetch
%cookies = fetch CGI::Cookie

Returns a hash containing cookies returned by the browser, in which the keys are the cookie names and the values are the cookie values. In a scalar context, fetch returns a hash reference.

name
$c->name(val)

Gets or sets the cookie's name. With no parameter, returns the current name; otherwise, sets the new value.

parse
%cookies = parse CGI::Cookie(stored_cookies)

Retrieves cookies stored in an external form.

path
$c->path(val)

Gets or sets the cookie's path. With no parameter, returns the current path; otherwise, sets the new value.

raw_fetch
%cookies = raw_fetch CGI::Cookie

Like fetch, but does no unescaping of reserved characters; useful for retrieving cookies set by a foreign server.

value
$c->value(val)

Gets or sets the cookie's value. With no parameter, returns the current value; otherwise, sets the new value. In array context, returns the current value as an array. In scalar context, returns the first value of a multivalued cookie.

Previous | Home | Next
8.35. CGI::Carp | Book Index | 8.37. CGI::Fast
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.37. CGI::Fast

CGI interface for FastCGI. FastCGI is a type of gateway for web servers that improves performance by loading scripts as persistently running processes. CGI::Fast provides a new constructor to create a CGI object that runs in this environment. FastCGI requires both a server and a version of Perl that are FastCGI-enabled. See www.fastcgi.com for more information.

Previous | Home | Next
8.36. CGI::Cookie | Book Index | 8.38. CGI::Pretty
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.38. CGI::Pretty

Allows users of CGI to output nicely formatted HTML code by adding carriage returns and indentations to HTML markup for easy readability. For example, the following code:

#!/usr/local/bin/perl -w

use CGI qw(:all);

my $query = CGI->new( );

print $query->start_html( );
print $query->table( TR( td( "foo" ) ) );
print $query->end_html( );

outputs the following HTML:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
        "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head><title>Untitled Document</title>
</head><body><table><tr><td>foo</td></tr></table></body></html>

which is ugly. You can make it prettier with CGI::Pretty:

#!/usr/local/bin/perl -w

use CGI::Pretty qw( :html3 );

my $query = CGI->new( );

print $query->start_html( );

# Print a table with a single data element
print $query->table( TR( td( "foo" ) ) );

print $query->end_html( );
Previous | Home | Next
8.37. CGI::Fast | Book Index | 8.39. CGI::Push
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.39. CGI::Push

Provides an interface to do server push operations, letting you rewrite pages with content that changes regularly. A server push operation automatically sends updates to a page on a push-capable browser. CGI::Push exports the function do_push to implement page redraws. This method can be used on a CGI::Push object or on its own:

$q = new CGI::Push;
$q->do_push(-next_page => \&sub);

or:

do_push (-next_page => \&sub);

do_push requires one argument: a reference to a subroutine that will draw the next page. You may optionally specify a subroutine that draws the last page and the interval between page updates. Additional parameters to do_push are those that can be used with a CGI::headers object.

do_push
do_push (params)

Implements a server push operation, which updates a page at specific intervals. Parameters are:

-delay => n
Specifies the number of seconds, n, to wait before the next call to the page-drawing subroutine.

-last_page => \&sublast
Runs the subroutine sublast to draw the last page update of a server push operation. The -last_page routine is invoked when the -next_page routine returns false. A reference to a subroutine glob should be provided for this parameter, but the name of the subroutine is also acceptable.

-next_page => \&sub
sub is the name of the subroutine responsible for redrawing the page and counting the number of iterations (if you want repeated updating). The do_push routine ends when sub returns false (or when the -last_page subroutine is invoked). A reference to a subroutine glob should be provided for this parameter, but the name of the subroutine is also acceptable.

-type = string
Specifies the content type of the pushed data. The default value is text/html.

Previous | Home | Next
8.38. CGI::Pretty | Book Index | 8.40. CGI::Switch
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.40. CGI::Switch

Provides a new method that tries to call new in each of the Apache::CGI, CGI::XA, and CGI classes, returning the first CGI object that it successfully gets.

Previous | Home | Next
8.39. CGI::Push | Book Index | 8.41. charnames
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.41. charnames

Pragma to provide support for \N{charname} escapes. Options are:

:full
Searches for charnames in the list of standard Unicode character names

:short
Searches for charnames in the specified script, with the \N escape expected to be of the form \N{script:charname}

scriptname
Searches for all charnames in script scriptname

For example:

#!/usr/local/bin/perl -w

use charnames ':short';
print "\N{greek:Sigma} is an upper-case sigma.\n";
Previous | Home | Next
8.40. CGI::Switch | Book Index | 8.42. Class::ISA
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.42. Class::ISA

Allows you to scan @ISA—in order and without duplicates—for names of classes that Perl would scan to find a method. This is important when using classes that are derived from other classes, which are themselves derived from other classes, and so forth. Class::ISA is bundled with the Perl 5.8 source kit.

Let's say that you called SomeClass->method(). Perl searches for method() first in SomeClass, but will search its superclasses for method() if it doesn't find it in SomeClass. For example:

@SomeClass::ISA = qw(SomeOther SomeOtherOther SomeOtherOtherOther);
 use Class::ISA;
print "SomeClass::ISA path is:\n ",
join(", ", Class::ISA::super_path(`SomeClass')), "\n";

This prints:

SomeOther, SomeOtherOther, SomeOtherOtherOther

Class::ISA doesn't export anything. If classes erroneously inherit from each other; i.e., if there's a loop (or cycle) between what's inherited between classes, Perl throws an error, and Class::ISA itself will ignore the loop. If Perl can't find the method in the @ISA tree, it looks in UNIVERSAL, but Class::ISA does not. You may do something like the following to search in UNIVERSAL as well:

@supers = (Class::Tree::super_path($CLASS), `UNIVERSAL');

Here are the Class::ISA methods.

self_and_super_path
Class::ISA::self_and_super_path($CLASS)

Identical to super_path, except that $CLASS is included as the first element.

self_and_super_versions
Class::ISA::self_and_super_versions($CLASS)

Returns a hash with keys that are $CLASS (and its superclasses) and values that are the contents of the $VERSION of each class. If $VERSION does not exist, sel_and_super_versions returns undef.

super_path
Class::ISA::super_path(class)

Returns an ordered list of names of classes that Perl would search through to find a method. Note that no duplicates will be allowed in the list; nor will class be included in the list. UNIVERSAL is not included in the list, but if you need it, you should add it to the end of the list.

Previous | Home | Next
8.41. charnames | Book Index | 8.43. Class::Struct
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.43. Class::Struct

Formerly named Class::Template; exports a single function, struct. struct takes a list of element names and types, and optionally a class name, and creates a Perl class that implements a struct-like data structure. It also creates a constructor method, new, for creating objects of the class (so a class created this way must not itself define a new method).

Each element in the struct data has an accessor method, which is used to assign to the element and to fetch its value. The default accessor can be overridden by declaring a sub of the same name in the package. Each element's type can be scalar, array, hash, or class.

struct
struct (paramlist)

Creates a class, with object methods for each element of the class. The parameter list paramlist can take one of three forms:

struct( CLASS_NAME => [ ELEMENT_LIST ]);
# Object is array-based
struct( CLASS_NAME => { ELEMENT_LIST });
# Object is hash-based
struct( ELEMENT_LIST );     # Class name is current, and package name
      # object is array-based

The array-based element lists are faster and smaller, but the hash-based list is more flexible. The class that is created can be a subclass of the UNIVERSAL class, but not of any other class.

Element list

The items in the ELEMENT_LIST are of the form:

NAME => TYPE, ...

in which each NAME=>TYPE pair declares one element of the struct. Each element name is defined as an accessor method, unless a method is explicitly defined with that name. (In that case, a warning is issued if the -w flag is set.)

Element types and accessor methods

There are four possible element types, each represented by a string. Each string may start with an asterisk (*), indicating that a reference to the element will be returned. The type of an element determines the accessor method provided. The following list shows the element types, the strings that represent them, and the accessor:

array (@ or *@)
The element is an array, initialized to ( ). With no argument, the accessor returns a reference to the element's whole array. With one or two arguments, the first argument is an index specifying one element of the array; the second argument, if present, is the value that will be assigned to that array element.

class (Class_Name or *Class_Name)
The element's value must be a reference blessed to the named class or to one of its subclasses. The element is initialized to the result of calling the new constructor of the named class. The accessor's argument, if any, is the value that will be assigned to the element. The accessor croak s if it's not an appropriate object reference.

hash (% or *%)
The element is a hash, initialized to ( ). With no argument, the accessor returns a reference to the element's whole hash. With one or two arguments, the first argument is a key specifying one element of the hash; the second argument, if present, is the value to be assigned to that hash element.

scalar ($ or *$)
The element is a scalar, initialized to undef. The accessor's argument, if any, is assigned to the element.

Previous | Home | Next
8.42. Class::ISA | Book Index | 8.44. Config
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.44. Config

Used to access configuration information. When Perl is built, the Configure script obtains and saves this information in a hash, %Config, in Config.pm itself. Config checks to be sure it's running with the same Perl version as the one that created the hash.

The index into the hash is the shell variable name. %Config is always exported; the following three functions are exported on request.

config_sh
config_sh

Returns all Perl configuration information.

use Config(qw(config_sh));
print config_sh( );

returns:

archlibexp='sun4-solaris'
cc='cc'
ccflags='-I/usr/local/include/sfio -I/usr/local/include'
...
config_vars
config_vars (names)

Returns the name/value pairs for the requested configuration variables. Prints the results to STDOUT.

use Config(qw(config_vars));
print config_vars(qw(osname ccflags));

returns:

osname='solaris'
ccflags='-I/usr/local/include/sfio -I/usr/local/include'
myconfig
myconfig

Returns a summary of the major Perl configuration values.

Previous | Home | Next
8.43. Class::Struct | Book Index | 8.45. constant
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.45. constant

A Perl pragma that declares compile-time constants with a given scalar or list value. By default, the value is evaluated in list context, but you can override the default by specifying scalar:

use constant NAME1 => value1;
use constant NAME2 => scalar value2;
Previous | Home | Next
8.44. Config | Book Index | 8.46. CPAN
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.46. CPAN

Lets you access CPAN; search for a module, a bundle, an author, or a distribution; download a module or distribution; install it; and make it. The CPAN module can be used either interactively from the command line or programmatically:

perl -MCPAN -eshell;          # Run from the command line

or:

use CPAN;

my $obj = CPAN::Shell->install('ExtUtils::MakeMaker');

This section describes the use of the CPAN module from a program. See Chapter 2, "Installing Perl" for information on using it interactively and for details of the available commands. These commands, available interactively from the shell, are methods of the class CPAN::Shell. From a program, they are available both as methods (e.g., CPAN::Shell->install(...)) and as functions in the calling package (e.g., install(...)).

Each of the commands that produce listings of modules (r, autobundle, and u) returns a list of the IDs of all modules within the list. The IDs of all objects available within a program are strings that can be expanded to the corresponding real objects with the CPAN::Shell->expand("Module",@things) method. expand returns a list of CPAN::Module objects according to the @things arguments. In scalar context, it returns only the first element of the list.

8.46.1. Session and Cache Managers

The CPAN module contains a session manager, which keeps track of objects that have been fetched, built, and installed in the current session. No status is retained between sessions.

There is also a cache manager, which keeps track of disk space used and deletes extra space. The cache manager keeps track of the build directory, $CPAN::Config->{build_dir}, and uses a simple FIFO mechanism to delete directories below build_dir when they grow bigger than $CPAN::Config->{build_cache}.

The original distribution files are kept in the directory $CPAN::Config->{keep_source_where}. This directory is not covered by the cache manager but must be controlled by the user. If the same directory is used as both build_dir and keep_source_where, your sources are deleted with the same FIFO mechanism.

8.46.2. Bundles

The CPAN module recognizes a bundle as a Perl module in the namespace Bundle:: that does not define any functions or methods and usually contains only pod documentation. It starts like a Perl module with a package declaration and a $VERSION variable. After that, the pod section looks like any other pod except that it contains a special section that begins with:

=head1 CONTENTS

This section consists of lines such as:

Module_Name [Version_String] [- optional text]

in which Module_Name is the name of a module (for example, Term::ReadLine), not the name of a distribution file, and the version and text are optional. If there is text, it is preceded by a -. The distribution of a bundle should follow the same convention as other distributions.

Bundles are treated specially in the CPAN package. When you tell CPAN to install a bundle, it installs all the modules in the CONTENTS section of the pod. You can install your own bundles locally by placing a conforming bundle file somewhere in your @INC path. The autobundle command available in the shell interface does that for you by including all currently installed modules in a snapshot bundle file (see Chapter 2, "Installing Perl").

8.46.3. Configuration

When the CPAN module is installed, a site-wide configuration file is created: CPAN/Config.pm. The default values defined there can be overridden locally in the file CPAN/MyConfig.pm. You can store this file in $HOME/.cpan/CPAN/MyConfig.pm, because $HOME/.cpan is added to the search path of the CPAN module before the use or require statements. Chapter 2, "Installing Perl" lists the keys defined in the hash reference $CPAN::Config and how to set and query them.

8.46.4. CD-ROM Support

The urllist parameter in the configuration table contains a list of URLs that will be used for downloading. If the list contains any file URLs, CPAN looks there first for files (except index files). So if you are using a CD-ROM containing the CPAN contents, include the CD-ROM as a file URL at the end of urllist since it is likely to be out-of-date. You can do this with:

o conf urllist push file://localhost/CDROM/CPAN
Previous | Home | Next
8.45. constant | Book Index | 8.47. CPAN::FirstTime
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.47. CPAN::FirstTime

The CPAN::FirstTime module has one function, init, which is an initialization routine called automatically the first time a user uses the CPAN module. It asks the user a series of questions and writes the answers into a CPAN::Config file.

Previous | Home | Next
8.46. CPAN | Book Index | 8.48. CPAN::Nox
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.48. CPAN::Nox

A wrapper for CPAN.pm that prevents the use of any compiled extensions while it's executing. Run it in interactive mode if you have upgraded Perl but your extensions aren't working:

perl -MCPAN::Nox -eshell;
Previous | Home | Next
8.47. CPAN::FirstTime | Book Index | 8.49. Cwd
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.49. Cwd

The Cwd module provides three functions that get the pathname of the current working directory. Using these functions instead of the pwd command will make your code more portable, because not all systems have pwd.

cwd
cwd

Gets the current working directory. This is the safest way to get it.

fastcwd
fastcwd

A faster way to get the directory, but somewhat more dangerous because of the way it works internally.

getcwd
getcwd

Does the same thing as cwd by reimplementing the C library functions getcwd(3) or getwd(3) in Perl.

Previous | Home | Next
8.48. CPAN::Nox | Book Index | 8.50. Data::Dumper
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.50. Data::Dumper

Converts Perl data structures into strings that can be printed or used with eval to reconstruct the original structures. Takes a list of scalars or reference variables and writes out their contents in Perl syntax. Several interfaces to Data::Dumper are provided:

  • Simple procedural interface:

    print Dumper($foo, $bar);

  • Extended usage with names:

    print Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);

  • Object-oriented interface:

    $d = Data::Dumper->new([$foo, $bar], [qw(foo *ary)]);
   ...
print $d->Dump;

By default, references are identified as $VAR n, in which n is a numeric suffix. References to substructures within $VAR n are labeled using arrow notation. In the extended usage form, references can be given user-specified names. See the Data::Dumper manpage for examples of the module's use.

Several configuration variables can be used to control the output generated using the procedural interface. These variables control the default state of the object created by the new method. Each variable has a corresponding method that can be used later to query or modify the object. In the following list, each variable is followed by the corresponding method:

$Data::Dumper::Bless
$obj->Bless([newval])
Can be set to a string that specifies an alternative to the bless built-in operator used to create objects. A function with the specified name should exist and should accept the same arguments as the built-in. Default is bless.

$Data::Dumper::Deepcopy
$obj->Deepcopy([newval])
If set to a Boolean value, enables deep copies of structures; cross-referencing is then done only when absolutely essential. Default is 0.

$Data::Dumper::Indent
$obj->Indent([newval])
Controls the style of indentation for the output. Can be set to:

0
No newlines, indentation, or spaces between list items

1
Newlines, but each level in the structure is indented a fixed amount

2
Default. Takes into account the length of hash keys so the hash values line up.

3
Like 2, but also annotates array elements with their index, with each annotation on its own line

$Data::Dumper::Freezer
$obj->Freezer([newval])
If set to a method name, Data::Dumper invokes that method via the object before attempting to turn it into a string. Set to an empty string to disable. Default is empty string.

$Data::Dumper::Pad
$obj->Pad([newval])
Specifies the string prefixed to every output line. Default is an empty string.

$Data::Dumper::Purity
$obj->Purity([newval])
Controls degree to which eval can recreate the original reference structures. Setting the value to 1 outputs additional Perl statements to correctly recreate nested references. Default is 0.

$Data::Dumper::Quotekeys
$obj->Quotekeys([newval])
If set to a Boolean value, controls whether hash keys are quoted. If false, avoids quoting hash keys that look like a simple string. Default is 1, which always quotes hash keys.

$Data::Dumper::Terse
$obj->Terse([newval])
When set, Data::Dumper outputs single, non-self-referential values as atoms or terms rather than as statements. $VAR n names are avoided as much as possible. Such output may not be parsable by eval.

$Data::Dumper::Toaster
$obj->Toaster([newval])
If set to a method name, Data::Dumper issues a method call for any objects that will be dumped using the syntax bless(data, class)->method( ). Set to an empty string to disable. Default is empty string.

$Data::Dumper::Useqq
$obj->Useqq([newval])
When set, enables the use of double quotes to represent string values. In addition, \n, \t, and \r are used to represent non-space whitespace; "unsafe" characters are backslashed; and unprintable characters are output as quoted octal integers. Default is 0. Currently, the Dumpxs method does not honor this flag.

$Data::Dumper::Varnam
$obj->Varname([newval])
Specifies the prefix to use for tagging variable names in the output. Default is VAR.

The following methods and functions are provided.

new
$obj = Data::Dumper->new(arrayref[, arrayref])

Constructor. Creates a new Data::Dumper object. The first argument is an anonymous array of values to be dumped. The optional second argument is an anonymous array of names for the values. The names don't need a leading $ and must be comprised of alphanumeric characters. You can begin a name with a * to specify that the dereferenced type must be dumped instead of the reference itself for array and hash references.

Dump
$obj->Dump
Data::Dumper->Dump(arrayref[, arrayref])

Returns stringified form of values stored in the object with their order preserved, subject to the configuration options. In array context, returns a list of strings corresponding to the supplied values.

Dumper
Dumper (list)

Function that returns the stringified form of the values in the list, subject to the configuration options. The values are named $VAR n in the output. Returns a list of strings in array context.

DumperX
DumperX (list)

Identical to Dumper, except that it calls the xsub implementation. Available only if the xsub extension to Data::Dumper is installed.

Dumpxs
$obj->Dumpxs
Data::Dumper->Dumpxs(arrayref[, arrayref])

Identical to Dump, but written in C and therefore much faster. Available only if the xsub extension to Data::Dumper is installed.

Reset
$obj->Reset

Clears the internal table of "seen" references, returning the object itself.

Seen
$obj->Seen([hashref])

Queries or adds to the internal table of references that have been encountered. The references aren't dumped, but their names are inserted when they are encountered subsequently. With no argument, returns the "seen" list of name => value pairs, in array context. Otherwise, returns the object itself.

Values
$obj->Values([arrayref])

Queries or replaces the internal array of values to be dumped. With no arguments, returns the names. Otherwise, returns the object itself.

Previous | Home | Next
8.49. Cwd | Book Index | 8.51. DB
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.51. DB

The DB module abstracts and provides all of the hooks into Perl internal debugging functionality, so that various implementations of Perl debuggers (or packages that want simply to get at the "privileged" debugging data) can all benefit from the development of this common code. The following "public" global names can be read by clients of this API, but should be considered read-only:

$DB_HASH
Stores key/data pairs in data files; equivalent to other hashing packages such as DBM, NDBM, ODBM, GDBM, and SDBM.

$DB::sub
Name of current executing subroutine.

%DB::sub
The keys of this hash are the names of all the known subroutines. Each value is an encoded string that has the sprintf format ("%s:%d-%d", filename, fromline, toline).

$DB::single
Single-step flag. Will be true if the API will stop at the next statement.

$DB::signal
Signal flag. Will be true if a signal was caught.

$DB::trace
This flag is set to true if the API is tracing through subroutine calls.

@DB::args
Contains the arguments of current subroutine, or the @ARGV array if in the toplevel context.

@DB::dbline
List of lines in currently loaded file.

%DB::dbline
Actions in current file (keys are line numbers). The values are strings that have the sprintf format ("%s\000%s", breakcondition, actioncode).

$DB::package
Package namespace of currently executing code.

$DB::filename
Currently loaded filename.

$DB::subname
Fully qualified name of currently executing subroutine.

$DB::lineno
Line number that will be executed next.

8.51.1. API Methods

The following are methods in the DB base class. A client must access these methods by inheritance, since the API keeps track of clients through the inheritance mechanism.

CLIENT->register( )
Registers a client object/package

CLIENT->evalcode(STRING)
eval s STRING in executing code context

CLIENT->skippkg('Skip::Me')
Asks DB not to stop in these packages

CLIENT->run( )
Runs some more (until a breakpt is reached)

CLIENT->step( )
Single step

CLIENT->next( )
Steps over

CLIENT->done( )
Deregisters from the debugging API

8.51.2. Client Callback Methods

The following "virtual" methods are called by the API at appropriate points. The API provides only empty versions of these methods by default, but they can be defined by the client as needed.

CLIENT->init( )
Called after debug API initializes itself.

CLIENT->prestop([STRING])
Usually inherited from DB package. If no arguments are passed, returns the prestop action string.

CLIENT->stop( )
Called when execution stops, with the filename and line number as arguments.

CLIENT->idle( )
Called while stopped, e.g., in a client event loop.

CLIENT->poststop([STRING])
Usually inherited from DB package. If no arguments are passed, returns the poststop action string.

CLIENT->evalcode(STRING)
Usually inherited from DB package. Asks for a STRING to be eval ed in executing code context.

CLIENT->cleanup( )
Called just before exit.

CLIENT->output(LIST)
Called when API must show a message (warnings, errors etc.).

Previous | Home | Next
8.50. Data::Dumper | Book Index | 8.52. DB_File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.52. DB_File

Ties a Perl hash to one of the Berkeley DB database types and lets you use functions provided in the DB API:

[$X =] tie %hash,  "DB_File", $filename [, $flags, $mode, $DB_HASH];
[$X =] tie %hash,  "DB_File", $filename, $flags, $mode, $DB_BTREE;
[$X =] tie @array, "DB_File", $filename, $flags, $mode, $DB_RECNO;

The types are:

$DB_HASH
Stores key/data pairs in data files. Equivalent to other hashing packages such as DBM, NDBM, ODBM, GDBM, and SDBM.

$DB_BTREE
Stores key/data pairs in a binary tree.

$DB_RECNO
Uses a record (line) number to access fixed-length and variable-length flat text files through the same key/value-pair interface as in $DB_HASH and $DB_BTREE.

After you've tie d a hash to a database:

$db = tie %hash, "DB_File", "filename";

you can access the Berkeley DB API functions:

$db->put($key, $value, R_NOOVERWRITE);  # Invoke the DB "put" function

All the functions defined in the dbopen(3) manpage are available except close and dbopen itself. The constants defined in the dbopen manpage are also available.

The following are the functions available (the comments note only the differences from the equivalent C function).

del
$X->del(key[, flags])

Removes key/value pairs from the database. flags is optional.

fd
$X->fd

Returns a file descriptor that represents the underlying database. No difference from the equivalent C function.

get
$X->get(key, value[, flags])

Retrieves data from the database by key. flags is optional. The value associated with key is returned in value.

put
$X->put(key, value[, flags])

Stores a key/value pair in the database. flags is optional. If R_IAFTER or R_IBEFORE is set, then key is set to the record number of the inserted key/value pair.

seq
$X->seq(key, value[, flags])

Returns the next sequential key/value pair from the database. flags is optional. Both key and value are set.

sync
$X->sync([flags])

Synchronizes the database by flushing any cached data to disk. flags is optional.

Previous | Home | Next
8.51. DB | Book Index | 8.53. Devel::DProf
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.53. Devel::DProf

Devel::DProf is a Perl code profiler. It collects information on the execution time of a Perl script and of the subroutines in that script. To profile a Perl script, run perl with the -d debugging switch:

perl -d:DProf test.pl

When the script terminates (or when the output buffer is filled) the profiler will dump the profile information to a file called tmon.out. A tool such as dprofpp can be used to interpret the information. The following command will print the top 15 subroutines that used the most time:

dprofpp

To print an execution graph of the subroutines in the script, use the following command:

dprofpp -T
Previous | Home | Next
8.52. DB_File | Book Index | 8.54. Devel::PPPort
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.54. Devel::PPPort

Allows you to write Perl code that's as compatible as possible with the widest range of Perl interpreters. Devel::PPPort ships with ppport.h, with which you can incorporate some of the newest features of Perl with your older Perl releases. Devel::PPPort is important for developing modules, since newer Perl versions do not have as many issues with namespace pollution that older Perl versions had.

To use Devel::PPPort, copy ppport.h to wherever you're doing your development work, and use the WriteFile() method when you're ready to generate the necessary code. WriteFile() is used to write a C header file for XS modules. ppport.h contains a series of macros that allow XS to be built under older versions of Perl. For example:

my $port_file = '/users1/nvp/Perl/XS/Projects/ppport.h';
Devel::PPPort::WriteFile($port_file);

This generates ppport.h in /users1/nvp/Perl/XS/Projects.

WriteFile() takes an optional parameter representing the filename of the ppport header file. If empty, ppport.h is generated in the current directory. WriteFile() returns true if the write was successful, and false otherwise.

ppport.h provides access to the Perl API.

Previous | Home | Next
8.53. Devel::DProf | Book Index | 8.55. Devel::SelfStubber
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.55. Devel::SelfStubber

Generates stubs in a module that uses the SelfLoader, either printing the necessary stubs or generating the whole module with the stubs inserted in the correct location before the _ _DATA_ _ token. The default is to simply print the stubs.

stub
stub (module[, dir])

Generates the stubs. Takes the following arguments:

module
Name of the module, in the form Devel::SelfStubber (with no .pm at the end).

dir
Library directory that contains the module. Defaults to the current directory.

To simply print the stubs:

use Devel::SelfStubber;
Devel::SelfStubber->stub(module, dir);

To generate the whole module, with the stubs inserted correctly, set the variable $Devel::SelfStubber::JUST_STUBS to 0:

use Devel::SelfStubber;
$Devel::SelfStubber::JUST_STUBS = 0;
Devel::SelfStubber->stub(module, dir);
Previous | Home | Next
8.54. Devel::PPPort | Book Index | 8.56. diagnostics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.56. diagnostics

Provides more descriptive diagnostics than those generated by the Perl compiler and interpreter. Uses the longer, more explanatory error messages found in the perldiag manpage. Can be used as a pragma or as a standalone program, splain. When used as a pragma, diagnostics affects the compilation phase of your program as well as the execution phase. As a standalone module, it is used to post-process errors after execution has completed.

The splain program links to diagnostics.pm to act on the standard error output of a Perl program. The program's output can be sent to a file, which is then used as input to splain, or it can be piped directly to splain. Output from splain is directed to STDOUT.

8.56.1. Options

-p
Sets the variable $diagnostics::PRETTY to true

-v
Prints the perldiag manpage introduction, then any diagnostic messages

As a pragma:

use diagnostics [-verbose]

enables the use of diagnostics in your program (and enables Perl's -w flag). Compilation is then subject to the enhanced diagnostics, which are issued to STDERR. Set the diagnostics::PRETTY variable in a BEGIN block to provide nicer escape sequences for pagers, so your output looks better. The -verbose option prints the perldiag manpage introduction, then any diagnostic messages. Functions are:

enable
Turns diagnostics on at runtime

disable
Turns diagnostics off at runtime

Previous | Home | Next
8.55. Devel::SelfStubber | Book Index | 8.57. Digest
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.57. Digest

The Digest modules (Digest::MD2, Digest::MD5, Digest::SHA1, and Digest::-HMAC) calculate a digest of data that they encounter. These digests are often referred to as "fingerprints," "hashes," or "sums." The Digest modules return a small, fixed-length string, depending on how you've requested your data. If you change your data and regenerate the digest, the digest will be different each time the data itself changes. As of Perl 5.8, the Digest modules are bundled with the Perl source kit.

The Digest modules both a functional interface and an object-oriented interface. If you use the object-oriented inteface, you have the benefit of being able to send data of arbitrary length. You can also tell the Digest module to read files directly.

Digest delivers the hashed data in one of three formats: binary, hex, or base64. The following example uses Digest and calculates an MD5 sum of a string, $text, that represents the data. The data is output in hexadecimal form.

#!/usr/local/bin/perl -w
use Digest;
my $text = 'Be the ball, Danny!';
my $md5 = Digest->MD5;

$md5->add($text);
my $hashed = $md5->hexdigest;

print "The sum of \$text is [$hashed].\n";

This gives you:

The sum of $text is [6eec91414372ad157fc9d3d15b496d93].

Digest implements the following functions for the object-oriented interface. These functions are available to all of the Digest modules.

reset
reset()

Alias for new.

add
add(data, ...)

Appends data to the message for which you calculate the digest. add returns the Digest object itself.

addfile
addfile(io_handle)

Reads io_handle until end-of-file and, like add, appends the content to the message for which you calculate the digest. addfile returns the Digest object itself.

b64digest
b64digest()

Same as digest, but returns the digest in base64-encoded form.

digest
digest()

Returns the binary digest for the message. Note that digest is a destructive operation, in that the Digest object is reset so it can be used to create another value.

hexdigest
hexdigest()

Same as digest, but returns digest in hexadecimal form.

Previous | Home | Next
8.56. diagnostics | Book Index | 8.58. Digest::MD5
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.58. Digest::MD5

The Digest::MD5 module allows simpler creation of MD5 hashes. MD5 takes as input a message of arbitrary length and creates a 128-bit fingerprint, or digest, of the input. Like the Digest module, Digest::MD5 implements both a functional and object-oriented interface, which offer the same benefits. Digest::MD5 also outputs binary (16 bytes long), hexadecimal (32 characters long), and base64 (22 characters long) data.

To rewrite the example in Section 8.57, "Digest":

#!/usr/local/bin/perl -w
# Yes, functional interface
use Digest::MD5 qw(md5_hex);

my $text = `Be the ball, Danny!';
my $hexed = md5_hex($text);

print "The sum of \$text is [$hexed].\n";

You can use the object-oriented interface like so:

#!/usr/local/bin/perl -w

use Digest::MD5;

my $text = `Be the ball, Danny!';
my $md5 = Digest::MD5->new();

$md5->add($text);

my $sum = $md5->hexdigest;
print "The sum of \$text is [$sum].\n";

Digest::MD5 implements (and exports) the following functions.

new
new()

Constructor. Returns a new Digest::MD5 object. You can add data to $object and retrieve the digest itself. If you can new more than once, it will reset the existing digest and create a new Digest::MD5 object.

reset
reset()

An alias for new.

add
add(data, ...)

Appends data to the message for which you calculate the digest. add returns the Digest object itself. For example:

open(FILE, ...) or ...
while (<FILE>) {
    $md5->add($_);
} close(FILE);
addfile
addfile(io_handle)

Reads io_handle until end-of-file and appends the content to the message for which you calculate the digest. addfile returns the Digest object itself. For example:

open(FILE, $file) or ...
print Digest::MD5->new->addfile(*FILE)->hexdigest, " $file\n";
close(FILE);
b64digest
b64digest()

Same as digest, but returns the digest in base64-encoded form.

digest
digest()

Returns the binary digest for the message. Note that digest is a destructive operation, in that the Digest object is reset so it can be used to create another value.

hexdigest
hexdigest()

Same as digest, but returns digest in hexadecimal form.

The following functions are implemented by the functional interface.

md5
md5(data, ...)

Calculates the MD5 digest of data and returns it in binary form.

md5_base64
md5_base64(data,...)

Same as md5, but returns the digest as a base64-encoded string.

md5_hex
md5_hex(data,...)

Same as md5, but returns the digest in hexadecimal form.

Previous | Home | Next
8.57. Digest | Book Index | 8.59. DirHandle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.59. DirHandle

Provides methods for accessing Perl's directory functions, avoiding namespace pollution. Creates anonymous glob to hold a directory handle and closes the dirhandle automatically when the last reference goes out of scope. The following methods are provided.

new
$dh = new DirHandle [dirname]

Constructor. Creates a new directory handle. The optional directory name, dirname, defaults to the current directory.

close
$dh->close(  )

Closes a directory handle; equivalent to the closedir function.

open
$dh->open(dirname)

Opens directory dirname; equivalent to the opendir function.

read
$dh->read(  )

Reads directory entries. Equivalent to the readdir function. In scalar context, reads the next directory entry; in list context, reads all entries.

rewind
$dh->rewind(  )

Sets current position to beginning of directory; equivalent to the rewinddir function.

Previous | Home | Next
8.58. Digest::MD5 | Book Index | 8.60. Dumpvalue
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.60. Dumpvalue

The Dumpvalue module is used to provide a screen dump of Perl data. Whether you're trying to look at global variables or you'd like to dump the symbol table so that you can examine it, Dumpvalue will prove useful to you. Here's an example that dumps the symbol table of CGI.pm:

#!/usr/local/bin/perl -w

use Dumpvalue;
use CGI qw(:all);

my $dumper = Dumpvalue->new('DumpPackages' => 1);

$dumper->dumpvars('CGI');
Previous | Home | Next
8.59. DirHandle | Book Index | 8.61. DynaLoader
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.61. DynaLoader

The standard Perl interface to the dynamic linking mechanisms available on many platforms.

8.61.1. Using DynaLoader

Use DynaLoader like this:

package Module;
require DynaLoader;
@ISA = qw(... DynaLoader ...);

bootstrap Module;

The bootstrap method calls your module's bootstrap routine directly if the module is statically linked into Perl. Otherwise, the module inherits the bootstrap method from DynaLoader, which loads in your module and calls its bootstrap method.

8.61.2. Extending to New Architectures

If you want to extend DynaLoader to a new architecture, you need to know about its internal interface. The variables it uses are:

$dl_debug
Enables internal debugging messages on the Perl side of the DynaLoader; by default, is set to $ENV{'PERL_DL_DEBUG'} if that is defined. A similar debugging variable is added to the C code (see dlutils.c) and enabled if Perl was built with the -DDEBUGGING flag, or it can be set via the PERL_DL_DEBUG environment variable. Set to 1 for minimal information or higher for more detail.

@dl_library_path
Default list of directories to search for libraries; initialized to hold the list of directories in $Config{'libpth'}. Should also be initialized with other directories that can be determined from the environment at runtime.

@dl_resolve_using
List of additional libraries or other shared objects for resolving undefined symbols. Required only on platforms without automatic handling for dependent libraries.

@dl_require_symbols
List of one or more symbol names in the library/object file to be dynamically loaded. Only required on some platforms.

Of the following subroutines, bootstrap and dl_findfile are standard across all platforms and are defined in DynaLoader.pm. The others are defined in the .xs file that supplies the implementation for the platform.

bootstrap
bootstrap (modulename)

Normal entry point for automatic dynamic loading in Perl.

dl_error
dl_error

Gets error message text from the last failed DynaLoader function:

$message = dl_error(  );
dl_expandspec
dl_expandspec (spec)

Used for systems that require special filename handling to deal with symbolic names for files. spec specifies the filenames that need the special handling.

dl_findfile
dl_findfile (names)

Determines the full paths to one or more loadable files, given their generic names and optionally one or more directories. Searches directories in @dl_library_path by default and returns an empty list if no files are found.

dl_find_symbol
dl_find_symbol (libref, symbol)

Looks in libref for the address of symbol symbol. Returns the address, or undef if not found.

dl_install_xsub
dl_install_xsub (perl_name, symref[, filename])

Creates a new Perl external subroutine. Takes the following arguments:

perl_name
Name of the new subroutine.

symref
Pointer to the function that implements the routine.

filename
The source file for the function. If not defined, DynaLoader is used.

dl_load_file
dl_load_file (filename)

Dynamically loads filename, which must be the path to a shared object or library; returns undef on error.

dl_undef_symbols
dl_undef_symbols

Returns list of symbol names that remain undefined after dl_load_file, or ( ) if the names are unknown.

Previous | Home | Next
8.60. Dumpvalue | Book Index | 8.62. encoding
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.62. encoding

Although Perl 5.6.0 introduced Unicode support, it was not complete until Perl 5.8. With encoding.pm, you can write any Perl script with whatever encoding type you want. If you're a show off and worship anime movies, and want to write your Perl program in Kanji, use encoding, and be our guest:

# Cute example, slightly modified from the encoding.pm doc
#!/usr/local/bin/perl -w

use encoding 'euc-jp'; # Note that we support only one encoding

my $book = 'Camel';
my $Rakuda = "\xF1\xD1\xF1\xCC"; # Camel in Kanji
$book =~ s/\bCamel\b/$Rakuda/;
Previous | Home | Next
8.61. DynaLoader | Book Index | 8.63. English
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.63. English

Provides aliases for the Perl built-in special variables. Everything else about the variables and their use remains the same. Be aware, though, that using the English module significantly slows down a program for regular expressions.

Some of the Perl variables match some awk built-in variables. For those cases, you'll find two English names: a short version (which is the awk name) and a longer version. For example, you can use either $ERRNO (the awk name) or $OS_ERROR to refer to the Perl variable $!.

Here is the list of variables and their English alternatives:

Perl | English | Perl | English
@_ | @ARG | $? | $CHILD_ERROR
$_ | $ARG | $! | $OS_ERROR
$% | $MATCH | $! | $ERRNO
$' | $PREMATCH | $@ | $EVAL_ERROR
$' | $POSTMATCH | $$ | $PROCESS_ID
$+ | $LAST_PAREN_MATCH | $$ | $PID
$. | $INPUT_LINE_NUMBER | $< | $REAL_USER_ID
$. | $NR | $< | $UID
$/ | $INPUT_RECORD_SEPARATOR | $> | $EFFECTIVE_USER_ID
$/ | $RS | $> | $EUID
$| | $OUTPUT_AUTOFLUSH | $( | $REAL_GROUP_ID
$, | $OUTPUT_FIELD_SEPARATOR | $( | $GID
$, | $OFS | $) | $EFFECTIVE_GROUP_ID
$\ | $OUTPUT_RECORD_SEPARATOR | $) | $EGID
$\ | $ORS | $0 | $PROGRAM_NAME
$" | $LIST_SEPARATOR | $] | $PERL_VERSION
$; | $SUBSCRIPT_SEPARATOR | $^A | $ACCUMULATOR
$; | $SUBSEP | $^D | $DEBUGGING
$% | $FORMAT_PAGE_NUMBER | $^F | $SYSTEM_FD_MAX
$= | $FORMAT_LINES_PER_PAGE | $^I | $INPLACE_EDIT
$- | $FORMAT_LINES_LEFT | $^P | $PERLDB
$~ | $FORMAT_NAME | $^T | $BASETIME
$^ | $FORMAT_TOP_NAME | $^W | $WARNING
$: | $FORMAT_LINE_BREAK_CHARACTERS | $^X | $EXECUTABLE_NAME
$^L | $FORMAT_LINEFEED | $^O | $OSNAME

Previous | Home | Next
8.62. encoding | Book Index | 8.64. Env
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.64. Env

Lets your program treat environment variables as simple variables instead of having to access them from the %ENV pseudo-hash where they are kept. (Note that pseudo-hashes will disappear as of Perl 6.)

use Env;

use Env qw(var1 var2 ...);

Internally, Env uses an import function that ties suitably named environment variables to global Perl variables with the same names. By default, it ties all variables yielded by keys %ENV. A "suitable" environment has a name that begins with an alphabetic character and contains only alphanumeric characters or underscores.

When use Env is invoked with arguments, the arguments are interpreted as a list of environment variables to tie, but the variables don't have to exist yet. After a variable has been tied, you can use it like a normal variable, accessing or changing its value.

You untie a variable by setting its value to undef.

Previous | Home | Next
8.63. English | Book Index | 8.65. Errno
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.65. Errno

Provides system errno constants from errno.h include file. Defines and conditionally exports all the error constants defined in errno.h. There is one export tag, :POSIX, which exports all POSIX-defined error numbers.

The file Errno.pm is automatically generated and shouldn't be updated. Any changes made to the file will be lost.

Previous | Home | Next
8.64. Env | Book Index | 8.66. Exporter
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.66. Exporter

Implements a default import method for other modules to inherit if they don't want to define their own. If you are writing a module, you can do the following:

package Module;
use Exporter ( );
@ISA = qw(Exporter);

@EXPORT = qw(...);
@EXPORT_OK = qw(...);
%EXPORT_TAGS = (tag => [...]);

in which @EXPORT is a list of symbols to export by default, @EXPORT_OK is a list of symbols to export on request, and %EXPORT_TAGS is a hash that defines names for sets of symbols. Names in %EXPORT_TAGS must also appear in @EXPORT or @EXPORT_OK.

Then Perl programs that want to use your module just say:

use Module;                   # Import default symbols
use Module qw(...);           # Import listed symbols
use Module ( );              # Do not import any symbols

The Exporter can handle specialized import lists. An import list is the list of arguments passed to the import method. If the first entry begins with !, :, or /, the list is treated as a series of specifications that add to or delete from the list. A leading ! means delete, rather than add.

Symbol | Meaning
[!]name | This name only
[!]:DEFAULT | All names in @EXPORT
[!]:tag | All names in $EXPORT_TAGS{tag} anonymous list
[!]/pattern/ | All names in @EXPORT and @EXPORT_OK that match pattern

Exporter's methods are the following.

export_fail
module_name->export_fail(failed_symbols)

Returns a list of symbols that couldn't be imported. The default method provided by Exporter returns the list unchanged.

export_ok_tags
export_ok_tags(taglist)

Adds tagged sets of symbols to @EXPORT_OK.

export_tags
export_tags(taglist)

Adds tagged sets of symbols to @EXPORT.

export_to_level
package->export_to_level(n, what_to_export)

Used when you can't use Exporter's import method directly. Takes the following arguments:

n
An integer specifying how far up the calling stack to export your symbols

what_to_export
Array of symbols to export, usually @_

import
import

The default import method.

require_version
module_name->require_version(value)

Validates the version of module module_name, checking that it is at least value.

Previous | Home | Next
8.65. Errno | Book Index | 8.67. ExtUtils::Command
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.67. ExtUtils::Command

Provided with the standard Win32 port to replace common Unix commands in MakeFiles. Includes subroutines for the following commands.

cat
cat file... [> destination]

Concatenates all specified files into destination file or to STDOUT.

chmod
chmod mode files...

Sets Unix-like permissions on all files specified. mode gives the permissions to set.

cp
cp source... destination

Copies a single source file source to destination. Multiple source files can be specified if destination is an existing directory.

eqtime
eqtime source destination

Sets the "modified time" of destination to that of source.

mkpath
mkpath directory...

Creates directory, including any parent directories.

mv
mv source... destination

Moves sourcefile source to destination. Multiple sourcefiles are allowed if destination is an existing directory.

rm_f
rm_f files....

Removes files, even if they are read-only.

rm_rf
rm_rf directories....

Removes directories recursively, even if they are read-only.

test_f
test_f file

Tests for the existence of file.

touch
touch file....

Makes sure file exists and sets the current timestamp.

Previous | Home | Next
8.66. Exporter | Book Index | 8.68. ExtUtils::Command::MM
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.68. ExtUtils::Command::MM

Sets commands for MakeMaker to use in Makefiles. ExtUtils::Command::MM encapsulates code that would otherwise have to be done with large one-liners. This module is shipped with the Perl 5.8 source kit.

Everything is read from @ARGV, unless otherwise noted. For example:

test_harness($verbose, @test_libs);

runs the tests on @ARGV via Test::Harness passing through the $verbose flag. Any @test_libs will be unshifted onto the test's @INC.

Previous | Home | Next
8.67. ExtUtils::Command | Book Index | 8.69. ExtUtils::Constant
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.69. ExtUtils::Constant

Generates XS code to import C header constants, allowing Perl modules to AUTOLOAD constants defined in C library header files. Generally, you should not touch ExtUtils::Constant functions, since they are already implemented by h2xs.

For example:

use ExtUtils::Constant qw (WriteConstants);
WriteConstants(
    NAME => `Nate',
    NAMES => [qw(Nate Nathan Nathaniel)], # not Nat
);
# Generates wrapper code to make the values of the constants
# Nate Nathan Nathaniel available to perl

Currently, this module understands the following types, although h2xs may only know a subset. The sizes of the numeric types are chosen by the Configure script at compile time.

IV
Signed integer. At least 32 bits.

UV
Unsigned integer. The same size as IV.

NV
Floating-point type. Probably double. Possibly long double.

PV NUL[L]
Terminated string. Length will be determined with strlen.

PVN
A fixed-length thing, given as a pointer, length pair. If you know the length of a string at compile time, you can use this instead of PV.

SV
A mortal SV.

YES
Truth (PL_sv_yes). The value is not needed (and is ignored).

NO
Defined falsehood (PL_sv_no). The value is not needed (and is ignored).

UNDEF
The value of the macro is not needed.

ExtUtils::Constant implements the following functions.

assign
assign indent, type, pre, post, value ...

Returns a suitable assignment clause. If type is aggregate (e.g., PVN expects both pointer and length), then there should be multiple values for the components. pre and post, if defined, give snippets of C code to proceed and follow the assignment. preis at the start of a block, so variables may be defined in it.

autoload
autoload package, version, autoloader

Generates the AUTOLOAD subroutine for the module package. version is the Perl version with which the code should be backwards-compatible. It defaults to the version of Perl running the subroutine. If autoloaderis true, the AUTOLOAD subroutine falls back on AutoLoader::AUTOLOAD for all names that the constant() routine doesn't recognize.

C_constant
C_constant package, subname, default_type, types, indent,  breakout, item ...

Returns a list of C subroutine definitions that return the value and type of constants when passed the name by the XS wrapper. item... gives a list of constant names. These can be strings, which are taken as a C macro name, or references to a hash with the following keys:

name
The name of the constant, as seen by the Perl code.

type
The type of the constant (IV, NV, etc.).

value
A C expression for the value of the constant, or a list of C expressions if the type is aggregate. Defaults to name if not given.

macro
The C preprocessor macro to use in the #ifdef. Defaults to name and is primarily used if value is an enum. If a reference or an array is passed, then the first element is used in place of the #ifdef line, and the second element is used in place of the #endif. This allows preprocessor constructions such as:

#if defined (foo)
#if !defined (bar)
...
#endif
#endif

which are used to determine if a constant will be defined.

A macro of 1 signals that the constant is always defined, so the #if/#endif test is omitted.

default
Default value to use (instead of croak ing with "your vendor has not defined . . . ) if the macro isn't defined. Specifies a reference to an array with type followed by value(s).

pre
C code to use before the assignment of the value of the constant. This allows you to use temporary variables to extract a value from part of a struct and return this as value. This C code is placed at the start of a block, so you can declare variables in it.

post
C code to place between the assignment of value (temporary) and the return from the function. This allows you to clear up anything in pre. Rarely needed.

def_pre
def_post
Equivalents of pre and post for the default value.

utf8
Generated internally. Is 0 or undefined if name is 7-bit ASCII, no if the name is 8-bit (and so should match only if SvUTF8() is false), and yes if the name is utf8-encoded.

constant_types
constant_types

Returns a single scalar with #define definitions for the constants used internally between the generated C and XS functions.

C_stringify
C_stringify name

Returns a 7-bit ASCII correctly \-escaped version of the string passed. Suitable for C "" or ''. It will die if passed Unicode characters.

dump_names
dump_names default_type, types, indent, options, item ...

An internal function to generate the embedded Perl code to regenerate the constant subroutines. default_type, types, and items are the same as for C_constant. indent is the number of spaces to indent. options is a hashref of options; currently, only declare_types is recognized. If the value is true, a types is always declared in the generated Perl code; if defined and false, one is never declared; and if undefined, types is declared only if the values in types as passed in cannot be inferred from default_types and the items.

memEQ_clause
memEQ_clause name, checked_at, indent

Returns a suitable C if statement to check whether name is equal to the C variable name. If checked_at is defined, then it is used to avoid memEQ for short names.

params
params what

An internal function. what should be a hashref of types the constant function will return. params returns a hashref keyed IV NV PV SV to show which combination of pointers will be needed in the C argument list.

perl_stringify
perl_stringify name

Returns a 7-bit ASCII correctly \-escaped version of the string passed. Suitable for a Perl "" string.

return_clause
return_clause item, indent

Returns a suitable #ifdef clause. item is a hashref passed to C_constant and match_clause. indent is the number of spaces to indent; defaulting is 6.

switch_clause
switch_clause indent, namelen, itemhash, item ...

An internal function to generate a suitable switch clause, called by C_constant. items are in the hashref format as given in the description of C_constant and must all have names of the same length, given by namelen. itemhash is a reference to a hash, keyed by name, with values as the hashrefs in the item list.

XS_constant
XS_constant package, types, subname, c_subname

Generates the XS code to implement the Perl subroutine package::constant used by package::AUTOLOAD to load constants. This XS code is a wrapper around a C subroutine usually generated by C_constant and usually named constant

types should be given either as a comma-separated list of types that the C subroutine constant will generate or as a reference to a hash. It should be the same list of types that C_constant was given. Otherwise, XS_constant and C_constant may have different ideas about the number of parameters passed to the C function constant.

You can call the Perl visible subroutine something other than "constant" if you give the parameter subname. The C subroutine it calls defaults to the name of the Perl visible subroutine, unless you give the parameter c_subname.

Previous | Home | Next
8.68. ExtUtils::Command::MM | Book Index | 8.70. ExtUtils::Embed
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.70. ExtUtils::Embed

Generally called from the Makefile that builds your application to provide initialization functions for embedding Perl code in C or C++ applications. For example:

perl -MExtUtils::Embed -e xsinit
perl -MExtUtils::Embed -e ldopts

Uses the configuration information kept in Config.pm (see the Config module above). Exports the following functions.

ccdlflags
ccdlflags

Prints $Config{ccdlflags}.

ccflags
ccflags

Prints $Config{ccflags}.

ccopts
ccopts

Combines perl_inc, ccflags, and ccdlflags.

ldopts
ldopts

Outputs arguments for linking the Perl library and extensions to your application. When invoked as:

perl -MExtUtils::Embed -e ldopts -

the following options are recognized:

-std
Outputs arguments for linking the Perl library and any extensions linked with the current Perl.

-I <path1:path2>
Search path for ModuleName.a archives. Default is @INC.

-- <list of linker args>
Additional linker arguments to be considered.

Any additional arguments found before the -- token are taken as the names of modules to generate code for. Can also be called with parameters:

'ldopts($std,[@modules],[@link_args],$path)'

When called this way, returns the argument string rather than printing it to STDOUT. The optional parameters are:

$std
Boolean, equivalent to the -std option.

[@modules]
Array reference. Equivalent to adding module names before the -- token.

[@link_args]
Array reference. Equivalent to adding linker arguments after the -- token.

$path
Equivalent to the -I option.

perl_inc
perl_inc

For including Perl header files. For example, if you say:

perl -MExtUtils::Embed -eperl_inc

the module prints the following:

-I$Config{archlibexp}/CORE
xsi_body
xsi_body (modules)

Returns string of calls to newXS that glue the module bootstrap function to boot_ModuleName for each module in modules.

xsi_header
xsi_header

Returns a string defining the same EXTERN_C macro as perlmain.c; also #include s perl.h and EXTERN.h.

xsinit
xsinit

Generates C/C++ code for the XS initializer function. When invoked as:

perl -MExtUtils::Embed -e xsinit -

the following options are recognized:

-o [filename]
Prints to the filename specified. Defaults to perlxsi.c. If filename is STDOUT, prints to standard output.

-std
Writes code for extensions that are linked with the current Perl.

Any additional arguments are expected to be names of modules to generate code for. Can also be called with parameters:

'xsinit($filename,$std,[@modules])'

When called this way, the following optional parameters are accepted:

$filename
Equivalent to the -o option.

$std
Boolean. Equivalent to the -std option.

[@modules]
An array reference. Equivalent to adding module names after the -- token.

xsi_protos
xsi_protos (modules)

Returns string of boot_$ModuleName prototypes for each module in modules.

Previous | Home | Next
8.69. ExtUtils::Constant | Book Index | 8.71. ExtUtils::Install
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.71. ExtUtils::Install

Used by MakeMaker for handling the platform-dependent installation and deinstallation of modules; not meant to provide general-purpose tools. Exports the following functions.

install
install (\hashref, verbose, nonono)

Installs files. Takes the following arguments:

\hashref
Reference to a hash, in which each key is a directory to copy from and the value is the directory to copy into. The whole tree below the "from" directory is copied, with timestamps and permissions preserved.

The hash has two additional keys: read and write. After copying everything, install writes the list of target files to the file named by $hashref->{write}. If there is another file named by $hashref->{read}, its contents are merged into the written file.

verbose
Verbose switch.

nonono
Don't-really-do-it switch.

install_default
install_default ([fullext])

Calls install with the same arguments as the MakeMaker defaults. Takes zero or one argument. With no argument, it treats $ARGV[0] as the argument. If present, the argument contains the value of MakeMaker's FULLEXT key.

pm_to_blib
pm_to_blib (\hashref[, dir])

Takes a hash reference as the first argument and copies all the keys of the hash to the corresponding values. Filenames with the .pm extension are autosplit. The optional second argument is the autosplit directory.

uninstall
uninstall (packlistfile, verbose, nonono)

Uninstalls files. Takes the following arguments:

packlistfile
Name of file containing filenames to be unlinked

verbose
Verbose switch

nonono
No-don't-really-do-it-now switch

Previous | Home | Next
8.70. ExtUtils::Embed | Book Index | 8.72. ExtUtils::Installed
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.72. ExtUtils::Installed

Provides inventory management for installed modules, based on the contents of the .packlist files that are created during installation. It also permits classifying the installed files and extracting directory information from the .packlist files.

new
$inst = ExtUtils::Installed->new(  )

Searches for all installed .packlists on the system and stores their contents. Takes no parameters; uses ExtUtils::Packlist to read the .packlist files.

directories
$inst->directories(module[, string[, dir[,...]]])

Returns list of directories. Returns only directories that contain files from the specified module. Parameters are:

module
Required. The name of a module; returns a list of all directories in the package.

string
Optional. Possible values are prog, man, or all to return program directories, manual directories, or all directories, respectively.

dir
Optional. One or more directories. If specified, only directories under the specified directories are returned.

directory_tree
$inst->directory_tree(module[, string[, dir[,...]]])

Like directories, but includes all intermediate directories.

files
$inst->files(module[, string[, dir[,...]]])

Returns list of filenames. Parameters are:

module
Required. The name of a module; returns a list of all filenames in the package. For a list of core files, use the special module name Perl.

string
Optional. Possible values are prog, man, or all to return program files, manual files, or all files, respectively.

dir
Optional. One or more directories. If specified, only filenames under the specified directories are returned.

modules
$inst->modules(  )

Returns list of names of all the installed modules. Calls the Perl "core" by the special name Perl.

packlist
$inst->packlist(module)

Returns the ExtUtils::Packlist object for the specified module.

validate
$inst->validate(module[, arg])

Takes the name of a module as a required parameter and validates that all files listed in the packlist for the module actually exist. Returns list of any missing files. With an optional second argument that evaluates to true, removes missing files from .packlist.

version
$inst->version(module)

Returns the version number of the specified module.

Previous | Home | Next
8.71. ExtUtils::Install | Book Index | 8.73. ExtUtils::Liblist
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.73. ExtUtils::Liblist

Used for building a Makefile for a Perl module. Takes a list of libraries and returns platform-appropriate lines that can be included in the Makefile.

require ExtUtils::Liblist;
ExtUtils::Liblist::ext($potential_libs[, $verbose]);

The input list $potential_libs is in the form -llib1 -llib2 -llib3. Additional library paths may be included in the form -L/another/path, which affects searches for all subsequent libraries. If the Boolean $verbose is specified, verbose output messages are provided. Returns a list of four scalar values:

EXTRALIBS
List of libraries that need to be linked with ld when linking a Perl binary that includes a static extension

LDLOADLIBS
List of static or dynamic libraries that can or must be linked when creating a shared library using ld

LD_RUN_PATH
Colon-separated list of the directories in LDLOADLIBS

BSLOADLIBS
List of libraries that are needed but can be linked in dynamically with the DynaLoader at runtime

The Win32 version (in the standard Perl distribution) is different from the Unix-OS/2 version in several ways:

  • -l and -L are not required on the library and path specifications.

  • Entries must be libraries, not plain object files.

  • If $potential_libs is empty, the return value is also empty.

  • The specified libraries can include both static and import libraries.

  • LDLOADLIBS and EXTRALIBS are always identical; BSLOADLIBS and LD_RUN_PATH are always empty.

Previous | Home | Next
8.72. ExtUtils::Installed | Book Index | 8.74. ExtUtils::MakeMaker
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.74. ExtUtils::MakeMaker

Writes a Makefile for module installation. Provides a function, WriteMakefile, which creates an object with attributes that are set from various sources and that actually write the Makefile. See Chapter 2, "Installing Perl" for information about the using the Makefile and MakeMaker during module installation. This section explains the details of actually creating the Makefile with MakeMaker. It assumes an understanding of make and Makefiles.

If you are a Perl programmer writing a module, you should run h2xs to generate the template for your module. Among other things, h2xs creates a file called Makefile.PL, and it's Makefile.PL that runs MakeMaker. On the other hand, if you are installing a module, you can usually just run the Makefile.PL that came with the module, perhaps adding a PREFIX argument if you are installing the module locally (see Chapter 2, "Installing Perl"). In either case, you shouldn't need to run ExtUtils::MakeMaker directly unless you have special requirements.

A typical call to MakeMaker might look like this example from the CGI distribution:

use ExtUtils::MakeMaker;
WriteMakefile(
        NAME => "CGI",
        DISTNAME => "CGI-modules",
        VERSION => "2.76",
        linkext => { LINKTYPE => '' },
        dist => {COMPRESS=>'gzip -9f', SUFFIX => 'gz'},
);

MakeMaker attributes can be passed as arguments to WriteMakefile, as in the example, or they can be passed as name=value pairs on the command line:

perl Makefile.PL PREFIX=/home/mydir/Perl/Modules

To see what MakeMaker is doing, you can say:

perl Makefile.PL verbose

The following attributes can be specified:

C
Reference to array of *.c filenames. Initialized from a directory scan and the values portion of the XS attribute hash. Not currently used by MakeMaker but may be handy in Makefile.PLs.

CCFLAGS
String to be included in the compiler call command line between the INC and OPTIMIZE arguments.

CONFIG
An array reference containing a list of attributes to get from %Config. The following values are always added to CONFIG:

ar       cc          cccdlflags   ccdlflags
dlext    dlsrc       ld           lddlflags
ldflags  libc        lib_ext      obj_ext
ranlib   sitelibexp  sitearchexp  so
CONFIGURE
Reference to a subroutine that should return a hash reference. The hash may contain further attributes that need to be determined by some evaluation method.

DEFINE
An attribute containing additional defines.

DIR
Reference to array of subdirectories containing Makefile.PL files.

DISTNAME
Your name for distributing the package (by tar file). Defaults to NAME, which is described below.

DL_FUNCS
Reference to a hash of symbol names for routines to be made available as universal symbols. Each key/value pair consists of the package name and an array of routine names in that package. Used only under AIX (export lists) and VMS (linker options) at present. Defaults to "$PKG" => ["boot_$PKG"].

DL_VARS
Array of symbol names for variables to be made available as universal symbols. Used only under AIX (export lists) and VMS (linker options) at present. Defaults to [].

EXCLUDE_EXT
Array of module names to exclude when doing a static build. Ignored if INCLUDE_EXT is present.

EXE_FILES
Reference to array of executable files to be copied to the INST_SCRIPT directory. make realclean deletes them from there.

NO_VC
If set, the Makefile does not check the current version of MakeMaker against the version the Makefile was built under. Should be used interactively, not written into your Makefile.PL file.

FIRST_MAKEFILE
Name of the Makefile to be produced. Defaults to the contents of MAKEFILE, but can be overridden.

FULLPERL
Perl binary that can run this module.

H
Reference to array of *.h filenames. Similar to C attribute.

IMPORTS
Used only on OS/2.

INC
Directories containing include files, in -I form. For example:

INC => "-I/usr/5include -I/path/to/inc"
INCLUDE_EXT
Array of module names to be included when doing a static build. If present, only those modules that are explicitly mentioned are used for the build (instead of all installed extensions). It is not necessary to mention DynaLoader or the current module when filling in INCLUDE_EXT—they are always included.

INSTALLARCHLIB
Used by make install, which copies files from INST_ARCHLIB to this directory if INSTALLDIRS is set to perl.

INSTALLBIN
Directory to install binary files into.

INSTALLDIRS
Determines which of the two sets of installation directories to choose. There are two possible values:

perl
Uses INSTALLLPRIVLIB and INSTALLARCHLIB directories.

site
The default. Uses INSTALLSITELIB and INSTALLSITEARCH directories.

INSTALLMAN1DIR
Directory where command manpages are put during make install. Defaults to $Config{installman1dir}.

INSTALLMAN3DIR
Directory where library manpages are put during make install. Defaults to $Config{installman3dir}.

INSTALLPRIVLIB
Used by make install, which copies files from INST_LIB to this directory if INSTALLDIRS is set to perl.

INSTALLSCRIPT
Used by make install, which copies files from INST_SCRIPT to this directory.

INSTALLSITELIB
Used by make install, which copies files from INST_LIB to this directory if INSTALLDIRS is set to site (the default).

INSTALLSITEARCH
Used by make install, which copies files from INST_ARCHLIB to this directory if INSTALLDIRS is set to site (the default).

INST_ARCHLIB
Same as INST_LIB for architecture-dependent files.

INST_BIN
Directory where real binary files are put during make, for later copying to INSTALLBIN during make install.

INST_EXE
Deprecated. Old name for INST_SCRIPT, which you should use instead.

INST_LIB
Directory to hold library files for this module while it is being built.

INST_MAN1DIR
Directory to hold the command manpages at make time.

INST_MAN3DIR
Directory to hold the library manpages at make time.

INST_SCRIPT
Directory where executable files should be installed during make. Defaults to ./blib/bin, to have a dummy location during testing. make install copies the files in INST_SCRIPT to INSTALLSCRIPT.

LDFROM
Used by the ld command to specify the files to link/load from. Defaults to $(OBJECT).

LIBPERL_A
Filename of the Perl library that will be used with this module. Defaults to libperl.a.

LIB
Can be set only when Makefile.PL is run; both INSTALLPRIVLIB and INSTALLSITELIB are set to the value of LIB.

LIBS
Anonymous array of alternative library specifications to be searched for (in order) until at least one library is found. Note that any element of the array contains a complete set of arguments for the ld command.

LINKTYPE
Should be used only to force static linking (see the linkext attribute below). Possible values are static or dynamic. Default is dynamic unless usedl=undef in config.sh.

MAKEAPERL
Boolean. Tells MakeMaker to include the rules for making a Perl binary. Normally handled automatically by MakeMaker and not needed by the user.

MAKEFILE
Name of the Makefile to be produced.

MAN1PODS
Reference to a hash of pod-containing files to be converted to manpages and installed as requested at configure time. Default is all EXE_FILES files that include pod directives.

MAN3PODS
Reference to a hash of .pm and .pod files to be converted to manpages and installed as requested at configure time. Default is all .pod and any .pm files that include pod directives.

MAP_TARGET
Name for new Perl binary if one will be produced. Default is perl.

MYEXTLIB
Name of library that the module builds and links to.

NAME
Perl module name for this module (e.g., DBD::Oracle). Defaults to the directory name but should be explicitly defined in the Makefile.PL.

NEEDS_LINKING
Boolean. Can be set to speed up MakeMaker processing a little bit, but not needed since MakeMaker will figure out if linking is needed.

NOECHO
Controls make's echo (@) feature. Defaults to @. By setting it to an empty string, you can generate a Makefile that echos all commands. Used mainly in debugging MakeMaker itself.

NORECURS
Boolean. If set, inhibits descending into subdirectories.

OBJECT
List of object files. Defaults to $(BASEEXT)$(OBJ_EXT); can be set to a long string containing all object files.

OPTIMIZE
If set to -g, turns debugging on. Defaults to -O. Passed to subdirectory makes.

PERL
Perl binary for tasks that can be done by miniperl.

PERLMAINCC
The call to the program that can compile perlmain.c. Defaults to $(CC).

PERL_LIB
Directory containing the Perl library to use.

PERL_ARCHLIB
Same as PERL_LIB for architecture-dependent files.

PERL_SRC
Directory containing the Perl source code. Avoid using this attribute, since it may be undefined.

PL_FILES
Reference to hash of files to be processed as Perl programs. By default, MakeMaker turns any *.PL file it finds (except the Makefile.PL) into a key and the basename of the file into the value. The *.PL files are expected to produce output to the target files themselves.

PM
Reference to hash of .pm and *.pl files to be installed.

PMLIBDIRS
Reference to array of subdirectories containing library files. Defaults to ['lib', $(BASEEXT)]. The directories are scanned, and any files they contain are installed in the corresponding location in the library. A libscan method can be used to alter the behavior. Defining PM in the Makefile.PL overrides PMLIBDIRS.

PREFIX
Can be used to set the three INSTALL* attributes at once so they have PREFIX as a common directory node.

PREREQ_PM
Reference to a hash of modules that need to be available to run this module (e.g., Fcntl for SDBM_File). The name of each required module is the key, and the desired version is the value. If the required version is 0, MakeMaker just checks to see if any version is installed.

SKIP
Reference to an array specifying sections of the Makefile that shouldn't be written. Do not use the SKIP attribute for the negligible speedup, which may seriously damage the resulting Makefile.

TYPEMAPS
Reference to array of typemap filenames. Use when the typemaps are in a directory other than the current directory or when they are not named typemap. The last typemap in the list takes precedence, but a typemap in the current directory has highest precedence even if it isn't listed in TYPEMAPS. The default system typemap has lowest precedence.

VERSION
Your version number for the package. Defaults to 0.1.

VERSION_FROM
Names a file for MakeMaker to parse to find the version number for the package, so you don't need to specify VERSION. The file must contain a single line to compute the version number. The first line in the file that contains the regular expression:

/([\$*])(([\w:\']*)\bVERSION)\b.*\=/

is evaluated with eval and the result assigned to VERSION.

XS
Reference to a hash of .xs files. MakeMaker defaults this. For example:

{'name_of_file.xs' => 'name_of_file.c'}

The .c files are automatically deleted by a make clean.

XSOPT
String of options to pass to xsubpp, which might include -C++ or -extern but not typemaps, which go in TYPEMAPS.

XSPROTOARG
May be set to an empty string, which is identical to -prototypes or -noprototypes. Defaults to the empty string.

XS_VERSION
Your version number for the package's .xs file. Defaults to the value of VERSION.

The following lowercase attributes can be used to pass parameters to the methods that implement the corresponding part of the Makefile:

clean
Extra files to clean.

depend
Extra dependencies.

dist
Distribution options.

dynamic_lib
Options for dynamic library support.

installpm
Installation options related to AutoSplit. Deprecated as of MakeMaker 5.23. See the pm_to_blib entry for ExtUtils::Install.

linkext
Linking style.

macro
Extra macros to define.

realclean
Extra files to make realclean.

tool_autosplit
Attributes for the tool_autosplit method.

If specifying attributes isn't sufficient to accomplish what you want, you can define your own subroutines in the Makefile.PL that return the text to be written to the Makefile. You can also override MakeMaker's subroutines (described in Section 8.85, "ExtUtils::MM_Unix") this way.

Previous | Home | Next
8.73. ExtUtils::Liblist | Book Index | 8.75. ExtUtils::Manifest
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.75. ExtUtils::Manifest

Provides utilities for maintaining and using a MANIFEST file. The MANIFEST file is essentially a packing list, included with a module, so the user who installs the module can be sure that all the files are actually present. The file created by ExtUtils::Manifest is a list of filenames, one per line, with an optional comment on each line.

ExtUtils::Manifest optionally uses a file called MANIFEST.SKIP, which contains regular expressions specifying files that are not to be included in MANIFEST. Manifest also defines two global variables that are used by several of the functions:

$ExtUtils::Manifest::MANIFEST
The name of the MANIFEST file. Changing the value results in different MANIFEST and different MANIFEST.SKIP files. Default is MANIFEST.

$ExtUtils::Manifest::Quiet
If true, the functions work silently. Default is 0.

Provides six functions, which are exportable on request.

filecheck
filecheck

Finds files below the current directory that are not mentioned in the MANIFEST file. Consults MANIFEST.SKIP for files that shouldn't be included.

fullcheck
fullcheck

Does both manicheck and filecheck.

manicheck
manicheck

Checks whether all files in current directory's MANIFEST file really exist.

manicopy
manicopy (read, target, how)

Copies files to a target directory. Takes the following arguments:

read
Hash with keys that are the names of the files to be copied. Typically returned by maniread.

target
Target directory into which files are to be copied.

how
Can be used to specify a different method of "copying." Values are:

cp
Copy the files.

ln
Create hard links.

best
Link the files, but copy any symbolic link to make a tree with no symbolic links (the default).

manifind
manifind

Returns a hash reference whose keys are the files found below the current directory. The values are null strings, representing the MANIFEST comments that aren't there.

maniread
maniread ([file])

Reads the MANIFEST file specified in $file (the default is MANIFEST). Returns a hash reference whose keys are the filenames and whose values are the comments. Discards blank lines and lines starting with #.

mkmanifest
mkmanifest

Writes the names of all files in and below the current directory to the file in the current directory named in the $ExtUtils::Manifest::MANIFEST variable. Skips files in MANIFEST.SKIP.

skipcheck
skipcheck

Lists files that were skipped because they were found in MANIFEST.SKIP.

Previous | Home | Next
8.74. ExtUtils::MakeMaker | Book Index | 8.76. ExtUtils::Miniperl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.76. ExtUtils::Miniperl

Generates a file, perlmain.c, that contains the bootstrap code to make the modules associated with the libraries available from within Perl. ExtUtils::Miniperl itself is generated automatically from a script called minimod.PL when Perl is built; typically, it is used from within a Makefile generated by ExtUtils::MakeMaker rather than being called directly. The module exports one subroutine.

writemain
writemain (dirs)

Takes an argument list of directories that contain archive libraries needed by Perl modules and writes the file to be compiled as perlmain.c to STDOUT.

Previous | Home | Next
8.75. ExtUtils::Manifest | Book Index | 8.77. ExtUtils::Mkbootstrap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.77. ExtUtils::Mkbootstrap

Typically called from a module's Makefile. It writes a *.bs file that is needed by some architectures to do dynamic loading.

use ExtUtils::Mkbootstrap;
mkbootstrap( );
Previous | Home | Next
8.76. ExtUtils::Miniperl | Book Index | 8.78. ExtUtils::Mksymlists
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.78. ExtUtils::Mksymlists

Produces option files used by some operating systems' linkers during creation of shared libraries for dynamic extensions. Normally called from a Makefile when a module is built; it exports one function.

Mksymlists
Mksymlists (varlist)

Creates the linker option file. The varlist argument is a list of key/value pairs. For example:

use ExtUtils::Mksymlists;
Mksymlists({ NAME     => $name,
             DL_VARS  => [$var1, $var2, $var3],
             DL_FUNCS => [$pkg1 => [$func1, $func2],
                          $pkg2 => [$func3]});

Valid keys are:

DLBASE
The name by which the linker knows the module. If not specified, it is derived from the NAME attribute. Currently used only by OS/2.

DL_FUNCS
Identical to the MakeMaker DL_FUNCS attribute and usually taken from it. Its value is a reference to a hash, in which each key is a package name, and each value is a reference to an array of function names to be exported by the module.

DL_VARS
Identical to the MakeMaker DL_VARS attribute, and usually taken from it. Its value is a reference to an array of variable names to be exported by the extension.

FILE
The name of the linker option file (minus the OS-specific extension) if you don't want to use the default value (the last word of the NAME attribute).

FUNCLIST
An alternate way of specifying function names to be exported from the module. Its value is a reference to an array of function names to be exported, which are passed unaltered to the linker options file.

NAME
The name of the module for which the linker option file is to be produced. Should always be specified.

Previous | Home | Next
8.77. ExtUtils::Mkbootstrap | Book Index | 8.79. ExtUtils::MM
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.79. ExtUtils::MM

ExtUtils::MM is an OS-adjusted ExtUtils::MakeMaker subclass. For internal use only. For example:

require ExtUtils::MM;
my $mm = MM->new(...);
Previous | Home | Next
8.78. ExtUtils::Mksymlists | Book Index | 8.80. ExtUtils::MM_Any
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.80. ExtUtils::MM_Any

Performs platform-agnostic MM methods. ExtUtils::MM_Any is a superclass for the ExtUtils::MM_ set of modules. For internal use only.

Previous | Home | Next
8.79. ExtUtils::MM | Book Index | 8.81. ExtUtils::MM_BeOS
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.81. ExtUtils::MM_BeOS

Provides methods to override Unix behavior in ExtUtils::MakeMaker. Essentially, this module works the same way as ExtUtils::MM_Unix, but allows override for BeOS. For internal use only.

Previous | Home | Next
8.80. ExtUtils::MM_Any | Book Index | 8.82. ExtUtils::MM_DOS
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.82. ExtUtils::MM_DOS

Provides methods to override Unix behavior in ExtUtils::MakeMaker. Essentially, this module works the same way as ExtUtils::MM_Unix, but allows override for MS-DOS. For internal use only.

Previous | Home | Next
8.81. ExtUtils::MM_BeOS | Book Index | 8.83. ExtUtils::MM_NW5
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.83. ExtUtils::MM_NW5

Provides methods to override Unix behavior in ExtUtils::MakeMaker. Essentially, this module works in the same way as ExtUtils::MM_Unix, but allows override for Netware 5. For internal use only.

Previous | Home | Next
8.82. ExtUtils::MM_DOS | Book Index | 8.84. ExtUtils::MM_OS2
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.84. ExtUtils::MM_OS2

Provides methods for use with MakeMaker for OS2 systems. Used internally by MakeMaker if needed. (See ExtUtils::MM_Unix for documentation of the methods provided there.) Overrides the implementation of the methods, not the interface.

Previous | Home | Next
8.83. ExtUtils::MM_NW5 | Book Index | 8.85. ExtUtils::MM_Unix
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.85. ExtUtils::MM_Unix

Provides methods for MakeMaker to handle portability issues. You never need to require this module, but you might want to if you are working on improving MakeMaker's portability

Provides methods for both Unix and non-Unix systems; on non-Unix systems, they can be overridden by methods defined in other MM_* modules. The methods are the following.

catdir
catdir list

Concatenates a list of directory names to form a complete path ending with a directory. On Unix, joins the names with /.

catfile
catfile list

Concatenates one or more directory names and a filename to form a complete path ending with a filename. On Unix, joins the names with /.

dir_target
dir_target array

Takes an array of required directory names and returns a Makefile entry to create an .exists file in the directories. Returns nothing if the entry has already been processed.

file_name_is_absolute
file_name_is_absolute filename

Takes a path as argument and returns true if it is an absolute path.

find_perl
find_perl version, \names, \dirs, trace

Searches for an executable Perl. Takes the following arguments:

version
The executable must be at least the version given by version.

\names
Array reference. The name of the executable must be an entry in the array.

\dirs
Array reference. The executable must be in a directory that is one of the entries in the array.

trace
If true, prints debugging information.

guess_name
guess_name

Guesses the name of the package based on the working directory's name. Called only if the NAME attribute is missing.

has_link_code
has_link_code

Returns true if there are C, XS, MYEXTLIB, or similar objects in this object that need a compiler. Does not descend into subdirectories.

libscan
libscan filename

Uses init_dirscan to find a file; returns false if the file should not be included in the library. Used primarily to keep revision-control directories from being installed.

lsdir
lsdir dir, regexp

Returns all entries in the specified directory that match the regular expression. Takes the following arguments:

dir
Name of the directory

regexp
Regular expression to match the entries against

maybe_command
maybe_command filename

Returns true if filename is likely to be a command.

maybe_command_in_dirs
maybe_command_in_dirs

For future use.

needs_linking
needs_linking

Returns true if the module needs linking. Searches subdirectories.

nicetext
nicetext target

The MM_Unix version returns the argument with no processing.

path
path

Returns PATH environment variable as an array.

perl_script
perl_script filename

Returns true if filename is likely to be a Perl script. With MM_Unix, this is true for any ordinary, readable file.

prefixify
prefixify attrname, oldprefix, newprefix

Processes a path attribute in $self->{ attrname }. Looks up the attribute in %Config if it doesn't have a value. Takes the following arguments:

attrname
Name of the attribute to be processed

oldprefix
Prefix to be replaced

newprefix
New prefix, replaced in-place

replace_manpage_separator
replace_manpage_separator filename

Takes the filename of a package and replaces the subdirectory delimiter (/ in Unix) with ::. Returns the altered name.

8.85.1. Methods to Produce the Makefile

ExtUtils::MM_Unix has some additional methods that are called in sequence to produce a Makefile. The list of methods is specified in the array @ExtUtils::MakeMaker::MM_Sections, one method per section. The routines are all called the same way and so are just listed here. Each method returns the string to be put into its section of the Makefile.

The methods are called in the order that they are listed in the following table, reading down the columns:

post_initialize | top_targets | realclean
const_config | linkext | dist_basics
constants | dlsyms | dist_core
const_loadlibs | dynamic | dist_dir
const_cccmd | dynamic_bs | dist_test
tool_autosplit | dynamic_lib | dist_ci
tool_xsubpp | static | install
tools_other | static_lib | force
dist | installpm | perldepend
macro | installpm_x | makefile
depend | manifypods | staticmake
post_constants | processPL | test
pasthru | installbin | test_via_harness
c_o | subdirs | test_via_script
xs_c | subdir_x | postamble
xs_o | clean |

Finally, there are two special methods: post_initialize and postamble. They each return an empty string by default and can be defined in Makefile.PL to insert customized text near the beginning or end of the Makefile.

Previous | Home | Next
8.84. ExtUtils::MM_OS2 | Book Index | 8.86. ExtUtils::MM_UWIN
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.86. ExtUtils::MM_UWIN

Provides methods to override Unix behavior in ExtUtils::MakeMaker. Essentially, this module works the same way as ExtUtils::MM_Unix, but allows override for the U/WIN emulator. For internal use only.

Previous | Home | Next
8.85. ExtUtils::MM_Unix | Book Index | 8.87. ExtUtils::MM_VMS
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.87. ExtUtils::MM_VMS

Provides methods for use with MakeMaker for VMS systems. Used internally by MakeMaker if needed. (See ExtUtils::MM_Unix for documentation of the methods provided there.) Overrides the implementation of the methods, not the interface.

Previous | Home | Next
8.86. ExtUtils::MM_UWIN | Book Index | 8.88. ExtUtils::MM_Win32
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.88. ExtUtils::MM_Win32

Provides methods for use with MakeMaker for Win32 systems. Used internally by MakeMaker in the standard Win32 Perl distribution if needed. (See ExtUtils::MM_Unix for a documentation of the methods provided there.) Overrides the implementation of these methods, not the interface.

catfile
catfile

Concatenates one or more directory names and a filename to form a complete path, ending with a filename.

constants
constants

Initializes constants, .SUFFIXES, and .PHONY.

dynamic_bs
dynamic_bs

Defines targets for bootstrap files.

dynamic_lib
dynamic_lib

Defines how to produce the *.so (or equivalent) files.

canonpath
canonpath

Performs a logical cleanup of a path.

dist_ci
dist_ci

Changes command-line quoting (same as MM_Unix version).

dist_core
dist_core

Changes command-line quoting (same as MM_Unix version).

manifypods
manifypods

Disables manpage process.

pasthru
pasthru

Defines the string that is passed to recursive make calls in subdirectories.

perl_script
perl_script filename

Takes one argument, a filename, and returns the filename if the argument is likely to be a Perl script.

pm_to_blib
pm_to_blib

Defines a target that copies all files in the hash PM to their destination and autosplits them. See ExtUtils::Install.

static_lib
static_lib

Defines how to produce the *.a (or equivalent) files.

test_via_harness
test_via_harness

Helper method to write the test targets.

tool_autosplit
tool_autosplit

Use Win32-style quoting on command line.

tools_other
tools_other

Win32 overrides. Defines SHELL, LD, TOUCH, CP, MV, RM_F, RM_RF, CHMOD, and UMASK_NULL in the Makefile. Also defines the Perl programs MKPATH, WARN_IF_OLD_PACKLIST, MOD_INSTALL, DOC_INSTALL, and UNINSTALL.

top_targets
top_targets

Defines the targets all, subdirs, config, and O_FILES.

xs_o
xs_o

Defines suffix rules to go from XS to object files directly.

Previous | Home | Next
8.87. ExtUtils::MM_VMS | Book Index | 8.89. ExtUtils::MY
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.89. ExtUtils::MY

Allows ExtUtils::MakeMaker subclass for customization. For internal use only.

Previous | Home | Next
8.88. ExtUtils::MM_Win32 | Book Index | 8.90. ExtUtils::Packlist
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.90. ExtUtils::Packlist

Manages .packlist files. Supports an extended .packlist format. The original format is a list of absolute pathnames, one pathname per line. In the extended format, each line can also contain a list of attributes as key/value pairs, which are used by the installperl script. For example:

/usr/local/bin/perl from=/usr/local/pbeta/bin/perl5.005 type=link
/usr/local/bin/perl5.005 type=file
/usr/local/lib/perl5/5.005/AnyDBM_File.pm type=file

Also see ExtUtils::Installed.

new
$pl = ExtUtils::Packlist->new([plfile])

Constructor. Takes the name of a .packlist as the optional parameter and returns a reference to a hash that has an entry for each line in the .packlist. The value associated with each key is undef for oldstyle .packlists. For files in the extended format, the value for each key is a hash containing the key/value pairs on the line associated with that key.

packlist_file
$pl->packlist_file(  )

Returns the name of the associated .packlist file.

read
$pl->read([plfile])

Reads the .packlist specified by the plfile parameter if given; otherwise, reads the file associated with $pl. Calls Carp::croak if the file doesn't exist.

validate
$pl->validate([arg])

Checks that each file in the .packlist exists. An optional argument can be specified; if the argument is present and evaluates to true, missing files are removed from the internal hash. Returns a list of missing files, or an empty list if the files all exist.

write
$pl->write([plfile])

Writes to a .packlist. Optionally takes the name of the .packlist to be written; otherwise, overwrites the .packlist associated with $pl. If the value associated with a hash key is a scalar, the entry written to the .packlist is a simple filename. If the value is a hash, the entry written is the filename followed by the key/value pairs from the hash.

Previous | Home | Next
8.89. ExtUtils::MY | Book Index | 8.91. ExtUtils::testlib
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.91. ExtUtils::testlib

Used for testing a module after it's been built and before it's been installed, when you don't want to (or can't) run make test. Adding:

use ExtUtils::testlib;

to your test program causes the intermediate directories used by make to be added to @INC, allowing you to run the test.

Previous | Home | Next
8.90. ExtUtils::Packlist | Book Index | 8.92. Fatal
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.92. Fatal

Provides a way to replace functions that return false on failure with equivalents that die instead, so you can use the functions without having to test the return values explicitly. Fatal reports errors via die; you can trap them with $SIG{_ _DIE_ _} if you want to take action before the program exits. You can use Fatal for both user-defined functions and Perl core operators except exec and system.

import
import Fatal function

Wraps function in an equivalent function that will die on failure.

Previous | Home | Next
8.91. ExtUtils::testlib | Book Index | 8.93. Fcntl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.93. Fcntl

A translation of the C fcntl.h program that uses h2xs (which builds a Perl extension from a C header file) and the C compiler to translate #define symbols and make them available as functions. Exports the following routines by default; each routine returns the value of the #define that is the same as the routine name:

FD_CLOEXEC | F_DUPFD | F_GETFD | F_GETFL | F_GETLK
F_RDLCK | F_SETFD | F_SETFL | F_SETLK | F_SETLKW
F_UNLCK | F_WRLCK | O_APPEND | O_CREAT | O_EXCL
O_NDELAY | O_NOCTTY | O_NONBLOCK | O_RDONLY | O_RDWR
O_TRUNC | O_WRONLY |  |  |

Previous | Home | Next
8.92. Fatal | Book Index | 8.94. fields
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.94. fields

Pragma that provides the ability to define class fields at compile time by updating the %FIELDS hash in the calling package. The %FIELDS hash is set up at compile time as well; use the base pragma to copy fields from base classes, and then fields to add new fields. Lets you have objects with named fields that are as compact and fast as arrays to access. For more details, see the fields manpage and the pseudo-hash section of the perlref manpage.

Previous | Home | Next
8.93. Fcntl | Book Index | 8.95. File::Basename
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.95. File::Basename

Parses a file's path, returning its three component pieces: the path to the file, the file's basename, and the file's extension. For example, for:

/usr/local/lib/perl5/SelectSaver.pm

the path is /usr/local/lib/perl5, the basename is SelectSaver, and the extension is .pm. File::Basename exports the following functions.

basename
basename (fullname[, suffixlist])

Returns the first element of the list that would be produced if you called fileparse with the same arguments. Provides compatibility with the Unix basename command. Takes the following arguments:

fullname
Input file specification

suffixlist
Optional list containing patterns to be matched against the end of fullname to find the suffix

dirname
dirname (fullname)

Returns the directory portion of the input file specification. fullname is the input file specification.

fileparse
fileparse (fullname[, suffixlist])

Divides a file specification into its three parts, returning them in this order: filename, path, suffix.

($name, $path, $suffix) = fileparse($fullname, @suffixlist)

The arguments are the same as for basename.

fileparse_set_fstype
fileparse_set_fstype (os-string)

Called before the other routines to select the appropriate file specification syntax for your operating system, to be used in future File::Basename calls. Currently valid values for os-string (the operating system) are VMS, MSWin32, MSDOS, AmigaOS, os2, RISCOS, and MacOS. Uses Unix syntax by default.

Previous | Home | Next
8.94. fields | Book Index | 8.96. File::CheckTree
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.96. File::CheckTree

Runs file tests on a set of files. Exports one function, validate, which takes a single multiline string as input. Each line of the string contains a filename plus a test to run on the file. The test can be followed with || die to make it a fatal error if it fails. The default is || warn. Prepending ! to the test reverses the sense of the test. You can group tests (e.g., -rwx); only the first failed test of the group produces a warning. For example:

use File::CheckTree;
$warnings += validate( q{
    /vmunix            -e || die
    /bin               cd
        csh            !-ug
        sh             -ex
    /usr               -d || warn "What happened to $file?\n"
});

Available tests include all the standard Perl file-test operators except -t, -M, -A, and -C. Unless it dies, validate returns the number of warnings issued.

Previous | Home | Next
8.95. File::Basename | Book Index | 8.97. File::Compare
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.97. File::Compare

Compares the contents of two sources, each of which can be a file or a filehandle. Returns 0 if the sources are equal, 1 if they are unequal, and -1 on error. File::Compare provides two functions.

cmp
cmp (file1, file2[, buffsize])

cmp is a synonym for compare. Exported on request.

compare
compare (file1, file2[, buffsize])

Compares file1 to file2. Exported by default. If present, buffsize specifies the size of the buffer to use for the comparison.

Previous | Home | Next
8.96. File::CheckTree | Book Index | 8.98. File::Copy
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.98. File::Copy

Copies or moves files or filehandles from one location to another. Returns 1 on success, 0 on failure, or sets $! on error.

copy
copy (source, dest[, buffsize])

Copies source to dest. Takes the following arguments:

source
The source string, FileHandle reference, or FileHandle glob. If source is a filehandle, it is read from; if it's a filename, the filehandle is opened for reading.

dest
The destination string, FileHandle reference, or FileHandle glob. dest is created if necessary and written to.

buffsize
Specifies the size of the buffer to be used for copying. Optional.

cp
cp (source, dest[, buffsize])

Like copy, but exported only on request:

use File::Copy "cp"
move
move (source, dest)

Moves source to dest. If the destination exists and is a directory, and the source is not a directory, then the source file is renamed into the directory specified by dest. Return values are the same as for copy.

mv
mv (source, dest)

Like move, but exported only on request:

use File::Copy "mv"
Previous | Home | Next
8.97. File::Compare | Book Index | 8.99. File::DosGlob
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.99. File::DosGlob

Provides a portable enhanced DOS-like globbing for the standard Perl distribution. DosGlob lets you use wildcards in directory paths, is case-insensitive, and accepts both backslashes and forward slashes (although you may have to double the backslashes). Can be run three ways:

  • From a Perl script:

    require 5.004
use File::DosGlob 'glob';

@perlfiles = glob  "..\pe?l/*.p?";
print <..\pe?l/*.p?>;

  • With the perl command, on the command line:

    # From the command line (overrides only in main::)
% perl -MFile::DosGlob=glob -e "print <../pe*/*p?>"

  • With the perlglob.bat program on the DOS command line:

    % perlglob ../pe*/*p?

When invoked as a program from the command line, File::DosGlob prints null-separated filenames to STDOUT.

Previous | Home | Next
8.98. File::Copy | Book Index | 8.100. File::Find
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.100. File::Find

Looks for files that match a particular expression. Exports two functions.

find
find (\&wanted, dir1[, dir2 ...])

Works like the Unix find command; traverses the specified directories, looking for files that match the expressions or actions you specify in a subroutine called wanted, which you must define. For example, to print out the names of all executable files, you could define wanted this way:

sub wanted {
    print "$File::Find::name\n" if -x;
}

Provides the following variables:

$File::Find::dir
Current directory name ($_ has the current filename in that directory).

$File::Find::name
Contains $File::Find::dir/$_. You are chdired to $File::Find::dir when find is called.

$File::Find::prune
If true, find does not descend into any directories.

$File::Find::dont_use_nlink
Set this variable if you're using the Andrew File System (AFS).

finddepth
finddepth (\wanted, dir1[, dir2...])

Like find, but does a depth-first search.

The standard Perl distribution comes with a Perl script, find2perl, which takes a Unix find command and turns it into a wanted subroutine.

Previous | Home | Next
8.99. File::DosGlob | Book Index | 8.101. File::Path
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.101. File::Path

Creates and deletes multiple directories with specified permissions. Exports two methods.

mkpath
mkpath (path, bool, perm)

Creates a directory path and returns a list of all directories created. Takes the following arguments:

path
Name of the path or reference to a list of paths to create.

bool
Boolean. If true, mkpath prints the name of each directory as it is created. Default is false.

perm
Numeric mode indicating the permissions to use when creating the directories. Default is 0777.

rmtree
rmtree (root, prt, skip)

Deletes subtrees from the directory structure, returning the number of files successfully deleted. Symbolic links are treated as ordinary files. Takes the following arguments:

root
Root of the subtree to delete or reference to a list of roots. The roots, and all files and directories below each root, are deleted.

prt
Boolean. If true, rmtree prints a message for each file, with the name of the file and whether it's using rmdir or unlink to remove it (or if it's skipping the file). Default is false.

skip
Boolean. If true, rmtree skips any files to which you do not have delete access (under VMS) or write access (under other operating systems). Default is false.

Previous | Home | Next
8.100. File::Find | Book Index | 8.102. File::Spec
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.102. File::Spec

Performs common operations on file specifications in a portable way. To do this, it automatically loads the appropriate operating system-specific module, which is one of File::Spec::Mac, File::Spec::OS2, File::Spec::Unix, File::Spec::VMS, or File::Spec::Win32. The complete reference of available functions is given in File::Spec::Unix; the functions are inherited by the other modules and overridden as necessary. Subroutines should be called as class methods, rather than directly.

Previous | Home | Next
8.101. File::Path | Book Index | 8.103. File::Spec::Cygwin
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.103. File::Spec::Cygwin

Implements methods for Cygwin file specs. You do not need to call this module. It is called internally by File::Spec.

Previous | Home | Next
8.102. File::Spec | Book Index | 8.104. File::Spec::Mac
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.104. File::Spec::Mac

File::Spec for MacOS.

canonpath
File::Spec->canonpath

Nothing to do; returns what it's given.

catdir
File::Spec->catdir(dir[, dir...])

Concatenates two or more directory names to form a complete path. Ends with a directory name and appends a trailing : if there isn't one. You can get a relative path by either beginning the first argument with : or putting "" as the first argument.

catfile
File::Spec->catfile(dir[, dir...], file)

Concatenates one or more directory names and a filename to form a complete path that ends with a filename. Uses catdir.

curdir
File::Spec->curdir

Returns string representing the current directory.

file_name_is_absolute
File::Spec->file_name_is_absolute(path)

Takes a path as argument and returns true if it is an absolute path.

path
File::Spec->path

Returns null list for MacPerl applications, or $ENV{Commands}, suitably split, for the MacPerl tool under MPW.

rootdir
File::Spec->rootdir

Returns string representing the root directory. Under MacPerl, returns the name of the startup volume.

updir
File::Spec->updir

Returns string representing the parent directory.

Previous | Home | Next
8.103. File::Spec::Cygwin | Book Index | 8.105. File::Spec::OS2
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.105. File::Spec::OS2

File::Spec for OS/2. Overrides the implementation of the File::Spec::Unix methods, but not the interface.

Previous | Home | Next
8.104. File::Spec::Mac | Book Index | 8.106. File::Spec::Unix
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.106. File::Spec::Unix

File::Spec for Unix. Provides methods for File::Spec to use in manipulating file specifications.

canonpath
File::Spec->canonpath

Does logical cleanup of path.

catdir
File::Spec->catdir(dir[, dir...])

Concatenates two or more directory names to form a complete path. Ends with a directory name.

catfile
File::Spec->catfile(dir[, dir...], file)

Concatenates one or more directory names and a filename to form a complete path that ends with a filename.

curdir
File::Spec->curdir

Returns ., representing the current directory.

file_name_is_absolute
File::Spec->file_name_is_absolute(path)

Takes a path as argument and returns true if it is an absolute path.

join
File::Spec->join(dir[, dir...], file)

Same as catfile.

no_upwards
File::Spec->no_upwards(files)

Strips names of files referring to a parent directory from a list of filenames. Doesn't strip symbolic links.

path
File::Spec->path

Returns the PATH environment variable as an array.

rootdir
File::Spec->rootdir

Returns /, representing the root directory.

updir
File::Spec->updir

Returns .., representing the parent directory.

Previous | Home | Next
8.105. File::Spec::OS2 | Book Index | 8.107. File::Spec::VMS
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.107. File::Spec::VMS

File::Spec for VMS. Overrides the implementation of the File::Spec::Unix methods, but not the interface.

catdir
File::Spec->catdir(dirspecs)

Concatenates a list of directories and returns the result as a VMS-syntax directory specification.

catfile
File::Spec->catfile(filespecs)

Concatenates a list of file specifications and returns the result as a path.

curdir
File::Spec->curdir

Returns string representing the current directory.

file_name_is_absolute
File::Spec->file_name_is_absolute(path)

Takes a path as argument and returns true if it is an absolute path. Checks for VMS directory specification as well as Unix separators.

path
File::Spec->path

Translates the logical name DCL$PATH as a searchlist.

rootdir
File::Spec->rootdir

Returns string representing the root directory.

updir
File::Spec->updir

Returns string representing the parent directory.

Previous | Home | Next
8.106. File::Spec::Unix | Book Index | 8.108. File::Spec::Win32
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.108. File::Spec::Win32

File::Spec for Win32. Overrides the implementation of the File::Spec::Unix methods, but not the interface.

canonpath
File::Spec->canonpath

Performs logical cleanup of a path; doesn't physically check the filesystem.

catfile
File::Spec->catfile(dir[, dir...], file)

Concatenates one or more directory names and a filename to form a complete path that ends with a filename.

Previous | Home | Next
8.107. File::Spec::VMS | Book Index | 8.109. File::stat
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.109. File::stat

Provides the same file status information as the Perl functions stat and lstat. Exports two functions that return File::stat objects. The objects have methods that return the equivalent fields from the Unix stat(2) call:

Field | Meaning
dev | Device number of filesystem
ino | Inode number
mode | File mode
nlink | Number of links to the file
uid | Numeric user ID of owner
gid | Numeric group ID of owner
rdev | Device identifier
size | Size of file, in bytes
atime | Last access time
mtime | Last modified time
ctime | Inode change time
blksize | Preferred blocksize for filesystem I/O
blocks | Number of blocks allocated

You can access the status fields either with the methods or by importing the fields into your namespace with the :FIELDS import tag and then accessing them by prepending st_ to the field name (e.g., $st_mode). Here are examples of doing it both ways:

use File::stat;

$stats = stat($file);
print $stats->uid;
print $st_uid;
lstat
lstat (file)

Returns the same information as stat, but if file is a symbolic link, returns the status information for the link.

stat
stat (file)

Returns status information for the file or filehandle pointed to by file. If fileis a symbolic link, returns the information for the file that the link points to.

Previous | Home | Next
8.108. File::Spec::Win32 | Book Index | 8.110. File::Temp
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.110. File::Temp

File::Temp can be used to create and open temporary files safely. The tempfile( ) function returns the name and the open filehandle of a temporary file. The tempdir( ) function creates a temporary directory. File::Temp guarantees that race conditions cannot occur since it returns both a filehandle and filename. In addition, File::Temp checks for safe file and directory permissions, so the sticky bits are checked for group-writable directories. To write a temp file into /tmp (default), you would do something like the following:

#!/usr/local/bin/perl -w

use File::Temp qw(tempfile);

my($fh, $filename) = tempfile( );

print "opening $filename for writing...\n";
print $fh "some data ...\n";
Previous | Home | Next
8.109. File::stat | Book Index | 8.111. FileCache
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.111. FileCache

Closes and reopens files as necessary so you can always write to a file even if you already have the maximum number of files open. Exports one function.

cacheout
cacheout (path)

Makes sure the file at path is created and accessible through the filehandle also named path. You don't need to invoke cacheout between successive accesses to the same file.

Previous | Home | Next
8.110. File::Temp | Book Index | 8.112. FileHandle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.112. FileHandle

Provides object methods for working with filehandles. Provides the following methods.

new
$fh = new FileHandle [filename[, mode]]

Constructor. Creates a FileHandle, which is a reference to a newly created symbol. The optional parameters, filename and mode, are passed to open. The FileHandle object is returned if the open succeeds; otherwise, it is destroyed.

new_from_fd
$fh = new_from_fd FileHandle fd, mode

Constructor. Creates a FileHandle, but it takes the file descriptor, fd, instead of filename as a parameter, along with mode; the parameters are required.

fdopen
$fh->fdopen fdname [openmode]

Like open, except that its first parameter is not a filename but a filehandle name, a FileHandle object, or a file descriptor number.

getpos
$pos = $fh->getpos

If the C functions fgetpos(3) and fsetpos(3) are available, getpos returns the current position, $pos, of the FileHandle.

open
$fh->open filename [openmode]

Takes filename and, optionally, the open mode, and opens a file. If the mode is present, it can be in Perl form (e.g., >, +<) or in POSIX form (e.g., w, r+).

setpos
$fh->setpos pos

Uses the value (pos) returned by getpos to restore a previous position of the FileHandle.

setvbuf
$fh->setvbuf(params)

Takes the same parameters as the C function setvbuf(3) and uses the C function to set the buffering policy for the FileHandle.

The following additional FileHandle methods act as front-ends for the corresponding built-in Perl functions (see the O'Reilly book Programming Perl or the perlfunc manpage for more details):

clearerr | getc
close | gets
eof | seek
fileno | tell

The next group of FileHandle methods correspond to Perl special variables (see Programming Perl or the perlvar manpage):

autoflush | format_page_number
format_formfeed | format_top_name
format_line_break_characters | input_line_number
format_lines_left | input_record_separator
format_lines_per_page | output_field_separator
format_name | output_record_separator

Finally, the following methods are useful:

$fh->print
See Perl's built-in print function.

$fh->printf
See Perl's built-in printf function.

$fh->getline
Works like Perl's <FILEHANDLE> construct, except that it can be safely called in an array context (but it still returns just one line).

$fh->getlines
Works like Perl's <FILEHANDLE> construct when called in an array context to read all remaining lines in a file.

Previous | Home | Next
8.111. FileCache | Book Index | 8.113. Filter::Simple
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.113. Filter::Simple

Source filtering is a nice feature of newer versions of Perl (5.6 and later) because it allows the programmer to write extensions to the Perl language without tampering with the Perl source code itself. That is, you can create a macro language out of Perl.

Filter::Simple is based on Filter:Util::Call, but simplifies the means by which you can begin doing your own source filtering with Perl. Filter::Simple ships with the Perl 5.8 source kit.

Using Filter::Simple is, well, easy. Basically, Filter::Simple implements FILTER { ... }, which you can use to handle many of your simple source-filtering needs. Let's say that you want a good glass of ale, and you decide that you don't want Perl to print, but pint instead. You can implement something like the following with Filter::Simple. First, create a module called Print_to_Pint:

package Print_to_Pint;

use Filter::Simple;
FILTER { s/pint/print/g; }

# true
1;

Now, use Print_to_Pint to do something with pint:

#!/usr/local/bin/perl -w

use Print_to_Pint;

my $bottles = 99;
my $last = 1;

foreach my $bottle (reverse($last .. $bottles)) {
    pint "$bottle -> burp\n";
}

By default, Filter::Simple ignores no behavior, i.e., it stops filtering after a no Module is encountered. You can alter this behavior by passing another argument to use Filter::Simple or to FILTER { ... }. For example:

package Print_to_Pint;
use Filter::Simple;
    FILTER {
        s/pint/print/g;
}
"";

Filter::Simple also supports FILTER_ONLY, which allows you to support multiple filters to handle different parts of your source code. FILTER_ONLY takes several subroutines as options: code, executable, string, regex, quotelike, and all. code or executable filters all Perl code, except Pod or _ _DATA_ _ types. quotelike filters other Perl quotelike stuff, including here documents. string filters all string-related parts. regex filters all pattern-literal parts of quotelike.

For example, the following module will skip all incidences of Pod in the PodSucks module:

package PodSucks;

use Filter::Simple;

FILTER_ONLY
    executable => sub { s/x/X/g },
    executable => sub { print }

# True. True.
1;

The above code might not make that much sense, but take a look at the test program now, and it should become clear:

#!/usr/local/bin/perl -w

use PodSucks;

print "Flocks of Red Sox cause shocks to the Bronx.\n";

=pod
You will fear the wrath of Pod! Fear my wrath!
=cut

This prints:

Flocks of Red SoX cause shocks to the BronX.
Previous | Home | Next
8.112. FileHandle | Book Index | 8.114. Filter::Util::Call
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.114. Filter::Util::Call

Provides a framework for implementing source filters in Perl code. While you may use Filter::Util::Call directly, we suggest you use Filter::Simple instead.

For example:

package Milter; # Could just as well be called 'OldJoke'

use Filter::Util::Call ;

sub import {
    my($type) = @_ ;
    filter_add(bless []) ;
}

sub filter {
    my($self) = @_;
    my($status);

    s/Shut-Up/Trouble/g

    if ($status = filter_read()) > 0;
    $status ;
 }
 1;

You'd use the above in your code like so:

#!/usr/local/bin/perl -w
use Milter;
print "Are you looking for Shut-Up?\n" ;

This prints:

Are you looking for Trouble?

Filter::Util::Call implements the following methods.

filter
filter()

Performs the main processing for the filter. Used with closure filters; that is, a closure filter handles the lexical variables that are maintained by the closure. The finished source, as processed by filter, will be returned in $_.

filter returns a status, as follows:

< 0
An error has been encountered.

EOF
End-of-file has been reached unexpectedly.

> 0
Everything is OK.

filter_add
filter_add(ref)

Installs the filter. filter_add takes one parameter, a reference, and depending on the kind of reference used, dictates which of the two filter types is used. CODE references result in a closure filter; otherwise, method filters are assumed.

filter_del
filter_del()

Disables the current filter. It doesn't destroy any filters, just tells Perl to stop using them.

filter_read
filter_read(n)

Obtains a line or block from the next filter in the chain. If there are no other filters, then the actual source file is obtained. For example:

$status = filter_read();      # Requests a line
$status = filter_read($size); # Requests a block of $size
filter_read_exact
filter_read_exact()

Obtains a line or block from the next filter in the chain. If there are no other filters, then the actual source file is obtained.

import
import()

Creates an instance of the filter. Perl calls import indirectly when it encounters use Milter in your Perl program. import will always have one parameter passed by Perl, which corresponds to the name of your package—in this case, Milter.

So, if you do this:

use Milter qw(pinta nina santa-maria);

You get in @_:

@_[0] => "Milter"
@_[1] => "pinta"
@_[2] => "nina"
@_[3] => "santa-maria"

import then calls filter_add before finishing.

Previous | Home | Next
8.113. Filter::Simple | Book Index | 8.115. FindBin
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.115. FindBin

Finds the full path to a script's bin directory, letting you use relative paths to that directory without needing to know the actual location:

use FindBin;
use lib "$FindBin::Bin/../lib";

or:

use FindBin qw($Bin);
use lib "$Bin/../lib";

FindBin exports the following variables:

$Bin
Path to bin directory from which script was invoked

$Script
Basename of script from which Perl was invoked

$RealBin
$Bin with all links resolved

$RealScript
$Script with all links resolved

If you invoke Perl with the -e option or read the Perl script from STDIN, then FindBin sets both $Bin and $RealBin to the current directory.

Previous | Home | Next
8.114. Filter::Util::Call | Book Index | 8.116. GDBM_File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.116. GDBM_File

Allows Perl programs to make use of the facilities provided by the GNU gdbm library. Most of the libgdbm.a functions are available as methods of the GDBM_File interface. (See the gdbm(3) manpage and the description of DB_File in this chapter.) The following is an example of the use of GDBM_File:

use GDBM_File;

tie %hash, "GDBM_File", $filename, &GDBM_WRCREAT, 0644);
# Read/writes of %hash are now read/writes of $filename
untie %hash;
Previous | Home | Next
8.115. FindBin | Book Index | 8.117. Getopt::Long
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.117. Getopt::Long

Lets your program accept command-line options with long names, introduced by --. Standard single-character options are also accepted. Options that start with -- may have an argument appended, following a space or an equals sign (=):

--foo=bar
--foo bar

Provides two functions: GetOptions and config.

config
Getopt::Long::config(optionlist)

Sets the variables in optionlist to change the default behavior of GetOptions. The following options are available:

$Getopt::Long::autoabbrev
If true, option names can be invoked with unique abbreviations. Default is 1 (true) unless the environment variable POSIXLY_CORRECT has been set.

$Getopt::Long::getopt_compat
If true, options can start with +. Default is 1 unless the environment variable POSIXLY_CORRECT has been set.

$Getopt::Long::order
Value indicates whether options and non-options may be mixed on the command line:

$PERMUTE
Non-options may be mixed with options. The default if POSIXLY_CORRECT is not set.

$REQUIRE_ORDER
Mixing is not allowed. The default if POSIXLY_CORRECT is set.

$Getopt::Long::ignorecase
If true, ignore case when matching options. Default is 1.

$Getopt::Long::VERSION
The version number of this Getopt::Long implementation in the format major.minor.

$Getopt::Long::error
Internal error flag. May be incremented from a callback routine to cause options-parsing to fail.

$Getopt::Long::debug
If true, enables debugging output. Default is 0 (false).

GetOptions
$result = GetOptions(option-descriptions)

Uses descriptions from option-descriptionsto retrieve and process the command-line options with which your Perl program was invoked. The options are taken from @ARGV. After GetOptions has processed the options, @ARGV contains only command-line arguments that were not options. Returns 0 if errors are detected. Each option description consists of two elements:

Option specifier
Defines the option name and optionally a value as an argument specifier.

Option linkage
A reference to a variable that is set when the option is present.

GetOptions can also take as a first argument a reference to a hash that describes the linkage for the options. The linkage specified in the argument list takes precedence over the one specified in the hash. Thus, the following are equivalent:

%optctl = (size => \$offset);
&GetOptions(\%optctl, "size=i");

and:

&GetOptions("size=i" => \$offset);

Option specifiers

Each option specifier consists of an option name and possibly an argument specifier. The name can be a name, or a list of names separated by |; the first name in the list is the true name of the option, and the others are treated as aliases. Option names may be invoked with the shortest unique abbreviation. Values for argument specifiers are:

<none>
Option takes no argument. The option variable is set to 1.

!
Option does not take an argument and may be negated, that is, prefixed by no.

=s
Option takes a mandatory argument that is a string that will be assigned to the option variable. Even if the argument starts with - or --, it is assigned to the option variable rather than treated as another option.

:s
Option takes an optional string argument. If the option is invoked with no argument, an empty string ("") is assigned to the option variable. If the argument starts with - or --, it is treated as another option rather than assigned to the option variable.

=i
Option takes a mandatory integer argument, which may start with - to indicate a negative value.

:i
Option takes an optional integer argument that may start with - to indicate a negative value. With no argument, the value 0 is assigned to the option variable.

=f
Option takes a mandatory floating-point argument that may start with - to indicate a negative value.

:f
Option takes an optional floating-point argument that may start with - to indicate a negative value. With no argument, the value 0 is assigned to the option variable.

A hyphen (-) by itself is considered an option whose name is the empty string. A double hyphen (--) by itself terminates option processing. Any options following the double hyphen remain in @ARGV when GetOptions returns. If an argument specifier ends with @ (e.g., =s@), then the option is treated as an array.

The special option specifier <> can be used to designate a subroutine to handle non-option arguments. For this specifier to be used, the variable $Getopt::Long::order must have the value of the predefined and exported variable, $PERMUTE. See the description of Getopt::Long::config below.

Linkage specification

The linkage specifier can be a reference to any of the following:

Scalar
The new value is stored in the referenced variable. If the option occurs more than once, the previous value is overwritten.

Array
The new value is appended (pushed) onto the referenced array.

Subroutine
The referenced subroutine is called with two arguments: the option name, which is always the true name, and the option value.

If no linkage is explicitly specified, but a hash reference is passed, GetOptions puts the value in the hash. For array options, a reference to an anonymous array is generated.

If no linkage is explicitly specified, and no hash reference is passed, GetOptions puts the value into a global variable named after the option, prefixed by opt_. Characters that are not part of the variable syntax are translated to underscores. For example, --fpp-struct-return sets the variable $opt_fpp_struct_return.

Previous | Home | Next
8.116. GDBM_File | Book Index | 8.118. Getopt::Std
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.118. Getopt::Std

Processes single-character, command-line options with option clustering. Exports two functions, which analyze @ARGV, extract information about the options, and return this information to your program in a set of variables. Processing of @ARGV stops when an argument without a leading - is encountered, if that argument is not associated with a preceding option. Otherwise, @ARGV is processed to the end and left empty.

getopt
getopt ('switches'[, \%opts])

switches is a string of the command-line options that take arguments. For each option, getopt sets $opt_x (in which x is the switch) to the value entered as an argument. If \%optsis specified, it is a reference to a hash in which getopt sets the key to the name of the switch and the value to the argument (and the $opt_ variables are not set).

getopts
getopts ('switches'[, \%opts])

Like getopt, except that all valid options are included in switches, and options that take an argument are followed by a colon (:). For example:

getopt('oDI')    # -o, -D, & -I take arguments; there may
                 # be other options
getopts('o:DI')  # -o, -D, and -I are the only valid
                 # options; only -o takes an argument

\%opts means the same as with getopt.

Previous | Home | Next
8.117. Getopt::Long | Book Index | 8.119. Hash::Util
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.119. Hash::Util

Offers a selection of general-utility hash subroutines. Starting with Perl 5.8, hashes allow you to restrict access to the data that's stored in the hash. Individual keys can be locked so they cannot be deleted, nor can their values be changed. Hash::Util is largely intended to replace the deprecated pseudo-hashes.

For example:

 #!/usr/local/bin/perl -w

%hash = (foo => 42, bar => 23);
lock_keys(%hash);

# Now, try to set %hash{'something'}
while(my($key, $value) = each %hash) {
    print "$key -> $value\n";
}

unlock_keys(%hash);

You can lock specific values as follows:

#!/usr/local/bin/perl -w

%hash = (foo => 42, bar => 23);
lock_key(%hash, 'foo');

# Now, try to set 'foo' and see what happens

unlock_keys(%hash, 'foo');
Previous | Home | Next
8.118. Getopt::Std | Book Index | 8.120. I18N::Collate
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.120. I18N::Collate

The use of I18N::Collate is now deprecated, although it is still provided for compatibility with older programs. Don't use it in new programs, because its functionality was integrated into the core Perl in Perl 5.004. See the locale pragma.

Previous | Home | Next
8.119. Hash::Util | Book Index | 8.121. I18N::Langinfo
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.121. I18N::Langinfo

Provides locale-specific information for constants supported in langinfo.h. I18N::Langinfo implements just one function, langinfo.

langinfo
langinfo(constant)

Returns the locale-specific data associated with the specified constant. For example, the following prints the date and time in the format for the current locale:

print langinfo(D_T_FMT);
Previous | Home | Next
8.120. I18N::Collate | Book Index | 8.122. I18N::LangTags
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.122. I18N::LangTags

Implements language tags per RFC 3066. Language tags let you specify a certain language that you'll use in a segment of text or code. I18N::LangTags lets you perform a number of common tasks with language tasks that you might come across when dealing with different protocols and applications.

I18N::LangTags is shipped with the Perl 5.8 source kit. It implements the following methods.

alternate_language_tags
alternate_language_tags(language)

Returns all language tags that are alternate forms of language:

alternate_language_tags('en'); # Returns ()
alternate_language_tags('he'); # Returns ('iw')
alternate_language_tags('iw'); # Returns ('he')
encode_language_tag
encode_language_tag(language)

Returns the encoding of a language tag. Returns undef if language is invalid.

extract_language_tags
extract_language_tags(source)

Returns a list of what is perceived as valid language tags from source. For example:

my $chewbacca_dialect = 'growl, growl, fr, growl, growl!';
extract_language_tags($chewbacca_dialect);
# Returns 'fr'  Chewbacca is French?!  Say it isn't so!
is_dialect_of
is_dialect_of(lang1, lang2)

Returns true if lang1 represents a form of lang2. It doesn't go both ways, so make sure that lang1 comes first.

is_dialect_of('en-US', 'en'); # true
is_dialect_of('en', 'en-US'); # false
is_language_tag
is_language_tag(language)

Returns true if language is a valid language tag. For example:

my $gutteral = 'Chewbacca';
is_language_tag($gutteral);  # false

my $pourquois = 'fr';
is_language_tag($pourquois); # true
locale2language_tag
locale2language_tag(locale)

Takes a locale name and maps it to a language tag. Certain tags aren't mappable, such as C or POSIX, in which case local2language_tag will return an empty list.

locale2language_tag('en');    # Returns 'en'
locale2language_tag('POSIX'); # Returns undef or ()
same_language_tag
same_language_tag(lang1, lang2)

Returns true if lang1 and lang2 both represent the same language form. For example:

same_language_tag('en', 'en-US'); # Returns false
en != en-US
similarity_language_tag
similarity_language_tag(lang1, lang2)

Returns an integer that represents the degree of similarity between lang1 and lang2:

similarity_language_tag('fr', 'fr-ca'); # 1
similarity_language_tag('fr', 'en-US'); # 0
super_languages
super_languages(language)

Returns a list of language tags that are superordinate to language:

super_languages('en-US'); # Gets 'en'
super_languages('en');    # Gets an empty list
Previous | Home | Next
8.121. I18N::Langinfo | Book Index | 8.123. I18N::LangTags::List
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.123. I18N::LangTags::List

Provides a lengthy and nearly comprehensive list of any language tags that you might need, from ab to zn. You should refer to the I18N::LangTags::List documentation for the list of these tags and what they represent.

I18N::LangTags::List implements the name() function that takes a language tag and returns its best attempt at an English name for it. If name() doesn't understand the language tag, it returns undef.

For example:

#!/usr/local/bin/perl -w
use I18N::LangTags::List;

my $tag = 'en-CA';
print "What is this tag aboot? ",
        I18N::LangTags::List::name($tag),

"\n";

Previous | Home | Next
8.122. I18N::LangTags | Book Index | 8.124. if
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.124. if

The if pragma "uses" a Perl module if a condition exists. For example:

use if CONDITION, MODULE => ARGUMENTS;
Previous | Home | Next
8.123. I18N::LangTags::List | Book Index | 8.125. integer
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.125. integer

Pragma that tells the compiler to use integer operations from here to the end of the enclosing block. Improves processing time on systems without floating-point hardware support.

use integer;

$x = 10/3;   # $x is now 3, not 3.33333333333333333

Use the no integer directive to turn off integer inside an inner block.

Previous | Home | Next
8.124. if | Book Index | 8.126. IO
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.126. IO

Loads all of the following IO modules with a single use statement: IO::Handle, IO::Seekable, IO::File, IO::Pipe, and IO::Socket.

Previous | Home | Next
8.125. integer | Book Index | 8.127. IO::File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.127. IO::File

Inherits from IO::Handle and IO::Seekable, extending them with methods specific to filehandles. Provides three such methods.

new
$fh = new ([params])

Constructor. Creates an IO::File object, passing any parameters to the method open. If the open fails, the object is destroyed. Otherwise, it is returned to the caller.

new_tmpfile
$fh = new_tmpfile

Constructor. Creates an IO::File object opened for read/write on a newly created temporary file. If the system permits, the temporary file is anonymous; if the temporary file cannot be created or opened, the object is destroyed. Otherwise, it is returned to the caller.

open
$fh->open(filename[, mode[, perms]])

Opens the newly created filehandle. Accepts one, two, or three parameters. With one parameter, it acts as a frontend for Perl's built-in open function. With two parameters, the first parameter is a filename, and the second is the open mode, optionally followed by a third parameter, the file permission value.

Previous | Home | Next
8.126. IO | Book Index | 8.128. IO::Handle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.128. IO::Handle

The base class for all other IO handle classes. Its main purpose is for the other IO classes to inherit from it; programs should not create IO::Handle objects directly. Provides the following methods.

new
new

Constructor. Creates a new IO::Handle object.

new_from_fd
new_from_fd (fd, mode)

Constructor. Like new, creates an IO::Handle object. It requires two parameters, which are passed to the method fdopen; if fdopen fails, the object is destroyed. Otherwise, it is returned to the caller.

clearerr
$fh->clearerr

Clears the given handle's error indicator.

error
$fh->error

Returns true if the given handle has experienced any errors since it was opened or since the last call to clearerr.

fdopen
$fh->fdopen (fd, mode)

Like an ordinary open except that the first parameter is a filehandle name, an IO::Handle object, or a file descriptor number.

flush
$fh->flush

Flushes the given handle's buffer.

getline
$fh->getline

Works like <$fh>, described in the section on "I/O Operators" in the perlop manpage, but is more readable and can be safely called in an array context, while still returning one line.

getlines
$fh->getlines

Works like <$fh> when called in an array context to read all the remaining lines in a file, but is more readable. croak s if called in scalar context.

opened
$fh->opened

Returns true if the object is currently a valid file descriptor.

ungetc
$fh->ungetc (ord)

Pushes a character with the ordinal value ord back onto the given handle's input stream.

untaint
$fh->untaint

Special method for working under -T and setuid/gid scripts. Marks the object as taint-clean, and as such, data read from it is also considered taint-clean.

write
$fh->write (buf, len[, offset])

Like write found in C; that is, the opposite of read. The wrapper for the Perl write function is format_write.

IO::Handle also provides the following methods, which are not described in detail here because they are simply frontends for the corresponding built-in functions. See Chapter 5, "Function Reference" for more information.

Method | Description
close | Closes file or pipe
eof | Returns 1 if next read will return end-of-file
fileno | Returns file descriptor for a filehandle
getc | Returns next character from input file
print | Prints a string or comma-separated list of strings
printf | Prints a formatted string
read | Reads data from a filehandle
stat | Returns an array of status information for a file
sysread | Reads data from a filehandle with system call read(2)
syswrite | Writes data to a filehandle with system call write(2)
truncate | Truncates a file to a specified length

Finally, the following methods act on the equivalent Perl variables. See Chapter 4, "The Perl Language" for more information.

Method | Description
autoflush | If nonzero, forces a flush now and after each write or print (default 0)
format_page_number | Current page number
format_lines_per_page | Current page length (default 60)
format_lines_left | Number of lines left on page
format_name | Name of current report format
format_top_name | Name of current top-of-page format
format_line_break_characters | Current set of linebreak chars for a format
format_formfeed | Formfeed char used by formats (default \f)
format_write | Wrapper for write function
input_record_separator | Input record separator (default newline)
input_line_number | Current input line number for last filehandle accessed
output_field_separator | Output field separator for print
output_record_separator | Output record separator for print
Previous | Home | Next
8.127. IO::File | Book Index | 8.129. IO::Pipe
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.129. IO::Pipe

Provides an interface for creating pipes between processes.

new
$pipe = new IO::Pipe([readfh, writefh])

Constructor. Creates an IO::Pipe object, which is a reference to a newly created symbol. The two optional arguments should be objects blessed into IO::Handle or one of its subclasses. These objects are used for the system call to pipe. With no arguments, the method handles is called on the new IO::Pipe object.

handles
$pipe->handles(  )

Called during construction by IO::Pipe::new on the newly created IO::Pipe object. Returns an array of two objects blessed into IO::Pipe::End, or a subclass.

reader
$pipe->reader([args])

Object is reblessed into a subclass of IO::Handle and becomes a handle at the reading end of the pipe. If there are any args, then fork is called, and the arguments are passed to exec.

writer
$pipe->writer([args])

The object is reblessed into a subclass of IO::Handle and becomes a handle at the writing end of the pipe. If there are any args, then fork is called, and the arguments are passed to exec.

Previous | Home | Next
8.128. IO::Handle | Book Index | 8.130. IO::Seekable
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.130. IO::Seekable

Intended to be inherited by other IO::Handle-based objects to provide methods that allow you to seek the file descriptors. Has no constructor.

use IO::Seekable;
package IO::XXX;
@ISA = qw(IO::Seekable);

Provides two methods.

seek
$fh->seek(offset, whence)

Frontend for the corresponding built-in seek function, which sets a filehandle's position in the file. Takes the following arguments:

offset
The offset where you want to set the position.

whence
The position in the file that the offset is relative to. Possible values are: 0 for the beginning of the file, 1 for the current position, or 2 for end of file. May also be expressed as the following constants, which are exported:

SEEK_SET
Beginning of file

SEEK_CUR
Current position

SEEK_END
End of file

tell
$fh->tell(  )

Frontend for the corresponding built-in tell function, which returns the current file position in bytes (starting from 0).

Previous | Home | Next
8.129. IO::Pipe | Book Index | 8.131. IO::Select
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.131. IO::Select

Implements an object-oriented approach to the system select function call. Allows the user to see which I/O handles are ready for reading, writing, or have an error condition pending.

new
new $s = IO::Select->new([handles])

Constructor. Creates a new object and optionally initializes it with a set of handles.

add
$s->add(handles)

Adds list of handles to the IO::Select object, to be returned when an event occurs. IO::Select keeps the list of handles in a cache, which is indexed by the handle's file number. Each handle can be an IO::Handle object, an integer, or a reference to an array, in which the first element is an IO::Handle object or an integer.

bits
$s->bits(  )

Returns the bit string that is suitable for use as an argument to the core select call.

can_read
$s->can_read([timeout])

Returns array of handles that are ready for reading. timeout is the maximum amount of time to wait before returning an empty list. If timeout is not given, and any handles are registered, then the call blocks.

can_write
$s->can_write([timeout])

Same as can_read, but checks for handles that can be written to.

count
$s->count(  )

Returns the number of handles that the object checks for when one of the can_ methods is called or the object is passed to the select static method.

exists
$s->exists(handle)

Returns the handle if it is present; otherwise, returns undef.

handles
$s->handles

Returns an array of all registered handles.

has_error
$s->has_error([timeout])

Same as can_read, but checks for handles that have an error condition.

remove
$s->remove(handles)

Removes all the given handles from the object, locating them by file number.

select
$s->select(read, write, error[, timeout])

Static method. Call it with the package name as with new. read, write, and error are either undef or IO::Select objects. The optional argument timeout has the same effect as for the core select call.

Returns an array of three elements, each a reference to an array or an empty array on error. The arrays hold the handles that are ready for reading, ready for writing, and have error conditions, respectively.

Previous | Home | Next
8.130. IO::Seekable | Book Index | 8.132. IO::Socket
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.132. IO::Socket

Provides an object interface to creating and using sockets. It is built on the IO::Handle interface and inherits all the methods defined by IO::Handle.

IO::Socket defines methods for only those operations that are common to all types of socket. IO::Socket exports all functions (and constants) defined by Socket. See Chapter 13, "XML and Perl" for detailed information.

Previous | Home | Next
8.131. IO::Select | Book Index | 8.133. IPC::Msg
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.133. IPC::Msg

System V Msg IPC object class. Uses constants defined in IPC::SysV.

new
$msg = new IPC::Msg(key, flags)

Creates a new message queue associated with key and uses flags to set the permissions. Creates the new message queue if the following are true:

  • key is equal to IPC_PRIVATE.

  • key doesn't already have an associated message queue, and FLAGS & IPC_CREAT is true.

id
$msg->id

Returns the system identifier for the message queue.

rcv
$msg->rcv(buf, len[, type[, flags]])

Reads a message from the queue, returning the type of the message.

remove
$msg->remove

Removes and destroys the message queue.

set
$msg->set(stat)
$msg->set(name=>value[,name=>value...])

Accepts either a stat object as returned by the stat method or a list of name/value pairs and sets the following values of the stat structure associated with the message queue:

uid
gid
mode (the permission bits)
qbytes
snd
$msg->snd(type, msg[, flags])

Puts a message of type type on the queue with the data from msg. See the msgsnd function.

stat
$ds = $msg->stat

Returns an object of type IPC::Msg::stat (which is a subclass of Class::Struct) that provides the following fields:

uid    gid    cuid    cgid
mode   qnum   qbytes  lspid
lrpid  stime  rtime   ctime

See the stat function and your system documentation for more information.

Previous | Home | Next
8.132. IO::Socket | Book Index | 8.134. IPC::Open2
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.134. IPC::Open2

Opens a child process that allows two-way communication between your program and the child. Returns the process ID of the child process or reports a fatal error on failure. Exports one function.

open2
open2 (\*rdr, \*wtr, cmd_with_args)

Forks a child process to execute the specified command. Takes the following arguments:

\*rdr
Represents a read filehandle that your program can use to read from the command $cmd's standard output. Can be a filehandle object or a reference to a typeglob.

\*wtr
Represents a write filehandle that your program can use to write to the command $cmd's standard input. Can be a filehandle object or a reference to a typeglob.

cmd_with_args
The command to be executed by the child process and its arguments. Can be specified two ways:

$cmd_with_args
$cmd, "arg1", "arg2", ...
Previous | Home | Next
8.133. IPC::Msg | Book Index | 8.135. IPC::Open3
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.135. IPC::Open3

IPC::Open3 works like IPC::Open2.

use IPC::Open3;

$pid = open3($wtr, $rdr, $err, $cmd_with_args);
$pid = open3($wtr, $rdr, $err, $cmd, "arg1", "arg2", ...);

The following differences apply:

  • The first two arguments ($wtr and $rdr) are passed in the opposite order.

  • A third filehandle can be passed, for standard error. If this argument is given as "", then STDERR and STDOUT for $cmd are on the same filehandle.

  • If $wtr begins with <, then the leading < is stripped from the name, and the remainder is assumed to be a regular filehandle for an open file, rather than a reference to a typeglob. open3 opens this file as STDIN for $cmd and closes it in the parent. Likewise, if $rdr or $err begins with >, then $cmd directs STDOUT or STDERR directly to that file rather than to the parent.

Previous | Home | Next
8.134. IPC::Open2 | Book Index | 8.136. IPC::Semaphore
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.136. IPC::Semaphore

System V Semaphore IPC object class. Uses constants defined in IPC::SysV.

new
$sem = new IPC::Semaphore(key, nsems, flags)

Creates a new semaphore set associated with key and containing nsems semaphores. Uses flags to set the permissions. Creates the new set if the following are true:

  • key is equal to IPC_PRIVATE.

  • key doesn't already have an associated semaphore identifier, and FLAGS & IPC_CREAT is true.

getall
$sem->getall

Returns the values of the semaphore set as an array.

getncnt
$sem->getncnt(sem)

Returns the number of processes waiting for the semaphore sem to become greater than its current value.

getpid
$sem->getpid(sem)

Returns the process ID of the last process that operated on semaphore sem.

getval
$sem->getval(sem)

Returns the current value of semaphore sem.

getzcnt
$sem->getzcnt(sem)

Returns the number of processes waiting for the semaphore sem to become 0.

id
$sem->id

Returns the system identifier for the semaphore set.

op
$sem->op(oplist)

Passes a list of operations to the semop function. oplist is the list of operations, consisting of a concatenation of smaller lists. Each of the smaller lists has three values: the semaphore number, the operation, and a flag. See the semop function in Chapter 5, "Function Reference" for more information.

remove
$sem->remove

Removes and destroys the semaphore set.

set
$sem->set(stat
$sem->set(name=>value[, name=>value...])

Accepts either a stat object as returned by the stat method or a list of name/value pairs and sets the following values of the stat structure associated with the semaphore set:

uid
gid
mode (the permission bits)
setall
$sem->setall(values)

Sets the values of all the semaphores in the set to those given by the values list. The number of values on the list must match the number of semaphores in the set.

setval
$sem->setval(n, value)

Sets the nth value in the semaphore set to value.

stat
$ds = $sem->stat

Returns an object of type IPC::Semaphore::stat (which is a subclass of Class::Struct) that provides the following fields:

uid    gid    cuid    cgid
mode   ctime  otime   nsems
Previous | Home | Next
8.135. IPC::Open3 | Book Index | 8.137. IPC::SysV
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.137. IPC::SysV

Defines and conditionally exports all the constants defined in your system include files that are needed by the System V IPC calls.

ftok
ftok (path, id)

Returns a key based on path and id for use by msgget, semget, and shmget.

Previous | Home | Next
8.136. IPC::Semaphore | Book Index | 8.138. less
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.138. less

Pragma, currently unimplemented, that may someday be a compiler directive to make certain trade-offs, such as:

use less 'memory';
Previous | Home | Next
8.137. IPC::SysV | Book Index | 8.139. lib
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.139. lib

Permits adding additional directories to Perl's default search path at compile time. The directories are added at the front of the search path.

use lib list;

adds the directories specified in list to @INC.

For each directory $dir in list, lib looks for an architecture-specific subdirectory that has an auto subdirectory under it—that is, it looks for $dir/$archname/auto. If it finds that directory, then $dir/$archname is also added to the front of @INC, preceding $dir.

Normally, you should only add directories to @INC. However, you can also delete directories. The statement:

no lib list

deletes the first instance of each named directory from @INC. To delete all instances of all the specified names from @INC, specify :ALL as the first parameter of list.

As with adding directories, lib checks for a directory called $dir/$archname/auto and deletes the $dir/$archname directory from @INC. You can restore @INC to its original value with:

@INC = @lib::ORIG_INC;
Previous | Home | Next
8.138. less | Book Index | 8.140. List::Util
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.140. List::Util

A collection of list-related subroutines. As of Perl 5.8, List::Util is included with the Perl source kit.

You can get the first item of a list (that matches the condition in BLOCK) like so:

#!/usr/local/bin/perl -w
use List::Util qw(first);

my @ll = qw(one two three);

my $fir = first { defined($_) } @ll;
print "$fir\n"; # Prints 'one'

List::Util implements (but does not export) the following methods.

first
first { BLOCK } @list

Evaluates a block of Perl code and sets $_ to each element of the list in turn. If BLOCK is true, first returns the first element. If BLOCK never returns true, or @list has no items, then first returns undef. Note that first doesn't necessarily return the first item in a list. Consider the following:

my @ll = qw(1 2 3);
my $fir = first { $_ > 1 } @ll;
print "$fir\n"; # Prints '2', since as 2 is the first item
                # in BLOCK that's > 1
max
max @list

Returns the entry in the list with the highest numerical value. If the list is empty, max returns undef:

my @ll = qw(100 294 2 4 95 73);
my $max_num = max @ll;
print "$max_num\n"; # Prints '294'
maxstr
maxstr @list

Similar to max, except that maxstr treats all list items as strings. maxstr will return the "highest string" as determined by the gt operator. As always, if list is empty, maxstr returns undef.

my @ll = qw(1 3 5 nate Person pizza man carl_everett dinosaur);
my $max_s = maxstr(@ll);
print "$max_s\n"; # Prints 'pizza'
min
min @list

Returns the lowest numerical value. If the list is empty, min returns undef.

minstr
minstr @list

Treats all list items as strings, but returns the "lowest string" as determined by the lt operator. If the list is empty, minstr returns undef.

reduce
reduce { BLOCK } @list

Literally "reduces" @list by calling BLOCK until there are no more items to operate on in @list. reduce sets $a and $b for each operation in BLOCK and returns the reduced list as a scalar. If @list is 0, BLOCK is not executed, and $list[0] is returned. If @list is empty, then reduce returns undef.

You can sum and concatenate a list using reduce like so:

my $sum_of_list = reduce { $a + $b } @ll; # sum
my $concat_list = reduce { $a . $b } @ll; # concat
shuffle
shuffle @LIST

Returns list items in random order.

sum
sum @LIST

Returns the sum of all items in the list. Note that sum deals only with numerical list items and will ignore any other list items. For example:

my @ll = qw(1 3 5 nate Person pizza man carl_everett dinosaur 6.54);
my $sum_of_list = sum(@ll);
print "$sum_of_list\n"; # Prints '15.54'
Previous | Home | Next
8.139. lib | Book Index | 8.141. locale
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.141. locale

Pragma that tells the compiler to disable (or enable) the use of POSIX locales for built-in operations (LC_CTYPE for regular expressions and LC_COLLATE for string comparison). Each no locale or use locale affects statements to the end of the enclosing block.

Previous | Home | Next
8.140. List::Util | Book Index | 8.142. Math::BigFloat
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.142. Math::BigFloat

Provides methods that permit use of floating-point numbers of arbitrary length. The following apply to all methods, except as noted:

  • The object $f remains unchanged.

  • All methods except fcmp return a number string (nstr) of the form /[+-]\d+E[+-]\d+/, with embedded whitespace ignored.

  • A return value of NaN indicates that either an input parameter was "Not a Number" or that an illegal operation was attempted.

  • A similar default scale value is computed for square roots.

new
$f = Math::BigFloat->new(string)

Creates a new object, $f.

fabs
$f->fabs(  )

Returns absolute value of $f.

fadd
$f->fadd(nstr)

Returns sum of nstr and $f.

fcmp
$f->fcmp(nstr)

Compares $f to nstr. Returns -1, 0, or 1 depending on whether $f is less than, equal to, or greater than nstr, or undef if nstr is not a number.

fdiv
$f->fdiv(nstr[,n])

Returns $f divided by nstr to nplaces. If scale (the number of digits) is unspecified, division is computed to the number of digits given by:

max($div_scale, length(dividend)+length(divisor))
ffround
$f->ffround(n)

Returns $f rounded at nth place.

fmul
$f->fmul(nstr)

Returns $f multiplied by nstr.

fneg
$f->fneg(  )

Returns negative of $f.

fnorm
$f->fnorm(  )

Returns normalization of $f.

fround
$f->fround(n)

Returns value of $frounded to n digits.

fsqrt
$f->fsqrt([n])

Returns square root of $f to n places.

fsub
$f->fsub(nstr)

Returns $f minus nstr.

Previous | Home | Next
8.141. locale | Book Index | 8.143. Math::BigInt
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.143. Math::BigInt

Allows use of arbitrary length integers, in which the following apply to all methods, except as noted:

  • The object $i remains unchanged.

  • Big integer strings (bints) have the form /^\s*[+-]?[\d\s]+$/.

  • All methods except bcmp return a big integer string or strings.

  • Embedded whitespace is ignored.

  • Output values are always in the canonical form: /^[+-]\d+$/.

  • The return value NaN results when an input argument is not a number, or when a divide by zero is attempted.

new
$i = Math::BigInt->new(string)

Creates a new object, $i.

babs
$i->babs

Returns absolute value of $i.

badd
$i->badd(bint)

Returns sum of bint and $i.

bcmp
$i->bcmp(bint)

Compares $i to bint. The bcmp method returns -1, 0, or 1 depending on whether $f is less than, equal to, or greater than the number string given as an argument. If the number string is undefined or null, undef is returned.

bdiv
$i->bdiv(bint)

Returns $i divided by bint. In list context, returns a two-element array containing the quotient of the division and the remainder; in scalar context, returns only the quotient.

bgcd
$i->bgcd(bint)

Returns greatest common divisor of $i and bint.

bmod
$i->bmod(bint)

Returns $i modulus bint.

bmul
$i->bmul(bint)

Returns $i multiplied by bint.

bneg
$i->bneg

Returns negative of $i.

bnorm
$i->bnorm

Returns normalization of $i.

bsub
$i->bsub(bint)

Returns $i minus bint.

Previous | Home | Next
8.142. Math::BigFloat | Book Index | 8.144. Math::BigInt::Calc
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.144. Math::BigInt::Calc

Supports big integer calculations. Math::BigInt::Calc allows you to use library modules for core math routines. This module is shipped with the Perl 5.8 source kit.

If you've written a module that uses the same API as Math::BigInt, you can use Math::BigInt::Calc as follows:

use Math::BigInt lib => 'yourlibname';
use Math::BigInt lib => 'Math::BigInt::yourlibname';

Math::BigInt exports the following functions, which must be defined in your module so Math::BigInt can support it:

_new(string)
Returns a reference to new object from reference to decimal string.

_zero()
Returns a new object with value 0.

_one()
Returns a new object with value 1.

_str(obj)
Returns a reference to a string representing the object.

_num(obj)
Returns a Perl integer or floating-point number. This may not necessarily be accurate, depending on machine-dependent, floating-point size limitations.

_add(obj, obj)
Allows simple addition of two objects.

_mul(obj, obj)
Allows multiplication of two objects.

_div(obj, obj)
Implements division of the first object by the second. In a list context, div() returns result, remainder.

_sub(obj, obj)
Implements simple subtraction of one object from another. A third, optional parameter indicates that the parameters are swapped.

_dec(obj)
Decrements object by one.

_inc(obj)
Increments object by one.

_acmp(obj, obj)
The <=> operator for objects, which returns -1, 0, or 1.

_len(obj)
Returns count of the decimal digits of the object.

_digit(obj, n)
Returns the nth decimal digit of object.

_is_one(obj)
Returns true if argument is 1.

_is_zero(obj)
Returns true if the argument is 0.

_is_even(obj)
Returns true if argument is even.

_is_odd(obj)
Returns true if argument is odd.

_copy()
Returns a reference to a true copy of the object.

_check(obj)
Checks whether the internal representation is still intact. Returns 0 for OK or an error message as a string.

The following functions are optional and can be defined if the underlying library can do them quickly. If undefined, Math::BigInt will use pure Perl fallback routines to emulate these. Note that falling back to Perl's routines will cause a performance hit.

_from_hex(string)
Returns a reference to a new object from a reference to a hexadecimal string.

_from_bin(string)
Returns a reference to a new object from a reference to a binary string.

_as_hex(string)
Returns a reference to a scalar string containing the value as an unsigned hex string. _as_hex() prepends the 0x, although you must strip all leading zeros.

_as_bin(string)
Similar to _as_hex(), except that it takes a binary string that contains only zeros and ones.

_rsft(obj, n, b)
Shifts object (right) in base B by n digits. Returns undef on failure.

_lsft(obj, n, b)
Shifts object in base b by n digits. Returns undef on failure.

_xor(obj1, obj2)
Does an XOR of object 1 with object 2.

_and(obj1, obj2)
Does an AND of object 1 with object 2.

_or(obj1, obj2)
Does an OR of object 1 with object 2.

_mod(obj1, obj2)
Returns remainder of division of the first object by the second object.

_sqrt(obj)
Returns the square root of the object.

_fac(obj)
Returns. factorial of object.

_pow(obj1, obj2)
Returns object 1 to the power of object 2.

_gcd(obj1, obj2)
Returns the greatest common divisor of two objects.

_zeros(obj)
Returns the number of trailing decimal zeros.

Previous | Home | Next
8.143. Math::BigInt | Book Index | 8.145. Math::BigRat
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.145. Math::BigRat

Allows you to use arbitrarily big rationals. Math::BigRat is shipped with the Perl 5.8 source kit.

For example:

#!/usr/local/bin/perl -w
use Math::BigRat;
my $rat = Math::BigRat->new('2/7');

print $rat->bstr(), "\n";

Math::BigRat implements the following methods.

new
new(value)

Creates a new Math::BigRat object. You can use all types of input for new(): '3/5', '2/33', '6/9', etc.

denominator
denominator()

Returns a copy of the denominator as a positive BigInt:

my $rat = Math::BigRat->new('2/7')

print $rat->denominator(), "\n"; # Prints 7
numerator
numerator()

Returns a copy of the numerator as a signed BigInt:

my $rat = Math::BigRat->new('2/7');
print $rat->numerator(), "\n"; # Prints 2
parts
parts()

Returns a list consisting of a signed numerator and unsigned denominator. Both are BigInts.

my($n, $d) = $rat->parts(); ### Ewwww, rat parts!
print "numerator: $n\n";
print "denominator: $d\n";
Previous | Home | Next
8.144. Math::BigInt::Calc | Book Index | 8.146. Math::Complex
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.146. Math::Complex

Provides support for complex numbers, including a full set of mathematical functions; permits creation and manipulation of complex numbers. Numerous overload and other operations are provided for working with complex numbers. See the documentation for the module for the complete list and also for a discussion of complex numbers. The following methods are provided.

emake
$z = Math::Complex->emake(args)

cplxe $z = cplxe(args)

Creates a complex number using the polar form.

display_format
display_format ([format])

When called as a method, sets display format for current object. If format is not specified, returns the current setting. Possible settings are:

c
Cartesian format

p
Polar format

When called as a function, overrides the default display format, which is Cartesian.

make
$z = Math::Complex->make(args)

cplx $z = cplx(args)

Creates a complex number using the Cartesian form.

Previous | Home | Next
8.145. Math::BigRat | Book Index | 8.147. Math::Trig
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.147. Math::Trig

Defines many trigonometric functions not defined by the core Perl, plus the constant pi and some additional functions for converting angles. For example:

use Math::Trig;

$x = tan(0.9);
$halfpi = pi/2;

The following functions are defined. A slash (/) between two functions means the values are aliases.

acsc/acosec, asec, acot/acotan
Arcus cofunctions of sine, cosine, and tangent

acsch/acosech, asech, acoth/acotanh
Arcus cofunctions of hyperbolic sine, cosine, and tangent

asin, acos, atan
Arcus (inverse) functions of sine, cosine, and tangent

asinh, acosh, atanh
Arcus functions of hyperbolic sine, cosine, and tangent

atan2(y, x)
Principal value of arc tangent of y/x

csc/cosec, sec, cot/cotan
Cofunctions of sine, cosine, and tangent

csch/cosech, sech, coth/cotanh
Cofunctions of hyperbolic sine, cosine, and tangent

deg2rad
Degrees to radians

deg2grad
Degrees to gradians

grad2deg
Gradians to degrees

grad2rad
Gradians to radians

pi
The trigonometric constant Figure 8.147

rad2deg
Radians to degrees

rad2grad
Radians to gradians

sinh, cosh, tanh
Hyperbolic sine, cosine, and tangent

tan
Tangent

Previous | Home | Next
8.146. Math::Complex | Book Index | 8.148. MIME::Base64
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.148. MIME::Base64

Provides functions to encode and decode strings into the Base64 encoding scheme as specified in RFC 2045 (dealing with MIME, or Multipurpose Internet Mail Extensions). Base64 encoding was designed to represent data in octets in an encoded form; all data is encoded using a 65-character subset, which is comprised of A-Z, a-z, 0-9+, /, and =. MIME::Base64 ships with the Perl source kit as of 5.8.

For example:

#!/usr/local/bin/perl -w
use MIME::Base64;
my $stone = 'purplebarneystone';
my $b64 = encode_base64($stone);
print "$b64\n";

MIME::Base64 implements the following functions, both of which are exported.

decode_base64
decode_base64(string)

Unpacks the base64-encoded string and returns the decoded data. In addition, decode_base64 ignores any character that's not part of the recognized 65-character base64 subset.

encode_base64
encode_base64(string, [end_of_line])

Base64-encodes string with the optional end_of_line argument. To base64-encode a JPEG image that lives in a file, you should specify end_of_line, since encode_base64 returns base64-encoded content that's broken down into 76 characters per line. If you do not want the 76-character breaks to be imposed on you, set end_of_line to an empty string ("").

Previous | Home | Next
8.147. Math::Trig | Book Index | 8.149. MIME::QuotedPrint
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.149. MIME::QuotedPrint

Provides functions to encode and decode strings into the quoted-printable encoding as specified in RFC 2045 (MIME). Quoted-printable encoding is used to represent data that's comprised of data that corresponds to ASCII characters. Nonprintable characters are represented by a triplet consisting of the = character followed by two hexadecimal digits. MIME::QuotedPrint ships with the Perl source kit as of 5.8.

MIME::QuotedPrint implements and exports the following functions.

decode_qp
decode_qp(string)

Returns the plain-text version of string, which is quoted-printable-encoded.

encode_qp
encode_qp(string)

Returns a quoted-printable-encoded version of string. The returned version of string will not be CRLF-terminated.

Previous | Home | Next
8.148. MIME::Base64 | Book Index | 8.150. NDBM_File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.150. NDBM_File

Provides Perl programs with tied access to NDBM database files. See Perl's built-in tie function and the DB_File module.

Previous | Home | Next
8.149. MIME::QuotedPrint | Book Index | 8.151. Net::Cmd
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.151. Net::Cmd

The network command class, which is required by all of the modules under the libnet umbrella: Net::FTP, Net::SMTP, Net::POP3, etc. In addition, Net::Cmd can be inherited by a subclass of IO::Handle. Unless you are writing a new module that will become a part of libnet, Net::Cmd probably doesn't have any servicable parts that you'd be interested in, since these parts are already implemented in the underlying modules. This module is part of the core Perl distribution starting with Perl 5.8.

Net::Cmd implements the following methods, which provide an interface to the Net::Cmd object.

code
code()

Returns the three-digit code from the last command. If the last command is still pending, code returns 0.

dataend
dataend()

Stops sending data to the remote server and ensures that a final CRLF has been sent.

datasend
datasend(data)

Sends data to the remote server, converting LF to CRLF. data can be an array or reference to an array.

debug
debug(level)

Sets the debug level for the object. If you do not specify a value, then no debugging information will be provided. If you specify undef as the value, then the debug level will be determined by the debug level of the class.

message
message()

Returns a text message from the last command.

ok
ok()

Returns nonzero if the last code value was greater than 0 and less than 400.

status
status()

Returns the current status code and, if pending, returns CMD_PENDING.

Net::Cmd implements the following class methods, which you should probably never touch at a user level.

command
command(command, [, args, ...])

Sends a command to the remote server. Returns undef on failure.

debug_print
debug_print(dir, text)

Outputs debugging information. dirrepresents data sent to the server, and text is the text that is sent.

debug_text
debug_text(text)

Prints debugging information.

getline
getline()

Retrieves one line, delimited by CRLF, from the remote server. Returns undef on failure.

parse_response
parse_response(text)

Returns an array of two values: the three-digit status code and a flag that is true when this is part of a multiline response. Called by response as a method with one argument.

read_until_dot
read_until_dot()

Reads data from the remote server until a line consisting of a single . is encountered. If the line matches .., one of the dots will be removed. Returns a reference to a list containing the lines or undef on failure.

response
response()

Obtains a response from the server. On success, it returns the status code, or undef on failure.

tied_fh
tied_fh()

Returns a filehandle tied to the Net::Cmd object. After you send a command, you can read from this filehandle with read() or from <>. Returns end-of-file when the final dot is encountered.

ungetline
ungetline(text)

Pushes back a line of text from the server.

unsupported
unsupported()

Sets the status code to 580 and the response to Unsupported command. Returns 0.

Net::Cmd exports CMD_INFO, CMD_OK, CMD_MORE, CMD_REJECT, CMD_ERROR, and CMD_PENDING.

Previous | Home | Next
8.150. NDBM_File | Book Index | 8.152. Net::Config
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.152. Net::Config

Holds configuration data for the modules in the libnet distribution. Net::Config builds this configuration interactively at install time of libnet, and the Net::Config file is further queried when you use modules such as Net::FTP. This module is part of the core Perl distribution starting with Perl 5.8.

Net::Config stores the following values (which can be undef): nntp_hosts, snpp_hosts, pop3_hosts, smtp_hosts, ph_hosts, daytime_hosts, and time_hosts. Each is a reference to an array of hostnames (in order of preference), which should be used for the given protocol. You can override any of the Net::Config values when you use any of the modules that live under the libnet umbrella. In addition, you can maintain your own .libnetrc to hold your custom values all the time. A sample .libnetrc follows:

$ cat .libnetrc
# .libnetrc
{
    nntp_hosts => [ "news.my.host", "news.their.host" ]
}
_  _END_  _

In addition to the options listed previously, the following options can be specified:

inet_domain
Your Internet domain name.

ftp_firewall
If you have an FTP proxy firewall (not an HTTP or SOCKS firewall), then this value should be set to the firewall hostname. If your firewall does not listen on port 21, then this value should be set to hostname:port (e.g., hostname:99).

ftp_firewall_type
An integer from 1 to 7 signifying the sequence of commands that Net::FTP will use to traverse a firewall, as follows:

*
There is no firewall (default).

1
USER user@remote.host
PASS password
2
USER firewall_username
PASS firewall_password
USER user@remote.host
PASS pass
3
USER firewall_username
PASS firewall_password
SITE remote.site
USER user
PASS pass
4
USER firewall_username
PASS firewall_password
OPEN remote.site
USER user
PASS pass
5
USER user@firewall_username@remote.site
PASS pass@firewall_password
6
USER firewall_username@remote.site
PASS firewall_password
USER user
PASS pass
7
USER user@remote.host
PASS pass
AUTH firewall_username
RESP firewall_password
ftp_ext_passive
ftp_int_passive
FTP servers normally work in a nonpassive mode: when you want to transfer data, you have to tell the server the address and port to connect to. This becomes a problem because some servers cannot connect to your machine through the second port because it's being used by the FTP connection. In this case, set ftp_ext_passive to true.

If your server is configured to only work in passive mode, you can force Net::FTP to always transfer in passive mode when not going via a firewall by setting ftp_int_passive to true.

local_netmask
A reference to a list of netmask strings. To be used by the requires_firewall function to determine if a given host is inside or outside your firewall.

The following method is supported by Net::Config.

requires_firewall
requires_firewall(host)

Determines if host is outside of your firewall. Possible return values are:

-1
Cannot look up hostname

0
Host is inside firewall (or there is no FTP_firewall entry)

1
Host is outside the firewall

Previous | Home | Next
8.151. Net::Cmd | Book Index | 8.153. Net::Domain
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.153. Net::Domain

Attempts to evaluate the current host's Internet name and domain using several methods. This module is part of the core Perl distribution starting with Perl 5.8.

For example, each of the following Net::Domain functions will return undef if the FQDN cannot be determined.

hostdomain
hostdomain()

Returns the remainder of the FQDN after the hostname has been removed.

hostfqdn
hostfqdn()

Identifies and returns the FQDN of the current host.

hostname
hostname()

Returns the smallest part of the FQDN that can be used to identify the host.

Previous | Home | Next
8.152. Net::Config | Book Index | 8.154. Net::FTP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.154. Net::FTP

Implements a simple FTP client in Perl (see Chapter 16, "Email Connectivity"). This module is part of the core Perl distribution starting with Perl 5.8.

Previous | Home | Next
8.153. Net::Domain | Book Index | 8.155. Net::hostent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.155. Net::hostent

Overrides the core gethostbyname and gethostbyaddr functions with object-oriented versions that return Net::hostent objects. The objects have methods that return the fields of the same name from the hostent structure in netdb.h:

Field | Description
addr | Address of host, for backward compatibility
addr_list | List of addresses returned from name server
addrtype | Host address type
aliases | List of aliases
length | Length of address
name | Name of host

You can access the structure fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and accessing them by prepending h_ to the field name:

$host_obj->name( )
$h_name

Net::hostent exports the following.

gethost
gethost (host)

Frontend for gethostbyaddr and gethostbyname. If hostis numeric, calls gethostbyaddr; otherwise, calls gethostbyname.

gethostbyaddr
gethostbyaddr (addr, addrtype)

Returns information about the host with address addr of type addrtype.

gethostbyname
gethostbyname (hostname)

Returns information about the host with name hostname.

Previous | Home | Next
8.154. Net::FTP | Book Index | 8.156. Net::netent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.156. Net::netent

Returns information for a network. Overrides the core getnetbyname and getnetbyaddr functions with object-oriented versions that return Net::netent objects. The objects have methods that return the fields of the same name from the netent structure in netdb.h:

Field | Description
addrtype | Net address type
aliases | Array of aliases
name | Name of net
net | Network number

You can access the structure fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and accessing them by prepending n_ to the field name:

$net_obj->name( )
$n_name

Net::netent exports the following.

getnet
getnet (net)

Frontend for getnetbyaddr and getnetbyname. If net is numeric, calls getnetbyaddr; otherwise, calls getnetbyname.

getnetbyaddr
getnetbyaddr (addr, addrtype)

Returns information about the net with address addr of type addrtype.

getnetbyname
getnetbyname (netname)

Returns information about the net with name netname.

Previous | Home | Next
8.155. Net::hostent | Book Index | 8.157. Net::Netrc
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.157. Net::Netrc

Implements a simple interface to .netrc in Perl (see Chapter 16, "Email Connectivity"). This module is part of the core Perl distribution starting with Perl 5.8.

Previous | Home | Next
8.156. Net::netent | Book Index | 8.158. Net::NNTP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.158. Net::NNTP

Implements a simple NNTP client in Perl (see Chapter 17, "Usenet News"). This module is part of the core Perl distribution starting with Perl 5.8.

Previous | Home | Next
8.157. Net::Netrc | Book Index | 8.159. Net::Ping
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.159. Net::Ping

Provides methods to create ping objects and test the reachability of remote hosts on the network. After the object has been created, a variable number of hosts can be pinged multiple times before closing the connection. The methods are the following.

new
$p = Net::Ping->new([proto[, def_timeout[, bytes]]])

Creates a new ping object. All arguments are optional. Takes the following arguments:

proto
The protocol to use when doing a ping. Default is udp. The possible protocols are:

icmp
Sends an icmp echo message to the remote host. If the echoed message is received back correctly from the remote host, that host is considered reachable. Requires the program to be run as root or setuid to root.

tcp
Attempts to establish connection to remote host's echo port. If successful, remote host is considered reachable. No data is actually echoed. No special privileges are required, but overhead is higher than for the others.

udp
Sends a udp packet to remote host's echo port. If the echoed packet is received back from the remote host and contains the same data that was sent, the remote host is considered reachable. Requires no special privileges.

def_timeout
Default timeout in seconds to be used if timeout not passed to the ping method. Must be greater than zero; defaults to five seconds.

bytes
Number of bytes included in the ping packet sent to the remote host. Ignored if protocol is tcp. Default is 1 if protocol is udp, otherwise 0. These are also the minimum number of bytes; the maximum is 1,024.

close
$p->close(  )

Closes network connection for this ping object. The connection can also be closed by undef $p and is automatically closed if the ping object goes out of scope.

ping
$p->ping(host[, timeout])

Pings remote host and waits for a response. Takes the following arguments:

host
Specified as either the hostname or the IP number of the remote host.

timeout
Optional, must be greater than 0 seconds if specified. Defaults to whatever was specified when the ping object was created.

If host cannot be found, or if there is a problem with the IP number, returns undef. Otherwise, returns 1 if the host is reachable and 0 if it is not.

pingecho
pingecho (host[, timeout])

Provides backward compatibility with the previous version of Net::Ping. Uses the tcp protocol, with return values and parameters the same as described for ping.

Previous | Home | Next
8.158. Net::NNTP | Book Index | 8.160. Net::POP3
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.160. Net::POP3

Implements a simple POP3 client in Perl (see Chapter 17, "Usenet News"). This module is part of the core Perl distribution starting with Perl 5.8.

Previous | Home | Next
8.159. Net::Ping | Book Index | 8.161. Net::protoent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.161. Net::protoent

Returns information for an Internet protocol. Overrides the core getprotoent, getprotobyname, and getprotobynumber functions with object-oriented versions that return Net::protoent objects. The functions take a default second argument of tcp. The objects have methods that return the fields of the same name from the protoent structure in netdb.h:

Field | Description
aliases | List of aliases
name | Name of host
proto | Protocol

You can access the structure fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and accessing them by prepending p_ to the field name:

$proto_obj->name( )
$p_name
getproto
getproto (protocol)

Frontend for getprotobynumber and getprotobyname. If protocol is numeric, calls getprotobynumber; otherwise, calls getprotobyname.

getprotobyname
getprotobyname (addr, addrtype)

Returns information about the host with address addr of type addrtype.

getprotobynumber
getprotobynumber (hostname)

Returns information about the host with name hostname.

getprotoent
getprotoent (protocol)

Frontend for getprotobynumber and getprotobyname. If protocol is numeric, calls getprotobynumber; otherwise, calls getprotobyname.

Previous | Home | Next
8.160. Net::POP3 | Book Index | 8.162. Net::servent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.162. Net::servent

Returns information for an Internet service. Overrides the core getservent, getservbyname, and getservbyport functions, replacing them with versions that return Net::servent objects. The functions take a default second argument of tcp. The objects have methods that return the fields of the same name from the servent structure in netdb.h:

Field | Description
aliases | List of aliases
name | Name of service
port | Port
proto | Protocol to use

You can access the structure fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and accessing them by prepending s_ to the field name:

$serv_obj->name( )
$s_name
getserv
getserv(service)

Frontend for getservbyport and getservbyname. If service is numeric, calls getservbyport; otherwise, calls getservbyname.

getservbyname
getservbyname(name)

Returns information for the Internet service with protocol name name.

getservbyport
getservbyport(port)

Returns information for the Internet service with port number port.

getservent
getservent

Returns entries from the database of Internet services.

Previous | Home | Next
8.161. Net::protoent | Book Index | 8.163. Net::SMTP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.163. Net::SMTP

Implements a simple SMTP client in Perl (see Chapter 16, "Email Connectivity"). This module is part of the core Perl distribution starting with Perl 5.8.

Previous | Home | Next
8.162. Net::servent | Book Index | 8.164. Net::Time
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.164. Net::Time

Provides subroutines that obtain the time on a remote machine. This module is part of the core Perl distribution starting with Perl 5.8.

Net::Time implements the following functions.

inet_daytime
inet_daytime( [host [, protocol [, timeout]]])

Obtains the time on host , or a default host if host is not given. inet_daytime uses protocol, which can be either udp or tcp. Returns an ASCII string or undef on failure.

inet_time
inet_time( [host [, protocol [, timeout]]])

Obtains the time on host, or a default host if host is not given. inet_time uses protocol, which can be either udp or tcp. Returns some units of time on success or undef on failure.

Previous | Home | Next
8.163. Net::SMTP | Book Index | 8.165. O
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.165. O

Generic interface to the Perl compiler backends. See also the B module.

perl -MO=backend[,options] perlscript
Previous | Home | Next
8.164. Net::Time | Book Index | 8.166. ODBM_File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.166. ODBM_File

Provides Perl programs with tied access to ODBM database files. See Perl's built-in tie function and the DB_File module.

Previous | Home | Next
8.165. O | Book Index | 8.167. Opcode
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.167. Opcode

Permits defining an operator mask (opmask) so that any code containing a masked opcode will not compile or execute when Perl next compiles any code. Not usually used directly; for examples of Opcode's use, see the ops pragma and the Safe module.

Valid opcodes are listed in the array op_name in the file opcode.h. Many Opcode functions and methods take lists of operators, which are composed of elements. Each element can be a:

name (opname) or negated name
Name of operator, usually lowercase. Prefixing the name with an exclamation mark (!) removes it from the accumulated set of operations.

set (opset)
Operator set. Binary string holding a set of zero or more operators.

tag name (optag) or negated tag
Operator tag name; refers to groups (or sets) of operators. Begins with a colon (:). Negated by prefixing with an exclamation mark (!). Several optags are predefined, including the following. See the Opcode module's manpage for the opcodes included in each tag.

:base_core      :base_io        :base_loop
:base_math      :base_mem       :base_orig
:browse         :dangerous      :default
:filesys_open   :filesys_read   :filesys_write
:others         :ownprocess     :still_to_be_decided
:subprocess     :sys_db

8.167.1. Functions

All the following functions can be exported.

define_optag
define_optag (optag, opset)

Defines optag as symbolic name for the set opset.

empty_opset
empty_opset

Returns an empty opset.

full_opset
full_opset

Returns an opset that includes all operators.

invert_opset
invert_opset (opset)

Returns an opset that is the inverse of opset.

opcodes
opcodes

In scalar context, returns the number of opcodes in this version of Perl.

opdesc
opdesc (op, ...)

Takes list of operator names and returns the corresponding list descriptions.

opdump
opdump ([pat])

Writes two-column list of operator names and descriptions to STDOUT. If pat is specified, only lines matching the (case-insensitive) pattern are output.

opmask
opmask

Returns an opset corresponding to the current opmask.

opmask_add
opmask_add (opset)

Adds opset to the current opmask.

opset
opset (op, ...)

Returns an opset containing the listed operators.

opset_to_hex
opset_to_hex (opset)

Returns string representation of opset.

opset_to_ops
opset_to_ops (opset)

Returns list of operator names corresponding to the operators in the set opset.

verify_opset
verify_opset (opset[, ...])

Returns true if opset appears to be a valid opset, else returns false. croak s instead of returning false if optional second parameter is true.

Previous | Home | Next
8.166. ODBM_File | Book Index | 8.168. ops
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.168. ops

Pragma that disables unsafe opcodes during compilation. Can also be used to specify opcodes to be disabled. Generally used with the -M option on the command line:

perl -Mops=:default ...    # Allow only reasonably safe operations
perl -M-ops=system ...     # Disable system opcode

See the Opcode module for more information.

Previous | Home | Next
8.167. Opcode | Book Index | 8.169. overload
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.169. overload

Lets you substitute class methods or your own subroutines for standard Perl operators. For example, the code:

package Number;
use overload
    "+"  => \add,
    "*=" => "muas";

declares function add for addition and method muas in the Number class (or one of its base classes) for the assignment form *= of multiplication.

Arguments to use overload are key/value pairs, in which the key is the operation being overloaded, and the value is the function or method that is to be substituted. Legal values are values permitted inside a &{ ... } call, so a subroutine name, a subroutine reference, or an anonymous subroutine are all legal. Legal keys (overloadable operations) are:

Type | Operations
Arithmetic | + - * / % ** << >> x . += -= *= /= %= **= <<= >>= x= .=
Comparison | < <= > >= == != <=> lt le gt ge eq ne cmp
Bit and unary | % ^ | neg ! ~
Increment, decrement | ++ -
Transcendental | atan2 cos sin exp abs log sqrt
Boolean, string, numeric conversion | bool "" 0+
Special | nomethod fallback =

The functions specified with the use overload directive are typically called with three arguments. If the corresponding operation is binary, then the first two arguments are the two arguments of the operation. However, the first argument should always be an object in the package, so in some cases, the order of the arguments will be interchanged before the method is called. The third argument provides information on the order and can have these values:

False (0)
The order of arguments is as in the current operation.

True (1)
The arguments are reversed.

Undefined (undef)
The current operation is an assignment variant, but the usual function is called instead.

Unary operations are considered binary operations with the second argument undefined.

The special nomethod key should be followed by a reference to a function of four parameters and called when the overloading mechanism cannot find a method for an operation. The first three arguments are the arguments for the corresponding method if it was found; the fourth argument is the symbol corresponding to the missing method. If several methods are tried, the last one is used.

For example, 1-$a can be equivalent to:

&nomethodMethod($a, 1, 1, "-")

if the pair "nomethod" => "nomethodMethod" was specified in the use overload directive.

The special fallback key governs what to do if a method for a particular operation is not found. There are three possible cases, depending on the value associated with the fallback key:

Undefined
Tries to use a substituted method. If that fails, it tries to call the method specified for nomethod; if that also fails, an exception is raised.

True
The same as undefined, but no exception is raised. Instead, Perl silently reverts to non-overloaded operation.

Defined, but false
Tries to call the method specified for nomethod; if that fails, an exception is raised.

The overload module provides the following public functions.

Method
overload::Method(obj, op)

Returns the undefined value or a reference to the method that implements op.

Overloaded
overload::Overloaded(arg)

Returns true if arg is subject to overloading of some operations.

StrVal
overload::StrVal(arg)

Gives string value of arg if stringify overloading is absent.

Previous | Home | Next
8.168. ops | Book Index | 8.170. PerlIO
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.170. PerlIO

An on-demand loader for PerlIO layers and the root of the PerlIO namespace. PerlIO allows you to expand the functionality of open(). For example:

use PerlIO 'special';

The code in PerlIO.pm then attempts to find 'special':

require PerlIO::special;

PerlIO currently defines the following layers:

unix
Low-level layer that calls read, write, lseek, etc.

stdio
Calls fread, fwrite, fseek, ftell, etc. stdio will use your operating system's I/O via the C library. That is, you cannot place any layers beneath stdio.

perlio
A reimplementation of a stdio-like buffering written as a PerlIO layer. As such, it will call whatever layer is below it for its operations.

crlf
Does CRLF translation depending on distinguishing text, and binary files a la MS-DOS.

utf8
Declares that the stream accepts Perl's internal encoding of characters (which is really UTF-8 on ASCII machines and UTF-EBCDIC on EBCDIC machines). This allows any character Perl can represent to be read from or written to the stream. The UTF-X encoding is chosen to render simple text parts (i.e., nonaccented letters, digits, and common punctuation) human-readable in the encoded file.

raw
A pseudo-layer that performs two functions. It forces the filehandle to be considered binary at that point in the layer stack, and it prevents the I/O system from searching before it in the layer specification. For example:

open($fh,":raw:perlio",...);

raw forces the use of the perlio layer even if the platform default or the use open default is something else (such as :encoding(iso-8859-7)).

Previous | Home | Next
8.169. overload | Book Index | 8.171. PerlIO::Scalar
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.171. PerlIO::Scalar

Supports in-memory I/O. It exists so it can use XSLoader to load C code that supports treating a scalar as an "in-memory" file. PerlIO::Scalar allows all normal file operations to be performed on the handle. Returns undef.

For example:

#!/usr/local/bin/perl -w
use PerlIO::Scalar;
open($fh, "<...", \$some_scalar);

This module is part of the core Perl distribution starting with Perl 5.8.

Previous | Home | Next
8.170. PerlIO | Book Index | 8.172. PerlIO::Via
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.172. PerlIO::Via

A helper class for PerlIO layers implemented in Perl. PerlIO::Via ships with the Perl 5.8 source kit.

For example, you can use PerlIO::Via to call MIME::Base64::encode_base64() via open():

#!/usr/local/bin/perl -w;
use MIME::Base64;
open(my $fh, ">Via(MIME::Base64)", "encode_base64");

PerlIO::Via implements the following methods.

CLOSE
CLOSE(fh)

Returns 0 on success and -1 on error.

EOF
EOF(fh)

Returns end-of-file state. The default behavior is to return a value of FILL() or READ().

ERROR
ERROR(fh)

Returns error state.

FILENO
FILENO(fh)

Returns a numeric value that represents the Unix-like file descriptor, or -1 if no file descriptor exists.

FILL
FILL(fh)

Returns a string that will be placed in the buffer.

FLUSH
FLUSH(fh)

Flushes any buffered write data. Returns 0 on success and -1 on error.

POPPED
POPPED([fh])

Removes a layer from PerlIO::Via.

PUSHED
$class->PUSHED([mode [,fh]])

Returns an object or the class, or -1 on failure. PUSHED takes optional arguments for file open mode—r, w, w+, etc.—and takes a mandatory filehandle for the PerlIO layer itself.

READ
READ(buffer, len, fh)

Returns the number of octets in buffer, which must be less than or equal to len.

SEEK
SEEK(posn, where, fh)

Returns 0 on success and -1 on error.

TELL
TELL(fh)

Returns the file position, without an available default.

UNREAD
UNREAD(buffer, fh)

Returns the number of octets from bufferthat have been successfully saved.

WRITE
WRITE(buffer, fh)

Returns the number of octets in buffer that have been written.

Previous | Home | Next
8.171. PerlIO::Scalar | Book Index | 8.173. Pod::Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.173. Pod::Functions

Used internally by Pod::Html for converting from pod to HTML.

Previous | Home | Next
8.172. PerlIO::Via | Book Index | 8.174. Pod::Html
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.174. Pod::Html

Converts files from pod to HTML format. Not generally used directly, but via the pod2html script (see Chapter 4, "The Perl Language"), which is included in the standard distribution.

Previous | Home | Next
8.173. Pod::Functions | Book Index | 8.175. Pod::ParseLink
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.175. Pod::ParseLink

Parses an L<> formatting code in POD text. It implements a single function, parselink(), which takes the text of an L<> formatting code and parses it. parselink() returns the anchor text for the link, the anchor text possibly inferred from the name and section, the name or URL, and the section and the type of link. The link type will be url, pod, or man. For example:

#!/usr/local/bin/perl -w
use Pod::ParseLink;
my $link = 'L<http://www.some-site.com/indexes/index.html>';
my ($text, $inferred, $name, $section, $type) = parselink ($link);
Previous | Home | Next
8.174. Pod::Html | Book Index | 8.176. Pod::Text
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.176. Pod::Text

Converts files from pod format to formatted ASCII text. Not generally used directly, but via the pod2text script (see Chapter 4, "The Perl Language"). Termcap is optionally supported for boldface and underlining and can be enabled with:

$Pod::Text::termcap=1

Otherwise, backspaces are used to simulate bold and underlined text. Exports one function.

pod2text
pod2text (filename[, filehandle])

Converts from pod to text format. Takes the following arguments:

filename
File to convert, or <&STDIN to read from STDIN.

filehandle
Optional. Filehandle glob to which output should be sent (*STDOUT to write to STDOUT).

Previous | Home | Next
8.175. Pod::ParseLink | Book Index | 8.177. POSIX
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.177. POSIX

Provides access to standard POSIX 1003.1 identifiers: functions, classes, and constants. Can be use d to import one or multiple symbols:

use POSIX;                        # Import all symbols
use POSIX qw(setsid);             # Import one symbol
use POSIX qw(:errno_h :fcntl_h);  # Import sets of symbols

Functions listed as C-specific are not implemented.

Function | Description
_exit | Identical to C function _exit(2)
abort | Identical to C function abort(3)
abs | Identical to Perl's abs function
access | Determines accessibility of a file; returns undef on failure
acos | Identical to C function acos(3)
alarm | Identical to Perl's alarm function
asctime | Identical to C function asctime(3)
asin | Identical to C function asin(3)
assert | Similar to C macro assert(3)
atan | Identical to C function atan(3)
atan2 | Identical to Perl's atan2 function
atexit | C-specific; use END {}
atof | C-specific
atoi | C-specific
atol | C-specific
bsearch | Not supplied
calloc | C-specific
ceil | Identical to C function ceil(3)
chdir | Identical to Perl's chdir function
chmod | Identical to Perl's chmod function
chown | Identical to Perl's chown function
clearerr | Uses method FileHandle::clearerr
clock | Identical to C function clock(3)
close | Closes a file; returns undef on failure
closedir | Identical to Perl's closedir function
cos | Identical to Perl's cos function
cosh | Identical to C function cosh(3)
creat | Creates a new file
ctermid | Generates pathname for the controlling terminal
ctime | Identical to C function ctime(3)
cuserid | Gets user's login name
difftime | Identical to C function difftime(3)
div | C-specific
dup | Similar to C function dup(2); returns undef on failure
dup2 | Similar to C function dup2(2); returns undef on failure
errno | Returns the value of errno
execl | C-specific; use Perl's exec
execle | C-specific; use Perl's exec
execlp | C-specific; use Perl's exec
execv | C-specific; use Perl's exec
execve | C-specific; use Perl's exec
execvp | C-specific; use Perl's exec
exit | Identical to Perl's exit function
exp | Identical to Perl's exp function
fabs | Identical to Perl's abs function
fclose | Uses method FileHandle::close
fcntl | Identical to Perl's fcntl function
fdopen | Uses method FileHandle::new_from_fd
feof | Uses method FileHandle::eof
ferror | Uses method FileHandle::error
fflush | Uses method FileHandle::flush
fgetc | Uses method FileHandle::getc
fgetpos | Uses method FileHandle::getpos
fgets | Uses method FileHandle::gets
fileno | Uses method FileHandle::fileno
floor | Identical to C function floor(3)
fmod | Identical to C function fmod(3)
fopen | Uses method FileHandle::open
fork | Identical to Perl's fork function
fpathconf | Returns value of a configurable limit on a file or directory, or undef on failure
fprintf | C-specific; use Perl's printf function
fputc | C-specific; use Perl's print function
fputs | C-specific; use Perl's print function
fread | C-specific; use Perl's read function
free | C-specific
freopen | C-specific; use Perl's open function
frexp | Returns mantissa and exponent of a floating-point number
fscanf | C-specific; use <> and regular expressions
fseek | Uses method FileHandle::seek
fsetpos | Uses method FileHandle::setpos
fstat | Gets file status
ftell | Uses method FileHandle::tell
fwrite | C-specific; use Perl's print function
getc | Identical to Perl's etc function
getchar | Returns one character from STDIN
getcwd | Returns name of current working directory
getegid | Returns effective group ID (gid)
getenv | Returns value of the specified environment variable
geteuid | Returns the effective user ID (uid)
getgid | Returns the user's real group ID (gid)
getgrgid | Identical to Perl's getgrgid function
getgrnam | Identical to Perl's getgrnam function
getgroups | Returns IDs of the user's supplementary groups
getlogin | Identical to Perl's getlogin function
getpgrp | Identical to Perl's getpgrp function
getpid | Returns ID of the process (pid)
getppid | Identical to Perl's getppid function
getpwnam | Identical to Perl's getpwnam function
getpwuid | Identical to Perl's getpwuid function
gets | Returns one line from STDIN
getuid | Returns user's ID (uid)
gmtime | Identical to Perl's gmtime function
isalnum | Identical to C function, but can apply to one character or a whole string
isalpha | Identical to C function, but can apply to one character or a whole string
isatty | Returns Boolean indicating whether the specified filehandle is connected to a TTY
iscntrl | Identical to C function, but can apply to one character or a whole string
isdigit | Identical to C function, but can apply to one character or a whole string
isgraph | Identical to C function, but can apply to one character or a whole string
islower | Identical to C function, but can apply to one character or a whole string
isprint | Identical to C function, but can apply to one character or a whole string
ispunct | Identical to C function, but can apply to one character or a whole string
isspace | Identical to C function, but can apply to one character or a whole string
isupper | Identical to C function, but can apply to one character or a whole string
isxdigit | Identical to C function, but can apply to one character or a whole string
kill | Identical to Perl's kill function
labs | C-specific; use Perl's abs function
ldexp | Identical to C function ldexp(3)
ldiv | C-specific; use division operator (/) and Perl's int function
link | Identical to Perl's link function
localeconv | Gets numeric formatting information; returns reference to a hash containing the current locale formatting values
localtime | Identical to Perl's localtime function
log | Identical to Perl's log function
log10 | Identical to C function log10(3)
longjmp | C-specific; use Perl's die function
lseek | Moves the read/write file pointer; returns undef on failure
malloc | C-specific
mblen | Identical to C function mblen(3)
mbstowcs | Identical to C function mbstowcs(3)
mbtowc | Identical to C function mbtowc(3)
memchr | C-specific; use Perl's index
memcmp | C-specific; use eq
memcpy | C-specific; use =
memmove | C-specific; use =
memset | C-specific; use x
mkdir | Identical to Perl's mkdir function
mkfifo | Similar to C function mkfifo(2); returns undef on failure
mktime | Converts date/time information to a calendar time; returns undef on failure
modf | Returns integral and fractional parts of a floating-point number
nice | Similar to C function nice(3); returns undef on failure
offsetof | C-specific
open | Opens file for reading or writing; returns undef on failure
opendir | Opens directory for reading; returns undef on failure
pathconf | Retrieves value of a configurable limit on a file or directory; returns undef on failure
pause | Similar to C function pause(3); returns undef on failure
perror | Identical to C function perror(3)
pipe | Creates an interprocess channel
pow | Computes $x raised to the power $exponent
printf | Prints specified arguments to STDOUT
putc | C-specific; use Perl's print function
putchar | C-specific; use Perl's print function
puts | C-specific; use Perl's print function
qsort | C-specific; use Perl's sort function
raise | Sends specified signal to current process
rand | Nonportable; use Perl's rand function
read | Reads from a file; returns undef on failure
readdir | Identical to Perl's readdir function
realloc | C-specific
remove | Identical to Perl's unlink function
rename | Identical to Perl's rename function
rewind | Seeks to beginning of file
rewinddir | Identical to Perl's rewinddir function
rmdir | Identical to Perl's rmdir function
scanf | C-specific; use <> and regular expressions
setgid | Sets real group ID for this process
setjmp | C-specific; use eval {}
setlocale | Modifies and queries program's locale
setpgid | Similar to C function setpgid(2); returns undef on failure
setsid | Identical to C function setsid(8)
setuid | Sets real user ID for this process
sigaction | Detailed signal management; returns undef on failure
siglongjmp | C-specific; use Perl's die function
sigpending | Examines blocked, pending signals; returns undef on failure
sigprocmask | Changes and/or examines this process's signal mask; returns undef on failure
sigsetjmp | C-specific; use eval {}
sigsuspend | Installs signal mask and suspends process until signal arrives; returns undef on failure
sin | Identical to Perl's sin function
sinh | Identical to C function sinh(3)
sleep | Identical to Perl's sleep function
sprintf | Identical to Perl's sprintf function
sqrt | Identical to Perl's sqrt function
srand | Identical to Perl's srand function
sscanf | C-specific; use regular expressions
stat | Identical to Perl's stat function
strcat | C-specific; use .=
strchr | C-specific; use index
strcmp | C-specific; use eq
strcoll | Identical to C function strcoll(3)
strcpy | C-specific; use =
strcspn | C-specific; use regular expressions
strerror | Returns error string for the specified errno
strftime | Converts date and time to string and returns the string
strlen | C-specific; use length
strncat | C-specific; use .= and/or substr
strncmp | C-specific; use eq and/or substr
strncpy | C-specific; use = and/or substr
stroul | C-specific
strpbrk | C-specific
strrchr | C-specific; use rindex and/or substr
strspn | C-specific
strstr | Identical to Perl's index function
strtod | C-specific
strtok | C-specific
strtol | C-specific
strtoul | C-specific
strxfrm | String transformation; returns the transformed string
sysconf | Retrieves values of system configurable variables; returns undef on failure
system | Identical to Perl's system function
tan | Identical to C function tan(3)
tanh | Identical to C function tanh(3)
tcdrain | Similar to C function tcdrain(3); returns undef on failure
tcflow | Similar to C function tcflow(3); returns undef on failure
tcflush | Similar to C function tcflush(3); returns undef on failure
tcgetpgrp | Identical to C function tcgetpgrp(3)
tcsendbreak | Similar to C function tcsendbreak(3); returns undef on failure
tcsetpgrp | Similar to C function tcsetpgrp(3); returns undef on failure
time | Identical to Perl's time function
times | Returns, in clock ticks, elapsed realtime since a point in the past, user and system times for this process, and user and system times for child processes
tmpfile | Uses method FileHandle::new_tmpfile
tmpnam | Returns a name for a temporary file
tolower | Identical to Perl's lc function
toupper | Identical to Perl's uc function
ttyname | Identical to C function ttyname(3)
tzname | Retrieves time conversion information from the tzname variable
tzset | Identical to C function tzset(3)
umask | Identical to Perl's umask function
uname | Gets name of current operating system
ungetc | Uses method FileHandle::ungetc
unlink | Identical to Perl's unlink function
utime | Identical to Perl's utime function
vfprintf | C-specific
vprintf | C-specific
vsprintf | C-specific
wait | Identical to Perl's wait function
waitpid | Waits for child process to change state; identical to Perl's waitpid function
wcstombs | Identical to C function wcstombs(3)
wctomb | Identical to C function wctomb(3)
write | Writes to file; returns undef on failure

The following sections show the classes that are defined and their methods.

8.177.1. POSIX::SigAction

new
$sigaction = POSIX::SigAction->new(sigsub, sigset, flags)

Constructor. Creates a new POSIX::SigAction object. Takes the following arguments:

sigsub
The fully qualified name of a signal-handler subroutine

sigset
A POSIX::SigSet object

flags
The sa_flags

8.177.2. POSIX::SigSet

new
$sigset = POSIX::SigSet->new[(  )]

Constructor. Creates new SigSet object. Optional arguments are used to initialize the set.

addset
$sigset->addset(sig)

Adds signal sig to SigSet object; returns undef on failure.

delset
$sigset->delset(sig)

Removes signal sig from SigSet object; returns undef on failure.

emptyset
$sigset->emptyset(  )

Initializes SigSet object to empty; returns undef on failure.

fillset
$sigset->fillset(  )

Initializes SigSet object to include all signals; returns undef on failure.

ismember
$sigset->ismember(sig)

Tests SigSet object for a specific signal sig.

8.177.3. POSIX::Termios

new
$termios = POSIX::Termios->new

Constructor. Creates new Termios object.

getattr
$termios->getattr([fd])

Gets terminal control attributes for a given fd (default is 0 for STDIN); returns undef on failure.

getcc
$c_cc[ind] = $termios->getcc(ind)

Retrieves value from the c_cc field of a Termios object. Takes index ind since @c_cc is an array.

getcflag
$c_cflag = $termios->getcflag

Retrieves c_cflag field of a Termios object.

getiflag
$c_iflag = $termios->getiflag

Retrieves c_iflag field of a Termios object.

getispeed
$ispeed = $termios->getispeed

Retrieves input baud rate.

getlflag
getlflag $c_lflag = $termios->getlflag

Retrieves c_lflag field of a Termios object.

getoflag
$c_oflag = $termios->getoflag

Retrieves c_oflag field of a Termios object.

getospeed
$ospeed = $termios->getospeed

Retrieves output baud rate.

setattr
$termios->setattr(fd, option)

Sets terminal control attributes for a given fd; returns undef on failure. option tells when to set the attributes and is one of TCSADRAIN, TCSAFLUSH, or TCSANOW.

setcc
$termios->setcc(ind, value)

Sets value in the c_cc field, indexed by ind, of a Termios object.

setcflag
$termios->setcflag(flag)

Sets flag in the c_cflag field of a Termios object.

setiflag
$termios->setiflag(flag)

Sets flag in the c_iflag field of a Termios object.

setispeed
$termios->setispeed(value)

Sets input baud rate to value; returns undef on failure.

setlflag
$termios->setlflag(flag)

Sets flag in the c_lflag field of a Termios object.

setoflag
$termios->setoflag(flag)

Sets flag in the c_oflag field of a Termios object.

setospeed
$termios->setospeed(value)

Sets the output baud rate to value; returns undef on failure.

8.177.4. Constants

The following constants are associated with the Termios class:

Baud rate values
B0  B75  B134 B200 B600  B1800 B4800 B19200
B50 B110 B150 B300 B1200 B2400 B9600 B38400
c_cc index values
VEOF VERASE VKILL VSUSP  VSTOP VTIME
VEOL VINTR  VQUIT VSTART VMIN  NCCS
c_cflag field values
CLOCAL CSIZE CS6 CS8    HUPCL  PARODD
CREAD  CS5   CS7 CSTOPS PARENB
c_iflag field values
BRKINT IGNBRK IGNPAR INPCK  IXOFF PARMRK
ICRNL  IGNCR  INLCR  ISTRIP IXON
c_lflag field values
ECHO  ECHONL ISIG
ECHOE ICANON NOFLSH
ECHOK IEXTEN TOSTOP
c_oflag field values
OPOST
Terminal interface values
TCSADRAIN TCIOFLUSH TCIFLUSH
TCSANOW   TCOFLUSH  TCSAFLUSH
TCOON     TCION     TCIOFF

The following are other constants defined in the POSIX module:

Pathname constants
_PC_CHOWN_RESTRICTED  _PC_LINK_MAX  _PC_MAX_CANON
_PC_MAX_INPUT         _PC_NAME_MAX  _PC_NO_TRUNC
_PC_PATH_MAX          _PC_PIPE_BUF  _PC_VDISABLE
POSIX constants
_POSIX_ARG_MAX      _POSIX_CHILD_MAX  _POSIX_CHOWN_RESTRICTED
_POSIX_JOB_CONTROL  _POSIX_LINK_MAX   _POSIX_MAX_CANON
_POSIX_MAX_INPUT    _POSIX_NAME_MAX   _POSIX_NGROUPS_MAX
_POSIX_NO_TRUNC     _POSIX_OPEN_MAX   _POSIX_PATH_MAX
_POSIX_PIPE_BUF     _POSIX_SAVED_IDS  _POSIX_SSIZE_MAX
_POSIX_STREAM_MAX   _POSIX_TZNAME_MAX _POSIX_VDISABLE
_POSIX_VERSION
System configuration
_SC_ARG_MAX      _SC_CHILD_MAX  _SC_CLK_TCK    _SC_JOB_CONTROL
_SC_NGROUPS_MAX  _SC_OPEN_MAX   _SC_SAVED_IDS  _SC_STREAM_MAX
_SC_TZNAME_MAX   _SC_VERSION
Error constants
E2BIG   EACCES  EAGAIN    EBADF   EBUSY         ECHILD  EDEADLK
EDOM    EEXIST  EFAUL     EFBIG   EINTR         EINVAL
EIO     EISDIR  EMFILE    EMLINK  ENAMETOOLONG  ENFILE
ENODE   ENOENT  ENOEXEC   ENOLCK  ENOMEM        ENOSPC
ENOSYS  ENOTDIR ENOTEMPTY ENOTTY  ENXIO         EPERM
EPIPE   ERANGE  EROFS     ESPIPE  ESRCH         EXDEV
File control constants
FD_CLOEXEC  F_DUPFD    F_GETFD   F_GETFL  F_GETLK   F_OK
F_RDLCK     F_SETFD    F_SETFL   F_SETLK  F_SETLKW  F_UNLCK
F_WRLCK     O_ACCMODE  O_APPEND  O_CREAT  O_EXCL    O_NOCTTY
O_NONBLOCK  O_RDONLY   O_RDWR    O_TRUNC  O_WRONLY
Floating-point constants
DBL_DIG         DBL_EPSILON     DBL_MANT_DIG  DBL_MAX
DBL_MAX_10_EXP  DBL_MAX_EXP     DBL_MIN       DBL_MIN_10_EXP
DBL_MIN_EXP     FLT_DIG         FLT_EPSILON   FLT_MANT_DIG
FLT_MAX         FLT_MAX_10_EXP  FLT_MAX_EXP   FLT_MIN
FLT_MIN_10_EXP  FLT_MIN_EXP     FLT_RADIX     FLT_ROUNDS
LDBL_DIG        LDBL_EPSILON    LDBL_MANT_DIG LDBL_MAX
LDBL_MAX_10_EXP LDBL_MAX_EXP    LDBL_MIN      LDBL_MIN_10_EXP
LDBL_MIN_EXP
Limit constants
ARG_MAX    CHAR_BIT  CHAR_MAX    CHAR_MIN    CHILD_MAX
INT_MAX    INT_MIN   LINK_MAX    LONG_MAX    LONG_MIN
MAX_CANON  MAX_INPUT MB_LEN_MAX  NAME_MAX    NGROUPS_MAX
OPEN_MAX   PATH_MAX  PIPE_BUF    SCHAR_MAX   SCHAR_MIN
SHRT_MAX   SHRT_MIN  SSIZE_MAX   STREAM_MAX  TZNAME_MAX
UCHAR_MAX  UINT_MAX  ULONG_MAX   USHRT_MAX
Locale constants
LC_ALL  LC_COLLATE  LC_CTYPE  LC_MONETARY  LC_NUMERIC  LC_TIME
Math constants
HUGE_VAL
Signal constants
SA_NOCLDSTOP SIGABRT    SIGALRM    SIGCHLD  SIGCONT  SIGFPE
SIGHUP       SIGILL     SIGINT     SIGKILL  SIGPIPE  SIGQUIT
SIGSEGV      SIGSTOP    SIGTERM    SIGTSTP  SIGTTIN  SIGTTOU
SIGUSR1      SIGUSR2    SIG_BLOCK  SIG_DFL  SIG_ERR  SIG_IGN
SIG_SETMASK  SIG_UNBLOCK
Stat constants
S_IRGRP  S_IROTH  S_IRUSR  S_IRWXG  S_IRWXO  S_IRWXU  S_ISGID
S_ISUID  S_IWGRP  S_IWOTH  S_IWUSR  S_IXGRP  S_IXOTH  S_IXUSR
Stat macros
S_ISBLK  S_ISCHR  S_ISDIR  S_ISFIFO  S_ISREG
Stdlib constants
EXIT_FAILURE  EXIT_SUCCESS  MB_CUR_MAX  RAND_MAX
Stdio constants
BUFSIZ  EOF  FILENAME_MAX  L_ctermid  L_cuserid  L_tmpname  TMP_MAX
Time constants
CLK_TCK  CLOCKS_PER_SEC
Unistd constants
R_OK   SEEK_CUR  SEEK_END       SEEK_SET  STDIN_FILENO
STDOUT_FILENO    STRERR_FILENO  W_OK      X_OK
Wait constants
WNOHANG  WUNTRACED
Wait macros
WIFEXITED  WEXITSTATUS  WIFSIGNALED  WTERMSIG   WIFSTOPPED   WSTOPSIG
Previous | Home | Next
8.176. Pod::Text | Book Index | 8.178. re
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.178. re

Pragma that lets you alter the behavior of regular expressions. Permits the following alterations:

use re 'debug'
Causes Perl to produce debugging messages when compiling and at runtime when using regular expressions. See the re manpage and the section on "Debugging regular expressions" in the perldebug manpage for details.

use re 'eval'
Permits a regular expression to contain (?{...}) zero-width assertion even if the regular expression contains variable interpolation, which normally isn't permitted for security reasons. The pragma is ignored if the regular expression comes from tainted data.

use re 'taint'
When a tainted string is the target of a regular expression, causes the regular expression memories (or the values returned by the m// operator in list context) to be tainted.

Previous | Home | Next
8.177. POSIX | Book Index | 8.179. Safe
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.179. Safe

Creates compartments for evaluating untrusted Perl code. Each compartment has an associated operator mask for excluding particular Perl operators from the compartment. (See the Opcode module for more information on operators and operator masks.) The default mask is applied during compilation to prevent all operations that give access to the system. Safe provides the following methods.

new
$cpt = new Safe [(namespace, mask)]

Constructor. Creates a new compartment. Takes the following arguments:

namespace
Optional. Root namespace to use for the compartment. Default is Safe::Root0, which autoincrements for each new compartment.

mask
Optional. Operator mask to use; defaults to a restrictive set.

mask
$cpt->mask ([mask])

Sets operator mask for the compartment if mask is specified; otherwise, it gets the current mask.

rdo
$cpt->rdo (filename)

Evaluates the contents of file filenameinside the compartment.

reval
$cpt->reval (string)

Evaluates string as Perl code inside the compartment.

root
$cpt->root ([namespace])

If namespace is specified, sets the root namespace for the compartment; otherwise, gets the current namespace.

share
$cpt->share (varname[, ...])

Shares the variable(s) in the argument list with the compartment.

trap
$cpt->trap (op[, ...])

For each operator specified in the argument list, sets the corresponding bit in the compartment's operator mask.

untrap
$cpt->untrap (op[, ...])

For each operator specified in the argument list, resets the corresponding bit in the compartment's operator mask.

varglob
$cpt->varglob (varname)

Returns a glob for the symbol table entry of varname in the compartment's package.

The following subroutines are available for export by Safe. The operator names can be found in the array op_name in the file opcode.h in the Perl distribution.

emptymask
emptymask

Returns a mask with all operators unmasked.

fullmask
fullmask

Returns a mask with all operators masked.

mask_to_ops
mask_to_ops (mask)

Takes an operator mask mask and returns a list of the names of operators masked in mask.

MAXO
MAXO

Returns the number of operators in a mask (and hence its length).

opcode
opcode (op[, ...])

Takes a list of operator names and returns the corresponding list of opcodes.

op_mask
op_mask

Returns the operator mask in effect at the time the invocation to the subroutine was compiled.

opname
opname (op[, ...])

Takes a list of opcodes and returns the corresponding list of operator names.

ops_to_mask
ops_to_mask (op[, ...])

Takes a list of operator names and returns an operator mask with those operators masked.

Previous | Home | Next
8.178. re | Book Index | 8.180. Scalar::Util
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.180. Scalar::Util

Implements a few useful scalar-related subroutines. Like List::Util, Scalar::Util is something useful that doesn't necessarily fit well as a keyword in the Perl core. By default, Scalar::Util does not export any subroutines. As of Perl 5.8, Scalar::Util is shipped with the source kit.

Scalar::Util implements the following methods.

blessed
blessed expr

Evaluates whether expr is a blessed reference. If successful, blessed returns the name of the package. Otherwise, blessed returns undef.

use Scalar::Util qw(blessed);
use CGI;

my $cgi = CGI->new();
my $not_cgi = "IamNotCGI";

my $is_blessed = blessed($cgi);
if(defined($is_blessed) { print "$cgi\n;" } # Prints CGI

my $is_blessed2 = blessed($not_cgi);
if(defined($is_blessed2) { print "$not_cgi\n"; } # undef
dualvar
dualvar number, string

Returns a string that has the value numberin a numeric context and a value string in a string context. For example:

my $context = dualvar(10, "Nathan");
my $add_nums = $context + 1; # '11'
my $str_add = $context . "Patwardhan"; # Nathan Patwardhan
isweak
isweak expr

Returns true if expr is a scalar, which is a weak reference:

my $weak_ref = \$boo_hoo;
my $i_am_weak = isweak($weak_ref); # false
weaken($weak_ref);
$i_am_weak = isweak($weak_ref); # true
openhandle
openhandle fh

Returns fh if fh is an open filehandle. fh may also be a tied filehandle. Returns undef on failure.

my $fh = openhandle(*STDIN);
$fh = openhandle("sumfin"); # undef, since sumfin isn't
                            # open
readonly
readonly scalar

Returns true if scalar is read-only.

reftype
reftype expr

Returns the reference type of expr if expr is a reference. Otherwise, returns undef.

my $r_type = reftype "ORA"; # undef, not a reference
my $r_type = reftype [];    # ARRAY
tainted
tainted expr

Returns true if the result of expr is tainted:

my $is_tainted = tainted($ENV{PATH});
# Returns true if -T is enabled
weaken
weaken ref

Returns ref into a weak reference. When the reference count on an object reaches 0, ref will be set to undef.

Previous | Home | Next
8.179. Safe | Book Index | 8.181. SDBM_File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.181. SDBM_File

Provides Perl programs with tied access to SDBM database files. See Perl's built-in tie function and the DB_File module.

Previous | Home | Next
8.180. Scalar::Util | Book Index | 8.182. Search::Dict
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.182. Search::Dict

Searches for a key in an ordered text file and sets the file position. Exports one function.

look
look *fh, key, dict, fold

Performs string search and sets the position in filehandle fh to the first line with a key equal to or greater than key. Returns the new file position, or -1 in case of error. Takes the following arguments:

fh
Filehandle of the dictionary file

key
Key to search for

dict
If true, searches in dictionary order, considering only word characters and whitespace

fold
If true, ignores case

Previous | Home | Next
8.181. SDBM_File | Book Index | 8.183. SelectSaver
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.183. SelectSaver

Provides a way to save and restore filehandles so you can temporarily use a different filehandle.

new
$saver = new SelectSaver[(fh)]

Constructor. Creates a new SelectSaver object, $saver, which saves the current filehandle. The optional parameter fh is the filehandle that will temporarily replace the current filehandle. If fh is present, the current filehandle is saved in $saver, and the new one becomes the current filehandle. With no parameter, the current filehandle is saved in the object $saver, and it remains current.

You can use the newly selected filehandle within the current block. When you exit the block, the previous filehandle is again made the current one, and the SelectSaver object in which it was stored is destroyed.

Previous | Home | Next
8.182. Search::Dict | Book Index | 8.184. SelfLoader
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.184. SelfLoader

Used when you want to include functions in your program but want to load them only if necessary. Functions that will be self-loaded are placed after the line:

_  _DATA_  _

in your program. When the code is compiled, compilation stops at the _ _DATA_ _ token. The SelfLoader exports the AUTOLOAD subroutine to the package; this subroutine loads the subroutines after _ _DATA_ _ when they are require d.

Previous | Home | Next
8.183. SelectSaver | Book Index | 8.185. Shell
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.185. Shell

Allows you to invoke Unix shell utilities as if they were Perl subroutines. Arguments (including switches) are passed to the utilities as strings:

use Shell qw(date cp ps);  # List shell commands you want to use

$date = date( );   # Put the output of the date(1) command into $date
cp("-p" "/etc/passwd", "/tmp/passwd");  # Copy password file to a tmp file
print ps("-ww");  # Print the results of a "ps -ww" command
Previous | Home | Next
8.184. SelfLoader | Book Index | 8.186. sigtrap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.186. sigtrap

Pragma to enable simple signal handling. Provides two signal handlers that can be installed, or you can install your own handler; also provides options to specify which signals to trap. Ignores requests to trap signals not used in your system's architecture.

use sigtrap;               # Initialize default signal handlers
use sigtrap qw(die normal-signals);
use sigtrap 'handler' => \handlername, 'normal-signals';
use sigtrap qw(handler handlername normal-signals
               stack-trace error-signals);

8.186.1. Signal Handler Options

Used to specify which handler will be installed for signals installed after the handler:

die
Installs handler that die s with a message indicating the signal that was trapped.

handler handlername
Installs your handler handlername.

stack-trace
Default signal handler. Outputs stack trace to STDERR and tries to dump core.

8.186.2. Signal List Options

You can specify your own list of options:

use sigtrap qw(BUS SEGV PIPE ABRT);

or use one of the following built-in option lists:

error-signals
Signals that indicate a serious problem: ABRT, BUS, EMT, FPE, ILL, QUIT, SEGV, SYS, and TRAP.

normal-signals
Signals a program is most likely to encounter: HUP, INT, PIPE, and TERM.

old-interface-signals
Default. Signals trapped by default in older versions of sigtrap: ABRT, BUS, EMT, FPE, ILL, PIPE, QUIT, SEGV, SYS, TERM, and TRAP.

8.186.3. Other Options

any
Installs handlers only for subsequently listed signals that aren't already taken care of.

number
Requires that the version of sigtrap being used must be at least number.

signal
Installs a handler for any argument that looks like a signal name.

untrapped
Installs handlers only for subsequently listed signals not already trapped or ignored.

Previous | Home | Next
8.185. Shell | Book Index | 8.187. Socket
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.187. Socket

Translation of the C socket.h file that uses h2xs and your C compiler. See Chapter 13, "XML and Perl" for details.

Previous | Home | Next
8.186. sigtrap | Book Index | 8.188. sort
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.188. sort

The sort pragma allows you to control sort() behavior. In Perl 5.6 and earlier, the default sort() behavior was written with quicksort. Perl 5.8, with which sort.pm is shipped in the source kit, implements mergesort. mergesort guarantees the worst-case behavior of O(N log N), where quicksort guarantees O(N ** 2).

Perl 5.8 and later shuffle large arrays before sorting. Note that sort.pm is global and not lexical in scope.

For example:

#!/usr/local/bin/perl -w
use sort '_quicksort'; # Or _qsort, if you'd like
sort(@something);

mergesort is better than quicksort for several reasons. First, mergesort is more stable and does fewer comparisons than quicksort, so it's better for more complicated sorting routines. In addition, mergesort takes preexisting order into account.

Previous | Home | Next
8.187. Socket | Book Index | 8.189. Storable
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.189. Storable

Storable.pm allows you to keep peristent state on your Perl data structures, which include objects of type SCALAR, ARRAY, HASH, and REF. In other words, Storable lets you deal with any Perl types that can be conveniently stored on disk and retrieved at a later time. At the heart of Storable is store, which takes a reference to the object that will be stored and the filename where the information should be written. And, while you're statefully keeping your Perl data on a filesystem, retrieve will open the file where the data is kept so you can work with it. As of Perl 5.8, Storable is shipped with the source kit.

For the cost of a slight header overhead, you can store to an already opened file descriptor using the store_fd routine and retrieve from a file via fd_retrieve. These names aren't imported by default, so you will have to do this explicitly if you need these routines. The file descriptor you supply must be opened for read if you're going to retrieve and for write if you wish to store. For example:

#!/usr/local/bin/perl -w
use Storable;

my $state_file = '/tmp/emp.cache';
my %empdata = (EmployeeNumber => 1, Person => 'Nathan Patwardhan');

store(\%empdata, $state_file);
my $h_ref = retrieve($state_file);

Storable implements the following methods.

lock_retrieve
lock_retrieve()

Gets an exclusive lock at the file before writing.

lock_store
lock_store()

Same as store, except that it gets an exclusive lock at the file before writing.

nlock_store
nlock_store()

Same as nstore(), except that it gets an exclusive lock at the file before writing.

nstore_fd
nstore_fd()

Allows you to store data in network order so it can be shared across platforms. It also stores stringified double values to ensure portability. nstore_fd works the same as store_fd and behaves the same if errors are encountered.

retrieve
retrieve(file)

Takes file as an option and recreates the objects in memory for you; a reference to the object is returned. retrieve returns undef if an I/O error is encountered.

store
store(type, file)

Takes type (HASH, SCALAR, etc.) and writes it to file. store returns undef if an I/O error is encountered.

store_fd
store_fd(type, fh)

Allows you to store type in an existing fh (filehandle). Similarly, you can retrieve data from fh using fd_retrieve. If fhisn't open, both store_fd and fd_retrieve will fail.

Previous | Home | Next
8.188. sort | Book Index | 8.190. strict
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.190. strict

Pragma for doing strict error checking within the current block. Can be turned off by prefixing with no:

use strict 'vars';
...
no strict 'vars';

Provides three kinds of restriction:

strict 'refs'
Generates runtime error if you use any symbolic references.

strict 'subs'
Generates compile-time error if you use a bareword identifier that's not a predeclared subroutine.

strict 'vars'
Generates compile-time error if you access a variable that wasn't declared via my, isn't fully qualified, or wasn't imported.

use strict by itself (with no import list) is the most restrictive, causing all possible restrictions to be imposed.

Previous | Home | Next
8.189. Storable | Book Index | 8.191. subs
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.191. subs

Pragma that predeclares subroutines whose names are given in a list:

use subs qw(sub[, ...]);
sub $arg[, ...];

This lets you use the subroutines without parentheses even before they're defined and lets you override built-in functions.

Previous | Home | Next
8.190. strict | Book Index | 8.192. Switch
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.192. Switch

Switch.pm implements a switch statement for Perl, which works something like the switch statement you'd find in C and other languages. Switch.pm is intended to supplement the standard Perl syntax with two control statements: switch and case. switch takes a single scalar argument of any type, specified in parentheses, that is then stored in a localized control variable. It is followed by any number of Perl statements (in a block) that are checked to meet various conditions, or cases, of the switch. case takes a single scalar argument, variable, or regular expression as an argument. If case finds a match, it will take the action that's specified between the braces on the right. Switch.pm is shipped with the Perl 5.8 source kit.

For example:

#!/usr/local/bin/perl -w
 use Switch;
 switch($some_value) {
      case 1          { print "number 1" }
      case "a"        { print "string a" }
      case [1..10,42] { print "number in list" }
      case (@array)   { print "number in list" }
      case /\w+/      { print "pattern" }
      case qr/\w+/    { print "pattern" }
      case (%hash)    { print "entry in hash" }
      case (\%hash)   { print "entry in hash" }
      case (\&sub)    { print "arg to subroutine" }
      else            { print "Get off my case." }
}
Previous | Home | Next
8.191. subs | Book Index | 8.193. Symbol
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.193. Symbol

Provides functions for creating anonymous globs and qualifying variable names. Exports the following.

gensym
gensym

Creates an anonymous glob and returns a reference to it that can be used as a filehandle or directory handle.

qualify
qualify (symname[, pkg])

Turns unqualified symbol names into qualified variable names (e.g., turns myvar into MyPackage::myvar).

qualify_to_ref
qualify_to_ref (symname[, pkg])

Like qualify, but returns a glob reference that can be used even if use strict 'refs' is in effect.

ungensym
ungensym

For backward compatibility only; does nothing.

Previous | Home | Next
8.192. Switch | Book Index | 8.194. Sys::Hostname
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.194. Sys::Hostname

Provides one function, hostname, which attempts to get the system hostname by doing checks appropriate to the operating system. Removes nulls, returns, and newlines from the result, which it then caches. croak s on failure.

use Sys::Hostname;
$host = hostname( );
Previous | Home | Next
8.193. Symbol | Book Index | 8.195. Sys::Syslog
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.195. Sys::Syslog

Interfaces to Unix syslog(3) program. Requires the file syslog.ph, which must be created with h2ph by your system administrator. Provides the following four functions.

closelog
closelog

Closes the log file.

openlog
openlog ident, logopt, facility

Opens the log file. Takes the following arguments:

ident
Prepended to every message

logopt
Logging options, containing one or more of:

cons
Writes messages to system console if they can't be sent to syslogd

ndelay
Opens the connection immediately

nowait
Doesn't wait for child processes before logging messages to the console

pid
Logs process ID

facility
Specifies the part of the system making the log entry

setlogmask
setlogmask mask_priority

Sets log mask to mask_priority and returns the old mask.

syslog
syslog priority, mask, format, args

If priority and mask permit, logs message formed as if by sprintf(format, args), with the addition that %m is replaced with the current error message from $!.

Previous | Home | Next
8.194. Sys::Hostname | Book Index | 8.196. Term::Cap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.196. Term::Cap

Provides low-level functions to extract and use capabilities from a terminal capability (termcap) database. For general information about the use of this database, see the termcap(5) manpage. Provides the following functions.

Tgetent
$terminal = Tgetent Term::Cap { TERM => termtype, OSPEED=>ospeed }

Acts as the constructor for Term::Cap. Extracts the termcap entry for terminal type termtype and returns a reference to a terminal object. The termcap entry itself is $terminal->{TERMCAP}. Calls Carp::croak on failure. Takes the following arguments:

TERM => termtype
Terminal type. Defaults to the value of the environment variable TERM if termtype is false or undefined.

OSPEED => ospeed
The terminal output bit rate, specified as either a POSIX termios/SYSV termio speed or an old BSD-style speed. You can use the POSIX module to get your terminal's output speed (in ospeed here).

Tgoto
$terminal->Tgoto('cm', col, row[, fh])

Produces control string to move the cursor relative to the screen. Doesn't cache output strings, but does % expansion as needed on control string. Takes the following arguments:

'cm'
Required first argument ("cursor move")

col, row
Column and row to move cursor to

fh
Filehandle that will receive the control string

Tpad
$terminal->Tpad(string, count, fh)

Specifies padding required to create delay needed by terminal. Takes the following arguments:

string
The string to pad with

count
The number of pad characters

fh
The filehandle to pad

Tputs
$terminal->Tputs('cap', count[, fh])

Produces control string for capabilities other than cursor movement. Does not do % expansion, but does cache output strings if $count = 1. Takes the following arguments:

cap
Capability to produce control string for

count
Should be 1 unless padding is required (see Tpad); if greater than 1, specifies amount of padding

fh
Filehandle to receive the control string

Trequire
$terminal->Trequire(caps)

Checks to see whether the named capabilities, caps, are defined in the terminal's termcap entry. For example:

$terminal->Trequire(qw/ce ku kd/);

Any undefined capabilities are listed, and Carp::croak is called.

Previous | Home | Next
8.195. Sys::Syslog | Book Index | 8.197. Term::Complete
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.197. Term::Complete

Provides word completion on list of words in a specified array. Exports one function.

Complete
Complete ('prompt_string', array)

Sends string to the currently selected filehandle, reads the user's response, and returns the response. Takes the following arguments:

prompt_string
The prompt for user input

array
The array of words against which the user's input is matched

If any of the following characters are included in the user's response to prompt_string, they are treated as special characters:

Tab
Does word completion, matching what the user has typed so far against the list of strings in completion_list. On a unique match, outputs the rest of the matched string and waits for the user to press Return. Otherwise, leaves partial input unchanged and sounds the bell.

Ctrl-D
Prints all possible completions of the user's partial input, or the entire completion list if the partial input string is null, and reissues the prompt string and the partial input. Redefine by setting the variable $Term::Complete::complete.

Ctrl-U
Erases any partial input. Redefine by setting the variable $Term::Complete::kill.

Del, BS
Delete and backspace characters; both erase one character from the partial input string. Redefine by setting the variables $Term::Complete::erase1 and $Term::Complete::erase2.

Previous | Home | Next
8.196. Term::Cap | Book Index | 8.198. Term::ReadLine
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.198. Term::ReadLine

Frontend to other ReadLine packages. Currently interfaces to Term-ReadLine, which is available on CPAN. Defines the variables $IN and $OUT, which return the filehandles for input and output, respectively, or undef if Readline input and output cannot be used for Perl. Provides the following methods.

new
$term = new Term::ReadLine 'name'

Constructor. Returns the handle for subsequent calls to other ReadLine methods. Argument name is the name of the application. Optionally can be followed by two arguments that are globs specifying input and output filehandles.

addhistory
$term->addhistory(line)

Adds line to the input history.

Features
$term->Features

Returns a reference to a hash whose keys are features present in the current implementation and whose values are assigned to each feature. Several optional features are used in the minimal interface:

appname
Should be present if the first argument to new is recognized

minline
Should be present if MinLine method is not a dummy

autohistory
Should be present if lines are put into history automatically (maybe subject to MinLine)

addhistory
Should be present if the addhistory method is not a dummy

findConsole
$term->findConsole

Returns array of two strings containing the most appropriate names for input and output files, using the conventions <$in and >$out.

MinLine
$term->MinLine([size])

With size argument, serves as a recommendation on minimal size of line to be added to history. Without an argument, does not add anything to the history. Returns the old value.

ReadLine
$term->ReadLine

Returns the actual package that executes the commands. Some possible
values are Term::ReadLine::Gnu,
Term::ReadLine::Perl, or
Term::ReadLine::Stub.

readline
$term->readline(prompt)

Prompts for input line and gets the result. Removes trailing newline and returns undef at end-of-file.

Previous | Home | Next
8.197. Term::Complete | Book Index | 8.199. Test
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.199. Test

Provides a framework for writing test scripts so you don't need to know the particular output that Test::Harness expects to see. Useful if you are writing modules and writing tests for those modules. Provides the following test types:

Normal
Tests that are expected to succeed.

Skip
Tests that need a platform-specific feature. They work like normal tests except that the first argument should evaluate to true if the required feature is not present.

Todo
Tests designed for maintaining an executable todo list; the tests aren't expected to succeed.

Test also provides an onfail hook that can trigger additional diagnostics for failures at the end of the test run. To use onfail, pass it an array reference of hash references in which each hash contains at least the package, repetition, and result fields, as well as any expected value or diagnostic string.

See the Test manpage for details and examples.

Previous | Home | Next
8.198. Term::ReadLine | Book Index | 8.200. Test::Builder
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.200. Test::Builder

A backend for building test libraries under Perl. Note that Test::Builder is in the early stages of development and that things may become more (or less) stable, or may change completely. Test::Builder is more flexible than other testing modules such as Test::Simple and Test::More.

Test::Builder implements the following methods.

new
new()

Returns a Test::Builder object representing the current state of the test. There's no need to create more than one Test::Builder object, since you run only one test per program.

BAILOUT
BAILOUT(reason)

Terminates all tests and exits immediately.

expected_tests
expected_tests()

Gets and sets the tests that will run and prints out the correct headers.

exported_to
exported_to(package)

Specifies the package you exported your functions to.

is_eq
is_eq(got_from_test, expected_from_test, name_of_test)

Checks if got_from_test eq expected_from_test.

isnt_eq
isnt_eq(got_from_test, did_not_expect, name_of_test)

Checks if got_from_test ne did_not_expect.

isnt_num
isnt_num(got_from_test, did_not_expect, name_of_test)

Checks if got_from_test!= did_not_expect.

is_num
is_num(got_from_test, expected_from_test, name_of_test)

Checks if got_from_test== expected_from_test.

like
like(string, '/regex/', name_of_test)

Checks if string matches the specified regular expression.

no_plan
no_plan()

Declares that there may be an infinite number of tests.

ok
ok(test, name)

Reports if test by name is true.

plan
plan()

Sets up the tests for you, prints appropriate headers, and takes appropriate actions. plan can be used in lieu of any of the subsequent methods.

skip
skip([reason])

Skips the current test, citing reason.

skip_all
skip_all(reason)

Shamelessly skips all the tests, citing the given reason . Exits with 0.

my $reason = "I didn't feel like it today.";
$Test->skip_all($reason);
unlike
unlike(string, '/regex/', name_of_test)

Checks if string does not match the specified regular expression.

Previous | Home | Next
8.199. Test | Book Index | 8.201. Test::Harness
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.201. Test::Harness

Used by MakeMaker; runs Perl test scripts and prints some statistics. You can use the Test module to write test scripts without knowing the exact output Test::Harness expects. Exports one function.

runtests
runtests (tests)

Runs all test scripts named in tests and checks standard output for the expected ok n strings. Prints performance statistics after all tests have been run.

Previous | Home | Next
8.200. Test::Builder | Book Index | 8.202. Test::More
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.202. Test::More

Yet another framework for writing test scripts. Its more flexible successor is Test::Builder.

Previous | Home | Next
8.201. Test::Harness | Book Index | 8.203. Test::Simple
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.203. Test::Simple

Provides basic utilities for writing tests. It is shipped with the Perl source kit as of 5.8. For example:

my $name = 'Inigo Montoya';
my $quote = 'Prepare to die';
ok($name eq $quote, 'name is quote');

The ok function is given an expression to evaluate. ok() prints out 'ok' or 'not ok' along with the number of the test.

Here's another example that tests if you can use CGI.pm:

#!/usr/local/bin/perl -w
use Test::Simple tests => 2;
use CGI; # Test this

my $cgi = CGI->new();

# Test #1—this will be ok
ok(defined($cgi) and ref $cgi eq 'CGI', 'I have your CGI right here!');

my $header = $cgi->header(-type => `text/plain');

# Test #2—this will not be ok
ok($header eq "Content-Type: text/mex");
Previous | Home | Next
8.202. Test::More | Book Index | 8.204. Text::Abbrev
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.204. Text::Abbrev

Given a list of strings, creates a hash of unambiguous abbreviations. Exports one function.

abbrev
abbrev (\%hashref, list)

Takes each string in list and constructs the hash referenced by \%hashref. Each key is an unambiguous truncation of one of the strings, and the value is the full string (in which unambiguous means that there is only one possible expansion that matches one of the strings in the list). For example, if list contains "file" and "find", then the key/value pairs created include:

fil  => file
file => file
fin  => find
find => find

Both "f" and "fi" are ambiguous, since they start both words, and therefore, they don't appear as keys.

Previous | Home | Next
8.203. Test::Simple | Book Index | 8.205. Text::Balanced
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.205. Text::Balanced

Extracts delimited text sequences from strings. It implements various extract_-named subroutines to capture the delimited string.

In a list context, all Text::Balanced methods return a list that contains the extracted string with delimiters, the remainder of the string, and the parts of the string that were skipped. Text::Balanced is shipped with the Perl source kit as of 5.8.

Text::Balanced implements the following methods.

extract_bracketed
extract_bracketed(text, delimiter)

Extracts the initial substring of textthat is bracketed with delimiters specified by delimiter. Note that delimiter should contain one of (), {}, [], or <>.

extract_codeblock
extract_codeblock(text, delimiter)

Extracts the initial substring of textthat represents a block of Perl code. This code is specified by delimiter, which contains one of (), {}, [], or <>.

extract_delimited
extract_delimited(text, delimiter)

Extracts the initial substring of textthat is delimited by two instances of delimiter.

extract_multiple
extract_multple(text ...)

Extracts the initial substrings of textthat would be extracted by one or more sequential applications of the specified functions.

extract_quotelike
extract_quotelike(text)

Extracts the quoted portion of text.

extract_tagged
extract_tagged(text, "TAG1", "TAG2", undef, nesting_allowed)

Extracts the initial substring of textthat is bounded by an HTML or XML tag:

# Extract HTML tags but don't allow <HTML> to be embedded
($extracted, $left) =
    extract_tagged($text,"<HTML>","</HTML>",
                    undef,{bad=>["<HTML>"]});
extract_multiple($text, ...)
gen_delimited_pat
gen_delimited_pat(q{pattern})

Creates a string that represents the optimized pattern that matches a substring delimited by q{ pattern}.

Previous | Home | Next
8.204. Text::Abbrev | Book Index | 8.206. Text::ParseWords
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.206. Text::ParseWords

Parses lines of text and returns an array of words. Provides three functions.

old_shellwords
old_shellwords (lines)

Splits an array of lines into words. Exported on request. Same as the pre-Perl 5 program shellwords.pl.

quotewords
quotewords (delim, keep, lines)

Accepts delimiter and list of lines and breaks the lines into a list of words at occurrences of the delimiter. Exported by default. Takes the following arguments:

delim
Delimiter, which can be a regular expression. Occurrences inside quotes are ignored.

keep
Boolean. If false, quotes and single backslashes are removed from the list of words returned, and a double backslash is returned as a single backslash. If true, quotes and backslashes are retained.

lines
The list of lines to be parsed.

shellwords
shellwords (lines)

Works like old_shellwords, but does not default to using $_ if there is no argument. Exported by default.

Previous | Home | Next
8.205. Text::Balanced | Book Index | 8.207. Text::Soundex
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.207. Text::Soundex

Implements the soundex algorithm, which hashes a word (in particular, a surname) into a compressed form that approximates the sound of the word when spoken by an English speaker:

use Text::Soundex;

$code = soundex $string;  # Get soundex code for a string
@codes = soundex @list;   # Get list of codes for list of strings

Returns the value of the variable $soundex_nocode if there is no soundex code representation for a string. $soundex_nocode is initially set to undef, but can be reset to another value. For example:

$soundex_nocode = 'Z000';
Previous | Home | Next
8.206. Text::ParseWords | Book Index | 8.208. Text::Tabs
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.208. Text::Tabs

Provides subroutines that expand tabs into spaces and compress ("unexpand") spaces into tabs. The appearance of the text is unchanged. Defines the tabstop variable, which defines the number of spaces equivalent to a tab. Default is 8. Exports the following functions.

expand
expand (text)

Given an array of strings (text) containing tabs, replaces each tab character with the equivalent number of spaces.

unexpand
unexpand (text)

Given an array of strings (text) that may or may not contain tabs, replaces each $tabstop consecutive spaces with a tab character.

Previous | Home | Next
8.207. Text::Soundex | Book Index | 8.209. Text::Wrap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.209. Text::Wrap

Wraps text into a paragraph. Defines the $columns variable, which specifies the output line length. Default is 76. Exported on request. Provides the following function.

wrap
wrap (init_str, other_str, text)

Breaks lines of array text at the word boundary closest to the size of a line. Prepends init_str to the first output line and other_str to subsequent lines, for indentation. Exported by default.

Previous | Home | Next
8.208. Text::Tabs | Book Index | 8.210. Thread
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.210. Thread

Provides Perl multithreading support. Distributed as a beta feature with Perl 5.005 and runs only on versions of Perl that were built with thread support. Has the following functions and methods.

new
$t = new Thread \&sub[, params]

Constructor. Starts a new thread in the referenced subroutine, \sub, returning a thread object that represents the new thread. The optional parameter list is passed to the subroutine. Execution continues in both the new thread and the code.

async
$t = async {block};

Creates a new thread to execute the block that follows it. The block is treated as an anonymous subroutine (and therefore has a semicolon after the closing bracket). Returns a thread object. async isn't exported by default, so you can specify use Thread qw(async); or fully qualify the name (Thread::async).

cond_broadcast
cond_broadcast var

Like cond_wait, but unblocks all threads blocked in a cond_wait on the locked variable, not just one thread.

cond_signal
cond_signal var

Takes the locked variable var and unblocks one thread that's cond_wait ing on that variable. If multiple threads are so blocked, the one that will be unblocked can't be determined.

cond_wait
cond_wait var

Takes the locked variable var, unlocks it, and blocks until another thread does a cond_signal or cond_broadcast for that variable. The variable is relocked after the cond_wait has been satisfied. If multiple threads are cond_wait ing, all but one will reblock waiting to reacquire the lock.

eval
eval {$t->join}

Wraps an eval around a join. Waits for a thread to exit and passes any return values from the thread, putting errors into $@.

join
$t->join

Waits for a thread to end. When it does, returns any exit values from the thread. Blocks until the thread has ended, unless the thread has already terminated.

list
Thread->list

Returns list of thread objects for all running and finished, but not join ed, threads.

lock
lock var
lock sub

Locks a variable or a subroutine. A lock on a variable is maintained until the lock goes out of scope. If the variable is already locked by another thread, the lock call blocks until the variable is available. You can recursively lock the variable, which stays locked until the outermost lock goes out of scope.

Note that locks on variables affect only other lock calls; they don't prevent normal access to a variable. Also, locking a container object (e.g., an array) doesn't lock each element of the container.

Locking a subroutine blocks any calls to the subroutine until the lock goes out of scope; no other thread can access the subroutine while the lock is in effect.

self
Thread->self

Returns an object representing the thread that made the call.

tid
$id = $t->tid

Returns an object representing the tid (thread ID) of a thread. The ID is simply an integer that is incremented each time a new thread is created, starting with zero for the main thread of a program.

Previous | Home | Next
8.209. Text::Wrap | Book Index | 8.211. Thread::Queue
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.211. Thread::Queue

Provides a thread-safe queue. Any number of threads can add elements to the end of the queue or remove elements from the head.

new
$q = new Thread::Queue

Creates a new empty queue. Returns an object representing the queue.

dequeue
$q->dequeue

Removes and returns a scalar from the head of the queue. If the queue is empty, dequeue blocks the thread until another thread enqueue s a scalar on the queue.

dequeue_nb
$q->dequeue_nb

Like dequeue, but returns undef if the queue is empty instead of blocking.

enqueue
$q->enqueue list

Adds the list of scalars, list, to the end of the queue.

pending
$q->pending

Returns the number of items remaining in the queue.

Previous | Home | Next
8.210. Thread | Book Index | 8.212. Thread::Semaphore
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.212. Thread::Semaphore

Provides a mechanism to regulate access to resources. Semaphores are more general than locks because they aren't tied to a particular scalar. They can have values other than 0 or 1 and can be incremented or decremented by a specified number.

new
$sem = new Thread::Semaphore([val])

Constructor. Creates a new semaphore object, with an optional initial count of val, or 1 if val isn't specified.

down
down [number]

Decrements the semaphore's count by the specified number, which defaults to 1. If the resulting count would be negative, blocks until the semaphore's count has been increased to be equal to or larger than the amount you want to decrease it.

up
up [number]

Increments the semaphore's count by the specified number, which defaults to 1. If a thread is blocked waiting to decrement the count, and the increment brings the count high enough, the blocked thread is unblocked.

Previous | Home | Next
8.211. Thread::Queue | Book Index | 8.213. Thread::Signal
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.213. Thread::Signal

Starts a special signal handler thread to reliably run signal handlers. All signals are handed to this thread, which runs the associated $SIG{signal} handlers for them.

use Thread::Signal;

$SIG{HUP} = handler;
Previous | Home | Next
8.212. Thread::Semaphore | Book Index | 8.214. Thread::Specific
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.214. Thread::Specific

Provides thread-specific keys.

key_create
$k = key_create Thread::Specific

Constructor. Creates a Thread::Specific key object.

Previous | Home | Next
8.213. Thread::Signal | Book Index | 8.215. Tie::Array, Tie::StdArray
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.215. Tie::Array, Tie::StdArray

Provides methods for array-tying classes. (See the perltie manpage for the functions needed for tying an array to a package.) The basic Tie::Array package provides stub DELETE and EXTEND methods and implements PUSH, POP, SHIFT, UNSHIFT, SPLICE, and CLEAR in terms of basic FETCH, STORE, FETCHSIZE, and STORESIZE.

Tie::StdArray inherits from Tie::Array and provides the methods needed for tied arrays implemented as blessed references to an "inner" Perl array. It causes tied arrays to behave like standard arrays, allowing for selective method overloading.

See the perltie manpage for more detailed information and for examples. To write your own tied arrays, use the following required methods.

TIEARRAY
TIEARRAY classname, list

Constructor. This method is invoked by the command tie @array , classname. Associates an array instance with the specified class. list represents additional arguments needed to complete the association. Should return an object of a class that provides the remaining methods.

CLEAR
CLEAR this

Clears all values from the tied array associated with object this.

DESTROY
DESTROY this

Normal object destructor.

EXTEND
EXTEND this, count

Doesn't need to do anything. Provides information that the array will likely grow to have count entries.

FETCH
FETCH this, index

Retrieves the data item in index for the tied array associated with object this.

FETCHSIZE
FETCHSIZE this

Returns the number of items in the tied array associated with object this.

POP
POP this

Removes the last element from the array and returns it.

PUSH
PUSH this, list

Appends elements of list to the array.

SHIFT
SHIFT this

Removes and returns the first element of the array, shifting the remaining elements down.

SPLICE
SPLICE this, offset, length, list

Performs the equivalent of a splice on the array. Returns a list of the original length elements at the specified offset. The arguments are:

offset
Optional. Defaults to 0; if negative, counts back from the end of the array.

length
Optional. Defaults to the rest of the array.

list
May be empty.

STORE
STORE this, index, value

Stores value of a data item into index for the tied array associated with object this. If the resulting array is larger than the class's mapping for the array, undef should be returned for new positions.

STORESIZE
STORESIZE this, count

Sets the total number of items in the tied array associated with object this to count. If this makes the array larger than the class's mapping for the array, then undef should be returned for new positions. If it makes the array smaller than the mapping, then entries beyond count should be deleted.

UNSHIFT
UNSHIFT this, list

Inserts list elements at the beginning of the array, moving existing elements up to make room.

Previous | Home | Next
8.214. Thread::Specific | Book Index | 8.216. Tie::File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.216. Tie::File

Represents a regular text file as a Perl array, such that each element in the array corresponds to a record in the file. The first line of the file is element 0 of the array, the second line is element 1, and so on. When you add a new item to the array, this change will be noted in the file immediately. Note that the file isn't loaded into memory, so the files can be very large if needed. Tie::File is shipped with the Perl 5.8 source kit.

Let's say that we have a file that contains:

One
Two
Three
Four
Five
Six

You can use Tie::File to report about the contents of the file as follows:

#!/usr/local/bin/perl -w

use Tile::File;

my $infile = 'mynotes.db.txt';
my @lines;

tie(@lines, 'Tie::File', $infile)
die("can't open $infile: $!");

my $n_recs = @lines;
print "$infile has [$n_recs]\n";

Now, set the second line of the file to 3:

$lines[2] = 3;

and lowercase everything that's in the file:

foreach my $line (@lines) {
    lc($line);
}

Add one line to the file:

push(@lines, "Here's one more for you");

Now we're done:

untie @lines;

Tie::File supports the following options:

recsep
Changes $/ to what you'll use to separate the records (or lines) in your file. recsep may not be undefined.

my $file = 'datafile';
my $recsep = "\cA"; # Break records on ^A

tie @lines, 'Tie::File', $file, recsep => $recsep;

Given the line:

this^Athat^Athe^Aother^Athing\n

Tie::File would see the records like so:

0: this
1: that
2: the
3: other
4: thing

If you do not specify a recsep, Tie::File will default to \n. Thus, the following are equivalent:

$lines[5] = "Sixty6";
$lines[5] = "Sixty6\n";
autochomp
If specified, and if \n is your default recsep, \n will be removed as the record separator. Default is 0.

mode
Sets if the file will be set for read, write, or read/write access. Options include O_RDWR and O_CREAT:

use Fcntl 'O_RDWR', 'O_CREAT';

# Open file RDWR, or CREAT if $file doesn't exist
tie @lines, 'Tie::File', $file, mode => O_RDWR | O_CREAT;
memory
Sets the upper limit on the amount of memory that Tie::File will consume.

dw_size
Specifies that data should be written into a deferred write buffer of a given size instead of in the file itself.

See the documentation for Tie for a description of the additional tie() methods.

Previous | Home | Next
8.215. Tie::Array, Tie::StdArray | Book Index | 8.217. Tie::Handle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.217. Tie::Handle

Provides skeletal methods for handle-tying classes. Tie::Handle provides a new method as backup in case a class has no TIEHANDLE method. (See the perltie manpage for more detailed information and for examples.) To write your own tied-handle classes, use the following methods.

TIEHANDLE
TIEHANDLE classname, list

Constructor. This method is invoked by the command tie *glob, classname. Associates new glob instance with class classname. list represents any additional arguments needed to complete the association.

DESTROY
DESTROY this

Frees storage associated with the tied handle this. Permits class to take some action when an instance is destroyed. Rarely needed.

GETC
GETC this

Gets one character from tied handle this.

PRINT
PRINT this, list

Prints the values in list.

PRINTF
PRINTF this, format, list

Prints the values in list using format.

READ
READ this, scalar, length, offset

Reads length bytes from scalar starting at offset.

READLINE
READLINE this

Reads one line from this.

WRITE
WRITE this, scalar, length, offset

Writes length bytes of data from scalar starting at offset.

Previous | Home | Next
8.216. Tie::File | Book Index | 8.218. Tie::Hash
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.218. Tie::Hash

Provides skeletal methods for hash-tying classes. Tie::Hash provides a new method, as well as the methods TIEHASH, EXISTS, and CLEAR. The new method is provided as backup in case a class has no TIEHASH method.

To write your own tied hashes, the methods listed here are required. See the perltie manpage for more detailed information and for examples.

TIEHASH
TIEHASH ClassName, list

Constructor. Associates a new hash instance with class ClassName. listis a list of additional arguments needed to complete the association.

tie %hash, ClassName, list
CLEAR
CLEAR this

Clears all values from tied hash this.

DELETE
DELETE this, key

Deletes key from tied hash this.

EXISTS
EXISTS this, key

Verifies that key exists for tied hash this.

FETCH
FETCH this, key

Retrieves value associated with key for tied hash this.

FIRSTKEY
FIRSTKEY this

Returns key/value pair for the first key in tied hash this.

NEXTKEY
NEXTKEY this, lastkey

Returns next key/value pair after lastkeyfor tied hash this.

STORE
STORE this, key, value

Stores value into tied hash this with key key.

Previous | Home | Next
8.217. Tie::Handle | Book Index | 8.219. Tie::Memoize
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.219. Tie::Memoize

Adds data to the hash when needed. That is, Tie::Memoize allows a tied hash to autoload all its values on first access and to use the cached value on subsequent accesses. Read accesses will result in one of the Tie::Memoize functions being called. Write accesses will act as if you're operating on a normal hash. For example:

#!/usr/local/bin/perl -w
require Tie::Memoize;
tie %hash, 'Tie::Memoize', \&fetch, $DATA, \&exists,
    {%ini_value}, {%ini_existence};
sub fetch { ... }
sub exists { ... }
Previous | Home | Next
8.218. Tie::Hash | Book Index | 8.220. Tie::RefHash
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.220. Tie::RefHash

Provides the ability to use references as hash keys after you've tied a hash variable to the module:

use Tie::RefHash;

tie hashvariable, 'Tie::RefHash', list;
untie hashvariable;

Uses the TIEHASH interface and provides the same methods.

Previous | Home | Next
8.219. Tie::Memoize | Book Index | 8.221. Tie::Scalar
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.221. Tie::Scalar

The basic Tie::Scalar package provides a new method, as well as methods TIESCALAR, FETCH, and STORE. The new method is provided as backup in case a class has no TIESCALAR method.

To write your own tied hashes, the methods listed here are required. See the perltie manpage for more detailed information and for examples.

TIESCALAR
TIESCALAR classname, list

Constructor. Associates new scalar instance with class classname. listrepresents any additional arguments needed to complete the association.

tie $scalar, classname, list
DESTROY
DESTROY this

Frees storage associated with the tied scalar referenced by this. Permits a class to perform specific actions when an instance is destroyed. Rarely needed.

FETCH
FETCH this

Retrieves value of the tied scalar referenced by this.

STORE
STORE this, value

Stores value in the tied scalar referenced by this.

Previous | Home | Next
8.220. Tie::RefHash | Book Index | 8.222. Tie::SubstrHash
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.222. Tie::SubstrHash

Provides a hash table-like interface to a fixed-sized array that has a constant key size and record size:

require Tie::SubstrHash;
tie %myhash, "Tie::SubstrHash", key_len, value_len, table_size;

To tie a new hash to this package, specify the following:

key_len
Length of each key

value_len
Length of each value

table_size
Size of the table given as the number of key/value pairs

An attempt to store a key/value pair in which either the key or the value is the wrong length, or in which the resulting table would be greater than table_size, results in a fatal error.

Previous | Home | Next
8.221. Tie::Scalar | Book Index | 8.223. Time::gmtime
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.223. Time::gmtime

Replaces Perl's core gmtime function with a version that returns Time::tm objects. Exports two functions.

gmctime
$gmc = gmctime(  )

Overrides the core gmtime function in scalar context; returns a string with the date and time:

use Time::gmtime;
$gmc = gmctime( );
print $gmc;

Then the output of the print command looks like:

Thu Apr 9 18:15:06 1998
gmtime
$gm = gmtime(  )

Overrides the core gmtime function. The Time::tm object returned has methods with the same names as the structure fields they return. That is, to return the field mon, use the mon method:

use Time::gmtime;
$gm = gmtime( );
print $gm->mon;

The field names (and therefore the method names) are the same as the names of the fields in the tm structure in the C file time.h: sec, min, hour, mday, mon, year, wday, yday, and isdst. You can access the fields either with the methods or by importing the fields into your namespace with the :FIELDS import tag and prepending tm_ to the method name (for example, $tm_mon).

Previous | Home | Next
8.222. Tie::SubstrHash | Book Index | 8.224. Time::HiRes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.224. Time::HiRes

Provides "high-resolution" functionality for alarm, sleep, gettimeofday, and interval timers. Ordinarily, Perl deals in seconds when you use something like sleep() or alarm(), with which only positive integers are allowed. Time::HiRes allows you to use more granular times for functions such as sleep() and alarm(). For example:

#!/usr/local/bin/perl -w
use Time::HiRes qw(usleep);
my $ms = 349_000; # That's 349,000 microseconds
usleep($ms);

print "I'm awake now.\n";

Time::HiRes implements a Perl interface to
usleep(), ualarm(),
gettimeofday(), setitimer(),
and getitimer().

Previous | Home | Next
8.223. Time::gmtime | Book Index | 8.225. Time::Local
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.225. Time::Local

Provides routines that take the time and return the number of seconds elapsed between January 1, 1970 and the specified time. The arguments are defined like the corresponding arguments returned by Perl's gmtime and localtime functions and the results agree with the results of those functions. Exports two functions; both return -1 if the integer limit is hit. On most machines, this applies to dates after January 1, 2038.

timegm
$time = timegm(sec, min, hours, mday, mon, year)

Converts from Greenwich time.

timelocal
$time = timelocal(sec, min, hours, mday, mon, year)

Converts from local time.

Previous | Home | Next
8.224. Time::HiRes | Book Index | 8.226. Time::localtime
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.226. Time::localtime

Replaces Perl's core localtime function with a version that returns Time::tm objects. Exports two functions.

ctime
$ct = ctime(  )

Overrides the core localtime function in scalar context; returns a string with the date and time:

use Time::gmtime;
$ct = ctime( );
print $ct

Then the output of the print command looks like:

Thu Apr  9 16:50:10 1998
localtime
$lt = localtime(  )

Overrides the core localtime function. The Time::tm object returned has methods with the same names as the structure fields they return. That is, to return the field mon, use the mon method:

use Time::localtime;
$lt = localtime( );
print $lt->mon;

The field names (and therefore the method names) are the same as the names of the fields in the tm structure in the C file time.h: sec, min, hour, mday, mon, year, wday, yday, and isdst. You can access the fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and prepending tm_ to the method name (for example, $tm_mon).

Previous | Home | Next
8.225. Time::Local | Book Index | 8.227. Time::tm
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.227. Time::tm

Used internally by Time::localtime and
Time::gmtime. Don't use it directly. Creates
addressable Time::tm struct object.

Previous | Home | Next
8.226. Time::localtime | Book Index | 8.228. UNIVERSAL
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.228. UNIVERSAL

Base class; all blessed references inherit from it:

$sub = $obj->can('print');

$yes = UNIVERSAL::isa($ref, "HASH");

Provides the following methods.

can
$sub = $obj->can(method)

Checks if object $objhas a method method. If so, returns a reference to the subroutine; otherwise, returns undef. Can be called as a static or object method call, or as a subroutine:

$ref = UNIVERSAL::can(val, method)

Returns a reference to the subroutine if val is a blessed reference with a method method, and undef if val is not blessed or does not have method.

isa
$io = $fd->isa(type)

Returns true if the reference is blessed into package type or inherits from that package. Can be called as a static or object method call, or as a subroutine:

UNIVERSAL::isa(val, type)

Returns true if the first argument is a reference and either of the following is true:

  • val is a blessed reference and is blessed into package type or inherits from package type.

  • val is a reference to a type of Perl variable (e.g., 'HASH').

VERSION
VERSION([require])

Returns the value of the variable $VERSION in the package the object is blessed into. With require specified, VERSION dies if the version of the package is not equal to or greater than the version specified in require. Can be called as either a static or object method call.

Previous | Home | Next
8.227. Time::tm | Book Index | 8.229. User::grent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.229. User::grent

Overrides core getgrent, getgruid, and getgrnam functions with versions that return User::grent objects. The object returned has methods with the same names as the structure fields they return. That is, to return the field name, use the name method:

use User::grent;
$gr = getgrgid(0) or die "No group zero";
if ( $gr->name eq 'wheel' && @{$gr->members} > 1 ) {
    print "gid zero name wheel, with other members";
}

The field names (and therefore the method names) are the same as the names of the fields in the group structure from the C file grp.h: name, passwd, gid, and members (not mem). The first three return scalars, the last an array reference. You can access the fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and prepending gr_ to the method name (for example, gr_name). Exports four functions.

getgr
$gr->getgr(arg)

Frontend that forwards a numeric arg to getgrid and other args to getgrname.

getgrent
$gr = getgrent(  )

Successive calls to getgrent return objects representing successive entries from the group file.

getgrgid
$gr = getgrgid(gid)

Accesses the group file by group ID gid.

getgrnam
$gr = getgrnam(gname)

Accesses the group file by group name gname.

Previous | Home | Next
8.228. UNIVERSAL | Book Index | 8.230. User::pwent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.230. User::pwent

Overrides core getpwent, getpwuid, and getpwnam functions with versions that return User::pwent objects. The object returned has methods with the same names as the structure fields they return. That is, to return the field name, use the name method:

use User::pwent;
$pw = getpwnam('daemon') or die "No daemon user";
if ( $pw->uid == 1 && $pw->dir =~ m#^/(bin|tmp)?$# ) {
    print "gid 1 on root dir";
}

The field names (and therefore the method names) are the same as the names of the fields in the passwd structure from the C file pwd.h: name, passwd, uid, gid, quota, comment, gecos, dir, and shell. You can access the fields with the methods or by importing the fields into your namespace with the :FIELDS import tag and prepending pw_ to the method name (for example, pw_name). Exports four functions.

getpw
$pw->getpw(arg)

Frontend that forwards a numeric arg to getpwuid and other args to getpwnam.

getpwent
$pw->getpwent(  )

Successive calls to getpwent return objects representing successive entries from the password table.

getpwnam
$pw->getpwnam(name)

Accesses the password table by user's name.

getpwuid
$pw->getpwuid(uid)

Accesses the password table by user's ID number, uid.

Previous | Home | Next
8.229. User::grent | Book Index | 8.231. utf8
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.231. utf8

While Perl's implementation of Unicode support is incomplete, the use utf8 pragma tells the Perl parser to allow UTF-8 in the program text in its current lexical scope. no utf8 tells Perl to switch back to treating text as literal bytes in the current lexical scope. You'll probably use use utf8 only for compatibility, since future versions of Perl will standardize on the UTF-8 encoding for source text.

use utf8 has the following effects: bytes with their high-bit set (identifiers, string constants, constant regular expressions, package names) will be treated as literal UTF-8 characters and regular expressions within the scope of the utf8 pragma and will default to using character semantics instead of byte semantics. For example:

@bytes_or_chars = split //, $data;  # May split to bytes if data
                                    # $data isn't UTF-8
            {
                use utf8;                       # Forces char semantics
                @chars = split //, $data;       # Splits characters
            }
Previous | Home | Next
8.230. User::pwent | Book Index | 8.232. vars
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.232. vars

Pragma that, given a list of variable names, predeclares all variables in the list, making sure they are available to routines with delayed loading (e.g., routines loaded by the AutoLoader or SelfLoader). This allows you to use the variables under use strict. The vars pragma also disables warnings about typographical errors.

use vars qw($var1 @var2 %var3);
Previous | Home | Next
8.231. utf8 | Book Index | 8.233. vmsish
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.233. vmsish

Controls VMS-specific language features. Currently, there are four VMS-specific features available: status ($?), exit, time, and hushed. If you're not using VMS, then this module won't have any affect.

vmsish is shipped with the Perl 5.8 source kit.

For example, without vmsish, you can't execute a hushed version of exit:

$ perl -e"exit 44;" Non-hushed error exit
%SYSTEM-F-ABORT, abort DCL message $ show sym $STATUS $STATUS ==
"%X0000002C"

When you use vmsish, you get . . . nothing!

$ perl -e"use vmsish qw(hushed); exit 44;"

vmsish implements the following options.

status
Causes $? and system to return the native VMS exit status instead of emulating the POSIX exit status.

exit
Causes exit 1 to produce a successful exit (with status SS$_NORMAL) instead of emulating Unix exit(), which considers exit 1 as an indication of an error. As with the CRTL's exit() function, exit 0 is also mapped to an exit status of SS$_NORMAL, and any other argument to exit() is used directly as Perl's exit status.

time
Makes all times relative to the local time zone instead of the default Universal Time (a.k.a. Greenwich Mean Time, or GMT).

hushed
Suppresses printing of VMS status messages to SYS$OUTPUT and SYS$ERROR if Perl terminates with an error status and allows programs that are expecting Unix-style Perl to avoid parsing VMS error messages. It does not supress any messages from Perl itself, just the messages generated by DCL after Perl exits. The DCL symbol $STATUS will still have the termination status, but with a high-order bit set.

Previous | Home | Next
8.232. vars | Book Index | 8.234. XS::Typemap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.234. XS::Typemap

Tests XS typemaps distributed with Perl. XS::Typemap implements a function that's available for each and every typemap that's in Perl. Generally, you should never use XS::Typemap directly. This module ships with the Perl 5.8 source kit.

Previous | Home | Next
8.233. vmsish | Book Index | IV. CGI
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part IV. CGI

Chapter 9, "CGI Overview"

Chapter 10, "The CGI.pm Module"

Chapter 11, "Web Server Programmingwith mod_perl"

Previous | Home | Next
8.234. XS::Typemap | Book Index | 9. CGI Overview
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 9. CGI Overview

Contents:

A Typical CGI Interaction
URL Encoding
Extra Path Information
CGI Environment Variables

Perl is the most commonly used language for CGI programming on the World Wide Web.The Common Gateway Interface (CGI) is an essential tool for creating and managing comprehensive web sites. With CGI, you can write scripts that create interactive, user-driven applications.

CGI allows the web server to communicate with other programs that are running on the same machine. For example, with CGI, the web server can invoke an external program, while passing user-specific data to the program (such as what host the user is connecting from, or input the user has supplied through an HTML form). The program then processes that data, and the server passes the program's response back to the web browser.

Rather than limiting the Web to documents written ahead of time, CGI enables web pages to be created on the fly, based upon the input of users. You can use CGI scripts to create a wide range of applications, from surveys to search tools, from Internet service gateways to quizzes and games. You can increment the number of users who access a document or let them sign an electronic guestbook. You can provide users with all types of information, collect their comments, and respond to them.

For Perl programmers, there are two approaches you can take to CGI. They are:

  • Programs that handle all CGI interaction directly, without the use of a module such as CGI.pm. While often frowned upon by Perl programmers because it's more likely to introduce bugs, bypassing the modules has the advantage of avoiding the overhead of CGI.pm for quick, dirty tasks. This chapter explains the concepts of CGI necessary if you intend to write CGI programs from scratch.

  • CGI.pm is a Perl module designed to facilitate CGI programming. For non-trivial CGI programs, especially ones that need to maintain state over multiple transactions, CGI.pm is indispensable, and is included in the standard Perl distribution as of Perl 5.004. Rather than discuss it in Chapter 8, "Standard Modules", with the rest of the standard libraries, however, its complexity and importance made it a candidate for its own chapter, Chapter 10, "The CGI.pm Module".

One performance hit for CGI programs is that the Perl interpreter needs to be started up each and every time a CGI script is called. For improving performance on Apache systems, the mod_perl Apache module embeds the Perl interpreter directly into the server, avoiding the startup overhead. Chapter 11, "Web Server Programmingwith mod_perl" talks about installing and using mod_perl.

9.1. A Typical CGI Interaction

For an example of a CGI application, suppose you create a guestbook for your website. The guestbook page asks users to submit their first name and last name using a fill-in form composed of two input text fields. Figure 9-1 shows the form you might see in your browser window.

Figure 9-1. HTML form

The HTML that produces this form might read as follows:

<HTML><HEAD><TITLE>Guestbook</TITLE></HEAD>
<BODY>
<H1>Fill in my guestbook!</H1>
<FORM METHOD="GET" ACTION="/cgi-bin/guestbook.pl">
<PRE>
First Name:   <INPUT TYPE="TEXT" NAME="firstname">
Last Name:    <INPUT TYPE="TEXT" NAME="lastname">

<INPUT TYPE="SUBMIT">    <INPUT TYPE="RESET">
</FORM>

The form is written using special "form" tags, as follows:

  • The <form> tag defines the method used for the form (either GET or POST) and the action to take when the form is submitted—that is, the URL of the CGI program to pass the parameters to.

  • The <input> tag can be used in many different ways. In its first two invocations, it creates a text input field and defines the variable name to associate with the field's contents when the form is submitted. The first field is given the variable name firstname and the second field is given the name lastname.

  • In its last two invocations, the <input> tag creates a "submit" button and a "reset" button.

  • The </form> tag indicates the end of the form.

When the user presses the "submit" button, data entered into the <input> text fields is passed to the CGI program specified by the action attribute of the <form> tag (in this case, the /cgi-bin/guestbook.pl program).

9.1.1. Transferring the Form Data

Parameters to a CGI program are transferred either in the URL or in the body text of the request. The method used to pass parameters is determined by the method attribute to the <form> tag. The GET method says to transfer the data within the URL itself; for example, under the GET method, the browser might initiate the HTTP transaction as follows:

GET /cgi-bin/guestbook.pl?firstname=Joe&lastname=Schmoe HTTP/1.0

The POST method says to use the body portion of the HTTP request to pass parameters. The same transaction with the POST method would read as follows:

POST /cgi-bin/guestbook.pl HTTP/1.0
        ... [More headers here]

firstname=Joe&lastname=Schmoe

In both of these examples, you should recognize the firstname and lastname variable names that were defined in the HTML form, coupled with the values entered by the user. An ampersand (&) is used to separate the variable=value pairs.

The server now passes the variable=value pairs to the CGI program. It does this either through Unix environment variables or in standard input (STDIN). If the CGI program is called with the GET method, then parameters are expected to be embedded into the URL of the request, and the server transfers them to the program by assigning them to theQUERY_STRING environment variable. The CGI program can then retrieve the parameters from QUERY_STRING as it would read any environment variable (for example, from the %ENV hash in Perl). If the CGI program is called with the POST method, parameters are expected to be embedded into the body of the request, and the server passes the body text to the program as standard input (STDIN).

Other environment variables defined by the server for CGI store such information as the format and length of the input, the remote host, the user, and various client information. They also store the server name, the communication protocol, and the name of the software running the server. (We provide a list of the most common CGI environment variables later in this chapter.)

The CGI program needs to retrieve the information as appropriate and then process it. The sky's the limit on what the CGI program actually does with the information it retrieves. It might return an anagram of the user's name, or tell her how many times her name uses the letter "t," or it might just compile the name into a list that the programmer regularly sells to telemarketers. Only the programmer knows for sure.

9.1.2. Creating Virtual Documents

Regardless of what the CGI program does with its input, it's responsible for giving the browser something to display when it's done. It must either create a new document to be served to the browser or point to an existing document. On Unix, programs send their output to standard output (STDOUT) as a data stream that consists of two parts. The first part is either a full or partial HTTP header that (at minimum) describes the format of the returned data (e.g., HTML, ASCII text, GIF, etc.). A blank line signifies the end of the header section. The second part is the body of the output, which contains the data conforming to the format type reflected in the header. For example:

Content-type: text/html
<HTML>
<HEAD><TITLE>Thanks!</TITLE></HEAD>
<BODY><H1>Thanks for signing my guest book!</H1>
        ...
</BODY></HTML>

In this case, the only header line generated is Content-type, which gives the media format of the output as HTML (text/html). This line is essential for every CGI program, since it tells the browser what kind of format to expect. The blank line separates the header from the body text (which, in this case, is in HTML format as advertised).

The server transfers the results of the CGI program back to the browser. The body text is not modified or interpreted by the server in any way, but the server generally supplies additional headers with information such as the date, the name and version of the server, etc.

CGI programs can also supply a complete HTTP header itself, in which case the server does not add any additional headers but instead transfers the response verbatim as returned by the CGI program. The server needs to be configured to allow this behavior; see your server documentation on NPH (no-parsed headers) scripts for more information.

Here is the sample output of a program generating an HTML virtual document, with a complete HTTP header:

HTTP/1.0 200 OK
Date:  Thursday, 28-June-96 11:12:21 GMT
Server: NCSA/1.4.2
Content-type: text/html
Content-length: 2041

<HTML>
<HEAD><TITLE>Thanks!</TITLE></HEAD>
<BODY>
<H1>Thanks for signing my guestbook!</H1>
         ...
</BODY>
</HTML>

The header contains the communication protocol, the date and time of the response, and the server name and version. (200 OK is a status code generated by the HTTP protocol to communicate the status of a request, in this case successful.) Most importantly, the header also contains the content type and the number of characters (equivalent to the number of bytes) of the enclosed data.

The result is that after users click the "submit" button, they see the message contained in the HTML section of the response thanking them for signing the guestbook.

Previous | Home | Next
IV. CGI | Book Index | 9.2. URL Encoding
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.2. URL Encoding

Before data supplied on a form can be sent to a CGI program, each form element's name (specified by the name attribute) is equated with the value entered by the user to create a key/value pair. For example, if the user entered "30" when asked for his or her age, the key/value pair would be "age=30". In the transferred data, key/value pairs are separated by the ampersand (&) character.

Since under the GET method the form information is sent as part of the URL, form information can't include any spaces or other special characters that are not allowed in URLs, and also can't include characters that have other meanings in URLs, like slashes (/). (For the sake of consistency, this constraint also exists when the POST method is being used.) Therefore, the web browser performs some special encoding on user-supplied information.

Encoding involves replacing spaces and other special characters in the query strings with their hexadecimal equivalents. (Thus, URL encoding is also sometimes called hexadecimal encoding.) Suppose a user fills out and submits a form containing his or her birthday in the syntax mm/dd/yy (e.g., 11/05/73). The forward slashes in the birthday are among the special characters that can't appear in the client's request for the CGI program. Thus, when the browser issues the request, it encodes the data. The following sample request shows the resulting encoding:

POST /cgi-bin/birthday.pl HTTP/1.0
Content-length: 21

birthday=11%2F05%2F73

The sequence %2F is actually the hexadecimal equivalent of the slash character.

CGI scripts have to provide some way to "decode" the form data that the client has encoded. The best way to do this is to use CGI.pm (covered in Chapter 10, "The CGI.pm Module") and let someone else do the work for you.

Previous | Home | Next
9. CGI Overview | Book Index | 9.3. Extra Path Information
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.3. Extra Path Information

In addition to passing query strings, you can pass additional data, known as extra path information, as part of the URL. The server gauges where the CGI program name ends; anything following is deemed "extra" and is stored in the environment variable PATH_INFO. The following line calls a script with extra path information:

http://some.machine/cgi-bin/display.pl/cgi/cgi_doc.txt

In this example, we use a script with a .pl suffix to make it clear where the CGI program's path ends and the extra path information begins. Everything after display.pl is the extra pathand is placed in the PATH_INFO environment variable. The PATH_TRANSLATED variable is also set, mapping the PATH_INFO to the DOCUMENT_ROOT directory (e.g., /usr/local/etc/httpd/public/cgi/cgi_doc.txt).

Previous | Home | Next
9.2. URL Encoding | Book Index | 9.4. CGI Environment Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.4. CGI Environment Variables

Most of the information needed by CGI programs is made available via Unix environment variables. Programs can access this information as they would any environment variable (via the %ENV hash in Perl). The table below lists environment variables commonly available through CGI. However, since servers occasionally vary on the names of environment variables they assign, check with your own server documentation for more information.

Environment variable | Content returned
AUTH_TYPE | The authentication method used to validate a user. See REMOTE_IDENT and REMOTE_USER.
CONTENT_LENGTH | The length of the query data (in bytes or the number of characters)passed to the CGI program through standard input.
CONTENT_TYPE | The media type of the query data, such as text/html.
DOCUMENT_ROOT | The directory from which web documents are served.
GATEWAY_INTERFACE | The revision of the Common Gateway Interface that the server uses.
HTTP_ACCEPT | A list of the media types that the client can accept.
HTTP_COOKIE | A list of cookies defined for that URL.
HTTP_FROM | The email address of the user making the query (many browsers do not support this variable).
HTTP_REFERER | The URL of the document the client read before accessing the CGI program.
HTTP_USER_AGENT | The browser the client is using to issue the request.
PATH_INFO | Extra path information passed to a CGI program.
PATH_TRANSLATED | The translated version of the path given by the variable PATH_INFO.
QUERY_STRING | The query information passed to the program. It is appended to the URL following a question mark (?).
REMOTE_ADDR | The remote IP address from which the user is making the request.
REMOTE_HOST | The remote hostname from which the user is making the request.
REMOTE_IDENT | The user making the request.
REMOTE_USER | The authenticated name of the user making the query.
REQUEST_METHOD | The method with which the information request was issued (e.g., GET, POST, HEAD).
SCRIPT_NAME | The virtual path (e.g., /cgi-bin/program.pl) of the script being executed.
SERVER_NAME | The server's hostname or IP address.
SERVER_PORT | The port number of the host on which the server is running.
SERVER_PROTOCOL | The name and revision number of the server protocol.
SERVER_SOFTWARE | The name and version of the server software that is answering the client request.

Here's a simple Perl CGI script that uses environment variables to display various information about the server:

#!/usr/local/bin/perl

print << EOF
Content-type: text/html

<HTML>
<HEAD><TITLE>About this Server</TITLE></HEAD>
<BODY><H1>About this Server</H1>
<HR><PRE>
Server Name:        $ENV{'SERVER_NAME'}<BR>
Running on Port:    $ENV{'SERVER_PORT'}<BR>
Server Software:    $ENV{'SERVER_SOFTWARE'}<BR>
Server Protocol:    $ENV{'SERVER_PROTOCOL'}<BR>
CGI Revision:       $ENV{'GATEWAY_INTERFACE'}<BR>
<HR></PRE>
</BODY></HTML>

The preceding program outputs five environments as an HTML document. In Perl, you can access the environment variables with the %ENV hash. Here's typical output of the program:

<HTML>
<HEAD><TITLE>About this Server</TITLE></HEAD>
<BODY><H1>About this Server</H1>
<HR><PRE>
Server Name:          www.whatever.com
Running on Port:      80
Server Software:      NCSA/1.4.2
Server Protocol:      HTTP/1.0
CGI Revision:         CGI/1.1
<HR></PRE>
</BODY></HTML>
Previous | Home | Next
9.3. Extra Path Information | Book Index | 10. The CGI.pm Module
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 10. The CGI.pm Module

Contents:

HTML Tag Generation
Importing Method Groups
Maintaining State
Named Parameters
Using JavaScript Features
Debugging
CGI.pm Reference

CGI.pm is a Perl module for creating and parsing CGI forms. It has been distributed with the Perl source kit since 5.004, but you can upgrade your existing CGI.pm installation from CPAN. As of the writing of this edition, the current version of CGI.pm is 2.81.

CGI is an object-oriented module. Don't let the object-oriented nature scare you off, though; CGI.pm is very easy to use, as evidenced by its overwhelming popularity among all levels of Perl programmers. To give you an idea of how easy it is to use CGI.pm, let's take a scenario in which a user fills out and submits a form containing her birthday. Without CGI.pm, the script would have to translate the URL-encoded input by hand (probably using a series of regular expressions) and assign it to a variable. For example, you might try an antiquated parsing method like this:

#!/usr/local/bin/perl
# CGI script without CGI.pm

$size_of_form_info = $ENV{'CONTENT_LENGTH'};
read ($STDIN, $form_info, $size_of_form_info);

# Split up each pair of key/value pairs
foreach $pair (split (/&/, $form_info)) {

   # For each pair, split into $key and $value variables
   ($key, $value) = split (/=/, $pair);

   # Get rid of the pesky %xx encodings
   $key =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
   $value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;

   # Use $key as index for $parameters hash, $value as value
   $parameters{$key} = $value;
}

# Print out the obligatory content type line
print "Content-type: text/plain\n\n";

# Tell the user what they said
print "Your birthday is on " . $parameters{birthday} . ".\n";

Regardless of whether this code actually works, you must admit it's ugly, and completely ignores important details such as dealing with tainted input. With CGI.pm, the script could be written as:

#!/usr/local/bin/perl -w
# CGI script with CGI.pm

use CGI;

my $query = CGI->new( );

my $bday = $query->param("birthday");

print $query->header(-type => 'text/plain');
print $query->p("Your birthday is $bday.");

Even for this tiny program, you can see that CGI.pm can alleviate many of the headaches associated with CGI programming.

As with any Perl module, the first thing you do is call the module with use. You then call the constructor (new( )), creating a new CGI object called $query. Next, get the value of the birthday parameter from the CGI program using the param method. Note that CGI.pm does all the work of determining whether the CGI program is called by the GET or POST methods, and it does all the URL decoding for you. To generate output, use the header method to return the content type header and the p method to generate a paragraph marker <P> tag.

However, this is only the tip of the iceberg as far as what CGI.pm can do for you. There are three basic categories of CGI.pm methods: CGI handling, creating forms, and retrieving environment variables. (A fourth category is creating HTML tags, but we don't cover those in detail.) Table 10-1 lists most of these methods. They are also covered in more detail later in this chapter.

Table 10-1. CGI.pm methods

Method | Description
CGI handling
keywords | Gets keywords from an <ISINDEX> search
param | Gets (or sets) the value of parameters
append | Appends to a parameter
import_names | Imports variables into a namespace
delete | Deletes a parameter
delete_all | Deletes all parameters
save | Saves all parameters to a file
self_url | Creates self-referencing URL
url | Gets URL of current script without query information
header | Creates HTTP header
redirect | Creates redirection header
cookie | Gets (or sets) a cookie
nph | Declares this to be a NPH script
dump | Prints all name/value pairs
Form generation
start_html | Generates an <HTML> tag
end_html | Generates an </HTML> tag
autoEscape | Sets whether to use automatic escaping
isindex | Generates an <ISINDEX> tag
startform | Generates a <FORM> tag
start_multipart_form | Generates a <FORM> tag for multipart/form-data encoding
textfield | Generates an <INPUT TYPE=TEXT> tag
textarea | Generates an <TEXTAREA> tag
password_field | Generates an <INPUT TYPE=PASSWORD> tag
filefield | Generates an <INPUT TYPE=FILE> tag
popup_menu | Generates a pop-up menu via <SELECT SIZE=1> and <OPTION> tags
scrolling_list | Generates a scrolling list via <SELECT> and <OPTION> tags
checkbox_group | Generates a group of checkboxes via multiple <INPUT TYPE=CHECKBOX> tags
checkbox | Generates a single checkbox via an <INPUT TYPE=CHECKBOX> tag
radio_group | Generates a group of radio buttons via <INPUT TYPE=RADIO> tags
submit | Generates a <SUBMIT> tag
reset | Generates a <RESET> tag
defaults | Generates a <DEFAULTS> tag
hidden | Generates an <INPUT TYPE=HIDDEN> tag
image_button | Generates a clickable image button via a <SELECT> tag
button | Generates a JavaScript button
Handling environment variables
accept | Gets accept types from ACCEPT header
user_agent | Gets value of USER_AGENT header
path_info | Gets value of EXTRA_PATH_INFO header
path_translated | Gets value of PATH_TRANSLATED header
remote_host | Gets value of REMOTE_HOST header
raw_cookie | Gets value of HTTP_COOKIE header
script_name | Gets value of SCRIPT_NAME header
referer | Gets value of REFERER header
auth_type | Gets value of AUTH_TYPE header
remote_user | Gets value of REMOTE_USER header
user_name | Gets user name (not via headers)
request_method | Gets value of REQUEST_METHOD header

10.1. HTML Tag Generation

In addition to the form-generation methods, CGI.pm includes a group of methods for creating HTML tags. The names of the HTML tag methods generally follow the HTML tag name (e.g., p for <P>) and take named parameters that are assumed to be valid attributes for the tag (e.g., img(src=>'camel.gif') becomes <IMG SRC="camel.gif">). We do not list all tags in this book; see the CGI.pm manpage for more information, or the book Official Guide to Programming with CGI.pm by Lincoln Stein (John Wiley & Sons, 1998).

Previous | Home | Next
9.4. CGI Environment Variables | Book Index | 10.2. Importing Method Groups
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.2. Importing Method Groups

The syntax for calling CGI methods can be unwieldy. However, if you choose not to use the object form of CGI.pm, you can import individual methods instead. The "birthday" example shown earlier could be written even more simply as:

#!/usr/local/bin/perl -w

use CGI qw(param header p);

my $bday = param("birthday");

print header('text/plain');
print "Your birthday is $bday.";

By importing the param, header, and p methods into your namespace, you no longer have to use the new constructor (since it is called automatically now), and you don't need to specify a CGI object with every method call.

CGI.pm also lets you import groups of methods, which can make your programs much simpler and more elegant. For example, to import all form-creation methods and all CGI-handling methods:

use CGI qw/:form :cgi/;

The method groups supported by CGI.pm are:

:cgi
All CGI-handling methods

:cgi-lib
All methods supplied for backward compatibility with cgi-lib

:form
All form-generation methods

:html
All HTML methods

:html2
All HTML 2.0 methods

:html3
All HTML 3.0 methods

:netscape
All methods generating Netscape extensions

:ssl
All SSL methods

:standard
All HTML 2.0, form-generation, and CGI methods

:all
All available methods

You can also define new methods for HTML tag generation by simply listing them on the import line and letting CGI.pm make some educated guesses. For example:

use CGI shortcuts,smell;

print smell {type=>'garlic',
           intensity=>'strong'}, "Scratch here!";

This will cause the following tag to be generated:

<SMELL TYPE="garlic" INTENSITY="strong">Scratch here!</SMELL>
Previous | Home | Next
10. The CGI.pm Module | Book Index | 10.3. Maintaining State
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.3. Maintaining State

One of the first complications for any nontrivial CGI script is how to "maintain state." Since HTTP is a stateless protocol, there's no built-in mechanism for keeping track of requests from the server end. A CGI transaction involving multiple forms, therefore, needs to find a way to remember information supplied on previous forms. One way to deal with this issue is to use cookies, which allow the CGI program to save information on the browser's end; but not all browsers support cookies, and some users are uncomfortable with the perceived privacy infringement associated with cookies.

CGI.pm simplifies maintaining state without cookies. When a CGI.pm script is called multiple times, the input fields are given default values from the previous invocation.

Previous | Home | Next
10.2. Importing Method Groups | Book Index | 10.4. Named Parameters
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.4. Named Parameters

For most CGI.pm methods, there are two syntax styles. In the "standard" style, the position of the parameters determines how they will be interpreted—for example, parameter 1 is the name that the script should assign, parameter 2 is the initial value, etc. For example:

print $query=textfield('username', 'anonymous');

In the "named parameters" style, the parameters can be assigned like a hash, and the order doesn't matter. For example:

print $query->textfield(-name=>'name',
                        -default=>'value');

If you want to use named parameters, just call the use_named_parameters method early in the script.

Which syntax style should you use? It depends on how lazy you are and how much control you need. Generally, standard syntax is faster to type. However, it is also harder to read, and there are many features that are simply not available using standard syntax (such as JavaScript support). In general, we recommend using the named parameters syntax for all but the most trivial scripts.

Previous | Home | Next
10.3. Maintaining State | Book Index | 10.5. Using JavaScript Features
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.5. Using JavaScript Features

CGI.pm supports JavaScript scripting by allowing you to embed a JavaScript script into the HTML form within <SCRIPT> tags and then calling the script using the -script parameter to the start_html method. You can then call the appropriate JavaScript functions to the form elements.

Previous | Home | Next
10.4. Named Parameters | Book Index | 10.6. Debugging
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.6. Debugging

A complication of writing CGI scripts is that when debugging the script, you have to wrestle with the web server environment. CGI.pm provides support for debugging the script on the command line.

If you run the script on the command line without arguments, you will be placed into an "offline" mode, in which name/value pairs can be entered one-by-one. When you press Ctrl-D, the script runs. For example:

% birthday
(offline mode: enter name=value pairs on standard input)
birthday=6/4/65
^D
Content-type: text/html

<P>Your birthday is 6/4/65.</P>

You can also supply the name/value parameters directly on the command line. For example:

% test birthday=6/4/65
Content-type: text/html

<P>Your birthday is 6/4/65.</P>

Multiple values can be separated by spaces (as separate arguments on the command line) or by ampersands (as in URL-encoded syntax). In fact, you can use URL-encoded syntax on the command line. This makes it easy to supply raw CGI input to the script for testing purposes. Just remember to protect the ampersand from the shell.

% test 'birthday=6%2f4%2f65&name=Fred%20Flintstone'
Content-type: text/html

<P>Fred Flintstone, your birthday is 6/4/65.</P>
Previous | Home | Next
10.5. Using JavaScript Features | Book Index | 10.7. CGI.pm Reference
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.7. CGI.pm Reference

The following methods are supported by CGI.pm.

accept
$query->accept(['content_type'])

Returns a list of media types that the browser accepts.

content_type
If specified, returns instead the browser's preference for the specified content type, between 0.0 and 1.0

append
$query->append(-name=>'name',-values=>'value')

Appends a value or list of values to the named parameter.

-name=>'name'
The parameter to append.

-values=>'value'
The value to append. Multiple values can be specified as a reference to an anonymous array.

auth_type
auth_type(  )

Returns the authorization method.

autoEscape
$query->autoEscape(undef)

Turns off autoescaping of form elements.

button
print $query->button('name','function')

Generates a JavaScript button.

name
The name of the button.

function
The function to execute when the button is clicked. Using named parameters, the syntax is:

print $query->button(-name=>'name',
                     -value=>'label',
                     -onClick=>"function");
-value=>'label'
The label to display for the button

checkbox
print $query->checkbox('name' [,'checked','value','label'])

Generates a single checkbox.

name
The name to assign the input to (required).

checked
Checkbox should be checked initially.

value
The value to return when checked (default is on).

label
The label to use for the checkbox (default is the name of the checkbox). Using named parameters, the syntax is:

print $query->checkbox(-name=>'name',
                       -checked=>'checked',
                       -value=>'value',
                       -label=>'label',
                       -onClick=>function);
-onClick=>function
Browser should execute function when the user clicks on any checkbox in the group

checkbox_group
print $query->checkbox_group('name', \@list [, selected,'true',\%labelhash ])

Generates a list of checkbox elements.

name
The name to assign the input to (required).

\@list
An array reference with the list items. You can also use an anonymous array reference.

selected
The menu item(s) to be initially selected (default is that nothing is selected). This can be a single value or a reference to an array of values.

'true'
Insert newlines between the checkboxes.

\%labelhash
A hash reference listing labels for each list item. Default is the list text itself. See popup_menu for an example. Using named parameters, the syntax is:

print $query->checkbox_group(-name=>'name',
                             -values=>\@list,
                             -default=>selected,
                             -linebreak=>'true',
                             -labels=>\%labelhash,
                             -columns=>n,
                             -columnheader=>'string',
                             -rows=>m,
                             -rowheader=>'string',
                             -onClick=>function);
-columns=>n
The number of columns to use.

-columnheader=>'string'
A header for the column.

-rows=m
The number of rows to use. If omitted, and -columns is specified, the rows will be calculated for you.

-rowheader=>'string'
A header for the row.

-onClick=>function
Browser should execute function when the user clicks on any checkbox in the group.

cookie
$cookie=$query->cookie('name')

Defines or retrieves a cookie. See also header.

name
Name of the cookie (required). Using named parameters, the syntax is:

$cookie = $query->cookie(-name=>'name',
                         -value=>'value',
                         -expires=>'expcode',
                         -path=>'partial_url',
                         -domain=>'domain_name',
                         -secure=>1);
print $query->header(-cookie=>$cookie);
-value=>'value'
A value to assign to the cookie. You can supply a scalar value, or a reference to an array or hash. If omitted, a cookie will be retrieved rather than defined.

-expires=>expcode
Specifies an expiration timestamp (such as +3d for three days). Values for expcode are:

n s
n seconds

n m
n minutes

n h
n hours

n d
n days

n M
n months

n y
n years

day_of_week, dd-MMM-YY hh:mm:ss GMT
At the specified time.

now
Expires immediately.

-path=>'partial_url'
The partial URL for which the cookie is valid. Default is the current URL.

-domain=>'domain_name'
The domain for which the cookie is valid.

-secure=>1
Use this cookie only for a secure session.

defaults
print $query->defaults('label')

Generates a button that resets the form to its defaults. See also reset.

'label'
The label to use for the button. If omitted, the label is Defaults.

delete
$query->delete('parameter')

Deletes a parameter.

'parameter'
The parameter to delete

delete_all
$query->delete_all(  )

Deletes the entire CGI object.

dump
print $query->dump([true])

Dumps all name/value pairs as an HTML list.

true
If specified, prints as plain text

end_html
print $query->end_html(  )

Ends an HTML document.

filefield
print $query->filefield('name' [,'default',size,maxlength ])

Generates a file upload field for Netscape browsers.

name
The filename to assign the supplied file contents to (required)

default
The initial value (filename) to place in the text field

size
The size of the text field (in characters)

maxlength
The maximum length of the text field (in characters)

Using named parameters, the syntax is:

print $query->textfield(-name=>'name',
                        -default=>'value',
                        -size=>size,
                        -maxlength=>maxlength,
                        -override=>1,
                        -onChange=>function,
                        -onFocus=>function,
                        -onBlur=>function,
                        -onSelect=>function);
-override=>1
Text field should not inherit its value from a previous invocation of the script

-onChange=>function
Browser should execute function when the user changes the text field

-onFocus=>function
Browser should execute function when the focus is on the text field

-onBlur=>function
Browser should execute function when the focus leaves the text field

-onSelect=>function
Browser should execute function when the user changes a selected portion of the text field

header
print $query->header([content_type ,status ,headers])

Generates the HTTP header for the document.

content_type
The content type to return. Default is text/html.

status
The HTTP status code and description to return. Default is 200 OK.

headers
Additional headers to include, such as Content-Length: 123. Using named parameters, the syntax is:

print $query->header(-type=>'content_type',
                     -nph=>1,
                     -status=>'status_code',
                     -expires=>'expcode',
                     -cookie=>'cookie',
                     -target=>'frame',
                     -header=>'value');
-type=>content_type
Specifies the content type.

-nph=>1
Uses headers for a no-parse-header script.

-status=>status_code
Specifies the status code.

-expires=>expcode
Specifies an expiration timestamp (such as +3d for three days). Values for expcode are:

n s
n seconds

n m
n minutes

n h
n hours

n d
n days

n M
n months

n y
n years

day_of_week, dd-MMM-YY hh:mm:ss GMT
At the specified time

now
Expires immediately

-cookie=>cookie
Specifies a cookie. The cookie may be a scalar value or an array reference.

-header=>value
Specifies any HTTP header.

-target=>frame
Writes to specified frame.

hidden
print $query->hidden('name', 'value' [,'value'... ])

Generates a hidden text field.

name
The name to give the value (required).

value
The value to assign to name. Multiple values can be specified. Using named parameters, the syntax is:

print $query->hidden(-name=>'name',
                       -default=>'value');

With named parameters, the value can also be represented as a reference to an array, such as:

print $query->hidden(-name=>'name',
                     -default=>['value1', 'value2',
...  ]);
image_button
print $query->image_button('name','url' [,'align'])

Generates a clickable image map.

name
The name to use. When clicked, the x,yposition is returned as name.xand name.y, respectively.

url
The URL of the image for the image map.

align
The alignment type. May be TOP, BOTTOM, or MIDDLE. Using named parameters, the syntax is:

print $query->image_button(-name=>'name',
                           -src=>'url',
                           -align=>'align',
                           -onClick=>function);
-onClick=>function
Browser should execute function when the user clicks on the image

import_names
$query->import_names('package')

Creates variables in the specified package. Called import in older versions of CGI.pm.

package
The package to import names into

isindex
print $query->isindex([action])

Generates an <ISINDEX> tag.

action
The URL of the index script. Default is the current URL. Using named parameters, the syntax is:

print $query->isindex(-action=>$action);
keywords
@keyarray = $query->keywords(  )

Retrieves keywords from an <ISINDEX> search.

@keyarray
The array that will contain the retrieved keywords

nph
nph(1)

Treats a CGI script as a no-parsed-header (NPH) script.

param
@name = $query->param([parameter [newvalue1, newvalue2, ...] ])

Gets or sets parameter names.

@name
The array that will contain the parameter names.

parameter
An optional single parameter to fetch. When used with no arguments, param returns a list of all known parameter names.

newvalue1, newvalue2, ...
The optional new values to assign to the parameter. Using named parameters, the syntax is:

$query->param(-name=>'parameter',
              -value=>'newvalue');

or:

$query->param(-name=>'parameter',
              -values=>'newvalue1', 'newvalue2', ...);
password_field
print $query->password_field('name' [,'value',size,maxlength ])

Generates a password input field.

name
The name to assign the input to (required).

value
The default password to place in the password field.

size
The size of the password field (in characters).

maxlength
The maximum length of the password field (in characters). Using named parameters, the syntax is:

print $query->password_field(-name=>'name',
                             -default=>'value',
                             -size=>size,
                             -maxlength=>maxlength,
                             -override=>1,
                             -onChange=>function,
                             -onFocus=>function,
                             -onBlur=>function,
                             -onSelect=>function);
-override=>1
Text field should not inherit its value from a previous invocation of the script

-onChange=>function
Browser should execute function when the user changes the text field

-onFocus=>function
Browser should execute function when the focus is on the text field

-onBlur=>function
Browser should execute function when the focus leaves the text field

-onSelect=>function
Browser should execute function when the user changes a selected portion of the text field

path_info
path_info(  )

Returns extra path information.

path_translated
path_translated(  )

Returns translated extra path information.

popup_menu
print $query->popup_menu('name', \@array [,'selected', \%labelhash])

Generates a popup menu.

name
The name to assign the input to (required).

\@array
An array reference listing the menu items. You can also use an anonymous array reference (see example below).

selected
The menu item to be initially selected (default is first menu item or the item selected in previous queries).

\%labelhash
A hash reference listing labels for each menu item. Default is menu item text. For example:

%labels = ('UPS'=>'United Parcel Service (UPS)',
         'FedExO'=>'Federal Express Overnight - 10AM delivery',
         'FedExS'=>'Federal Express Standard - 2PM delivery',
         'FedEx2'=>'Federal Express 2nd Day Delivery');

print $query->popup_menu('delivery_method',
                       ['UPS', 'FedExO', 'FedExS', 'FedEx2'],
                       'FedExO',
                       \%labels);

Using named parameters, the syntax is:

print $query->popup_menu(-name=>'name',
                         -values=>\@array,
                         -default=>'selected',
                         -labels=>\%labelhash,
                         -onChange=>function,
                         -onFocus=>function,
                         -onBlur=>function);
-onChange=>function
Browser should execute function when the user changes the text field

-onFocus=>function
Browser should execute function when the focus is on on the text field

-onBlur=>function
Browser should execute function when the focus leaves the text field

radio_group
print $query->radio_group('name', \@list [, selected, 'true', \%label ])

Generates a set of radio buttons.

name
The name to assign the input to (required).

\@list
An array reference with the list items. You can also use an anonymous array reference.

selected
The menu item to be initially selected.

'true'
Inserts newlines between radio buttons.

\%label
A hash reference listing labels for each list item. Default is the list text itself. (See popup_menu for an example.) Using named parameters, the syntax is:

print $query->radio_group(-name=>'name',
                          -values=>\@list,
                          -default=>'selected',
                          -linebreak=>'true',
                          -labels=>\%labelhash,
                          -columns=>n,
                          -columnheader=>'string',
                          -rows=>m,
                          -rowheader=>'string');
-columns=>n
The number of columns to use.

-columnheader=>'string'
A header for the column.

-rows=m
The number of rows to use. If omitted, and -columns is specified, the rows will be calculated for you.

-rowheader=>'string'
A header for the row.

raw_cookie
raw_cookie(  )

Returns the value of the HTTP_COOKIE header.

ReadParse
ReadParse(  )

Creates a hash named %in containing query information. Used for backwards compatibility with the Perl4 cgi-lib.pl.

redirect
print $query->redirect('url')

Generates a header for redirecting the browser.

url
The absolute URL to redirect to. Using named parameters, the syntax is:

print $query->redirect(-uri=>'url',
                       -nph=>1);
referer
referer(  )

Returns the referring URL.

remote_host
remote_host(  )

Returns the remote hostname or IP address, depending on the configuration of the server.

remote_user
remote_user(  )

Returns the username supplied for authorization.

request_method
request_method(  )

Returns the request method.

reset
print $query->reset

Generates a button that resets the form to its initial values. See also defaults.

save
$query->save(filehandle)

Saves the form to the specified filehandle, to be read back with the new constructor.

filehandle
The filehandle to save the file to

script_name
script_name(  )

Returns the current partial URL.

scrolling_list
print
$query->scrolling_list('name',\@list[,selected,size,'true',\%labelhash]);

Generates a scrolling list.

name
The name to assign the input to (required).

\@list
An array reference with the list items. You can also use an anonymous array reference.

selected
The menu item(s) to be initially selected (default is that nothing is selected). This can be a single value or a reference to a list of values.

size
The number of elements to display in the list box.

'true'
Allows multiple selections.

\%labelhash
A hash reference listing labels for each list item. Default is the list text itself. (See popup_menu for an example.) Using named parameters, the syntax is:

print $query->scrolling_list(-name=>'name',
                             -values=>\@listarray,
                             -default=>selected,
                             -size=>size,
                             -multiple=>'true',
                             -labels=>\%labelhash,
                             -onChange=>function,
                             -onFocus=>function,
                             -onBlur=>function);
-onChange=>function
Browser should execute function when the user changes the text field

-onFocus=>function
Browser should execute function when the focus is on on the text field

-onBlur=>function
Browser should execute function when the focus leaves the text field

self_url
$url = $query->self_url

Returns the URL of the current script with all its state information intact.

start_html
print $query->start_html(['title', 'email', 'base', attribute='value'])

Generates <HTML> and <BODY> tags.

title
The title of the page.

email
The author's email address.

base
Whether to use a <BASE> tag in the header.

attribute='value'
Specifies an attribute to the <BODY> tag. Using named parameters, the syntax is:

print $query->start_html(-title=>'title',
                         -author=>'email_address',
                         -base=>'true',
                         -xbase=>'url',
                         -meta=>{'metatag1'=>'value1',
                                 'metatag2'=>
                                            'value2'},
                         -script=>'$script',
                         -onLoad=>'$function',
                         -onUnload=>'$function',
                         -attribute=>'value');
-title=>'title'
Specifies the title of the page.

-author=>'email_address'
Specifies the author's email address.

-xbase=>'url'
Provides an HREF for the <BASE> tag. Default is the current location.

-meta=>{'metatag1'=>'value1', ... }
Adds arbitrary meta information to the header as a reference to a hash. Valid tags are:

keywords
Keywords for this document

copyright
Copyright for this document description

description
Description for this document

attribute=>'value'
Specifies an attribute to the <BODY> tag

-script=>'$script'
Specifies a JavaScript script to be embedded within a <SCRIPT> block.

-onLoad=>'$function'
Browser should execute specified function upon entering page.

-onUnload=>'$function'
Browser should execute specified function upon leaving page.

startform
print $query->startform([method, action, encoding])

Generates a <FORM> tag.

method
The request method for the form. Values are:

POST
Use the POST method (default).

GET
Use the GET method.

action
The URL of the CGI script. Default is the current URL.

encoding
The encoding scheme. Possible values are application/x-www-form-urlencoded and multipart/form-data. Using named parameters, the syntax is:

print $query->startform(-method=>$method,
                        -action=>$action,
                        -encoding=>$encoding,
                        -name=>$name,
                        -target=>frame,
                        -onSubmit=>function);
-name=>name
Names the form for identification by JavaScript functions

-target=>frame
Writes to the specified frame

-onSubmit=>function
A JavaScript function that the browser should execute upon submitting the form

start_multipart_form
print $query->start_multipart_form([method, action])

Generates <HTML> and <BODY> tags. Same as startform, but assumes multipart/form-data encoding as the default.

submit
print $query->submit([ 'label','value' ])

Generates a Submit button.

label
The label to use for the button.

value
The value to return when the form is submitted. Using named parameters, the syntax is:

print $query->submit(-name=>'name',
                     -value=>'value',
                     -onClick=>function);
-onClick=>function
Browser should execute function when the user clicks on the image

textarea
print $query->textarea('name' [,'value',rows,columns ])

Generates a large multiline text input box.

name
The name to assign the input to (required).

value
The initial value to place into the text input box.

rows
The number of rows to display.

columns
The number of columns to display. Using named parameters, the syntax is:

print $query->textarea(-name=>'name',
                       -default=>'value',
                       -rows=>rows,
                       -columns=>columns,
                       -override=>1,
                       -onChange=>function,
                       -onFocus=>function,
                       -onBlur=>function,
                       -onSelect=>function);
-override=>1
Text field should not inherit its value from a previous invocation of the script

-onChange=>function
Browser should execute function when the user changes the text field

-onFocus=>function
Browser should execute function when the focus is on the text field

-onBlur=>function
Browser should execute function when the focus leaves the text field

-onSelect=>function
Browser should execute function when the user changes a selected portion of the text field

textfield
print $query->textfield('name' [,'value', size, maxlength])

Generates a text input field.

name
The name to assign the input to (required).

value
The initial value to place in the text field.

size
The size of the text field (in characters).

maxlength
The maximum length of the text field (in characters). Using named parameters, the syntax is:

print $query->textfield(-name=>'name',
                        -default=>'value',
                        -size=>size,
                        -maxlength=>maxlength,
                        -override=>1,
                        -onChange=>function,
                        -onFocus=>function,
                        -onBlur=>function,
                        -onSelect=>function);
-override=>1
Text field should not inherit its value from a previous invocation of the script

-onChange=>function
Browser should execute function when the user changes the text field

-onFocus=>function
Browser should execute function when the focus is on the text field

-onBlur=>function
Browser should execute function when the focus leaves the text field

-onSelect=>function
Browser should execute function when the user changes a selected portion of the text field

url
$url = $query->url

Returns a URL of the current script without query information.

use_named_parameters
use_named_parameters(  )

Specifies that functions should take named parameters.

user_agent
$query->user_agent( [string] )

Returns the value of the HTTP_USER_AGENT header.

string
If specified, returns only headers matching the specified string

user_name
user_name(  )

Returns the remote user's login name; unreliable.

Previous | Home | Next
10.6. Debugging | Book Index | 11. Web Server Programmingwith mod_perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 11. Web Server Programming with mod_perl

Contents:

Design of mod_perl
Installing mod_perl
mod_perl Handlers
Running CGI Scripts with mod_perl
Server-Side Includes with mod_perl
<Perl> Sections
Apache:: Modules

A common criticism of CGI is that it requires forking extra processes each time a script is executed. If you have only a few hits an hour, or even a few hits a minute, this isn't a big deal. But for a high-traffic site, lots of repeatedly spawning CGI scripts can have an unfortunate effect on the machine running the web server. The CGI scripts will be slow, the web server will be slow, and other processes on the machine will slow to a crawl.

The solution to this problem is mod_perl. mod_perl, written by Doug MacEachern and distributed under CPAN, embeds the Perl interpreter directly into the web server. The effect is that your CGI scripts are precompiled by the server and executed without forking, thus running much more quickly and efficiently. Furthermore, CGI efficiency is only one facet of mod_perl. Since mod_perl is a complete Apache/Perl hybrid, other benefits to mod_perl include:

  • Writing server-side includes in Perl

  • Embedding Perl code into the Apache configuration files

  • Writing complete Apache modules in Perl

11.1. Design of mod_perl

mod_perl is a Perl runtime library linked into the Apache server. With mod_perl, the Perl programmer has access to Apache's C language API through an object-oriented Perl interface. This means that you can write Apache modules and extensions entirely in Perl and embed Perl code and custom directives in your Apache configuration files. Furthermore, the embedded Perl interpreter removes the overhead that you'd experience if you'd merely written a Perl CGI program and put it in Apache's cgi-bin.

Aside from the framework mentioned above, another major benefit of mod_perl is the Apache::Registry module. Apache::Registry implements the CGI environment under the mod_perl framework, which means that you can reuse most of your existing Perl CGI programs to realize the benefits of mod_perl. Apache::Registry caches compiled scripts on the first execution of a script and updates scripts that have changed on disk.

Finally, mod_perl gives the Perl programmer the ability to interact with all stages of an HTTP request, many of which aren't available through CGI. These include the Apache handler phase, the HTTP header parser, URI translation, authentication, authorization, access (permissions), type checking, fixup, and logger stages.

Now that you've been subjected to two rather optimistic paragraphs, we'll take a few moments to appease the cynics. It might occur to you that sticking a large program into another large program makes a very, very large program. mod_perl certainly makes httpd significantly bigger. If you have limited memory capacity, mod_perl may not be for you. There are several ways to minimize the size of Apache with mod_perl (which you can find in the mod_perl manpage or the FAQs), ranging from fiddling with Apache configuration directives to building Perl with reduced memory consumption.

Previous | Home | Next
10.7. CGI.pm Reference | Book Index | 11.2. Installing mod_perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.2. Installing mod_perl

If you already have Apache installed on your machine, you will have to rebuild it with mod_perl. If you prefer, you can install the mod_perl-enabled Apache installation somewhere else, which we'll also detail in this section. You can get the source for both Apache and mod_perl from http://www.apache.org/dist/httpd/. You can get mod_perl alone from CPAN or from http://perl.apache.org/dist/. The mod_perl build process is quite configurable, and after you've met some Perl module dependencies, you should be well on your way to building and getting your mod_perl-enabled Apache installation online.

First, you should take a look at your existing Apache installation (or installations) and make sure that you don't unintentionally interfere with a working Apache installation. If you're running Apache-1.3.X, it's likely that your Apache installation lives under /usr/local/apache, or C:\apache if you're on a Win32 platform. Second, make sure that you're running a current version of Perl and that you've installed the LWP Bundle of modules. If you haven't installed the LWP modules bundle, mod_perl might not build correctly and will not run its tests correctly.

Once you've met the requirements listed above, you should unpack the Apache and mod_perl distributions and run:

 % perl Makefile.PL EVERYTHING=1 APACHE_PREFIX=[target directory]

Next, run make, make test, and assuming all goes well, make install to install the mod_perl-enabled Apache:

 % make
 % make test
 % make install

The EVERYTHING=1 option says to build mod_perl with all of the supported features. If this isn't what you were looking for or if you'd like to learn more about making a custom Apache build with mod_perl, you should read the INSTALL file that ships with mod_perl.

At the time of this writing, both Apache and mod_perl have been ported to Win32. However, you might have the best results with mod_perl under Win32 if you run ActiveState's Perl distribution and its precompiled version of mod_perl. For further information about building mod_perl under Win32, see INSTALL.win32.

Previous | Home | Next
11. Web Server Programmingwith mod_perl | Book Index | 11.3. mod_perl Handlers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.3. mod_perl Handlers

To understand mod_perl, you should understand how the Apache server works. When Apache receives a request, it processes it in several stages. First, it translates the URL to the associated resource (i.e., filename, CGI script, etc.) on the server machine. Then it checks to see if the user is authorized to access that resource, perhaps by requesting and checking an ID and password or hostname and IP address. Once the user has passed inspection, the server figures out the kind of data it's sending back (e.g., it decides a file ending in .html is probably a text/html file), creates some headers, and sends those headers back to the client with the resource itself. When all is said and done, the server makes a log entry.

At each stage of this process, Apache looks for routines to "handle" the request. That is, if Apache doesn't find handlers you've told it to use, it knows to use its own. For example, if you've enabled CGI programs in httpd.conf, Apache knows to execute programs that live in cgi-bin if it encounters the cgi-script directive:

<Location /cgi-bin>
  ...
SetHandler cgi-script
  ...
</Location>

mod_perl allows you to write your own handlers in Perl by embedding the Perl runtime library directly into the Apache httpd server executable. To use mod_perl for CGI (which is all that most people want to do with it), assign the SetHandler directive to perl-script, and the mod_perl-specific PerlHandler directive to a special Perl module called Apache::Registry:

SetHandler perl-script
PerlHandler Apache::Registry

PerlHandler is the mod_perl handler for the content retrieval stage of the transaction.

To use other handlers, you don't need to reassign SetHandler. For example, to identify a handler for the logging stage of the request:

<Location /snoop/>
PerlLogHandler Apache::DumpHeaders
</Location>

For this to work, mod_perl must have been built with the logging hooks enabled (as described in the previous section), and the Apache::DumpHeaders module must have been installed. mod_perl looks in Apache::DumpHeaders for a routine called handler( ) and executes it as the logging handler for that resource.

The following is a list of each of the handler directives that can be enabled by mod_perl and the stages that each is used for. Only PerlHandler is enabled by default.

Handler | Purpose
PerlAccessHandler | Access stage
PerlAuthenHandler | Authentication stage
PerlAuthzHandler | Authorization stage
PerlChildInitHandler | Child initialization stage
PerlChildExitHandler | Child termination stage
PerlCleanupHandler | Cleanup stage
PerlFixupHandler | Fixup stage
PerlHandler | Response stage
PerlHeaderParserHandler | Header-parsing stage
PerlInitHandler | Initialization
PerlLogHandler | Logging stage
PerlPostReadRequestHandler | Post-request stage
PerlTransHandler | Translation stage
PerlTypeHandler | Type-handling stage

You can write your own handlers for each of these stages. But there are also dozens of modules that you can download from CPAN, some of which are listed at the end of this chapter.

Previous | Home | Next
11.2. Installing mod_perl | Book Index | 11.4. Running CGI Scripts with mod_perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.4. Running CGI Scripts with mod_perl

What most people want to do with mod_perl is improve CGI performance. The mod_perl installation assumes this request by enabling the PerlHandler callback hook by default and by installing the Apache::Registry module. PerlHandler is the handler used for the content retrieval stage of the server transaction. Apache::Registry is the Perl module that emulates the CGI environment so you can use "standard" Perl CGI scripts with mod_perl without having to rewrite them (much). This is by far the cheapest way to get improved CGI performance.

With Apache::Registry, each individual CGI program is compiled and cached the first time it is called (or whenever it is changed) and remains available for all subsequent instances of that CGI script. This process avoids the costs of startup time.

Whereas most CGI scripts are kept in cgi-bin, scripts that use Apache::Registry are placed in a separate directory, e.g., perl-bin. The access.conf Apache configuration file needs to point to this directory by setting an alias and defining a handler for this new location:

Alias /perl-bin/ /usr/local/apache/perl-bin/

<Location /perl-bin>
SetHandler perl-script
PerlHandler Apache::Registry
PerlSendHeader On
Options ExecCGI
</Location>

Instead of using the cgi-script handler, we use the perl-script handler to give control to mod_perl. Next, the PerlHandler directive tells mod_perl that the Apache::Registry module should be used for serving all files in that directory.PerlSendHeader is another mod_perl-specific directive; in this case, it tells mod_perl to send response lines and common headers—by default, none are sent. (For NPH scripts, you'll want to turn this feature off again.) Options ExecCGI is a standard Apache header that is needed to tell Apache to treat the script as a CGI script.

If you want to load Perl modules in addition to Apache::Registry, you can use the PerlModule directive:

PerlModule CGI

If you include this line, you shouldn't need to explicitly use CGI in each Perl CGI script anymore, since CGI.pm will be loaded directly from the Apache server. Up to ten modules can be listed with the PerlModule directive.

CGI scripts in the new directory should work now. However, if you have problems, the mod_perl manpage offers some words of wisdom:

  • Always use use strict. Standard CGI scripts start with a clean slate every time. When switching to mod_perl, CGI programmers are often surprised to learn how often they take advantage of this fact. use strict tells you when your variables haven't been properly declared and might inherit values from previous invocations of the script.

  • Don't call exit( ). Calling exit( ) at the end of every program is a habit of many programmers. While often totally unnecessary, it usually doesn't hurt . . . except with mod_perl. If you're using mod_perl without Apache::Registry, exit( ) kills the server process. If exit( ) is the last function call, you can just remove it. If the structure of your program is such that it is called from the middle of the script, you can just put a label at the end of the script and use goto( ). There's also an Apache->exit( ) call you can use if you're really attached to exit( ) s.

    If you're using Apache::Registry, you don't have to worry about this problem. Apache::Registry is smart enough to override all exit( ) calls with Apache->exit( ).

In addition, it is recommended that you should use recent versions of Perl and CGI.pm. You should scan the mod_perl documentation for the latest compatibility news.

Previous | Home | Next
11.3. mod_perl Handlers | Book Index | 11.5. Server-Side Includes with mod_perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.5. Server-Side Includes with mod_perl

Server-side includes (SSIs) are tags embedded directly into an HTML file that perform special functions. They are most commonly used for running CGI scripts and displaying the result; most web page counters are performed using SSIs.

If you use mod_perl with mod_include (another Apache server module), you can embed Perl subroutines into SSI directives. For example:

<!--#perl sub="sub {print ++Count}" -->

The Apache::Include module lets you include entire Apache::Registry scripts:

<!--#perl sub="Apache::Include" arg="/perl-bin/counter.pl"-->

You could have used standard SSIs to include a CGI script for the same purpose, but this way is faster. To use mod_include with mod_perl, you need to configure mod_perl to do so at compile time.

Previous | Home | Next
11.4. Running CGI Scripts with mod_perl | Book Index | 11.6. <Perl> Sections
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.6. <Perl> Sections

With mod_perl, you can use Perl in Apache configuration files. What this means is that you can make your Apache configuration much more flexible by using conditionals.

Any Perl code in Apache configuration files should be placed between <Perl> and </Perl> directives. This code can define variables and lists used by mod_perl to assign the associated Apache configuration directives; for example, assigning the $ServerAdmin variable will redefine the ServerAdmin Apache configuration directive.

Suppose you share the same Apache configuration files across multiple servers, and you want to allow personal directories on only one of them. You can use Perl directives like this:

<Perl>
if ('hostname' =~ /public/) {
        $UserDir = "public.html";
} else {
        $UserDir = "DISABLED";
}
1;
</Perl>

Directive blocks (such as <Location>...</Location>) can be represented as a hash. For example:

<Perl>
$Location{"/design_dept/"} = {
        DefaultType   => 'image/gif',
        FancyIndexing => 'On'
}
</Perl>
Previous | Home | Next
11.5. Server-Side Includes with mod_perl | Book Index | 11.7. Apache:: Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.7. Apache:: Modules

Apache::Registry is the most commonly used mod_perl module. But there are many more, all available on CPAN. The following table lists the Apache::* modules and the handler they're designed to be used with, but you should also check the apache-modlist.html file on CPAN for the latest listing.

Module | Description
PerlHandler
Apache::CallHandler | Maps filenames to subroutine calls
Apache::Dir | Controls directory indexing
Apache::Embperl | Embeds Perl code in HTML files
Apache::ePerl | Embedded Perl (ePerl) emulation
Apache::FTP | Emulates an FTP proxy
Apache::GzipChain | Compresses output from another handler
Apache::JavaScript | Generates JavaScript code
Apache::OutputChain | Chains multiple handlers via "filter" modules
Apache::PassFile | Sends files via OutputChain
Apache::Registry | Runs unaltered CGI scripts
Apache::RobotRules | Enforces robots.txt rules
Apache::Sandwich | Adds per-directory headers and footers
Apache::VhostSandwich | Adds headers and footers for virtual hosts
Apache::SSI | Implements server-side includes in Perl
Apache::Stage | Manages a document staging directory
Apache::WDB | Queries databases via DBI
PerlHeaderParserHandler
Apache::AgentDeny | Denies abusive clients
PerlAuthenHandler
Apache::Authen | Authenticates users
Apache::AuthCookie | Authenticates and authorizes users via cookies
Apache::AuthenDBI | Authenticates via Perl's DBI
Apache::AuthExpire | Expires authentication credentials
Apache::AuthenGSS | Authenticates users with Generic Security Service
Apache::AuthenLDAP | Authenticates users with LDAP
Apache::AuthNIS | Authenticates users with NIS
Apache::BasicCookieAuth | Accepts cookie or basic authentication credentials
Apache::DBILogin | Authenticates using a backend database
Apache::DCELogin | Authenticates within a DCE login context
Apache::AuthAny | Authenticates with any username/password
PerlAuthzHandler
Apache::AuthCookie | Authenticates and authorizes via cookies
Apache::AuthzAge | Authorizes based on age
Apache::AuthzDCE | Authorizes based on DFS/DCE ACL
Apache::AuthzDBI | Authorizes groups via DBI
Apache::AuthNIS | Authenticates and authorizes via NIS
Apache::RoleAuthz | Role-based authorization
PerlAccessHandler
Apache::AccessLimitNum | Limits user access by the number of requests
Apache::DayLimit | Limits access based on the day of the week
Apache::RobotLimit | Limits access of robots
PerlTypeHandler
Apache::AcceptLanguage | Sends file types based on user's language preference
PerlTransHandler
Apache::DynaRPC | Translates URIs into RPCs
Apache::Junction | Mounts remote web server namespace
Apache::LowerCaseGETs | Translates to lowercase URIs as needed
Apache::MsqlProxy | Translates URIs into mSQL queries
Apache::ProxyPassThru | Skeleton for vanilla proxy
Apache::ProxyCache | Caching proxy
PerlFixupHandler
Apache::HttpEquiv | Converts HTML HTTP-EQUIV tags to HTTP headers
Apache::Timeit | Benchmarks Perl handlers
PerlLogHandler
Apache::DumpHeaders | Displays HTTP transaction headers
Apache::Traffic | Logs the number of bytes transferred on a per-user basis
Apache::WatchDog | Looks for problematic URIs
PerlChildInitHandler
Apache::Resource | Limits resources used by httpd children
Server configuration
Apache::ConfigLDAP | Configures server via LDAP and <Perl> sections
Apache::ConfigDBI | Configures server via DBI and <Perl> sections
Apache::ModuleConfig | Interfaces to configuration API
Apache::PerlSections | Utilities for <Perl> sections
Apache::httpd_conf | Methods to configure and run an httpd
Apache::src | Methods for finding and reading bits of source
Database
Apache::DBI | Manages persistent DBI connections
Apache::Sybase | Manages persistent DBlib connections
Apache::Mysql | Manages persistent mysql connections
Interfaces and integration with various Apache C modules
Apache::Constants | Constants defined in httpd.h
Apache::Include | Enables use of Apache::Registry scripts within SSI with mod_include
Apache::Global | Gives access to server global variables
Apache::LogError | Gives an interface to aplog_error
Apache::LogFile | Gives an interface to Apache's piped logs, etc.
Apache::Mime | Gives an interface to mod_mime functionality
Apache::Module | Gives an interface to Apache C module structures
Apache::Options | Imports Apache::Constants "options"
Apache::Scoreboard | Gives an interface to scoreboard API
Apache::Servlet | Gives an interface to the Java Servlet engine
Apache::Sfio | Gives an interface to r->connection->client->sf*
Development and debug tools
Apache::Debug | Provides debugging utilities to mod_perl
Apache::DProf | Hooks Devel::DProf into mod_perl
Apache::FakeRequest | Implements Apache methods offline
Apache::Peek | Emulates Devel::Peek for mod_perl
Apache::SawAmpersand | Makes sure no one is using $&, $', or $'
Apache::StatINC | Reloads files that are use d or require d files when updated
Apache::Status | Gets information about loaded modules
Apache::Symbol | Supports symbols
Apache::test | Defines handy routines for make test scripts
Miscellaneous
Apache::Byterun | Runs Perl bytecode modules
Apache::Mmap | Shares data via Mmap module
Apache::Persistent | Stores data via IPC::, DBI, or disk
Apache::PUT | Handler for the HTTP PUT method
Apache::RegistryLoader | Apache::Registry startup script loader
Apache::Safe | Adaptation of safecgiperl
Apache::Session | Maintains client <-> httpd session/state
Apache::SIG | Signal handlers for mod_perl
Apache::State | Powerful state engine

Previous | Home | Next
11.6. <Perl> Sections | Book Index | V. Databases
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part V. Databases

Chapter 12, "Databases and Perl"

Previous | Home | Next
11.7. Apache:: Modules | Book Index | 12. Databases and Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 12. Databases and Perl

Contents:

DBM Databases and DBM Hashes
Design of DBI
DBI Methods
DBI Environment Variables

Since one of Perl's greatest strengths is working with text, a genuine concern is how to store data. Flat files are one possibility, but they don't scale very well for large amounts of data. When working with lots of data, you'll likely need database software to satisfy your capacity and performance requirements.

There are two general solutions to using databases with Perl. For simple database purposes, Database Management (DBM) will serve your needs. DBM is a library supported by many (if not all) Unix systems and many non-Unix systems as well. DBM is more efficient than flat text files because of how it packs records into the database files and the (large) size of data it can store and retrieve efficiently. Perl's interface to your system's DBM is based on a hash, so you can add, store, and delete data by key.

When you need to store a larger variety of data and need other goodies such as searchability on multiple records, you'll probably need to use a database that supports SQL. To this end, you can buy a prepackaged database product such as Oracle or Sybase, or a shareware equivalent such as MySQL or PostgreSQL. For these larger database projects, you should use DBI and DBD. DBI is a module that provides a consistent interface for database solutions. DBD is a database-specific driver that translates DBI calls as needed for that database.

In this chapter, we'll cover DBM and talk at length about DBI/DBD.

12.1. DBM Databases and DBM Hashes

DBM is a simple database management facility for Unix systems. It allows programs to store a collection of key/value pairs in binary form, thus providing rudimentary database support for Perl. Practically all Unix systems ship with built-in DBM support, some with a separate libdb and others with DBM calls built into libc. In the absence of DBM support on your system, you can use gdbm from GNU, which is an extension to vanilla DBM or BerkeleyDB-3.x from http://www.sleepycat.com/.

To use DBM databases in Perl, you can associate a hash with a DBM database through the AnyDBM module that uses tie( ). This hash (called a DBM array) is then used to access and modify the DBM database. Previously, you could use dbmopen( ) to open, read, write, and delete a database, but while dbmopen( ) remains available, you should use the AnyDBM module that's always suited to your underlying DBM implementation.[6]

[6]If you're using BerkeleyDB-2.x or newer, you should not use AnyDBM_File, but should instead install and use the BerkeleyDB module.

For example, with AnyDBM:

#!/usr/local/bin/perl -w

    use AnyDBM_File;
    use Fcntl; # needed for O_ thingies

    my %h;
    my $db_name = 'perl_in_a_nutshell2.dbmx';

    # tie %h. will fail if $db_name can't be created and $db_name can't be
    # written
    tie(%h, 'AnyDBM_File', $db_name, O_RDWR|O_CREAT, 0640)
        or die("can't create \%h: $!");

    # Populate %h
    foreach my $letter ('a' .. 'z') {
        $h{$letter} = uc($letter);
    }

    while(my($key, $value) = each(%h)) {
        print "$key -> $value\n";
    }

    untie(%h);

The %ARRAYNAME parameter is a Perl hash. (If it already has values, the values are discarded under DBM_File modules, although you can have multiple keys under BerkeleyDB-2.x and newer.) %ARRAYNAME is tied to a DBM database called $db_name. This database may be stored on disk as a single file, or as two files called $db_name.dir and $db_name.pag, depending on the DBM implementation.

The $mode parameter is a number that controls the permissions of the pair of files if the files need to be created. The number is in octal, so make sure that you use permissions such as 0640 instead of 640, which are different numbers in octal. If the files already exist, $mode has no effect. For example:

tie(%BOOKS, "bookdb", O_RDWR|O_CREAT, 0666); # Open %BOOKS onto bookdb

This invocation associates the hash %BOOKS with the disk files bookdb.dir and bookdb.pag in the current directory. If the files don't already exist, they are created with a mode of 0666, modified by the current umask.

tie( ) returns undef upon any failure in opening the $db_name and sets $!.

Once the database is opened, anything you do to the DBM hash is immediately written to the database. See Chapter 4, "The Perl Language" for more information on hashes.

tie(%BOOKS, "bookdb", O_RDWR|O_CREAT, 0666)
    or die("can't open bookdb: $!"); # Open %BOOKS onto bookdb
    $BOOKS{"1-56592-286-7"} = "Perl in a Nutshell";

The DBM array stays open throughout the program. When the program termi- nates, the association is terminated. You can also break the association in a manner similar to closing a filehandle by using untie( ). See Chapter 5, "Function Reference" for more information on tie.

Previous | Home | Next
V. Databases | Book Index | 12.2. Design of DBI
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.2. Design of DBI

If DBM is too primitive for your database requirements, you'll have to use a more sophisticated database package. Options include the commercial products Oracle, Sybase, and Informix, and the freely available MySQL and Postgres.

Prior to Perl Version 5 and DBI, the problem was that with all the database packages to choose from, there was no way to universalize database support for Perl. You'd have to rebuild the Perl executable itself against libraries that included subroutines for direct access to the database package. For example, sybperl and oraperl are both packages for building Perl Version 4 with Sybase and Oracle calls embedded, respectively. An application written for sybperl would not be portable to Oracle, or vice versa. However, since current versions of Perl support binary extension loading at runtime, database support can now be added at runtime, which simplifies adding database interfaces to Perl programs while keeping the size of the Perl binary to a minimum.

Support for binary extensions doesn't mean that database access has been standardized. There are still many database extensions to Perl, each with a different API. However, their underlying support for SQL (or ability to be manipulated into a form that mimics the behavior of SQL through a DBD) has made it possible to develop a standard set of methods to work with any database. DBI defines a set of functions, variables, and conventions that provide a consistent database programming interface for Perl.

12.2.1. Database Drivers (DBDs)

The success of DBI is that it is only half of the story. The other half is a DBD, or a database driver. DBI provides the interface and framework for the drivers, but it's the database drivers that do the real work. Drivers implement the DBI methods for the private interface functions of the corresponding database engine.

Unless you're developing a sophisticated database application, you probably don't care about the drivers except that you want to install the correct one. Table 12-1 lists database servers, where you can find them, and the DBD driver designed for it. (The freeware or shareware database servers are available for download, and some of the commercial servers offer evaluation copies for download.)

Table 12-1. Database servers

Server | URL | DBD
DB2 | http://www.software.ibm.com/data/db2/ | DBD::DB2
Empress | http://www.empress.com/ | DBD::Empress
Fulcrum | http://www.fulcrum.com | DBD::Fulcrum
Informix | http://www.informix.com/ | DBD::Informix
Ingres | http://www.cai.com/products/ingres.htm http://epoch.cs.berkeley.edu:8000/postgres/index.html | DBD::Ingres
miniSQL | http://www.hughes.com.au/ | DBD::mSQL
MySQL | http://www.tcx.se/ | DBD::mysql
Oracle | http://www.oracle.com/ | DBD::Oracle
PostgreSQL | http://www.postgresql.org/ | DBD::Pg
QuickBase | http://www.openbase.com/ | DBD::QBase
Solid | http://www.solidtech.com/ | DBD::Solid
Sybase | http://www.sybase.com/ | DBD::Sybase

12.2.2. Creating a Database

Before you can open a connection to a database with DBI, you must create the database. DBI can't do this step for you, although your DBD might allow you to. For example, DBD::MySQL implements a _CreateDB function. Your DBD might also support the func method, which is used to call private (and often nonportable) methods in the driver. You could use a one-liner like this to create the database from the command line:

perl -MDBI -e '$db_name = q[database_name_here]; \
     $result = DBD::mysql::dr->func($db_name, '_CreateDB');'

If your DBD allows to you to create databases via the API, it's likely that it will allow you to drop them, too:

perl -MDBI -e '$db_name = q[database_name_here]; \
    $result = DBD::mysql::dr->func($db_name, '_DropDB');'

12.2.3. Database Handles and Statement Handles

DBI methods work on two different types of handles: database handles and statement handles. A database handle is like a filehandle; connect is a DBI class method that opens a connection to a database and returns a database handle object:

$db_handle = DBI->connect(dbi:mSQL:bookdb, undef, undef)
    || die("Connect error: $DBI::errstr");

Statement handles are another thing entirely. DBI makes a distinction between the preparation of SQL statements and their execution by allowing you to preformat a statement into a statement handle. You can prepare a statement with the prepare method, which returns a statement handle. You can then assign a SQL statement to the statement handle via various statement handle methods and execute it with the execute method when you're done. (You can also prepare and execute in the same command with the do method.)

Changes to the database are written to the database automatically if the AutoCommit attribute is turned on. If AutoCommit is off, use the commit method when you're ready to write the changes to the database.

AutoCommit is only one of many attributes that can be set for both database and statement handles. For example, if $st_handle is a statement handle, you can set $st_handle->{NULLABLE} to determine if the fields can contain null characters. Table 12-2 is a listing of all the attributes supported by database handles, statement handles, or both.

Table 12-2. Attributes for database and statement handles

Attribute | Description
Attribute for database handles
AutoCommit | Commits any changes to the database immediately, instead of waiting for an explicit call to commit. Default is true.
Attributes for statement handles
CursorName | The name of the cursor associated with the statement handle.
NAME | A reference to an array of field names.
NULLABLE | A reference to an array describing whether each field can contain a null character.
NUM_OF_FIELDS | Number of fields the prepared statement will return.
NUM_OF_PARAMS | Number of placeholders in the prepared statement.
Attributes common to all handles
Warn | Enables warnings.
CompatMode | Enables compatible behavior for a specific driver.
InactiveDestroy | Destroying a handle does not close prepared statements or disconnect from the database.
PrintError | Errors generate warnings.
RaiseError | Errors raise exceptions.
ChopBlanks | Truncates trailing space characters in fixed-width character fields.
LongReadLen | Controls the maximum length of long data.
LongTruncOk | Controls whether fetching long data that has been truncated should fail.

12.2.4. Placeholders and Statement Handles

Many database drivers allow you to use question marks as placeholders in SQL statements and then bind values to the placeholders before executing them. This enables you to prepare a single statement with placeholders and reuse it for each row of the database. For example, the prepare statement might read:

$st_handle = $db_handle->prepare(q{
        insert into books (isbn, title) values (?, ?)
})  || die db_handle->errstr;

And a subsequent execute statement might read:

$st_handle->execute("1-56592-286-7", "Perl in a Nutshell")
        || die $db_handle->errstr;
Previous | Home | Next
12. Databases and Perl | Book Index | 12.3. DBI Methods
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.3. DBI Methods

The following methods are available under DBI.

available_drivers
@drivers = DBI->available_drivers([nowarn])

Returns a list of available drivers by searching @INC for the presence of DBD::* modules.

nowarn
A Boolean value specifying whether to suppress warnings if some drivers are hidden by others of the same name in earlier directories. Default is false (don't suppress).

bind_col
$result = $st_handle->bind_col(col, \variable [, \%attr ])

Binds a field of a select statement to a variable, to be updated whenever the row is fetched.

col
The column number to bind

\variable
A reference to the variable to bind

\%attr
Attributes to set for the statement handle

bind_columns
$result = $st_handle->bind_columns(\%attr, @reflist )

Runs bind_col on each column of the statement.

\%attr
Attributes to set for the statement handle

@reflist
A list of references to the variables to bind

bind_param
$result = $st_handle->bind_param(n, value [, type ])

Binds a value with a placeholder in a prepared statement.

n
The parameter number to bind.

value
The value to associate with parameter n.

type
The data type for the placeholder. The type can also be specified as an anonymous list ({TYPE => type}).

commit
$result = $db_handle->commit

Commits the most recent changes. See also the AutoCommit attribute.

connect
$db_handle = DBI->connect(data_source, user, passwd,[\%attr])

Connects to the specified database, returning a database handle object. The connect method automatically installs the driver if it has not already been installed.

data_source
A string identifying the driver to connect to, and any other additional driver-specific information needed to identify the driver (e.g., a port number). The driver name is written in the form dbi:driver_name, e.g., dbi:mysql. (Default value is taken from the DBI_DSN environment variable.) For example, a connection string for the MySQL driver always starts with dbi:mysql:. The second colon should be followed by any information required by the driver to make the database connection. In the case of MySQL, you must supply a database name (bookdb in the following example), a hostname (localhost), and the port number of the database server (1114):

DBI:$driver:database=$database;host=$hostname;port=
$port
user
The username for the database connection. (Default value is taken from the DBI_USER environment variable.)

passwd
The password for the database connection. (Default value is taken from the DBI_PASS environment variable. Set this value at your own risk.)

\%attr
A hash reference defining attributes for the database handle.

data_sources
@drivers = DBI->data_sources(driver)

Returns a list of all databases available for the named driver. (The database server must be running for data_sources to return any results.)

driver
The driver to list. If unspecified, the value of DBI_DRIVER is used.

disconnect
$result = $db_handle->disconnect

Disconnects the database.

do
$rows = $db_handle->do(statement [, \%attr, @bind_values ])

Prepares and executes a statement, returning the number of rows affected.

statement
The statement to execute

\%attr
Attributes to set for the new statement

@bind_values
Bind values for placeholder substitution

dump_results
$rows = DBI::dump_results(st_handle, maxlen, ldelim, fdelim, fileh)

Runs DBI::neat( ) on all the rows of a statement handle and prints them for testing purposes.

st_handle
The statement handle to retrieve.

maxlen
The length at which to truncate with "...". Default is 35.

ldelim
The delimiter between rows. Default is \n.

fdelim
The delimiter between individual fields. Default is , .

fileh
The filehandle to print to. Default is STDOUT.

err
$handle->err

Returns the error code from the last driver function called.

errstr
$handle->errstr

Returns the error message from the last driver function called.

execute
$result = $st_handle->execute([@bind_values])

Executes a prepared statement.

@bind_values
Binds values for placeholder substitution

fetch
$arrayref = $st_handle->fetch

Fetches the next row of data, returning an array reference with the field values.

fetchall_arrayref
$arrayref = $st_handle->fetchall_arrayref

Fetches all data from a prepared statement and returns a reference to an array of references.

fetchrow_array
$array = $st_handle->fetchrow_array

Fetches the next row of data, returning an array with the field values.

fetchrow_arrayref
$arrayref = $st_handle->fetchrow_arrayref

Fetches the next row of data, returning an array reference with the field values. Synonym for fetch.

fetchrow_hashref
$hashref = $st_handle->fetchrow_hashref

Fetches the next row of data, returning a hash reference containing the field values. The keys of the hash are the same as $st_handle->{NAME}.

finish
$result = $st_handle->finish

Disables further fetching from a statement.

func
$handle->func(@arguments, function)

Calls a private nonportable method on the specific handle.

@arguments
The arguments to the function.

function
The function name. Note that the function name is specified last.

neat
$newstring = DBI::neat(string, maxlength)

Converts a string to one with quoted strings, null values shown as undef, and unprintable characters shown as ".".

string
The string to convert

maxlength
The length at which to truncate the string with "..."

neat_list
$newstring = DBI::neat_list(\@list, maxlength, delim)

Converts each element of a list with DBI::neat and returns it as a string.

\@list
A reference to the list to convert.

maxlength
The length at which to truncate the string with "...".

delim
The delimiter to use between list elements in the new string. Default is , .

ping
$result = $db_handle->ping

Determines if the database is still connected.

prepare
$st_handle = $db_handle->prepare(statement [, \%attr ])

Prepares a statement for execution and returns a reference to a statement handle object.

statement
The statement to prepare

\%attr
Attributes to set for the assigned statement handle

quote
$sql = $db_handle->quote(string)

Escapes special characters in a string for use in a SQL statement.

string
The string to convert

rollback
$result = $db_handle->rollback

Undoes the most recent database changes if not yet committed.

rows
$rows = $st_handle->rows

Returns the number of rows affected by the last change to the database.

state
$handle->state

Returns an error code in a five-character format.

trace
DBI->trace(n, filename)

Traces the execution of DBI.

n
An integer indicating the level of trace/debugging information, as follows:

0
Disable the trace.

1
Trace the execution of the DBI.

2
Output detailed call trace information including parameters and return values.

filename
The file to append trace information to

trace
$handle->trace(n, filename)

Same as the class method DBI->trace, but for a specific database, statement, or driver handle.

Previous | Home | Next
12.2. Design of DBI | Book Index | 12.4. DBI Environment Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.4. DBI Environment Variables

The following environment variables are defined for use with DBI:

DBI_DSN
The data source value to use if none is specified with the connect method.

DBI_DRIVER
The driver to use if none is specified with the connect method.

DBI_USER
The username to use if none is specified with the connect method.

DBI_PASS
The password to use if none is specified with the connect method. (For security purposes, this environment variable should not be set except for testing.)

DBI_TRACE
Enables tracing behavior as with the trace method. DBI_TRACE can be set to any of the following values:

0
Disables the trace

1
Traces the execution of the DBI

2
Outputs detailed call trace information including parameters and return values

filename
Appends trace information to the specified file; the trace level is set to 2.

Previous | Home | Next
12.3. DBI Methods | Book Index | VI. XML and SOAP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part VI. XML and SOAP

Chapter 13, "XML and Perl"

Chapter 14, "SOAP"

Previous | Home | Next
12.4. DBI Environment Variables | Book Index | 13. XML and Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 13. XML and Perl

Contents:

XML Parsing and Validation
XML::Parser Methods
Expat Handlers
XML::Parser Styles
Expat Encodings
XML::Parser::ContentModel Methods

The Extensible Markup Language (XML) is a metalanguage for providing complete, configurable information for documents and other types of data. XML is based loosely on SGML, but has divorced itself of much of the complexity that made SGML unsuitable for everyday use. Without opening a can of worms about the differences between SGML and XML, suffice it to say that SGML is the predecessor to XML, and XML is a subset of SGML, with extensions.

With XML, you aren't bound by a fixed format, but can mark up a document to make it easily adaptable to whatever final format you later decide to apply it to. In fact, this book is written in XML, to be produced later not only in a print format but in an online format as well.

XML is often associated with web content, but it is much more flexible than that. Lately, XML's application to web services such as SOAP and XML-RPC has given it a chance to flex its muscles and show what it's capable of. XML gives you the structure to hold any content you'd like, whether it be the pages of this book in their rawest form, a list of your favorite recipes, or the ledger from your checkbook. XML is structured so that you can represent any kind of data in XML. XML's openness means that you can implement an XML-based application on any platform.

This chapter is focused on parsing, checking and delivering XML content. Chapter 14, "SOAP" covers SOAP programming in XML.

13.1. XML Parsing and Validation

The two most common tasks that you'll perform on your XML content are likely to be parsing and validating. If you've ever combed around on CPAN for XML-related modules, you probably already know that there's no shortage of resources when it comes to Perl and XML. On the contrary, the sheer volume of modules available for Perl and XML is rather daunting, so you might be looking for a place to start.

This chapter covers two Perl/XML modules in particular: XML::Simple and XML::Parser. These modules were selected because they allow you to parse and manipulate most XML. While these modules themselves don't validate XML, we'll resort to a little bit of trickery to show you how you can do exactly that.

XML::Simple provides an easy API that allows you to read and write XML. It is built on top of XML::Parser, which will be covered shortly. As its name suggests, XML::Simple implements only two methods: XMLin( ) and XMLout( ). But don't let its apparent lack of methods fool you; XML::Simple lets you do great things simply, such as parsing XML-written configuration files.

Let's say that your company keeps a log of its Sun Microsystems servers and their respective operation-system versions, IP addresses, and current patch levels. While you could keep this information in your home directory as a delimited file (which you can parse and analyze when you need to, or import into a database, such as PostGresSQL or MySQL), why not just write it in XML? You'll find that by writing this information in an XML document, you'll be able to operate on this information just as flexibly as you can with one of the aforementioned strategies. In addition, your information would reside in a structure in which the relationships between items and their meanings are clear.

Let's say that your flat text log file looks like this:

# sunhosts - patches and levels
atlas|solaris|2.8|192.168.0.2|Generic_108528-10|5.6.1
carrie|solaris|2.8|192.168.1.10|Generic_108527-12|5.6.0
not4sun|solaris|2.8|192.168.0.25|Generic_108482-06|5.005_03

While you could parse this configuration file easily, and generate some kind of report from it, your configuration file doesn't really tell you anything about the data that it represents. You can represent the same data in XML like so:

<config servertype="sunhosts" reporttype="patches and levels">
  <server name="atlas" osname="solaris" osversion="2.8">
    <address>192.168.0.2</address>
    <patchlevel>Generic_108528-10</patchlevel>
    <perlversion>5.6.1</perlversion>
  </server>

  <server name="carrie" osname="solaris" osversion="2.8">
    <address>192.168.1.10</address>
    <patchlevel>Generic_108527-12</patchlevel>
    <perlversion>5.6.0</perlversion>
  </server>

  <server name="not4sun" osname="solaris" osversion="2.8">
    <address>192.168.0.25</address>
    <patchlevel>Generic_108482-06</patchlevel>
    <perlversion>5.005_03</perlversion>
  </server>
</config>

In the above XML, all of the entries will be keyed on server so that for each entry in your XML that's called server, you'll be able to view its information for address, patchlevel, and perlversion. The following XML::Simple code does just that:

#!/usr/local/bin/perl -w

use XML::Simple;

my $config = XMLin('./myconfig.xml');

# Simply show us the IP address of each server in our table
foreach my $server (keys %{$config->{server}}) {
    print "$server -> $config->{server}{$server}{address}\n";
}

Now that you've parsed your configuration file, let's say you want to write XML back to your configration. To do this, you should use XMLout( ), which is covered in the XML::Simple documentation.

While XML::Simple doesn't provide a thorough method for validating XML, it does insist that a document is compliant XML. This means that if you present XML::Simple with a document that's not syntatically correct, XML::Simple will stop parsing the XML document and store the error message in $@. For example:

<config servertype="sunhosts" reporttype="patches and levels">
  <server name="atlas" osname="solaris" osversion="2.8">
    <address>192.168.0.2</address>
    <patchlevel>Generic_108528-10</patchlevel>
    <perlversion>5.6.1</perlversion>
</config>

The following code would find the error in your XML and exit upon finding it:

#!/usr/local/bin/perl -w

use XML::Simple;

my $config = eval { XMLin('./mybadconfig.xml') };
print("I found an error in your XML: $@") if $@;

foreach my $server (keys %{$config->{server}}) {
    print "$server -> $config->{server}{$server}\n";
}

This gives you:

I found an error in your XML:
mismatched tag at line 6, column 2, byte 241 at
/usr/local/lib/perl5/site_perl/5.6.1/sun4-solaris/XML/Parser.pm line 185

Two components are very useful for parsing XML with Perl: Expat and XML::Parser. Although there are several XML parsing options for Perl, such as GNOME's libxml and offerings from the PerlSAX2 project, we stick to Expat and XML::Parser in this chapter.

Expat is a nonvalidating (that is, it does not check XML for correctness) XML parser that was written by James Clark. XML::Parser, a Perl wrapper around Expat, was originally written by Larry Wall and later developed by Clark Cooper. If you're using the ActivePerl, you should be able to install XML::Parser with ppm. Otherwise, you'll have to build Expat first, then link XML::Parser against it.

Each call to one of the XML::Parser parsing methods creates a new instance of XML::Parser::Expat, which is then used to parse the document. Expat options may be provided when the XML::Parser object is created. These options are then passed on to the Expat object on each parse call. They can also be given as extra arguments to the parse methods, in which case they override options given at XML::Parser creation time.

The XML parser takes your XML document and turns it into a data structure that you can operate on. XML::Parser gives you low-level control (and precision) over the data structure that it created, from which you can build parsers on top of it. XML::Simple is an example of this.

The behavior of the parser is controlled either by Style and/or Handlers options or by the setHandlers method. These all provide mechanisms that XML::Parser can use to set the handlers needed by XML::Parser::Expat. If neither Style nor Handlers are specified, then parsing just checks if the document is well-formed.

When underlying handlers get called, they receive as their first parameter the Expat object, not the Parser object.

You can show the relationships between entries in a configuration file with XML::Parser as well. For example:

#!/usr/local/bin/perl -w

use XML::Parser;
use Data::Dumper;

# Simply dump all of the entries and their relationships
my $p1 = XML::Parser->new(Style => 'Tree');
my $tree = $p1->parsefile('myconfig.xml');

print Dumper($tree);
Previous | Home | Next
VI. XML and SOAP | Book Index | 13.2. XML::Parser Methods
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.2. XML::Parser Methods

The following methods are defined by XML::Parser.

new
new(%option)

Constructor. Options are passed as keyword/value pairs. Recognized options are:

Style
Sets the type of parser. The built-in styles are Debug, Subs, Tree, Objects, and Stream. Custom styles can be provided by giving a fully qualified package name containing at least one "::". This package must have subroutines defined for each parser type.

Handlers
An anonymous hash containing the handler types as the keys with their associated values, which are references to subroutines for handling that type of event.

Pkg
Some styles will refer to subroutines defined in the specified package.

ErrorContext
The number of lines to show surrounding the line in which an error occurred.

ProtocolEncoding
Sets the protocol-encoding name (default is none). The built-in encodings are UTF-8, ISO-8859-1, UTF-16, and US-ASCII. You may introduce additional encodings by adding directories to @Encoding_Path.

Namespaces
If true, then namespace processing is done during the parse.

NoExpand
Normally, the parser will try to expand references to entities defined internally. If this option is true and a default handler is also set, then the default handler will be called when an entity reference is encountered.

Stream_Delimiter
A string for XML::Parser to interpret as end-of-file if found alone on a line. Useful when working with MIME multipart documents. The string should not contain a trailing newline.

ParseParamEnt
Unless standalone is set to yes in the XML declaration, setting this to true allows the external DTD to be read, and parameter entities to be parsed and expanded.

NoLWP
If true, forces the use of a file-based external entity handler.

Non-Expat-Options
An anonymous hash whose keys are options that shouldn't be passed to Expat. This should be a concern only for those subclassing XML::Parser.

parse
parse(source [, opt => opt_value [...]])

Parses the document. The source parameter should be either a string containing the entire XML document or an open IO::Handle. Options given as keyword/value pairs may follow the source parameter and will override any options or attributes passed from the XML::Parser instance.

parse exits with die if a parse error occurs or returns 1 with success.

parsefile
parsefile(file [, opt => opt_value [...]])

Opens file for reading, then calls parse with the open handle. The file is closed no matter what parse returns. Returns what parse returns.

parse_start
parse_start([ opt => opt_value [...]])

Creates and returns a new instance of XML::Parser::ExpatNB. If an init handler is specified, it is called before returning the ExpatNB object. Documents are parsed with incremental calls to the parse_more. A single call to the parse_done method of this object indicates that the document is finished. The parse_done method returns whatever is returned by the final handler.

parsestring
parsestring

An alias for parse, for backwards compatibility.

setHandlers
setHandlers(type, handler [, type, handler [...]])

Registers handlers for various parser events. setHandlers overrides any previous handlers set in Style or Handler options or through earlier calls to setHandlers. Returns a list of type and handler pairs.

Previous | Home | Next
13. XML and Perl | Book Index | 13.3. Expat Handlers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.3. Expat Handlers

Expat is an event-based parser that recognizes parts of the document (such as the start or end tag for an XML element) and calls any handlers registered for that type of an event. All handlers receive an instance of XML::Parser::Expat as their first argument.

Init (Expat)
Called before parsing starts.

Final (Expat)
Called after parsing has finished, but only if no errors occurred.

Start (Expat, Element [, Attr, Val [,...]])
Generated when an XML start tag is encountered. Element is the name of the XML element type. Attr and Val pairs are generated for each attribute in the start tag of the element.

End (Expat, Element)
Generated when an XML end tag or empty tag (<foo/>) is encountered.

Char (Expat, String)
Generated when non-markup is recognized, with the non-markup sequence of characters in String given to the handler in UTF-8.

Proc (Expat, Target, Data)
Generated when a processing instruction is recognized.

Comment (Expat, Data)
Generated when a comment is recognized.

CdataStart (Expat)
Called at the start of a CDATA section.

CdataEnd (Expat)
Called at the end of a CDATA section.

Default (Expat, String)
Called for any characters that aren't tied to a registered handler, including markup declarations. Whatever the encoding in the original document, the string is returned to the handler in UTF-8.

Unparsed (Expat, Entity, Base, Sysid, Pubid, Notation)
Called for a declaration of an unparsed entity. Entity is the name of the entity. Base is the base to be used for resolving a relative URI. Sysid is the system ID. Pubid is the public ID. Notation is the notation name. Base and Pubidcan be undefined.

Notation (Expat, Notation, Base, Sysid, Pubid)
Called for a declaration of notation. Notation is the notation name. Base is the base to be used for resolving a relative URI. Sysid is the system ID. Pubid is the public ID. Base, Sysid, and Pubid can all be undefined.

ExternEnt (Expat, Base, Sysid, Pubid)
Called when an external entity is referenced. Base is the base to be used for resolving a relative URI. Sysid is the system ID. Pubid is the public ID. Base and Pubidmay be undefined. This handler should either return a string or an open filehandle that represents the contents of the external entity. A return value of undef indicates that the external entity couldn't be found.

If an open filehandle is returned, it must be returned as either a glob or as a reference to a glob (e.g., an instance of IO::Handle). The default handler installed for this event is XML::Parser::lwp_ext_ent_handler unless NoLWP option is true, in which case XML::Parser::file_ext_ent_handler is the default handler for external entities.

ExternEntFin (Expat)
Called after parsing an external entity unless no ExternEnt handler is set.

Entity (Expat, Name, Val, Sysid, Pubid, Ndata, IsParam)
Called when an entity is declared. For internal entities, Val will contain the value, and the remaining three parameters will be undefined. For external entities, Val will be undefined, and the Sysid, Pubid, and the Ndata parameters will be populated. The IsParam parameter is set to true if this is a parameter entity declaration.

If both this handler and the Unparsed handler are set, then this handler will not be called for unparsed entities.

Element (Expat, Name, Model)
Called when an element declaration is found. Name is the element name, and Model is the content model as an XML::Parser::Content object.

Attlist (Expat, Elname, Attname, Type, Default, Fixed)
Called for each attribute in an ATTLIST declaration. An ATTLIST with multiple attributes will generate multiple calls to Attlist. Elname is the name of the element with which the attribute is being associated. Attname is the name of the attribute. Type is the attribute type, given as a string. Default is the default value, which will be #REQUIRED, #IMPLIED, or a quoted string (i.e., the returned string will begin and end with a quote character). If Fixed is true, then this is a fixed attribute.

Doctype (Expat, Name, Sysid, Pubid, Internal)
Called for DOCTYPE declarations. Name is the document type name. Sysid is the system ID of the document type, if it was provided; otherwise, it's undefined. Pubid is the public ID of the document type, which will be undefined if no public id was given. Internal is the internal subset, given as a string.

DoctypeFin (Parser)
Called after parsing of the DOCTYPE declaration has finished, including any internal or external DTD declarations.

XMLDecl (Expat, Version, Encoding, Standalone)
Called for XML declarations. Version is a string containing the version. Encoding is either undefined or contains an encoding string. Standalone is either true or false.

Previous | Home | Next
13.2. XML::Parser Methods | Book Index | 13.4. XML::Parser Styles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.4. XML::Parser Styles

Debug
Prints out the document in outline form.

Subs
Allows you to define a subroutine so that when an element is encountered, the subroutine by that name is called, using the same parameters that the Start handler is called with. When an element ends, a subroutine with that name appended with an underscore ("_") is called with the same parameters that the End handler is called with.

Tree
Returns a parse tree for the document. Each node in the tree takes the form of a tag/content pair. Text nodes use a pseudo-tag of ``0'' and the string that is their content. Elements represent their content in an array reference, in which the first item in the array is a hash reference containing attributes (if any). The remainder of the array is a sequence of tag/content pairs representing the content of the element.

Objects
Similar to Tree, except that a hash object is created for each element.

Stream
Prints a copy of the document without comments or declarations if none of the following routines are found:

StartDocument
Called at the start of the parse.

StartTag
Called for every start tag with a second parameter of the element type. The $_ variable contains a copy of the tag, and the %_ variable contains attribute values supplied for that element.

EndTag
Called for every end tag with a second parameter of the element type. The $_ variable will contain a copy of the end tag.

Text
Called just before start or end tags with accumulated non-markup text in the $_ variable.

PI
Called for processing instructions. The $_ variable will contain a copy of the PI, and the target and data are sent as second and third parameters, respectively.

EndDocument
Called at conclusion of the parse.

Previous | Home | Next
13.3. Expat Handlers | Book Index | 13.5. Expat Encodings
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.5. Expat Encodings

XML documents may be encoded in character sets other than Unicode as long as they can be mapped into the Unicode character set. Expat has further restrictions on encodings. Read the xmlparse.h header file in the expat distribution to see details on these restrictions.

Expat has built-in encodings for: UTF-8, ISO-8859-1, UTF-16, and US-ASCII. Encodings are set through either the XML declaration encoding attribute or the ProtocolEncoding option to XML::Parser or XML::Parser::Expat.

For encodings other than the built-ins, Expat calls the function load_encoding in the Expat package with the encoding name. This function looks for a file in the path list @XML::Parser::Expat::Encoding_Path that matches the lowercased name with a .enc extension. The first one it finds, it loads.

If you wish to build your own encoding maps, check out the XML::Encoding module from CPAN.

Previous | Home | Next
13.4. XML::Parser Styles | Book Index | 13.6. XML::Parser::ContentModel Methods
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.6. XML::Parser::ContentModel Methods

The element declaration handlers are passed objects of this class as the content model of the element declaration. They also represent content particles, which are components of a content model.

When referred to as a string, these objects are automatically converted to a string representation of the model (or content particle):

isempty
Returns true if the object is EMPTY, false otherwise.

isany
Returns true if the object is ANY, false otherwise.

ismixed
Returns true if the object is (#PCDATA) or (#PCDATA|...)*, false otherwise.

isname
Returns true if the object is an element name.

ischoice
Returns true if the object is a choice of content particles.

isseq
Returns true if the object is a sequence of content particles.

quant
Returns undef or a string representing the quantifier (?, *, +) associated with the model or particle.

children
Returns undef or (for mixed, choice, and sequence types) an array of component content particles. There will always be at least one component for choices and sequences, but for a mixed content model of pure PCDATA, (#PCDATA), then undef is returned.

Previous | Home | Next
13.5. Expat Encodings | Book Index | 14. SOAP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 14. SOAP

Contents:

What Is SOAP?
SOAP::Lite
SOAP::Data
SOAP::Serializer
SOAP::Fault

XML's openness allows it to be implemented on any platform. Between the clear nature of XML and the ease at which you can deliver content over the Web, you can easily use XML to distribute content to a wide audience.

Imagine an order-entry system for a company with a heterogenous computing environment in locations all over the world. While you could write client software for every platform that you support, a preferable solution might be to deliver XML content over the Web and have an order-entry client that parses the XML, displays the results, and posts any changes back to the server via XML.

If you think that such an idea might be a workable one, but fear writing such a thing for yourself from scratch, you might consider trying SOAP or Frontier (XML-RPC2).

14.1. What Is SOAP?

SOAP (Simple Object Access Protocol) is a protocol that allows you to invoke methods on remote objects. SOAP was originally drafted in 1998 by Dave Winer, Microsoft, and DevelopMentor.

SOAP is not tied to any specific programming language. You can find similar SOAP implementations under Perl, Python, C, and Java. It is merely a protocol, one that is simple enough to function under HTTP.

SOAP implements its own XML vocabulary that represents methods, return values, and exceptions. By implementing its own set of HTTP headers, SOAP also allows you to handle SOAP packets at your firewall/proxy server.

There are two components to SOAP: RPC and EDI. RPC, or remote procedure call, is what you'd use to get a data response (in pairs) from another host, such as a set of items and prices from an order-entry system. EDI is the interface component of SOAP, returning content such as an order entry form, but leaving the actual data processing to RPC.

Previous | Home | Next
13.6. XML::Parser::ContentModel Methods | Book Index | 14.2. SOAP::Lite
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.2. SOAP::Lite

You can try an implementation of SOAP with Perl called SOAP::Lite, written by Paul Kulchenko. SOAP::Lite is a collection of Perl modules that provide a simple and lightweight interface for both the client and server side. This version of SOAP::Lite supports the SOAP 1.1 specification (http://www.w3.org/TR/SOAP) and works with many SOAP implementions, including Apache SOAP, Frontier, Microsoft SOAP, Microsoft .NET, DevelopMentor, XMethods, 4s4c, Phalanx, Kafka, SQLData, Lucin (in Java), Perl, C++, Python, VB, COM, and XSLT.

Here's an example that uses SOAP::Lite. The following code creates a SOAP::Lite object and uses it, but what's special about the SOAP::Lite object is that it's based on code that lives on www.soaplite.com. In other words, the code that lives on the remote end of the connection might not be Perl at all—but by using SOAP::Lite, you can execute the f2c( ) function as if you were calling f2c( ) from your own Perl program.

Also note the uri and proxy options. The uri option is the URI for SOAP methods. Basically, uri tells SOAP::Lite where SOAP-related content lives. In Perl terms, uri can represent the class in which you'll find the function to execute. For example, let's say you have the following SOAP server that uses HTTP as its transport mechanism:

#!/usr/local/bin/perl -w

use SOAP::Transport::HTTP;

SOAP::Transport::HTTP::CGI
    -> dispatch_to('Hello::(?:hello)')
    -> handle
    ;

This example has two key parts: it will look for a module named "Hello" and will execute Hello::hello( ) when called. Note that you don't have to explicitly "require" Hello.pm; SOAP::Lite does this for you. Now, let's look at the client:

#!/usr/local/bin/perl -w

use SOAP::Lite;

# If you want to see why something isn't working, enable +trace after
# use SOAP::Lite, as shown below

#use SOAP::Lite +trace;

my $proxy = 'http://www.some.server/cgi-bin/hello';

print SOAP::Lite
    -> uri('urn:Hello')
    -> proxy($proxy)
    -> hello()
    -> result . "\n\n"
    ;

It's essential that uri, as used above, matches the module in which the hello( ) function lives. If it doesn't, you won't see any returned results, since SOAP::Lite won't be able to find the module in @INC (using the +trace option makes it clear that an unavailable module was not found in @INC). Now that we have some context, let's take a look at the proxy option. In the above example, proxy is the URL where the SOAP server lives. When SOAP::Lite sees the proxy option, it loads the appropriate module based on what you request.

14.2.1. SOAP::Lite Methods

All methods that SOAP::Lite provides can be used for setting and retrieving values. If you provide no parameters, you will get the current value, and if parameters are provided, a new value will be assigned to the object, and the method in question will return the current object (if not stated otherwise). This is suitable for stacking these calls. For example:

  $lite = SOAP::Lite
    -> uri('http://simon.fell.com/calc')
    -> proxy('http://soap.4s4c.com/ssss4c/soap.asp')
  ;

The order is insignificant. You may call the new( ) method first, but if you don't, SOAP::Lite will do it for you. Calling the new( ) method explicitly gives you additional syntax:

  $lite = SOAP::Lite-&gt;new(
    uri => 'http://simon.fell.com/calc',
    proxy => 'http://soap.4s4c.com/ssss4c/soap.asp'
  );

The SOAP::Lite methods are:

new( )
Accepts a hash with method names as keys. It will call the appropriate methods together with the passed values..

transport( )
Provides access to the SOAP/Transport object. You probably shouldn't play with transport( ), since the object will be created for you.

serializer( )
Provides access to the SOAP/Serialization object. You probably shouldn't play with serializer( ), since the object will be created for you.

endpoint( )
Lets you specify an endpoint without changing/loading the protocol module. This is useful for switching endpoints without switching protocols. You should call proxy( ) first. No checks for protocol equivalence will be made.

outputxml( )
If true, all methods will return raw XML code, which you can then parse with XML::Parser or a similar module.

autotype( )
Specifies whether the serializer will try to enable autotyping. Default is true.

readable( )
Specifies the format for the generated XML code, adding carriage returns and indentation for readability.

namespace( )
Specifies the default namespace for generated envelopes (SOAP-ENV by default).

encodingspace( )
Specifies the default encoding namespace for generated envelopes (SOAP-ENC by default).

encoding( )
Specifies the encoding for generated envelopes (UTF-8 by default).

typelookup( )
Gives you access to the typelookup table used for autotyping.

multirefinplace( )
Determines whether the serializer should put values for multireferences in the first occurrence of the reference. Default is false.

on_action( )
Specifies a handler (either globally or locally) to be triggered for an on_action event. The default handler is uri#method.

on_fault( )
Specifies a handler (either globally or locally) to be triggered for an on_fault event. The default behavior will die on a transport error and do nothing on other error conditions.

on_debug( )
Globally specifies a handler to be triggered for an on_debug event. Default behavior is to do nothing, since moving the +trace/+debug options is preferred.

on_nonserialized( )
Specifies a handler to be triggered for an on_nonserialized event. The default behavior is to produce a warning, if warnings are enabled for these events.

call( )
Provides an alternative interface for remote method calls, with additional options:

Prefixed method
If you want to specify a prefix for generated method's element, try:

call('myprefix:method' => @parameters)
Access to any method
To access remote procedures that have the same names as methods of the SOAP::Lite object:

call(new => @parameters)
Implementation of OO interface
To use the object-oriented interface:

# You should specify uri( )
my $soap = SOAP::Lite
  -> uri('http://my.own.site/CLASS')
  # ..... other parameters
;

my $obj = $soap->call(new => @parameters)->result;
print $soap->call(method => $obj)->result;
Ability to set method's attributes
To specify attributes for a method element:

call(SOAP::Data->name('method')->attr({xmlns => 'mynamespace'})
    => @parameters)
self( )
Returns the object reference to global default object specified with the use SOAP::Lite ... interface. For example:

my $proxy = 'http://www.some.server';
my $soap - SOAP::Lite->proxy($proxy);
print $soap->self->proxy;

This prints http://www.some.server.

dispatch_from( )
The same as autodispatch, but doesn't install the UNIVERSAL::AUTOLOAD handler. It installs only the AUTOLOAD handlers in specified classes.

Previous | Home | Next
14. SOAP | Book Index | 14.3. SOAP::Data
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.3. SOAP::Data

The SOAP::Data class allows you specify a value, name, type, URI, or other attributes for SOAP elements. For example, you can serialize the name/value pair of "Nate/31" with the following code:

SOAP::Data->name('Nate')->value(31);

This becomes <Nate>31</Nate>.

You can also import SOAP::Data methods with import( ). To import 'name':

SOAP::Data->import('name');

Once imported, 'name' can be used as follows:

name(Nate => 31);

SOAP::Data also provides an interface to get or set specific
attributes, including actor( ),
mustUnderstand( ), encodingStyle(
), and root( ). For example:

SOAP::Data
    ->name(Nate => 31)
    ->encodingStyle('http://www.some.site/soap/showmetheliteral');

This is serialized as follows:

<Nate SOAP-ENV:encodingStyle="http://www.some.site/soap/showmetheliteral"
   xsi:type="xsd:int">31</Nate>
Previous | Home | Next
14.2. SOAP::Lite | Book Index | 14.4. SOAP::Serializer
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.4. SOAP::Serializer

SOAP::Serializer does not need to be used directly except when autotyping is enabled. It allows you to specify types for your data.

You can specify a type with SOAP::Data, with code similar to the following:

SOAP::Data->type(something => [ ... ])

When serialization is reached, SOAP::Lite will attempt to serialize your data with the as_something method, if such a method exists. If you don't create an as_something method, no serialization will occur. You can create as_something with the following:

sub SOAP::Serializer::as_something {
    my $self = shift;
    my($key, $val) = @_;
    ...
    return [$key, {'xsi:type' => 'xsd:something', %attr}, $val];
}
Previous | Home | Next
14.3. SOAP::Data | Book Index | 14.5. SOAP::Fault
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.5. SOAP::Fault

This class gives you access to a fault generated on the server side. To create a fault message, you can simply die on the server side, and the SOAP processor will wrap your message as a faultstring element and transfer the fault on the client side. But in some cases, you need to have more control over this process, and the SOAP::Fault class gives it to you. To use it, simply die with the SOAP::Fault object as a parameter:

  die SOAP::Fault->faultcode('Server.Custom') # Will be qualified
                 ->faultstring('Died in server method')
                 ->faultdetail(bless {code => 1} => 'BadError')
                 ->faultactor('http://www.soaplite.com/custom');

The faultdetail( ) and faultactor( ) methods are optional, and since faultcode and faultstring are required to represent a fault message, SOAP::Lite will use default values ("Server" and "Application error") if not specified.

Previous | Home | Next
14.4. SOAP::Serializer | Book Index | VII. Network Programming
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part VII. Network Programming

Chapter 15, "Sockets"

Chapter 16, "Email Connectivity"

Chapter 17, "Usenet News"

Chapter 18, "FTP"

Chapter 19, "Lightweight Directory Access with Net::LDAP"

Previous | Home | Next
14.5. SOAP::Fault | Book Index | 15. Sockets
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 15. Sockets

Contents:

Built-in Socket Functions
The IO::Socket Module

Why build networking functionality into your Perl scripts? You might want to access your email remotely, or write a simple script that updates files on an FTP site. You might want to check up on your employees with a program that searches for Usenet postings that came from your site. You might want to check a web site for any recent changes, or even write your own home-grown web server. The network is the computer these days, and Perl makes network applications easy.

Perl programmers have their choice of modules for doing common tasks with network protocols; Chapter 14, "SOAP" through Chapter 17, "Usenet News" cover the modules for writing email, news, FTP, and web applications in Perl. If you can do what you want with the available modules, you're encouraged to jump to those chapters and skip this one. However, there will be times when you'll have to wrestle with sockets directly, and that's when this chapter comes in.

Sockets are the underlying mechanism for networking on the Internet. With sockets, one application (a server) sits on a port waiting for connections. Another application (the client) connects to that port and says hello; then the client and server have a chat. Their actual conversation is done with whatever protocol they choose—for example, a web client and server would use HTTP, an email server would use POP3 and SMTP, etc. But at the most basic level, you might say that all network programming comes down to opening a socket, reading and writing data, and closing the socket.

You can work with sockets in Perl at various levels. At the lowest level, Perl's built-in functions include socket routines similar to the system calls in C of the same name. To make these routines easier to use, the Socket module in the standard library imports common definitions and constants specific to your system's networking capabilities. Finally, the IO::Socket module provides an object interface to the socket functions through a standard set of methods and options for constructing both client and server communications programs.

Sockets provide a connection between systems or applications. They can be set up to handle streaming data or discrete data packets. Streaming data continually comes and goes over a connection. A transport protocol such as TCP (Transmission Control Protocol) is used to process streaming data so that all of the data is properly received and ordered. Packet-oriented communication sends data across the network in discrete chunks. The message-oriented protocol UDP (User Datagram Protocol) works on this type of connection. Although streaming sockets using TCP are widely used for applications, UDP sockets also have their uses.

Sockets exist in one of two address domains: the Internet domain and the Unix domain. Sockets used for Internet connections require the careful binding and assignment of the proper type of address dictated by the Internet Protocol (IP). These sockets are referred to as Internet-domain sockets.

Sockets in the Unix domain create connections between applications either on the same machine or within a LAN. The addressing scheme is less complicated, often just providing the name of the target process.

In Perl, sockets are attached to a filehandle after they have been created. Communication over the connection is then handled by standard Perl I/O functions.

15.1. Built-in Socket Functions

Perl provides built-in support for sockets. The following functions are defined specifically for socket programming. For full descriptions and syntax, see Chapter 5, "Function Reference".

socket
Initializes a socket and assigns a filehandle to it.

bind
For servers, associates a socket with a port and address. For clients, associates a socket with a specific source address.

listen
(Server only.) Waits for incoming connection with a client.

accept
(Server only.) Accepts incoming connection with a client.

connect
(Client only.) Establishes a network connection on a socket.

recv
Reads data from a socket filehandle.

send
Writes data to a filehandle.

shutdown (or close)
Terminates a network connection.

Regular functions that read and write filehandles can also be used for sockets, e.g., write, print, printf, and the diamond input operator, <>.

The socket functions tend to use hardcoded values for some parameters, which severely hurts portability. Perl solves this problem with a module called Socket, included in the standard library. Use this module for any socket applications that you build with the built-in functions (e.g., use Socket). The module loads the socket.h header file, which enables the built-in functions to use the constants and names specific to your system's network programming, as well as additional functions for dealing with address and protocol names.

The next few sections describe Perl socket programming using a combination of the built-in functions together with the Socket module. After that, we describe the use of the IO::Socket module.

15.1.1. Initializing a Socket

Both client and server use the socket call to create a socket and associate it with a filehandle. The socket function takes several arguments: the name of the filehandle, the network domain, an indication of whether the socket is stream-oriented or record-oriented, and the network protocol to be used. For example, HTTP (web) transactions require stream-oriented connections running TCP. The following lines create a socket for this case and associates it with the filehandle SH:

use Socket;
socket(SH, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die $!;

The PF_INET argument indicates that the socket will connect to addresses in the Internet domain (i.e., IP addresses). Sockets with a Unix domain address use PF_UNIX.

Because this is a streaming connection using TCP, we specify SOCK_STREAM for the second argument. The alternative would be to specify SOCK_DGRAM for a packet-based UDP connection.

The third argument indicates the protocol used for the connection. Each protocol has a number assigned to it by the system; that number is passed to socket as the third argument. In the scalar context, getprotobyname returns the protocol number.

Finally, if the socket call fails, the program will die, printing the error message found in $!.

15.1.2. Client Connections

On the client side, the next step is to connect with a server at a particular port and host. To do this, the client uses the connect call. connect requires the socket filehandle as its first argument. The second argument is a data structure containing the port and hostname that together specify the address. The Socket package provides the sockaddr_in function to create this structure for Internet addresses and the sockaddr_un function for Unix domain addresses.

The sockaddr_in function takes a port number for its first argument and a 32-bit IP address for the second argument. The 32-bit address is formed from the inet_aton function found in the Socket package. This function takes either a hostname (e.g., www.oreilly.com) or a dotted-decimal string (e.g., 207.54.2.25) and returns the corresponding 32-bit structure.

Continuing with the previous example, a call to connect could look like this:

my $dest = sockaddr_in (80, inet_aton('www.oreilly.com'));
connect (SH, $dest) || die $!;

This call attempts to establish a network connection to the specified server and port. If successful, it returns true. Otherwise, it returns false and die s with the error in $!.

Assuming that the connect call has completed successfully and a connection has been established, there are a number of functions we can use to write to and read from the filehandle. For example, the send function sends data to a socket:

$data = "Hello";
send (FH, $data);

The print function allows a wider variety of expressions for sending data to a filehandle:

select (FH);
print "$data";

To read incoming data from a socket, use either the recv function or the diamond input operator regularly used on filehandles. For example:

recv (FH, $buffer);
$input = <FH>;

After the conversation with the server is finished, use close or shutdown to close the connection and destroy the socket.

15.1.3. Server Connections

After creating a socket with the socket function as you did previously, a server application must go through the following steps to receive network connections:

  1. Bind a port number and machine address to the socket

  2. Listen for incoming connections from clients on the port

  3. Accept a client request and assign the connection to a specific filehandle

We start out by creating a socket for the server:

my $proto = getprotobyname('tcp');
socket(FH, PF_INET, SOCK_STREAM, $proto) || die $!;

The filehandle $FH is the generic filehandle for the socket. This filehandle only receives requests from clients; each specific connection is passed to a different filehandle by accept, where the rest of the communication occurs.

A server-side socket must be bound to a port on the local machine by passing a port and an address data structure to the bind function via sockaddr_in. The Socket module provides identifiers for common local addresses, such as localhost and the broadcast address. Here we use INADDR_ANY, which allows the system to pick the appropriate address for the machine:

my $sin = sockaddr_in (80, INADDR_ANY);
bind (FH, $sin) || die $!;

The listen function tells the operating system that the server is ready to accept incoming network connections on the port. The first argument is the socket filehandle. The second argument gives a queue length, in case multiple clients are connecting to the port at the same time. This number indicates how many clients can wait for an accept at one time.

listen (FH, $length);

The accept function completes a connection after a client requests and assigns a new filehandle specific to that connection. The new filehandle is given as the first argument to accept, and the generic socket filehandle is given as the second:

accept (NEW, FH) || die $!;

Now the server can read and write to the filehandle NEW for its communication with the client.

15.1.4. Socket Module Functions

The following functions are imported from the Socket module for use in socket applications.

inet_aton
inet_aton (hostname)

Translates a hostname such as www.oreilly.com or 18.181.0.24 into a data structure (a four-byte string) used for socket addresses. If the hostname cannot be resolved, the function returns the undefined value.

inet_ntoa
inet_ntoa (addr_string)

Translates a four-byte address string (as returned by inet_aton) into a string with the dotted-quad form of IP address.

sockaddr_in
sockaddr_in (port, addr_string)
pack_sockaddr_in (port, addr_string)

Takes a port number and a four-byte addr_string(as returned by inet_aton) and returns the socket address structure including those arguments packed with the AF_INET argument. This structure is normally what you need for the arguments in bind, connect, and send, and is also returned by getpeername, getsockname, and recv.

sockaddr_un
sockaddr_un (pathname)
pack_sockaddr_un (pathname)

Takes one argument, a pathname, and returns the Unix domain socket address structure (the path packed in with AF_UNIX filled in). For Unix domain sockets, this structure is normally what you need for the arguments in bind, connect, and send, and is also returned by getpeername, getsockname, and recv.

unpack_sockaddr_in
unpack_sockaddr_in (sockaddr)
sockaddr_in (sockaddr)

Takes a socket address structure and returns an array of two elements (in list context): the port number and the four-byte IP address.

unpack_sockaddr_un
unpack_sockaddr_un (sockaddr_un)
sockaddr_un (sockaddr_un)

Takes a Unix domain socket address structure (as returned by sockaddr_un) and returns the pathname.

The following constants are defined in the Socket module:

INADDR_ANY
The four-byte packed string for the wildcard IP address that specifies any of the host's addresses (if the host has multiple addresses). This is equivalent to inet_aton('0.0.0.0').

INADDR_BROADCAST
The four-byte packed string for the broadcast address. This is equivalent to inet_aton('255.255.255.255').

INADDR_LOOPBACK
The four-byte packed string for the loopback address. This is equivalent to inet_aton('localhost').

INADDR_NONE
The four-byte packed string for the "invalid" IP address (bitmask). Equivalent to inet_aton('255.255.255.255').

Previous | Home | Next
VII. Network Programming | Book Index | 15.2. The IO::Socket Module
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.2. The IO::Socket Module

The IO::Socket module included in the core Perl distribution provides an object-oriented approach to socket programming. This module provides a convenient way to handle the large number of options you have to deal with, and it handles the laborious task of forming addresses. IO::Socket is built upon the Socket module provided in the standard library. It inherits from IO::Handle, which supports a class of filehandle objects for much of the IO library. The following IO::Socket functions are simply frontends for the corresponding built-in functions and use the same syntax:

socket
socketpair
bind
listen
send
recv
peername (same as getpeername)
sockname (same as getsockname)

The accept function in IO::Socket is slightly different from the equivalent function, however, and is described later in the chapter.

IO:Socket contains two subclasses: INET and UNIX. The INET subclass is used to create and manipulate Internet-domain sockets, such as those used in the examples. The UNIX subclass creates Unix domain sockets.

15.2.1. Client-Side Sockets

IO::Socket greatly simplifies the implementation of a socket for client communications. The following example creates an Internet-domain socket (using the INET subclass) and attempts to connect to the specified server:

use IO::Socket;
$sock = new IO::Socket::INET (PeerAddr => 'www.ora.com',
                              PeerPort => 80,
                              Proto    => 'tcp');
die "$!" unless $sock;

IO::Socket::INET::new creates an object containing a socket filehandle and connects it to the host and port specified in PeerAddr and PeerPort. The object $sock can then be written to and read from like other socket filehandles.

15.2.2. Server-Side Sockets

On the server side, IO::Socket provides a nice wrapper for creating server sockets. The wrapper encompasses the socket, bind, and listen procedures, while creating a new IO::Socket object. For example, we can create an Internet-domain socket with IO::Socket::INET:

use IO::Socket;
$sock = new IO::Socket::INET (LocalAddr => 'maude.ora.com',
                              LocalPort => 8888,
                              Proto     => 'tcp',
                              Listen    => 5);
die "$!" unless $sock;

The parameters for the new socket object determine whether it is a server or a client socket. Because we're creating a server socket, LocalAddr and LocalPort provide the address and port to bind to the socket. The Listen parameter gives the queue size for the number of client requests that can wait for an accept at any one time.

When the server receives a client request, it calls the accept method on the socket object. This creates a new socket object on which the rest of the communication can take place:

$new_sock = $sock->accept( );

When communication is finished on both client and server sockets, they should be destroyed with close. If a socket is not properly closed, the next time you attempt to use a socket with the same name, the system will complain that the socket is already in use.

15.2.3. IO::Socket Methods

The following methods are defined in IO::Socket and can be used on socket objects of either the INET or UNIX class.

accept
accept ([pkg])

Performs the accept system call on a socket and returns a new object. The new object is created in the same class as the listen socket, unless pkg is specified. The object can be used to communicate with the client that tried to connect. In a scalar context, the new socket is returned, or undef is returned on failure. In an array context, a two-element array is returned containing the new socket and the peer address, or an empty list is returned on failure.

protocol
protocol

Returns the protocol number for the protocol being used on the socket, if known. If the protocol is unknown, as with an AF_UNIX socket, returns 0

sockdomain
sockdomain

Returns the number representing the socket address domain. For example, an AF_INET socket has the value &AF_INET.

sockopt
sockopt (opt, [val])

Sets and retrieves socket option opt in the SOL_SOCKET level. The value val is set for the option, if given. If no value is provided, the function returns the current setting for the option.

socktype
socktype

Returns the number representing the socket type. For example, a SOCK_STREAM socket has the value &SOCK_STREAM.

timeout
timeout ([val])

Sets or retrieves the timeout value associated with a socket. Without an argument, the current value is returned. If a timeout of val is given, the setting is changed to val, and the previous value is returned.

15.2.4. IO::Socket::INET Reference

An Internet-domain socket is created with the new method from the IO::Socket::INET subclass. The constructor can take the following options:

PeerAddr => hostname[:port]
Specifies the remote host and optional port number for a client connection. hostname can be either a name, such as www.oreilly.com, or an IP number of the form 207.44.21.2.

PeerPort => port
Specifies the port number on the remote host for a client connection. The name of the service (such as http or nntp) may be used for the argument if the port number is not known.

LocalAddr => hostname[:port]
Specifies the local address (and optional port number) to bind to a server-side socket.

LocalPort => port
Specifies the local port number (or service name) to bind to a server-side socket.

Proto => name
Specifies the protocol to be run on the socket, i.e., tcp or udp.

Type => SOCK_STREAM | SOCK_DGRAM
Specifies the type of socket. SOCK_STREAM indicates a stream-based socket connection, and SOCK_DGRAM indicates a message-based (datagram) connection.

Listen => n
Sets the listen-queue size to n number of client requests.

Reuse => 1
Given a nonzero number, this option allows the local bind address to be reused should the socket need to be reopened after an error.

Timeout => n
Sets the timeout.

Whether a server (receiving) or client (requesting) socket is created depends on the parameters provided to the constructor. If Listen is defined, a server socket is automatically created. If no protocol is specified, it is derived from the service on the given port number. If no port number is given, tcp is used by default.

15.2.4.1. IO::Socket::INET methods

The following methods can be used on socket filehandle objects created by IO::Socket::INET.

peeraddr
peeraddr

Returns the address part (packed string) of the socket-address data structure for the remote host to which a socket connects.

peerhost
peerhost

Returns the remote host address in the dotted-quad string form, e.g., 207.44.27.2.

peerport
peerport

Returns the port number for the remote host to which a socket connects.

sockaddr
sockaddr

Returns the address part (as a packed string) of the socket-address data structure for the socket.

sockhost
sockhost

Returns the address part of the socket-address data structure in the dotted-quad string form, e.g., 207.44.27.2.

sockport
sockport

Returns the local port number for the socket.

15.2.5. IO::Socket::UNIX Reference

The IO::Socket::UNIX subclass creates a Unix-domain socket. Unix-domain sockets are local to the current host and are used internally to implement pipes, thus providing communication between unrelated processes. Using sockets provides finer control than using named pipes, also called FIFO (first-in, first-out) buffers. This is because receiving sockets can distinguish between different client connections, which can then be assigned to different sessions with the accept call.

The IO::Socket::UNIX constructor (new( )) creates the socket and returns an object containing a filehandle. The constructor can take the following options:

Type => SOCK_STREAM | SOCK_DGRAM
Indicates the type of socket: SOCK_STREAM for streaming, SOCK_DGRAM for packets or datagrams.

Local => pathname
Provides the pathname of the FIFO buffer to bind to the socket.

Peer => pathname
Provides the pathname to the destination FIFO buffer.

Listen => n
Creates a listen socket and sets the queue size to n.

The following methods can be used on an object created with IO::Socket::UNIX.

hostpath
hostpath

Returns the pathname to the local FIFO buffer.

peerpath
peerpath

Returns the pathname to the destination or peer FIFO.

Previous | Home | Next
15. Sockets | Book Index | 16. Email Connectivity
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 16. Email Connectivity

Contents:

The Net Modules
The Mail Modules

Electronic mail is arguably the most essential Internet application. In fact, for many people, it's their introduction to the Internet. Thus, the Perl modules that deal with email are among the most useful modules. There are two major groups of modules that provide email capabilities. The first group is Graham Barr's libnet collection, which contains packages for developing client-side applications over the Internet in Perl. Table 16-1 lists some of the protocols implemented by the libnet modules.

Table 16-1. Protocols implemented by the libnet modules

Protocol | Module | Description
POP3 | Net::POP3 | Post Office Protocol, for reading email
SMTP | Net::SMTP | Simple Mail Transfer Protocol, for sending email
FTP | Net::FTP | File Transfer Protocol, for transferring files between hosts
NNTP | Net::NNTP | Network News Transfer Protocol, for reading Usenet news

In this chapter, we discuss Net::SMTP and Net::POP3. Chapter 17, "Usenet News" talks about Net::NNTP, Chapter 18, "FTP" discusses Net::FTP, and Chapter 19, "Lightweight Directory Access with Net::LDAP" covers Net::LDAP. Other libnet modules, such as Net::SNPP and Net::Time, are not described in this book, but you can get information about them from CPAN or with the perldoc command if libnet is installed on your system.

The second group of mail-related modules are the Mail modules, which can be found on CPAN as the MailTools collection. Other interesting mail-related modules include Mail::Folder and its subclasses, Mail::RBL, Mail::Audit, and Unix::AliasFile. This chapter describes the following subset of the Mail modules:

Mail::Send
Built on top of Mail::Mailer, providing better control of mail headers

Mail::Mailer
Interacts with external mail programs to send mail

Mail::Folder
Provides a base class and subclasses to work with mail folders

Mail::Internet
Provides functions to manipulate a mail message

Mail::Address
Extracts and manipulates RFC 822-compliant mail addresses

Mail::RBL
Provides domain lookups to the Real-time Blackhole List (RBL)

Mail::Audit
Provides an easy interface for creating mail filters

Unix::AliasFile
Perl interface to /etc/aliases format files

The rest of this chapter describes the Net modules and the Mail modules.

16.1. The Net Modules

Net::SMTP and Net::POP3 are the modules for sending and receiving email via the SMTP and POP3 protocols. When you use these modules, you are working at the socket level; they directly implement the Internet protocols for sending and receiving mail as defined in the relevant RFCs: RFC 821 for SMTP and RFC 1081 for POP3.

16.1.1. Send Email with Net::SMTP

The Simple Mail Transfer Protocol, or SMTP, is responsible for clients negotiating RCPT ("to") and FROM ("from") requests with an SMTP server, sending data to the SMTP server, and then sending an end-of-data indicator. Net::SMTP is a subclass of Net::Cmd and IO::Socket::INET that implements an interface to the SMTP and ESMTP protocols. These protocols send mail by talking to an SMTP server through a socket, as described in RFC 821.

When would you want to use Net::SMTP instead of sending mail with an external program? Since socket communications don't involve spawning an external program, your programs won't suffer from the overhead associated with running an extra process. Talking to SMTP is convenient for sending a volume of mail messages. Naturally, your server must have an SMTP server running, or a remote mailhost must allow you to talk to it; otherwise, you won't be able to use this module. That's when you can turn to Mail::Mailer or Mail::Send and let them provide an interface to an external mail program for you. This is the case, for example, with home computers, which don't generally run their own SMTP server.

16.1.2. The SMTP Protocol and the SMTP Session

The SMTP protocol defines the set of commands a client sends to an SMTP server, which is generally bound to port 25 of a mailhost. Requests and responses are negotiated between client and server.

When a client negotiates an SMTP session with a server, the server tells the client that it's listening. Once you're connected, you introduce yourself to the server by issuing a HELO command. The HELO command accepts one parameter—your hostname—and defaults to your remote hostname if you don't specify one. If the command is successful, the server sends a 250 response, as follows:

HELO
250 mail.somename.com Hello some-remote-host.com [127.0.0.1], pleased to meet
you

After you've been greeted by the server, send the MAIL command to tell the server who the message is from. The MAIL command takes the string From: user@hostname as an argument, and the server responds with a 250 message to indicate success:

MAIL From: <realuser@realhost.com>
250 realuser@realhost.com ... Sender ok

Then send the RCPT command to tell the server who the recipient is:

RCPT To: <nospam@rid-spam-now.com>
250 nospam@rid-spam-now.com ... Recipient ok

Now you're ready to send the body of your message to the server. The DATA command tells the server that all data until a . on a line by itself should be treated as the body of the mail message:

DATA
354 Enter mail, end with "." on a line by itself
Subject: Hi, just thought you'd be interested ...

Hi, this is the text of my mail message that I'm going to
send with Net::SMTP to show you how it works.
.
250 VAA09505 Message accepted for delivery

Once again, you get a 250 response, indicating that the message has been accepted for delivery. At that point, you can exit the SMTP session with the QUIT command, which returns 221 on success:

QUIT
221 mail.somename.com closing connection
Connection closed by foreign host.

16.1.2.1. Net::SMTP methods

The following methods are defined by Net:SMTP.

new
$smtp = Net::SMTP->new(host[, options])

Constructor. Takes the hostname of the remote mail server, host, and possibly some options, and creates a new SMTP object. Any options are passed to new as a hash, in which the option is the key. The possible options are:

Debug
Enables debug mode if set to 1. Provides information about your connection, requests, and responses.

Hello
Sends a HELO command to the SMTP server. Takes a string that represents your domain; if not specified, Hello guesses your domain.

Timeout
Time (in seconds) after which the client stops trying to establish a connection with the SMTP server. Defaults to 120 seconds. If the connection cannot be established, the constructor returns undef.

banner
$smtp->data([banner])

Returns the banner message with which the server replied when the initial connection was made. For example:

my $banner = $smtp->banner( );
print "$banner\n";
data
$smtp->data([bodydata])

Starts sending the body of the current message to the server. If specified, bodydata can be a list or a reference to a list; the contents of the list and the termination string .\r\n are sent to the server. Returns true if accepted.

If bodydata is not specified, then a true result means that the server is ready to receive data, which must be sent with the datasend and dataend methods (inherited from Net::Cmd).

dataend
$smtp->dataend(  )

Net::Cmd method issued after datasend to end the sending of data. Sends .\r\n to the server telling it that there's no more data coming and that it should send the message.

Here's an example that uses datasend and dataend:

@list_data = (1..10);
$smtp->data( );
$smtp->datasend(@list_data);
$smtp->dataend( );
datasend
$smtp->datasend("data")

Net::Cmd method that sends the body of the message to the remote server if the body wasn't specified with the data method.

domain
$smtp->domain(  )

Returns the domain of the remote SMTP server, or undef.

expand
$smtp->expand(address)

Requests the server to expand address. Returns an array containing the text from the server.

hello
$smtp->hello(domain)

Identifies your domain to the mail server. Executes automatically when you create a Net::SMTP object, so you shouldn't have to do it manually.

help
$help_text = $smtp->help([subject])

Returns help text from the server, or undef on failure. If subject is specified, returns help for that topic.

mail
$smtp->mail(address[, options])
$smtp->send(address)
send_or_mail(address)
send_and_mail(address)

Takes the sender's address and sends the appropriate command (MAIL, SEND, SOML, or SAML) to the server to initiate the message-sending process.

mail can take some ESMTP options, passed as key/value pairs. See the Net::SMTP documentation for the details.

quit
$smtp->quit

This method sends the QUIT command to the remote SMTP server and closes the socket connection.

recipient
$smtp->recipient(addr[, addr[, ...]])

Tells the server to send the current message to all specified recipients. As defined in the RFC, each address is sent as a separate command to the server. If the sending of any address fails, the process aborts and returns false; you can then call reset to reset the server.

reset
$smtp->reset(  )

Resets the server's status. Useful for canceling a message after it has been initiated but before any data has been sent.

to
$smtp->to(address[, address[, ...]])

Interchangeable with recipient.

verify
$smtp->verify(address)

Verifies that the specified mail address is valid. However, many servers ignore verify, so it frequently doesn't work.

16.1.3. Retrieving Email with Net::POP3

You can use SMTP to send mail, but not to retrieve it. For retrieving messages, use the Post Office Protocol Version 3 (POP3), described in RFC 1081. One way to do this is to use the Net::POP3 module. POP3 provides commands for interacting with the POP server, typically bound to port 110. Net::POP3 automates the transfer of email from a remote server to the local machine.

The POP server retrieves messages from a specified spooling directory on the remote system. The messages are stored in a file named for the username; anonymous logins are not permitted. Authentication is based on username and password and is done by sending the USER and PASS commands to the POP server. For example, identification of user foo with password bar looks like this:

USER foo
PASS bar

Net::POP3 has user and pass methods but may also authenticate users with login, which takes both username and password arguments. If authentication fails, the user cannot retrieve, delete, or alter any messages from the mail server. login returns the number of messages on the POP server for the user, or undef if authentication fails.

Authenticated users can retrieve information about their mailboxes and can get specific messages by message number.

A POP session to retrieve a mail message is negotiated with the server through the following steps:

  1. Connect to the POP server (the default port is 110).

  2. Send USER command.

  3. Send PASS command.

  4. If authenticated, receive number of messages.

  5. Send RETR <message number> command to retrieve a specific message.

  6. Send QUIT command to end session.

The following methods are defined by Net:POP3.

new
$pop = Net::POP3->new([host,] [options])

Constructor. Creates a new Net::POP3 object. host is the name of the remote host to which a POP3 connection will be made. If host is not specified, then the POP3_Host specified in Net::Config is used.

options are passed as key/value pairs, in which the option is the key. The possible options are:

ResvPort
Optional. If given, then the socket for the Net::POP3 object will be bound to the given local port using bind when the socket is created.

Debug
Enables debugging information

Timeout
Maximum time, in seconds, to wait for a response from the POP3 server. Default is 120 seconds.

apop
$pop->apop(user, pass)

Authenticates user with password pass with the server. The password is not sent in clear text. Requires the MD5 package; otherwise, returns undef.

delete
$pop->delete(msgnum)

Marks message msgnum for deletion from the remote mailbox. All messages marked for deletion are removed when the connection to the server is closed.

get
$pop->get(msgnum)

Gets message msgnum from remote mailbox. Returns a reference to an array containing lines of text read from the server.

last
$pop->last(  )

Returns the highest message number.

list
$pop->list([msgnum])

If called with an argument, returns the size of message msgnum. If called without an argument, returns a hash reference, in which the keys are the message numbers of all undeleted messages, and each corresponding value is the size of the message.

login
$pop->login([user[, pass]])

Sends both USER and PASS commands. If the password, pass, is not given, then Net::Netrc is used to look up the password based on the host and the username, user. If user is not specified, the current username is used. Returns the count of messages in the mailbox, or undef if the server can't authenticate the user.

pass
$pop->pass(pass)

Sends the PASS command with the password. Returns the number of messages in the mailbox.

popstat
$pop->popstat(  )

Returns a list with two elements: the number of undeleted elements and the size of the mailbox.

quit
$pop->quit(  )

Quits, closing the connection to the remote POP3 server and deleting all messages marked for deletion.

Note that if a Net::POP3 object goes out of scope before quit has been called, reset is called before the connection is closed, and any messages marked for deletion are not deleted.

reset
$pop->reset(  )

Resets status of the remote POP3 server. Clears the delete status on all messages that were marked for deletion.

top
$pop->top(msgnum[, numlines])

Gets the header and the first numlines lines of body for message msgnum. Returns a reference to an array containing lines of text read from the server.

uidl
$pop->uidl([msgnum])

Returns a unique identifier for msgnum if specified. If msgnum is not specified, returns a reference to a hash in which the keys are the message numbers, and the values are the unique identifiers.

user
$pop->user(user)

Sends the USER command, identifying the user.

Previous | Home | Next
15.2. The IO::Socket Module | Book Index | 16.2. The Mail Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.2. The Mail Modules

The Mail modules operate at a higher level than the Net modules, interacting with external mail packages such as mail, mailx, sendmail, or a POP3 server in the case of Net::POP3. This section describes some of the MailTools modules, Mail::Folder, and the other mail-related modules that were mentioned at the beginning of this chapter.

16.2.1. Send Email with Mail::Mailer

The Mail::Mailer module interacts with external mail programs. When you use Mail::Mailer or create a new Mail::Mailer object, you can specify which mail program you want your program to talk to:

use Mail::Mailer qw(mail);

Another way to specify the mailer is:

use Mail::Mailer;
$type = 'sendmail';
$mailprog = Mail::Mailer->new($type);

in which $type is the mail program. Once you've created a new object, use the open function to send the message headers to the mail program as a hash of key/value pairs, in which each key represents a header type, and the value is the value of that header:

# Mail headers to use in the message
%headers = (
    'To' => 'you@mail.somename.com',
    'From' => 'me@mail.somename.com',
    'Subject' => 'working?'
);

This code represents headers in which the recipient of the mail message is you@mail.somename.com, the mail was sent from me@mail.somename.com, and the subject of the mail message is working?.

Once %headers has been defined, it is passed to open:

$mailprog->open(\%headers);

You then send the body of the message to the mail program:

print $mailprog "This is the message body.\n";

Close the program when the message is finished:

$mailprog->close;

A practical example of using Mail::Mailer might be a command line-driven application that works much like the Unix mail program, either reading STDIN until end-of-file or mailing a file specified on the command line.

Mail::Mailer uses the environment variable PERL_MAILERS to augment or modify the built-in mailer selection. PERL_MAILERS is specified in the following format:

"type1:mailbinary1;mailbinary2;...:type2:mailbinaryX;...:..."

The possible types are listed for the new method below.

The following methods are defined in Mail::Mailer.

new
$mailer = new Mail::Mailer [type, command]

Constructor. Creates a new Mailer object representing the message to be sent. If the optional arguments are specified, the value of command depends on type, which can be one of:

mail
Uses the Unix mail program. command is the path to mail. The module searches for mailx, Mail, and mail, in that order.

sendmail
Uses the sendmail program. command is the path to sendmail.

test
Used for debugging. Calls /bin/echo to display the data, but doesn't actually send any mail. command is ignored, if specified.

If no arguments are specified, the Mailer object searches for executables in the above order and uses the first one found as the default mailer.

close
$mailer->close

Closes the mail program.

open
$mailer->open(\%hashref)

Sends message headers to the mail program. The headers are passed via a reference to a hash, in which each key is the name of a header, and the value is the contents of the header field. The value can be either a scalar or a reference to an array of scalars.

16.2.2. Better Header Control with Mail::Send

Mail::Send is built on top of Mail::Mailer, which means that you can also choose the mail program that sends the mail. Mail::Send has implemented the methods to, cc, bcc, and subject to replace the %headers hash used in Mail::Mailer.

Mail::Send uses the
open method to open the mail program for output;
it is built on Mail::Mailer's new
method, so that:

# Start mailer and output headers
$fh = $msg->open('sendmail');

serves the same purpose as:

# Use sendmail for mailing
$mailer = Mail::Mailer->new('sendmail)';

This code tells Mail::Send to use sendmail as the mail program.

Mail::Send also provides the set and add functions, which assign a value to a header tag and append a value to a header tag, respectively. The set function takes two arguments—a header tag and a value—and is used like this:

$msg->set($scalar, @array);

Therefore, to address a message to you@mail.somename.com:

$msg->set('To', 'you@mail.somename.com');

The above sets the To header to you@mail.somename.com; however, the following sets the To header to postmaster@mail.somename.com and you@mail.somename.com because they represent an array of values:

$msg->set('To', ('you@mail.somename.com', 'postmaster@mail.somename.com'));

You might think that you could use the set function as follows to add multiple values to a header value:

$msg->set('To', 'you@mail.somename.com');
$msg->set('To', 'someone@their.mailaddress.com');

However, set doesn't append information from one call to another, and the above example would send the mail only to someone@their.mailaddress.com. To append a name to the To header, use the add method. For example:

$msg->add('To', 'you@mail.somename.com');
$msg->add('To', 'someone@their.mailaddress.com');

The following methods are defined for Mail::Send.

new
$msg = new Mail::Send [header=>'value'[, ...]]

Constructor. Creates a new Mail::Send object that is the mail message you want to send. You can include values for headers when you create the object, or include them later by calling the appropriate methods.

add
$msg->add(header, values)

Adds a header to the message. header is the header to be added, and values is a list of values to be appended to that header.

bcc
$msg->bcc(values)

Adds a Bcc header containing the mail addresses specified in the list of values to the message. If there already is a Bcc, the new values replace any old values.

cancel
$msg->cancel

Not implemented yet, but will cancel the message.

cc
$msg->cc(values)

Adds a Cc header containing the mail addresses in the list of values to the message. If there already is a Cc, the new values replace any old values.

close
$fh->close

Closes the filehandle $fh (which was returned by open) and sends the message.

delete
$msg->delete(header)

Deletes the header header from the message.

open
$fh = $msg->open

Opens a filehandle for the message object. The filehandle is a Mail::Mailer object.

set
$msg->set(header, values)

Sets the header header to the contents of the array values.

subject
$msg->subject('What this message is about')

Sets the value of the Subject field.

to
$msg->to(values)

Sets the To field to the list of recipients in values.

16.2.3. Handle Folders with Mail::Folder

Once you've begun downloading and reading your mail from a POP server, you might want to save or categorize your messages into folders, which allow you to add, delete, save, and move messages easily. You can do this with Mail::Folder, which was written by Kevin Johnson as an object-oriented, folder-independent interface to mail folders. Mail::Folder supports a number of mailbox formats with the following interfaces:

Mail::Folder::Emaul
A folder interface somewhat similar to MH.

Mail::Folder::Maildir
An interface to maildir folders.

Mail::Folder::Mbox
Standard Unix mailbox format.

Mail::Folder::NNTP
The beginnings of an interface to NNTP. Not all the methods are implemented yet.

If you are interested in writing a folder interface, see the documentation for the module. The documentation explains the concepts and issues involved and describes some of the methods you may need to override.

The following methods are defined for Mail::Folder.

new
$folder = new(ftype[, foldername][, options])

Creates a new Mail::Folder object of the specified type. Arguments are:

ftype
The type of folder. Possible values are mbox, maildir, emaul, or NNTP.

foldername
The name of the folder. If present, the open method is called with foldername as the argument.

options
A hash in which the following options may be the keys:

Content-Length
Content-length header is created or updated by append_message and update_message.

Create
If set, the folder is created if it doesn't already exist.

DefaultFolderType
Autodetects folder type if create option is set and AUTODETECT has been set.

DotLock
Uses .lock-style folder locking with the proper folder interface (currently used only with the mbox interface).

Flock
Uses flock-style folder locking with the proper folder interface (currently used only with the mbox interface).

NFSLock
Deals with NFS-style file locking with the proper folder interface and the NFS server in question.

notMUA
If set, makes updates but doesn't save message labels or the current message indicator. If not set (the default), saves labels and the current message indicator as appropriate for the folder interface.

Timeout
Overrides the default timeout value. Specified in seconds. Particularly useful for folder interfaces that involve network communications.

add_label
$folder->add_label(msg_num, label)

Associates the label label with the message msg_num. Returns 1 on success or 0 if the label has a length of 0. Possible values of label are:

deleted
Used by delete_message and sync to process message deletion.

edited
Added by update_message to indicate that the message has been edited.

filed, forwarded, printed, replied
Not acted on.

seen
Message has been viewed by the user. Set by get_message for any message it has retrieve d.

append_message
$folder->append_message(\$mi_ref)

Adds message to a folder. Argument is a reference to a Mail::Internet object.

clear_label
$folder->clear_label(label)

Deletes the association with label for all messages in the folder. Returns the number of messages for which there was an association.

close
$folder->close

Does any necessary housekeeping and closes the folder.

current_message
$folder->current_message([msg_num])

With no argument, returns the message number of the current message in the folder. With an argument, sets the current message number for the folder to msg_num.

debug
$folder->debug([value])

Sets the level of debugging information for the object to value. With no argument, returns the current debugging level.

debug_print
$folder->debug_print(text)

Prints text, plus some additional information, to STDERR.

delete_label
$folder->delete_label(msg_num, label)

Deletes the association of label with msg_num. Returns 1 on success and 0 if there was no association.

delete_message
$folder->delete_message(msgs)

Takes a list of messages, msgs, to be marked for deletion. The messages aren't actually deleted until sync is called.

dup
$folder->dup(msg_num, \$folder_ref)

Copies the message specified by msg_num to the folder referenced by \$folder_ref. Like refile, but doesn't delete the original message. Generates a fatal error if no folder is currently open or if the folder doesn't contain message msg_num.

first_labeled_message
$folder->first_labeled_message(label)

Returns the message number of the first message in the folder that has label associated with it, or 0 if there are none.

first_message
$folder->first_message

Returns the message number of the first message in the folder.

foldername
$folder->foldername

Returns the name of the folder that the object has opened.

get_fields
$folder->get_fields(msg_num, fields)

Retrieves the fields specified in the list fields for message msg_num. If called in list context, returns a list; in scalar context, returns a reference to a list of the fields. Returns the fields in the same order as they were specified.

get_header
$folder->get_header(msg_num)

Extracts a message header; takes one argument: the message number. Returns a reference to a Mail::Header object.

get_message
$folder->get_message(msg_num)

Takes a message number as argument and returns a Mail::Internet object reference to that message, or 0 on failure.

get_message_file
$folder->get_message_file(msg_num)

Like get_message, but returns a filename instead of a Mail::Internet object reference.

get_mime_header
$folder->get_mime_header(msg_num)

Works much like get_header, but returns a reference to a MIME::Head object instead. Takes one argument, the message number.

get_mime_message
$folder->get_mime_message (msg_num[, parserobject][, options])

Returns a MIME::Entity object for the specified message. Calls get_message_file to get a message to parse, creates a MIME::Parser object, and uses that to create the MIME::Entity object. The arguments are:

msg_num
The number of the message.

parserobject
If specified, used instead of internally creating a parser object.

options
Maps onto the equivalent MIME::Parser methods. Specified as key/value pairs, with possible values of: output_dir, output_prefix, output_to_core. See the MIME::Parser documentation for details.

get_option
$folder->get_option(option)

Returns the setting for the specified option, or undef if the option doesn't exist.

inverse_select
$folder->inverse_select(\$func_ref)

Returns a list, in no specific order, of message numbers that do not match a set of criteria. The argument, \$func_ref, is a reference to a function used to determine the criteria. The function is passed a reference to a Mail::Internet object containing only a header.

is_readonly
$folder->is_readonly

Returns 1 if the folder has the readonly attribute set; otherwise, returns 0.

label_exists
$folder->label_exists(msg_num, label)

Returns 1 if label is associated with message msg_num; otherwise, returns 0.

last_labeled_message
$folder->last_labeled_message(label)

Returns the message number of the last message in the folder with the label label associated with it, or 0 if there is no such message number.

last_message
$folder->last_message

Returns the message number of the last message in the folder.

list_all_labels
$folder->list_all_labels

Returns a list, in no specific order, of all labels associated with messages in the folder. If called in scalar context, returns the number of labels associated with the messages.

list_labels
$folder->list_labels(msg_num)

Returns a list, in no specific order, of all labels associated with msg_num. If called in scalar context, returns the number of labels associated with the message.

message_exists
$folder->message_exists(msg_num)

Returns 1 if a message with the number msg_num exists in the folder; otherwise, returns 0.

message_list
$folder->message_list

Returns a list of the message numbers in the folder, in no specific order. The syntax is:

print $folder->message_list."\n"
next_labeled_message
$folder->next_labeled_message(msg_num, label)

Returns the message number of the next message in the folder relative to msg_number that has the label label associated with it, or 0 if there is no such message.

next_message
$folder->next_message([msg_num])

Returns the number of the next message in the folder relative to msg_numif it is specified; otherwise, relative to the current message. Returns 0 if at end of folder.

open
$folder->open(foldername)

If you didn't specify a folder name in the constructor, you need to call the open method, which takes the folder name as an argument and opens the folder. Also sets readonly if the folder is determined to be read-only.

pack
$folder->pack

For formats that allow message number sequences to have gaps, renames the files in the folders to eliminate any such gaps. May result in renumbering some messages.

prev_labeled_message
$folder->prev_labeled_message(msg_num, label)

Returns the message number of the previous message in the folder relative to msg_num that has the label label associated with it, or 0 if there is no such message.

prev_message
$folder->prev_message([msg_num])

Returns the number of the previous message in the folder relative to msg_num if it is specified; otherwise, relative to the current message. Returns 0 if at the beginning of the folder.

qty
$folder->qty

Returns the number of messages in the folder. The syntax is:

print "There are ".$folder->qty." messages in your
folder\n";
refile
$folder->refile(msg_num, \$fldr_ref)

Moves messages between folders. Takes a message number and folder reference as arguments.

select
$folder->select(\$func_ref)

Returns a list of messages that meet a set of criteria. The argument, \$func_ref, is a reference to a function used to determine the criteria. The function is passed a reference to a Mail::Internet object containing only a header. The list is returned in no specific order.

select_label
$folder->select_label(label)

Returns a list of messages with the label label. If called in scalar context, returns the number of messages that have the label.

set_option
$folder->set_option(option, value)

Sets the specified option to value.

set_readonly
$folder->set_readonly

Sets the readonly attribute for the folder. Once readonly has been set, sync won't perform any updates to the actual folder.

sort
$folder->sort(\$func_ref)

Returns a sorted list of messages. \$func_ref is a reference to a function that is passed two Mail::Header message references and returns an integer less than, equal to, or greater than 0 to indicate the sort order.

sync
$folder->sync

Synchronizes the folder with internal data structures and reads in any new messages since the last open or sync. Does not perform any updates if the readonly attribute has been set.

undelete_message
$folder->undelete_message(msgs)

Unmarks a list of messages, msgs, that have been marked for deletion.

update_message
$folder->update_message(msg_num, \$mref)

Replaces the message specified by msg_num with the contents of the message given by \$mref, which is a reference to a Mail::Internet object.

16.2.4. Handle Messages with Mail::Internet

Mail::Internet implements a number of helpful functions for manipulating a mail message. These include body, print_header, and head. Mail::Internet is built on top of Mail::Header, which parses the header of an email message, and it inherits the Mail::Header constructor style that requires that a file descriptor or reference to an array be used. For example:

@lines = <STDIN>;
$mi_obj = new Mail::Internet([@lines]);

reads a mail message from STDIN (using a reference to an array). The following example reads a mail message from a filehandle, FILE:

open(FILE, "/home/nvp/Mail/nvp");
$mi_obj = new Mail::Internet(\*FILE);
close(FILE);

The print_header function outputs the header of a message to a file descriptor; the default is STDOUT:

open(FILE, "/home/nvp/Mail/nvp");
$mi_obj = new Mail::Internet(\*FILE);
close(FILE);
$mi_obj->print_header(\*STDOUT);

The above example might output:

From nvp Mon Jun  9 00:11:10 1997
Received: (from nvp@localhost) by mail.somename.com (8.8/8.8) id
    AAA03248 for nvp; Mon, 9 Jun 1997 00:11:09 -0500 (EST)
Date: Mon, 9 Jun 1997 00:11:09 -0500 (EST)
From: "Nathan V. Patwardhan" <nvp>
Message-Id: <199706090511.AAA03248@mail.somename.com>
To: nvp
Subject: pop test
X-Status:
X-Uid: 1
Status: RO

in which print_body also takes a file descriptor as an argument, but outputs only the body of the message, whereas the print function outputs an entire message.

16.2.5. Mail::Internet Reference

new
$mail = new Mail::Internet ([arg], [options])

Creates a new Mail::Internet object. arg is optional and may be either a file descriptor (a reference to a glob) or a reference to an array. If present, the new object is initialized with headers either from the array or read from the file descriptor. options is a list of options in the form of key/value pairs. Possible options are:

Header
Mail::Internet should not attempt to read a mail header from arg, if it was specified. Value is a Mail::Header object.

Body
Mail::Internet should attempt to read the body from arg, if it was specified. Value is a reference to an array that contains the lines of the message body.

Modify
Reformats the headers if true. Mail::Header option.

MailFrom
Specifies behavior for headers in the form "From ". Mail::Header option. Possible values are:

IGNORE
Ignores and discards the headers

ERROR
Calls die

COERCE
Renames headers to Mail-From

KEEP
Keeps headers as they are

FoldLength
Value is default line length for folding headers. Mail::Header option.

add_signature
$mail->add_signature([file])

Appends a signature to the message. file is a file that contains the signature; if not specified, the file $ENV{HOME}/.signature is checked for a signature.

body
$mail->body(  )

Returns the body of the message as a reference to an array. Each entry in the array represents one line of the message.

escape_from
$mail->escape_from(  )

Inserts a leading > on any line that starts with "From " to avoid the problems that some applications have if a message contains a line starting with "From ".

head
$headobj = $mail->head(  )

Returns the Mail::Header object that holds the headers for the current message.

nntppost
$mail->nntppost([options])

Posts an article via NNTP; requires Net::NNTP. Options are passed as key/value pairs. Available options are:

Debug
Debug value to pass to Net::NNTP

Host
Name of NNTP server to connect to

Port
Port number to connect to on remote host

print_header
$mail->print_header([\*fd])
$mail->print_body([\*fd])
$mail->print([\*fd])

Prints the header, body, or whole message to file descriptor \*fd, which should be a reference to a glob. If the file descriptor is not given, the output is sent to STDOUT:

$mail->print(\*STDOUT);  # Print message to STDOUT
remove_sig
$mail->remove_sig([nlines])

Removes a user's signature from the body of a message. Looks for a line equal to "-- " within the last nlines lines of the message and removes that line and all lines after it. nlinesdefaults to 10.

reply
$reply = $mail->reply(  )

Creates a new object with headers initialized for a reply to the current object and with a body that is an indented copy of the current message.

smtpsend
$mail->smtpsend(  )

Sends the Mail::Internet message via SMTP to all addresses on the To, Cc, and Bcc lines. Finds the SMTP host by trying to connect first to hosts specified in $ENV{SMTPHOSTS}, then to mailhost, and then to localhost.

In a future release of Mail::Internet, smtpsend will be able to take the hostname as a parameter, as nntppost does.

tidy_body
$mail->tidy_body(  )

Removes all leading and trailing lines that contain only whitespace from the message body.

unescape_from
$mail->unescape_from(  )

Removes the escaping added by escape_from.

16.2.6. Parse Email Addresses with Mail::Address

Mail::Address parses RFC 822-compliant mail addresses of the form:

"Full Name or Phrase" <username@host> (Comment Area)

For example, under RFC 822, an address might be represented as:

"Nathan V. Patwardhan" <nvp@mail.somename.com> (No Comment)

or:

"Nathan V. Patwardhan" <nvp@mail.somename.com>

The Mail::Address constructor parses an email address into three parts based on the categories shown above:

$addr = Mail::Address->new("Full Name or Phrase",
                           "username@host",
                           "(Comment Area)");

Mail::Address also outputs portions of the mail address with the functions phrase, address, comment, format, name, host, and user. The phrase, address, and comment functions represent the first, second, and third entities that were passed to the Mail::Address constructor, in which the phrase function:

print $addr->phrase( );

outputs:

Nathan V. Patwardhan

the address function:

print $addr->address( );

outputs:

nvp@mail.somename.com

and the comment function:

print $addr->comment( );

outputs:

No Comment

A real mail address can be "unmangled," or parsed from its user@somehost.com format, with the user and host functions. The user function removes everything starting with the @ to the end of the address, and host removes everything up to and including the @. Using the previous example of nvp@mail.somename.com, the following line:

print $addr->user;

outputs:

nvp

And the following line using the host function:

print $addr->host;

outputs:

nvp@mail.somename.com

16.2.7. Mail::Address Reference

new
$addr = Mail::Address->new(phrase, address[, comment])

Constructor. Creates new Mail::Address object representing an address with the specified elements. In a message, these three elements show up as:

phrase <address> (comment)
address (comment)
parse
Mail::Address->parse(line)

Constructor. Parses the specified line, usually a To, Cc, or Bcc line, and returns a list of extracted Mail::Address objects.

address
$addr->address(  )

Returns the address part of the object.

canon
$addr->canon(  )

Unimplemented, but should return the UUCP canon for the message.

comment
$addr->comment(  )

Returns the comment part of the object.

format
$addr->format(  )

Returns a string representing the address in a form suitable for the To, Cc, or Bcc line of a message

host
$addr->host(  )

Returns the host portion of the address.

name
$addr->name(  )

Takes information contained in the object and uses various heuristics to try to identify the name of the person or group.

path
$addr->path(  )

Unimplemented, but should return the UUCP path for the message.

phrase
$addr->phrase(  )

Returns the phrase part of the object.

user
$addr->user(  )

Returns the user ID portion of the address.

16.2.8. Checking Blacklisted Hosts with Mail::RBL

Mail::RBL eases the task of checking if a given host is in the real-time blackhole list. Mail::RBL does this by speaking directly to the RBL server and searching for a specified host. Ordinarily, you build this functionality into your MTA (sendmail, qmail, Exim, etc.), but if your system administrator hasn't built RBL support into your MTA, you might consider integrating Mail::RBL into your own mail filter.

new(suffix)
Creates a list handle. suffix is required because it denotes the host from which you'll check hostnames.

check($host)
Performs the lookup against the RBL. $host can be a hostname or IP address, without trailing netmasks (represented by a / followed by an octet).

For example:

use Mail::RBL;

my $host = q[some-spammer.domain.here];
my $rbl = Mail::RBL->new('list.org');

if($rbl->check($host)) {
    print "$host is in the RBL, and I won't deliver the mail."
} else {
    # Do something to deliver the email
}

16.2.9. Mail Filtering with Mail::Audit

Mail::Audit is a mail-filtering system for those who want to write good filter rules but choose not to use procmail. It was written to provide flexibility while realizing the strengths of Perl's regular expression engine. Inspired by Tom Christiansen's audit_mail and deliverdb programs, Mail::Audit allows an email message to be logged, examined, routed to another folder or INBOX, resent, or rejected. You should be able to write a simple ruleset or rulesets and put references to it in your .forward file. For example:

use Mail::Audit;

my $m_au = Mail::Audit->new( );

$m_au->reject("Let me call YOU at home!")
    if $m_au =~ /(spammer\@spammer.com|spammer2\@spammer2.com|spammer3\@spammer3.com)/;

$m_au->accept("Majordomo") if $mail->from =~ /Majordomo\@/;

$m_au->accept( );

Mail::Audit implements the following methods.

new
new(%options)

Constructor. Reads a mail message from STDIN (or, if the data option is set, from an array reference) and creates a Mail::Audit object from it. Options include:

log=>logfile
Writes a debugging log.

loglevel=>n
Sets verbosity of the log on a scale of 1 to 4.

noexit=>1
Do not exit after delivering mail.

If you specify a log level without a log file, logging will be written to /tmp/username-audit.log, where username is replaced by your username.

body
body(  )

Returns a reference to an array of lines in the body of the email.

get
get(header)

Retrieves the named header from the mail message.

header
header(  )

Returns the header as a single string.

ignore
ignore(  )

Ignores an email message completely, dumping it into the bit bucket.

pipe
pipe(program)

Opens a pipe to an external program and feeds the message to it.

put
put(header, value)

Inserts a new header into the mail message with the given value.

reject
reject(message)

Rejects an email message, then notifies the sender that the message is undeliverable with message as the reason given.

resend
resend(address)

Bounces the email in its entirety to another address.

tidy
tidy(  )

Tidies up the email as per the Mail::Internet manpage.

xaccept
xaccept(filename)

Writes the incoming (and filtered) mail into a mailbox at filename. If filename is undefined, mail is written to /var/spool/mail/$USER. If you use Maildir instead of mbox-formatted mail, it will deliver the mail in Maildir style.

16.2.10. Alias Manipulation with Unix::AliasFile

While not a member of the Mail umbrella, Unix::AliasFile is an important module since it implements a complete interface to the Unix aliases text file that allows you to query, add, update, and delete aliases. In addition, it has a cleaner interface than Mail::Alias. Unix::AliasFile automatically handles file locking, comma and colon placement, and any other detail that's related to manipulating your Unix mail alias file. For example:

use Unix::AliasFile;

my $aliasfile = '/etc/mail/aliases';
my $uaf = Unix::AliasFile->new($aliasfile);

foreach my $alias $uaf->aliases( ) {
    chomp($alias);

    if($uaf->alias($alias) ne "$alias\@yourpopserver.your.domain") {
        # Doesn't exist, so add alias of the form:
        # alias: alias@yourpopserver.your.domain

        $uaf->alias($alias, ("$alias\@yourpopserver.your.domain"));
    } else {
        print "I already have $alias that way.\n";
    }
}

$uaf->commit( );
undef $uaf;

Unix::AliasFile implements the following methods.

new
new(filename)

Constructor. Creates a new Unix::AliasFile object.

add_user
add_user(alias, @users)

Adds @users to alias. If a user in @users already exists in alias, duplicates will be ignored. If alias is set to *, @users will be added to every alias.

alias
alias(alias, @users)

Adds, modifies, or returns information about an alias. When only alias is suppled, alias( ) returns a list of all members of an alias, or undef if alias does not exist. If you supply @users, alias will be modified or created if it doesn't already exist.

aliases
aliases(  )

Returns an alphabetized list of all existing aliases. In scalar context, this method returns the total number of aliases.

comment
comment(alias, comment)

Inserts a comment line before alias. comment must begin with #, but a newline will be appended to it. Returns 1 on success and 0 on failure.

commit
commit(  )

Writes the alias file.

delempty
delempty(  )

Deletes all existing aliases that have no members, returning a count of the number of aliases deleted.

delete
delete(alias)

Deletes alias.

remove_user
remove_user(alias, @users)

Removes the list of users from an existing alias. If a user in @users isn't a member of alias, the removal attempt will be silently ignored. remove_user( ) returns 1 on success and 0 on failure.

rename_user
rename_user(oldname, newname)

Changes one username to another in every alias. Returns the number of aliases affected.

uncomment
uncomment(comment)

Removes the comment from the file that is exactly matched to the supplied text. Returns 1 on success and 0 on failure.

Previous | Home | Next
16. Email Connectivity | Book Index | 17. Usenet News
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 17. Usenet News

Contents:

The NNTP Protocol
Net::NNTP
The News::Newsrc Module

Usenet is a collection of bulletin board-like newsgroups on the Internet, covering thousands of topics. Whatever your interest, chances are you'll find a newsgroup in which it is discussed.

Usenet has been around since late 1979. The current implementation is based on the Network NewsTransfer Protocol (NNTP), defined in RFC 977 and released in March 1986. Information is propagated through Usenet by a system of newsfeeds in which one site requests a newsfeed from another site, and a third site requests a newsfeed from the second site, etc. There is no central Usenet authority—like Perl, it runs on the spirit of cooperation and sharing. When you run a news reader, such as tin or the news reader in a web browser, your client software talks to the NNTP server on the news host. When you post a message to a newsgroup, this posting is received by your NNTP server and passed on to other servers throughout the distribution area you specified for the posting. Each server periodically receives updated newsgroup information and newly posted news articles.

This chapter explores NNTP commands and responses. It introduces Net::NNTP, which implements NNTP commands and simplifies the process of writing a Perl-based NNTP news client. It also describes News::Newsrc, a module that provides methods for managing a .newsrc file.

There are two kinds of NNTP commands: the official set of commands as defined in RFC 977 and a number of extensions that have been added since the RFC was written. The extensions are described in an IETF Internet Draft document, "Common NNTP Extensions" by Stan Barber, which can be found at ftp://ftp.academ.com/pub/nntp/ietf/nntpext.txt.

17.1. The NNTP Protocol

Before you write your own news client, you should have some idea of how the NNTP protocol works. Like other servers, an NNTP server is bound to a port (usually port 119). It listens for incoming connections, takes the appropriate action, and returns a response to the client. When a news client connects with an NNTP server, or to the port on which the NNTP server is running, a message such as the following is produced:

Trying 0.0.0.0...
Connected to hostname.mydomain.com.
Escape character is '^]'.
200 newshost.mydomain.com InterNetNews NNRP server INN 1.5.1 17-Dec-1996 ready
(posting ok).

Many NNTP servers understand the help (or HELP) command. When a client issues a help command, many NNTP servers respond with a list of all available commands. For example:

200 news.mydomain.com InterNetNews NNRP server INN 1.5.1 17-Dec-1996 ready
(posting ok).
HELP
100 Legal commands
  authinfo user Name|pass Password|generic <prog> <args>
  article [MessageID|Number]
  body [MessageID|Number]
  date
  group newsgroup
  head [MessageID|Number]
  help
  ihave
  last
  list [active|active.times|newsgroups|distributions|distrib.pats|
overview.fmt|subscriptions]
  listgroup newsgroup
  mode reader
  newgroups yymmdd hhmmss ["GMT"] [<distributions>]
  newnews newsgroups yymmdd hhmmss ["GMT"] [<distributions>]
  next
  post
  slave
  stat [MessageID|Number]
  xgtitle [group_pattern]
  xhdr header [range|MessageID]
  xover [range]
  xpat header range|MessageID pat [morepat...]
  xpath MessageID
Report problems to <usenet@news.mydomain.com>
.

After connecting to the NNTP server, you can get a list of available newsgroups with the list active command, and you can then select a newsgroup. If you were to connect directly to news.mydomain.com and use the group command to select the newsgroup local.test, your session might look like this:

200 news.mydomain.com InterNetNews NNRP server INN 1.5.1 17-Dec-1996 ready
(posting ok).
group local.test
211 4 1 4 local.test
QUIT
205 .

The four numbers (in this example, 211 4 1 4) preceding the group name (local.test) represent the success code, total number of articles, and the first and last article numbers, respectively. So in this example, 211 is the success code. There are four articles in the local.test group, starting with article number 1 and ending with number 4.

Every article in a newsgroup has two identifiers associated with it. The first is the message number, and the second is a message ID. The message number is the number of that article on the server to which you are connecting. The message ID is an identifier that is always associated with the article on every server that receives the article. An article that has the message number 4 on your server might be number 83 on someone else's server. The message ID, however, will be the same on both. So, for example, if you want to post an article that refers to another article, use the message ID.

Once the group command has successfully identified a newsgroup, the client can request a particular article by sending an article request to the server. The article command takes either a message ID or a message number as an argument. For example:

article 4
Path: newshost.mydomain.com!news-w.ans.net!newsfeeds.ans.net!philabs ...
From: user@mydomain.com (User Name)
Newsgroups: local.test
Subject: Is anybody there?
Date: 21 Apr 1997
...

If the article command is successful, the server returns the selected message.

The xhdr command returns the selected headers ("X-headers") from articles in a certain newsgroup. The X-headers contain all the information about the news article, including the poster's email address, the subject of the message, the date and time the message was posted, the newsgroup(s) the message appears in, and the message ID. For example, if you want to see the subjects of the articles in the local.test newsgroup, you can run xhdr subject 1-4, as follows:

xhdr subject 1-4
221 subject fields follow
1   Is anybody there?
2   Re: Is anybody there?
3   Re: Is anybody there?
4   Get a life!

The 221 status code indicates that the xhdr completed successfully and returned the requested headers. A Usenet client might display these headers to the user, who can then select the articles to read based on the subject lines.

A command similar to xhdr is xpat, which matches X-headers against a pattern string you give it. For example, executing xpat subject 1-9 *anybody* for local.test might look like this:

xpat subject 1-9 *anybody*
221 subject matches follow.
1   Is anybody there?
2   Re: Is anybody there?
3   Re: Is anybody there?

You can also post news articles with NNTP. When you issue the post command, the server returns a code of 340 if posting is permitted. If you get an error, such as 501, you cannot post articles with this command. Most servers require that you include Newsgroups, Subject, and From headers. You will receive a 240 reply if your message has been successfully posted. Here's an example of posting to local.test using NNTP:

200 news.mydomain.com InterNetNews NNRP server INN 1.5.1 17-Dec-1996 ready
(posting ok).
post
340 Ok
Newsgroups: local.test
Subject: talking NNTP
From: user@mydomain.com
This is a test posting.
.
240 Article posted
QUIT
205 .

The server returns a code of 205 upon disconnecting. When the article arrives in local.test, it looks like this:

From news.mydomain.com!not-for-mail Sun Mar  9 19:18:37 1997
Path: news.mydomain.com!not-for-mail
From: user@mydomain.com
Newsgroups: local.test
Subject: talking NNTP
Date: 10 Mar 1997 00:09:33 GMT
Organization: Perl in a Nutshell
Lines: 2
Distribution: local
Message-ID: <5fvjft$k3$2@news.mydomain.com>
NNTP-Posting-Host: newshost.mydomain.com
Xref: newshost.mydomain.com local.test:6

This is a test posting.
Previous | Home | Next
16.2. The Mail Modules | Book Index | 17.2. Net::NNTP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.2. Net::NNTP

Net::NNTP is one of the libnet modules. It provides methods for programming a news client to interface with an NNTP server. Net::NNTP implements the NNTP protocol as defined in RFC 977, as well as a number of extensions defined in the IETF Internet Draft document mentioned earlier.

For example, the following code:

$nntp->post(@message);

is equivalent to issuing the post command and associated X-headers directly to an NNTP server on port 119.

17.2.1. Initializing the NNTP Client

To use Net::NNTP, create a new Net::NNTP object:

use Net::NNTP;
$nntp = Net::NNTP->new;   # Use default port and options

Once you've created the object, you can use any of the Net::NNTP methods on that object. The Net::NNTP methods generally parallel the functionality of the raw NNTP commands. Your news client can be written to perform many functions, including:

  • Authenticating a user to the server

  • Listing available newsgroups

  • Retrieving news headers and articles

  • Extracting headers

  • Checking for new articles

  • Posting articles

  • Listing information such as active messages in a newsgroup, new newsgroups, valid distribution areas, or message IDs of newly arrived messages

17.2.2. Net::NNTP Reference

Net::NNTP includes methods that implement many of the extensions to RFC 977; the description indicates if a method is an extension. Extensions that are not supported by Net::NNTP are AUTHINFO, GENERIC, XINDEX, XSEARCH, and XTHREAD. In addition, some extensions supported by Net::NNTP may not be supported by a particular server.

Unless otherwise stated, all the methods return either true or false to indicate success or failure. If a method returns a value instead, then it returns undef or an empty list to indicate failure.

In this list, message-spec refers to a single message ID, a single message number, or a reference to a list of two message numbers. It can also be passed as a list of two message numbers, but this is for compatibility only and is now deprecated.

Where pattern-matching is indicated, the matching is done according to the NNTP specification. See the Net::NNTP documentation for details.

new
$nntp = Net::NNTP->new([host[, options]])

Constructor. Creates a new Net::NNTP object. Arguments are:

host
The name of the remote host to which an NNTP connection is required. If not specified, the constructor checks the environment variables NNTPSERVER and NEWSHOST, in that order, then Net::Config. Defaults to news if nothing is found.

options
Options. Passed as key/value pairs. Possible options are:

Timeout
Maximum time, in seconds, to wait for a response from the NNTP server. Default is 120 seconds. A value of 0 causes all I/O operations to block.

Debug
Enables printing of debugging information to STDERR.

active
$nntp->active([pattern])

Similar to list, but returns only active groups that match the pattern (an extension).

active_times
$nntp->active_times(  )

Returns a reference to a hash in which the keys are the group names, and the values are references to arrays containing the time the group was created and an identifier, possibly an email address, for the creator (an extension).

article
$nntp->article([msgid|msgnum])

Retrieves the header, a blank line, then the body (text) of the article, specified as either a message ID or a message number. With no arguments, returns the current article in the current newsgroup as a reference to an array containing the article.

authinfo
$nntp->authinfo(user, pass)

Authenticates the user to the server, passing the user's username and password.

body
$nntp->body([msgid|msgnum])

Retrieves the body (text) of the article specified by either a message ID or a message number. Takes the same arguments as article. Returns a reference to an array containing the body of the article.

date
$nntp->date(  )

Returns the date on the remote server, in Unix time format (seconds since 1970).

distributions
$nntp->distributions(  )

Returns a reference to a hash in which the keys are the valid distribution names, and the values are the distribution descriptions (an extension).

group
$nntp->group([group])

Sets and/or gets the current group. With no argument, returns information about the current group; otherwise, sets the current group to group.

In a scalar context, group returns the group name. In an array context, it returns a list containing the number of articles in the group, the first article number, the last article number, and the group name.

head
$nntp->head([msgid|msgnum])

Retrieves the header of the article specified by msgid or msgnum. Takes the same arguments as article and returns a reference to an array containing the article's header.

ihave
$nntp->ihave(msgid[, message])

Informs the server that the client has an article whose ID is msgid. The optional argument message can be either an array of lines or a reference to an array. If message is specified, and the server wants a copy, it is sent, returning true on successful completion.

If message is not specified, then the message must be sent using the Net::Cmd datasend and dataend methods.

last
$nntp->last(  )

Sets the current article pointer to the previous article in the current newsgroup. Returns the article's message ID.

list
$nntp->list(  )

Returns information about all active newsgroups. The result is a reference to a hash in which the key is a newsgroup name, and each value is a reference to an array. The elements in the array are the first article number in the group, the last article number in the group, and any information flags.

listgroup
$nntp->listgroup([group])

Returns a reference to a list of all active messages in newsgroup group, or the current newsgroup if group is not specified (an extension).

newgroups
$nntp->newgroups(since[, distributions])

Like list, but returns groups created after a certain time and optionally in one of a set of distribution areas. Arguments are:

since
Time value; only groups created after this time should be returned.

distributions
Optional distribution pattern or reference to a list of distribution patterns. If present, only groups matching a specified distribution area should be returned.

newnews
$nntp->newnews(since[, groups[, distributions]])

Returns a reference to a list containing the message IDs of all news posted after since that are in newsgroups matching groups, with a distribution that matches distributions. Arguments are:

since
Time value; only groups created after this time should be returned.

groups
Optional group pattern or reference to a list of group patterns indicating which groups should be checked for new messages.

distributions
Optional distribution pattern or reference to a list of distribution patterns. If present, only groups matching a specified distribution area should be returned.

newsgroups
$nntp->newsgroups([pattern])

Returns a reference to a hash in which the keys are all newsgroup names that match pattern, or all newsgroups if no pattern is specified, and each value contains the description text for the group (an extension).

next
$nntp->next(  )

Sets the current article pointer to the next article in the current newsgroup. Returns the message ID of the article.

nntpstat
$nntp->nntpstat([msgid|msgnum])

Similar to article, except that no text is returned. When selecting by message number within a newsgroup, sets the current article pointer without sending text. Selecting by message ID is valid, but doesn't alter the current article pointer and therefore is of little use. Returns the message ID of the current article.

overview_fmt
$nntp->overview_fmt(  )

Returns a reference to an array containing the names of the fields returned by xover (an extension).

post
$nntp->post([message])

Posts a new article to the news server. If message is specified and posting is allowed, then the message is sent. If message is not specified, the message must be sent using the Net::Cmd datasend and dataend methods. message can be either an array of lines or a reference to an array.

postok
$nntp->postok(  )

Returns true if the server's initial response indicated that it allows posting.

quit
$nntp->quit(  )

Quits the remote server and closes the socket connection.

reader
$nntp->reader(  )

Tells the server that you are a reader and not another server; required by some servers (an extension).

slave
$nntp->slave(  )

Tells the remote server that this is not a user client, but is probably another news server.

subscriptions
$nntp->subscriptions(  )

Returns a reference to a default list of newsgroups recommended for new users to subscribe to (an extension).

xgtitle
$nntp->xgtitle(pattern)

Returns a reference to a hash in which the keys are all the newsgroup names that match pattern, and each value is the text of the newsgroup's description (an extension).

xhdr
$nntp->xhdr(header, message-spec)

Gets the header field header for all the messages specified in message-spec. Returns a reference to a hash in which the keys are the message numbers, and each value contains the text of the requested header for that message (an extension).

xover
$nntp->xover(message-spec)

Returns a reference to a hash in which the keys are the message numbers, and each value contains a reference to an array of the overview fields for that message (an extension).

The names of the fields can be obtained by calling overview_fmt.

xpat
$nntp->xpat(header, pattern, message-spec)

Like xhdr, but returns only headers in which the text of the header matches pattern (an extension).

xpath
$nntp->xpath(message-id)

Returns the path to the file on the server that contains the specified message (an extension).

xrover
$nntp->xrover(message-spec)

Returns reference information for the article(s) specified. Returns a reference to a hash in which the keys are the message numbers, and the values are the References: lines from the articles (an extension).

Previous | Home | Next
17. Usenet News | Book Index | 17.3. The News::Newsrc Module
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.3. The News::Newsrc Module

Most Unix-based newsreaders parse and extract your newsgroup information from a .newsrc file. This file contains an entry for each newsgroup, with the name of the group and a comma-separated list of article numbers from 1 to the current article. The first entry in the list shows articles that have been read; the remaining entries list unread articles. Each entry also has a colon (:) following the name if you are subscribed to that newsgroup, or an exclamation point (!) if you are currently unsubscribed.

To read a newsgroup, your newsreader needs to be connected to an NNTP server. The newsreader then checks the .newsrc entry for that newsgroup to determine which articles you haven't read, and displays the first unread article. You can then read the articles sequentially or select which articles you want to read. When you "catch-up" a newsgroup by marking all the articles as "read", or when you exit from the newsreader program, your .newsrc file is updated to reflect your activity during that session.

The News::Newsrc module provides methods for managing your .newsrc file. Some of the functions it provides include letting you add, remove, or reorder newsgroups; subscribe to or unsubscribe from newsgroups; and mark articles as read or unmark them. Unless you tell it to rearrange the order of the newsgroups in .newsrc, News::Newsrc leaves the order unchanged.

17.3.1. News::Newsrc Reference

new
$newsrc = new News::Newsrc

Constructor. Creates a new News::Newsrc object that contains no newsgroups.

add_group
$newsrc->add_group(groupname[, options])

Adds newsgroup to .newsrc, as a subscribed group. Defaults to adding at the end. The arguments are:

groupname
Name of the newsgroup to add.

options
Hash with one entry, indicating where to put the newsgroup. Key is where, and possible values are:

after => group
Put immediately after newsgroup group, or last if group is not there.

alpha
Put in alphabetical order.

before => group
Put immediately before newsgroup group.

first
Put as first newsgroup.

last
Put as last newsgroup.

number => n
Put at position n, where the first position is 0. If position is negative, count from the end of the list backwards n positions.

del_group
$newsrc->del_group(groupname)

Removes specified newsgroup groupname from .newsrc.

exists
$newsrc->exists(groupname)

Returns true if newsgroup groupname is in .newsrc.

groups
$newsrc->groups(  )

Returns list of newsgroups in .newsrc. In scalar context, returns an array reference.

load
$newsrc->load([filename])

Loads newsgroups in filename into $newsrc, replacing any newsgroups that are already there. Defaults to $HOME/.newsrc.

mark
$newsrc->mark(groupname, article_number[, options])

Adds an article to the list for a specified newsgroup. Arguments are:

groupname
Newsgroup to add an article to.

article_number
Article number of the article to add.

options
Hash. See description under add_group.

marked
$newsrc->marked(groupname, article_number)

Returns true if the newsgroup exists and contains the specified article. Arguments are:

groupname
Group to report on

article_number
Number of the article to verify

marked_articles
$newsrc->marked_articles(groupname)

Returns the list of articles in group groupname. In scalar context, returns an array reference.

mark_list
$newsrc->mark_list(groupname, \@article_list[, options])

Adds articles to the list for a specified group. Arguments are:

groupname
Group to add articles to.

\@article_list
Reference to list of articles to add.

options
Hash. See description under add_group.

mark_range
$newsrc->mark_range(groupname, n, m[, options])

Adds articles in the specified range to the list. Arguments are:

groupname
Newsgroup to add articles to.

n
Number of the first article in the range.

m
Number of the last article in the range.

options
Hash. See description under add_group.

save
$newsrc->save(  )

Saves changes to .newsrc file.

save_as
$newsrc->save_as(filename)

Saves changes to specified file filename, rather than to .newsrc file.

sub_groups
$newsrc->sub_groups(  )

Returns list of subscribed groups in .newsrc.

subscribe
$newsrc->subscribe(groupname)

Subscribes to newsgroup groupname. If the group is not in .newsrc, it is added; its location may be given in options, as specified for add_group.

subscribed
$newsrc->subscribed(groupname)

Returns true if the group groupname exists and is subscribed to.

unmark
$newsrc->unmark(groupname, article_number[, options])

Removes specified article from the group list. Arguments are:

groupname
Newsgroup to remove articles from.

article_number
Article to remove.

options
Hash. See description under add_group.

unmarked_articles
$newsrc->unmarked_articles(groupname, n, m[, options])

Returns the list of articles from n to m, inclusive, that are not in the article list for the newsgroup. Arguments are:

groupname
Group to return articles from.

n
Number of the first article in the range.

m
Number of the last article in the range.

options
Hash. See description under add_group.

unmark_list
$newsrc->unmark_list(groupname, \@article_list[, options)

Removes specified list of articles from the group list. Arguments are:

groupname
Group to remove articles from.

\@article_list
Reference to list of articles to remove.

options
Hash. See description under add_group.

unmark_range
$newsrc->unmark_range(groupname, n, m[, options])

Removes a range of articles from n to mfrom .newsrc. Arguments are:

groupname
Group to remove articles from.

n
Number of the first article in the range.

m
Number of the last article in the range.

options
Hash. See description under add_group.

unsub_groups
$newsrc->unsub_groups(  )

Returns list of unsubscribed groups in .newsrc. In scalar context, returns an array reference.

unsubscribe
$newsrc->unsubscribe(groupname[, options])

Unsubscribes from newsgroup in .newsrc. If the group is not in .newsrc, it is added. Arguments are:

groupname
Group to unsubscribe from.

options
Hash. See description under add_group.

Previous | Home | Next
17.2. Net::NNTP | Book Index | 18. FTP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 18. FTP

Contents:

The FTP Protocol
Net::FTP
FTP Configuration with Net::Netrc

The File Transfer Protocol (FTP) is a popular means of transferring files between computers. FTP communication follows the client/server model: the client initiates a conversation by sending commands, and the server responds with messages and status codes, as well as by sending or receiving files. This chapter discusses two FTP-related modules included in the libnet distribution: Net::FTP, which provides a number of wrapper functions for implementing the client side of FTP, and Net::Netrc, which provides an interface for getting information from a .netrc file.

The FTP protocol permits two-way file transactions, in which files can be sent to or taken from an FTP server. These transactions involve the local filesystem (on the client side) and the remote filesystem (on the server side). When a file is transferred between the local and remote systems, its filename on the destination system is the same as on the source system, unless you specify a new filename.

The FTP protocol also lists the types of files that can be transferred. These types define (among many other things) how end-of-line characters are handled for different types of files.

18.1. The FTP Protocol

When a server accepts FTP requests, it opens a port (generally port 21) for incoming connections and authenticates clients based on account or anonymous privileges. A user may log in with a legitimate account on that machine, provide her own password, and access any file she normally has access to under the Unix shell. Many servers also allow "anonymous" FTP, in which users log in with the name "anonymous" and use their email address as the password. They are then granted restricted access to a limited portion of the filesystem.

The FTP commands defined in RFC 959 are listed in the following table:

Command | Meaning
ABOR | Abort previous FTP command.
ACCT | Specify the user's account.
ALLO | Tell server to allocate additional storage for new file.
APPE | Tell server to append to an existing file.
CDUP | Change to parent directory.
CWD | Change directory.
DELE | Delete a file.
HELP | Get help.
LIST | List files for display.
MKD | Make a directory.
MODE | Specify the data transfer mode.
NLST | List files for additional processing.
NOOP | No-op.
PASS | Specify the user's password.
PASV | Tell server to go into "passive" mode.
PORT | Specify data port for connection.
PWD | Print working directory.
QUIT | Close connection.
REIN | Reinitialize connection.
REST | Restart a file transfer.
RETR | Retrieve a file.
RMD | Remove a directory.
RNFR | Specify pathname of file to be renamed.
RNTO | Specify new name of file being renamed.
SITE | Provide additional site-specific services.
SMNT | Mount a different filesystem.
STAT | Get status.
STOR | Tell server to accept a file for storage.
STOU | Tell server to create unique name for new file.
STRU | Specify the file structure.
SYST | Tell server to declare its operating system.
TYPE | Specify the data representation type.
USER | Specify the username.

Exactly which FTP commands are available depends on the server; some servers implement a subset, or possibly a superset, of the commands defined in the RFC. Net::FTP, which we'll discuss in this chapter, provides methods that implement all the commands except the following:

ALLO

HELP

MODE

REIN

SITE

SMNT

STAT

STRU

SYST

Previous | Home | Next
17.3. The News::Newsrc Module | Book Index | 18.2. Net::FTP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.2. Net::FTP

Net::FTP is used to transfer files from remote hosts. With Net::FTP, you can write simple FTP clients that transfer files from remote servers based on information passed on the command line or from hardcoded variables. Here is an example of a client that connects to a remote FTP server and gets a file from the server:

#!/usr/local/bin/perl -w

use Net::FTP;

$hostname = 'remotehost.com';
$username = 'anonymous';
$password = 'myname@mydomain.com';

# Hardcode the directory and filename to get
$home = '/pub';
$filename = 'TESTFILE';

# Open the connection to the host
$ftp = Net::FTP->new($hostname);        # Construct object
$ftp->login($username, $password);      # Log in

$ftp->cwd($home),"\n";                  # Change directory
print $ftp->ls($home),"\n";

# Now get the file and leave
$ftp->get($filename);
$ftp->quit;

FTP clients have also been integrated with most World Wide Web browsers, using ftp:// in place of http://. When the URL points to a directory, the browser displays a listing of the directory, in which each filename is a link to that file. When the URL points directly to a file, the remote file is downloaded.

Here's an example that uses Net::FTP to list files from a remote FTP server on a web page, with a link from each file to the URL of the file on the remote site:

#!/usr/local/bin/perl -w

use Net::FTP;

$hostname = 'remotehost.com';        # FTP host
$username = 'anonymous';             # Username
$password = 'myname@mydomain.com';   # Password
$home = '/pub';

$ftp = Net::FTP->new($hostname);     # Net::FTP constructor
$ftp->login($username, $password);  # Log in w/username and password

$pwd = $ftp->pwd;                   # Get current directory

print <<HTML;                       # Output HTML page
Content-type: text/html
<HTML>

  <HEAD>
    <TITLE>Download Files</TITLE>
  </HEAD>
  <BODY>

      <B>Current working directory:</B> $pwd<BR>
      Files to download: <P>
HTML

    @entries = $ftp->ls($home);     # Slurp all entries into an array
    foreach (@entries) { # Output links for all files in the ftp area
                         # as links
        print "<INPUT TYPE=hidden NAME=\"files\" VALUE=\"$_\">\n";
        print "<A HREF=\"ftp://$hostname$_\">",
        "<IMG SRC=\"http://www/icons/f.gif\" border=0>\n";
        print " $_</A><BR>\n";
    }
    print <<HTML;
  </BODY>
</HTML>
HTML
$ftp->quit;             # end FTP session

The Net::FTP module implements a subset (as shown earlier in this chapter) of the FTP protocol as defined in RFC 959. In addition to providing the methods shown below, the module inherits from Net::Cmd. Some of the Net::FTP methods return an object derived from the dataconn class (which is in turn derived from the IO::Socket::INET class), as noted in the entries for those methods.

The following methods are defined by Net::FTP.

new
$ftp = Net::FTP->new(host[, options])

Constructs a new Net::FTP object. Arguments are:

host
The name of the remote host

options
A hash specifying any of the following information:

Firewall
Name of an FTP firewall.

Port
Port number to use for the FTP connection. Defaults to 21.

Timeout
Timeout value. Defaults to 120 seconds.

Debug
Debug level.

Passive
True or false, specifying whether to perform transfers in passive mode.

abort
$ftp->abort(  )

Aborts the current transaction.

appe
$ftp->appe(file)

Appends data to the end of the remote file file, which is created if it doesn't exist. If the user calls either pasv or port, returns true or false. Otherwise, returns a reference to a Net::FTP::dataconn object.

append
$ftp->append(local[, remote])

Appends the contents of a local file to an existing file on the remote system. Arguments are:

local
Either the name of the file on the local system to transfer or a filehandle.

remote
The name of the file on the remote system. If local is a filehandle, remote must be specified.

ascii
$ftp->ascii([args])

Changes the type of data transfer to ascii. Like type, without the need to specify the first argument.

authorize
$ftp->authorize([auth[, resp]])

Authorizes the user to send data outside the firewall, for use with FTP proxies. If authorization auth and response resp are not specified, authorize uses Net::Netrc to do a lookup.

Called with no arguments by login if the connection is through a firewall.

binary
$ftp->binary([args])

Changes the type of data transfer to binary. Like type, without the need to specify the first argument.

byte
$ftp->byte([args])

Changes the data transfer type to byte. Not supported. If specified, defaults to binary. Like type, without the need to specify the first argument.

cdup
$ftp->cdup(  )

Goes up one level in the directory hierarchy.

cwd
$ftp->cwd([dir])

Changes the working directory to dir. With no argument, changes the directory to root.

delete
$ftp->delete([filename])

Deletes the specified file from the server.

dir
$ftp->dir([dir])

Lists the specified server directory in long format. Returns a reference to the list. dir defaults to the current working directory.

ebcdic
$ftp->ebcdic([args])

Changes the data transfer type to ebcdic. Not supported. If specified, defaults to binary. Like type, without the need to specify the first argument.

get
$ftp->get(remote[, local])

Retrieves a file from the server. If specified, local is the name to give the file on the local system; otherwise, the name stays the same. Arguments are:

remote
Name of the file to retrieve from the remote system.

local
Either the new filename on the local system or a filehandle. If omitted, the same filename is used.

list
$ftp->list([dir])

Lists a directory, dir, for display. If the user calls either pasv or port, returns true or false. Otherwise, returns a reference to a Net::FTP::dataconn object. If directory is omitted, defaults to the current directory.

login
$ftp->([login[, passwd[, account]]])

Logs user into an FTP server. Arguments are:

login
Login name. If not specified, defaults to anonymous or to the value in $HOME/.netrc.

passwd
Password. If not specified, defaults to the user's email address or to the value in $HOME/.netrc.

account
Additional account information for files on the FTP server that have special access restrictions.

ls
$ftp->ls([dir])

Lists directory, dir, returning a reference to the list. Defaults to the current working directory.

mdtm
$ftp->mdtm(file)

Returns the modification time of remote file file.

mkdir
$ftp->mkdir(dir[, recursive])

Makes a new directory. Arguments are:

dir
The new directory name

recursive
If true, creates all directories in the path as needed

nlst
$ftp->nlst([dir])

Lists a directory, dir, for further processing. With no argument, defaults to the current directory. If the user calls either pasv or port, returns true or false. Otherwise, returns a reference to a Net::FTP::dataconn object.

pasv
$ftp->pasv(  )

Puts server in passive mode.

pasv_wait
$ftp->pasv_wait(server)

Waits for a transfer to complete between a passive and a nonpassive server, in which server is the Net::FTP object for the nonpassive server.

pasv_xfer
$ftp->pasv_xfer(file1, server, [file2])

Transfers a file between two remote servers. Arguments are:

file1
The file to transfer from the server represented by the Net::FTP object.

server
Destination server.

file2
New name of the file on the destination server. If omitted, the original name is used.

pasv_xfer_unique
$ftp->pasv_xfer_unique(file1, server[, file2])

Like pasv_xfer, but stores the file on the remote server with a new (unique) name.

port
$ftp->port([port])

Sends a PORT command telling the server to use port port. With no argument, a socket is created, and its information is sent.

put
$ftp->put(local[, remote])

Puts a file onto the server. Arguments are:

local
The name of the file to transfer from the local system, or a filehandle.

remote
The new filename on the remote system. If omitted, the same filename is used. If local is a filehandle, the remote filename must be specified.

put_unique
$ftp->put_unique(local[, remote])

Puts a file with a unique name onto the server. Arguments are:

local
The name of the file to transfer from the local system, or a filehandle.

remote
The new filename on the remote system. If a file exists by that name, a new unique filename is created.

pwd
$ftp->pwd(  )

Returns the current directory path.

quit
$ftp->quit(  )

Closes the connection.

quot
$ftp->quot(cmd[, args])

Sends a literal FTP protocol command to the server and waits for a response. Returns the most significant digit of the response code.

rename
$ftp->rename(file1, file2)

Renames a file on the server. Arguments are:

file1
The old name of the file

file2
The new name of the file

retr
$ftp->retr(file)

Retrieves file file from the remote server. If the user calls either pasv or port, returns true or false. Otherwise, returns a reference to a Net::FTP::dataconn object.

rmdir
$ftp->rmdir(dir)

Removes directory dir.

size
$ftp->size(file)

Returns the size of file file in bytes.

stor
$ftp->stor(file)

Tells the server to store a new file under the name file. If the user calls either pasv or port, returns true or false. Otherwise, returns a reference to a Net::FTP::dataconn object.

stou
$ftp->stou(file)

Like stor, but stores file on the remote server with a unique name, file. If the user calls either pasv or port, returns true or false. Otherwise, returns a reference to a Net::FTP::dataconn object.

supported
$ftp->supported(cmd)

Returns true if the server supports the command cmd.

type
$ftp->type(type[, args])

Changes the type of data transfer. Possible types are ascii, ebcdic, byte, and binary. The value of args depends on the type.

unique_name
$ftp->unique_name(  )

Returns the name of the last file stored with a unique name.

Previous | Home | Next
18. FTP | Book Index | 18.3. FTP Configuration with Net::Netrc
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.3. FTP Configuration with Net::Netrc

Unix-based FTP clients use a file called .netrc, which you can configure to automate FTP access to sites you frequently visit. With a properly defined .netrc file, you can simply execute the FTP command to a favorite FTP host and be automatically logged in to the FTP server. Your .netrc file contains one line for each connection you want to make. The following tokens can be specified for each entry:

machine name
Specifies a remote machine to which you want to autologin:

machine remotehost.com

Instead of machine name, you can specify the single word default to match any machine name. This is usually used for anonymous logins to machines not listed in .netrc.

login name
If present, identifies the user who logs in to the remote machine, in which name is the login name.

password passwd
If present, gives the password for the user. The autologin process uses the specified password if the remote server requires one.

account acctpw
If present, gives an additional password for the user. The autologin process uses this password if the remote server requires one.

macdef name
If present, defines a macro with the specified name. Net::Netrc simply parses this field, to maintain compatibility with FTP.

Here's an example of a typical .netrc entry:

machine remotehost.com login username password userpasswd

Entering your username and password for remote sites in unencrypted form has serious security implications. Many sites consider .netrc files a violation of security policy and do not allow them. In addition, most FTP clients require that the .netrc file be owned by you and readable by only you, with permissions set to 0400 or 0600. If the permissions aren't correctly set, the autologin process aborts. Net::Netrc follows this security convention—if the permissions and ownership are not correct, the .netrc file isn't read, and a warning message is issued.

Net::Netrc implements a simple interface to the .netrc file, telling you which hosts you can automatically connect to. It doesn't actually connect to any remote hosts; it's simply used to query your configuration file and return the value of the tokens.

The following methods are supplied by Net::Netrc.

lookup
$machine = Net::Netrc->lookup(host[, login])

Constructor. Looks up and returns a reference to the entry for the specified host machine host. Without the optional login argument, lookup returns the first entry in the .netrc file for the machine.

If there is no matching entry, lookup returns a reference to the default entry.

account
$machine->account

Returns account information specified by the .netrc account entry, if there is any.

login
$machine->login

Returns the username (login ID) specified by the .netrc login token.

lpa
(@login_pass_account) = $machine->lpa

Returns a list of login, password, and account information specified by the .netrc tokens.

password
$machine->password

Returns the password specified by the .netrc password token.

Previous | Home | Next
18.2. Net::FTP | Book Index | 19. Lightweight Directory Access with Net::LDAP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 19. Lightweight Directory Access with Net::LDAP

Contents:

How Data Is Stored in LDAP
Searching an LDAP Directory with Net::LDAP
Adding an Entry to the Directory with Net::LDAP
Net::LDAP Methods

LDAP was designed as a client/server protocol to provide quick and simple access to entries that live in a directory. Initially, LDAP was designed to provide a better interface to X.500 directory services, but its ease of implementation and IETF-based change control means that LDAP has carved its own niche as a directory service.

What is a directory service? In short, the directory is where you store an entry. Each entry implements information about an object. Entries have attributes with a type and at least one value. These attributes have a strict syntax that determines the types of values allowed for the attributes. Such attribute syntaxes include strings, JPEG photographs, and URLs.

If you've ever tried to solve a complex problem in a heterogenous computing environment, such as syncing user accounts between different computing platforms, managing a company-wide address book, or building a public-key infrastructure, you might be interested in what LDAP has to offer.

While the IETF governs changes to the LDAP spec, you are not limited to a single source for the availability of an LDAP server. Companies such as iPlanet, Novell, and Microsoft sell commercial LDAP implementations, and you'll also find a good, free LDAP implemenation in OpenLDAP (http://www.openldap.org).

Net::LDAP implements the LDAP API for Perl programs. You can use Net::LDAP to search or modify the contents of your LDAP directory. In other words, Net::LDAP does everything that you need it to.

This chapter covers Net::LDAP and how to operate on data in an LDAP directory, but it is not an LDAP tutorial. If you're unfamiliar with LDAP, it is strongly encouraged that you refer to your LDAP server documentation before attempting to make any changes to your directory.

19.1. How Data Is Stored in LDAP

LDAP stores data in a structure as described in RFC 1617, which also offers guidelines as to how your naming style might look. While there are many ways to implement a data hierarchy in LADP, you can implement your directory structure so that all entries live under a single root that represents your organization. For example, you can import all your Unix account data for your.domain into a directory server with the following:

object: your.domain
Organizational Unit: People
Type for login name: uid

Your Unix account information would be stored in LDAP like so:

uid=youruser,ou=People,o=your.domain

At the simplest level, data as imported into LDAP by way of the LDAP Directory Interchange Format (LDIF). LDIF is a standard data format that specifies all the information about a record that you will insert into the directory. Take, for instance, a Unix account that lives in /etc/passwd:

nvp:-password-:1000:1000:Nathan V. Patwardhan:/home/nvp:/usr/bin/bash

When you break the password entry down, the following fields exist:

login           nvp
password        -password-
uid             1000
gid             1000
gecos           Nathan V. Patwardhan
home directory  /users/nvp
shell           /usr/bin/bash

The Unix /etc/passwd entries correspond to entries that you've created in LDAP, with the following naming differences:

UNIX            LDAP equivalent
login           uid
password        userPassword
uid             uidNumber
gid             gidNumber
gecos           cn, gecos
home directory  homeDirectory
shell           loginShell

Every LDIF begins with a DN, or distinguished name, which describes where the entry will live in the directory. Without the distinguished name, the LDIF is invalid. Unix accounts might live under ou=People, while addressbook entries might live under ou=Addresses. The LDIF also contains all of the attributes for a given entry and their corresponding values. For the Unix password entry shown above, the LDIF would look like:

dn: uid=nvp,ou=People,o=your.domain
uid: nvp
cn: Nathan Patwardhan
givenname: Nathan
sn: Patwardhan
objectClass: person
objectClass: organizationalPerson
objectClass: account
objectClass: shadowAccount
objectClass: top
userPassword:   {crypt}/-password-
loginShell:     /usr/bin/bash
uidNumber:      1000
gidNumber:      1000
homeDirectory:  /users/nvp

Net::LDAP can output an LDIF file for the data that you give it (from which you can use a tool such as ldapadd to add it to the directory) or add the record to the directory.

Previous | Home | Next
18.3. FTP Configuration with Net::Netrc | Book Index | 19.2. Searching an LDAP Directory with Net::LDAP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


19.2. Searching an LDAP Directory with Net::LDAP

One of the most common actions you'll perform against LDAP is searching. If you're using LDAP as a repository for your mail aliases, you'll search the directory each time mail is sent to a given address. If you're using LDAP as a repository for user accounts, you'll search the directory every time a user logs into your system, or when a user performs a task on the system that requires information that resides only in LDAP.

Under LDAP, searching consists of three parts:

  1. Binding to a directory server by name (or by other credentials, such as Kerberos tokens) and port. You can provide a login and password for the authentication or bind anonymously if you have permissions to search or write a part of the directory.

  2. Passing your search request to the directory server.

  3. Unbinding from the directory server, thus closing the connection.

Let's say that you want to find a user called nvp in the directory server that's living on ldap.your.server. With Net::LDAP, do the following:

use Net::LDAP;

my $lsvr = 'ldap.your.domain';
my $ldap = Net::LDAP->new($lsvr)
    or die "error connecting to $lsvr: $@";

$ldap->bind;   # Bind anonymously, that is, no login and pass

my $results = $ldap->search (  # Perform a search for 'nvp'
    filter => "(&(uid=nvp) (o=your.domain))"
    );

if($results->code) {
    die "received LDAP error: @{[$results->error]};
}

foreach my $entry ($results->all_entries) {
    $entry->dump;
}

$ldap->unbind;   # Unbind and close connection
Previous | Home | Next
19. Lightweight Directory Access with Net::LDAP | Book Index | 19.3. Adding an Entry to the Directory with Net::LDAP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


19.3. Adding an Entry to the Directory with Net::LDAP

Now that you've searched the directory with Net::LDAP, let's add an item. In the previous example, you bound to the directory anonymously, but when writing changes to the directory (that is, adding or deleting entries), you'll probably have to bind as an administrator or another user delegated with similar privileges. In this example, we'll use "Directory Manager" as the directory administrator.

Adding to a directory with Net::LDAP is a two-phase process:

  1. Bind to the directory as a user who has privileges to write to the directory. In this instance, we'll use "Directory Manager".

  2. Use Net::LDAP::add( ) to add the entry. add( ) takes the parts of the record that you will add to the directory as arguments.

This example, based on the following LDIF, uses add( ) to add an account for 'nvp' to the directory:

dn: uid=nvp,ou=People,o=your.domain
uid: nvp
cn: Nathan Patwardhan
givenname: Nathan
sn: Patwardhan
objectClass: person
objectClass: organizationalPerson
objectClass: account
objectClass: shadowAccount
objectClass: top
userPassword: {crypt}/-password-
loginShell: /usr/bin/bash
uidNumber: 1000
gidNumber: 1000
homeDirectory: /users/nvp

Here's the code:

my $admin = q[cn=Directory Manager];
my $ad_pw = q[adminpass];
my $lsvr  = q[ldap.my.domain];
my $org   = q[o=my.domain];
my $o_ou  = q[ou=People];
my $o_act = q[uid=nvp];

my $ldap = Net::LDAP->new($lsvr);

# Bind to a directory with DN and password
$ldap->bind($admin, password => $ad_pw);

my $l_rec = qq[$o_act, $o_ou, $org];
$result = $ldap->add($l_rec,
                   attr => [ 'cn'   => ['Nathan Patwardhan'],
                             'sn'   =>  'Patwardhan',
                             'mail' => 'nvp@my.domain',
                             'objectclass' => ['top', 'person', 'organizationalPerson', 'inetOrgPerson'],
                             'gecos' => ['Nathan Patwardhan'],
                             'loginShell' => '/usr/bin/bash',
                             'uidNumber'  => 1000,
                             'gidNumber'  => 1000,
                             'shadowPass' => 'XXXXXXXXX'
                           ]
          );

if($result->code) {
    warn "failed to add entry: @{[$result->error]}";
}

$ldap->unbind;
Previous | Home | Next
19.2. Searching an LDAP Directory with Net::LDAP | Book Index | 19.4. Net::LDAP Methods
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


19.4. Net::LDAP Methods

Net::LDAP implements the following methods:

new (host [, %options ])
new( ) creates a new Net::LDAP object and opens a connection to host. %options include:

port
Port to connect to on the remote server.

timeout
The maximum time that Net::LDAP will take to connect to a host. The default is 120 seconds.

debug
Shows details of the conversion between Net::LDAP and the directory server.

async
Performs asynchronous entry retrieval so that search results are returned to the client as they are identified:

$ldap = Net::LDAP->new('ldap.my.domain', async => 1);
onerror
If set to true, and if async is also true, then Net::LDAP will check for errors on all methods. If an error exists in the resulting data, then one of the following actions will be taken: die( ), warn( ), undef.

CODEREF
Calls the given coderef in a scalar context with the result message as the argument.

version( )
Sets the version of the LDAP protocol to use. Values are LDAPv2 (default) and LDAPv3.

bind(dn [, %options ])
Binds to the server that's contained in the connection handle. dn is the DN to bind as. You'll end up binding anonymously if you call bind( ) without any arguments.

As for %options, you should give no more than one of the following:

noauth
Do not attempt to authenticate at all.

anonymous
Binds without any password; the value passed with this option is ignored. This is the default if no arguments are given.

password
Binds with the given password.

sasl
Binds using an SASL mechanism. The argument given should be a sub-class of Authen::SASL.

my $dn = 'cn=Directory Manager';
my $password = 'adminpass';
my $sasl = Authn::SASL::stuff::here;
$ldap->bind($dn, sasl => $sasl, version => 3);
unbind
Does not take any parameters and unbinds the connection from the server. You will probably need to call bind( ) again if you wish to reconnect to the LDAP server.

$ldap->unbind;
add ( dn [, %options ] )
Adds an entry to the directory. dn can be either a Net::LDAP::Entry object or a string that represents the DN.

attrs
A reference to a list of attribute/value pairs. These attribute/value pairs correspond to the attributes of an entry in the directory. Each attribute can have multiple values. attrs is not used if dn is an existing Net::LDAP::Entry object. For example:

$ldap->add($dn,
           attrs => [
               'uid'        => 'nvp',
               'cn'         => ['Nathan Patwardhan', 'Enrico Pallazo'],
               'gecos'      => 'Nathan Patwardhan',
               'loginShell' => '/usr/bin/bash'
           ]
);
delete(dn [, %options ])
Deletes dn from the server. dn may be a string that represents the DN or a Net::LDAP::Entry object. For example:

my $dn = q[uid=nvp,ou=People,o=my.domain];
$ldap->delete($dn);
moddn(dn, %options)
Modifies dn. dnmay be a string or a Net::LDAP::Entry object.

newrdn
A new RDN to assign to dn.

deleteoldrdn
True if the existing RDN will be deleted.

newsuperior
If given, this value should be the dn of the new superior for dn.

$ldap->moddn($dn, newrdn => 'cn=Nate Patwardhan');
modify(dn, %options)
Modifies the contents of dn. dn may be a string or a Net::LDAP::Entry object.

add
Should be a reference to a HASH. HASH is comprised of the attributes to add, and the values may be a string or a reference to a list of values.

delete
A reference to ARRAY that contains attributes to delete, or a reference to a HASH, if only specific values should be deleted. If the values for any attribute in HASH are references to an empty ARRAY, then all instances of the attribute will be deleted.

replace
Works like add, but will replace any of the existing attributes.

changes
An alternative to add, delete, and replace, in which the whole operation can be given in a single argument. The argument should be a reference to an ARRAY.

Values in the ARRAY are used in pairs; the first is the operation add, delete, or replace, and the second is a reference to an ARRAY of attribute values.

The attribute value list is also used in pairs. The first value in each pair is the attribute name, and the second is a reference to a list of values.

Use this form if you want to control the order in which the operations will be performed:

my $dn = q[uid=nvp,ou=People,o=my.domain];

$ldap->modify($dn, add => { sn => 'Patwardhan' } );
$ldap->modify($dn, delete => { 'weight' => '175' });
$ldap->modify($dn, replace => { 'loginShell' => '/usr/bin/tcsh' });
$ldap->modify( $dn,
   changes => [
     add     => [ sn => 'Patwardhan' ],
     delete  => [ faxNumber => []],
     delete  => [ weight => ['175']],
     replace => [ loginShell => '/usr/bin/tcsh']
   ]
);
search(@options)
Requests that an LDAP server perform a search and can read attributes from a single entry, entries immediately below a particular entry, or a whole subtree of entries. The result is an object of the class Net::LDAP::Search.

base
The DN that is the base object entry relative to the search that will be performed.

scope
By default, the search is performed on the whole tree below the specified base object. This may be changed by specifying a scope parameter with one of the following values:

base
Searches only the base object.

one
Searches the entries immediately below the base object.

sub
Searches the whole tree below the base object. This is the default.

deref
By default, aliases are dereferenced to locate the base object for the search, but not when searching subordinates of the base object. This may be changed by specifying a deref parameter with one of the following values:

never
Do not dereference aliases in searching or in locating the base object of the search.

search
Dereferences aliases in subordinates of the base object in searching, but not in locating the base object of the search.

find
Dereferences aliases in locating the base object of the search, but not when searching subordinates of the base object. This is the default.

always
Dereferences aliases both in searching and in locating the base object of the search.

sizelimit
Restricts the maximum number of entries to be returned as a result of the search. A value of 0, which is the default, means that no restriction is requested. Servers may enforce a maximum number of entries to return.

timelimit
Restricts the maximum time (in seconds) allowed for a search. A value of 0, which is the default, means that no timelimit will be requested.

typesonly
Indicates whether search results should contain both attribute types and values, or just attribute types. Setting this parameter to true causes only attribute types (no values) to be returned. Setting this field to false causes both attribute types and values to be returned. This is the default.

filter
Defines the conditions an entry in the directory must meet in order for it to be returned by the search. This may be a string or a Net object. See the Net::LDAP::Filter manpage for a further description of the filter format.

attrs
A reference to a list of attributes to be returned for each entry that matches the search filter.

If not specified, then the server will return the attributes that are specified as accessible by default given your bind credentials.

Certain additional attributes, such as createtimestamp, and other operational attributes may also be available for the asking:

$ldap->search( ... , attrs => ['createtimestamp'] , ... );

To retrieve the default attributes and additional ones, use "*":

my $base_dn = q[o=my.domain];
$mesg = $ldap->search(
  base   => $base_dn,
  scope  => 'sub',
  filter => '(|(objectclass=rfc822mailgroup)(sn=Patwardhan))'
);

Net::LDAP::LDIF->new(\*STDOUT,"w")->write($mesg->entries);
abandon(id [, %options ] )
Requires that a server abandons a request. id may be passed first, or as part of %options, and may be a number or a Net::LDAP::Message object that's returned from a previous method call.

$mesg = $ldap->search(@search_args);
$ldap->abandon($mesg); # This could be written as $mesg->abandon
compare(dn, %options)
Performs a comparison on the server. dn is the DN on which the comparison will be performed. dn may be a string or Net::LDAP::Entry object.

attr
The name of the attribute to compare.

value
The value to compare with.

my $dn = q[uid=nvp,ou=People,o=my.domain];
$ldap->compare($dn,
    attr  => 'cn',
    value => 'Nathan Patwardhan'
);
start_tls([%options])
Converts the connection to use Transport Layer Security (TLS), which provides an encrypted connection, if available. Bear in mind that TLS is supported only under LDAPv3. %options is a set of key/value pairs that describe how to configure the security of the connection:

verify
Indicates how to verify the server's certificate. Its values can be none (the server may provide a certificate, but it will not be checked—this may mean you are connected to the wrong server), optional (verifies if the server offers a certificate), or require (the server must provide a certificate, and it must be valid). If you set verify to optional or require, you must also set either cafile or capath. The most secure option is require.

sslversion
Defines the version of the SSL/TLS protocol to use. Defaults to tlsv1; other possible values are sslv2, sslv3, and sslv2/3.

ciphers
Specifies which subset of cipher suites is permissible for this connection, using the standard OpenSSL string format. The default value for ciphers is ALL, which permits all ciphers, even those that don't encrypt!

clientcert
clientkey
If you want to use the client to offer a certificate to the server for SSL authentication (which is not the same as for the LDAP Bind operation), then set clientcert to the user's certificate file and clientkey to the user's private key file. These files must be in PEM format.

capath
cafile
When verifying the server's certificate, set either capath to the pathname of the directory containing CA certificates or cafile to the filename containing the certificate of the CA who signed the server's certificate. These certificates must all be in PEM format.

The directory in capath must contain certificates named using the hash value of themselves. To generate these names, use OpenSSL in Unix, as follows:

ln -s cacert.pem 'openssl x509 -hash -noout < cacert.pem'.0

(assuming that the certificate of the CA is in cacert.pem).

cipher
Returns the cipher mode being used by the connection in the string format used by OpenSSL.

certificate
Returns an X509_Certificate object containing the server's certificate. For example, to get the subject name (in a peculiar OpenSSL-specific format, different from RFC 1779 and RFC 2253) from the server's certificate, do the following:

print "Subject DN: " . $ldaps->certificate->subject_name . "\n";
version
Returns the version of the LDAP protocol that is being used.

Previous | Home | Next
19.3. Adding an Entry to the Directory with Net::LDAP | Book Index | VIII. LWP
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part VIII. LWP

Chapter 20, "The LWP Library"

Previous | Home | Next
19.4. Net::LDAP Methods | Book Index | 20. The LWP Library
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 20. The LWP Library

Contents:

LWP Overview
The LWP Modules
The HTTP Modules
The HTML Modules
The URI Module

The library for web access in Perl (LWP), is a bundle of modules that provide a consistent, object-oriented approach to creating web applications. The library, downloaded as the single file named libwww-perl, contains the following classes:

File
Parses directory listings.

Font
Handles Adobe Font Metrics.

HTML
Parses HTML files and converts them to printable or other forms.

HTTP
Provides client requests, server responses, and protocol implementation.

LWP
The core of all web client programs. It creates network connections and manages the communication and transactions between client and server.

URI
Creates, parses, and translates URLs.

WWW
Implements standards used for robots (automatic client programs).

Each module in LWP provides different building blocks that allow you to do basically anything you can do in a Web browser—from connection, to request, to response and returned data. These parts are then encapsulated by an object to give a standard interface to every web program you write.

This chapter covers all the modules in the LWP distribution. While some modules are more useful than others, everything you need to know about LWP is included here. To begin with, the following section gives an overview of how LWP works to create a web client.

20.1. LWP Overview

Any web transaction requires an application that can establish a TCP/IP network connection and send and receive messages using the appropriate protocol (usually HTTP). TCP/IP connections are established using sockets, and messages are exchanged via socket filehandles. (See Chapter 15, "Sockets" for information on how to manually create socket applications.) LWP provides an object for this application with LWP::UserAgent for clients; HTTP::Daemon provides a server object. The UserAgent object acts as the browser: it connects to a server, sends requests, receives responses, and manages the received data. This is how you create a UserAgent object:

use LWP::UserAgent;
$ua = LWP::UserAgent->new( );

The UserAgent now needs to send a message to a server requesting a Universal Resource Locator (URL) using the request method. request forms an HTTP request from the object given as its argument. This request object is created by HTTP::Request.

An HTTP request message contains three elements. The first line of a message always contains an HTTP command called a method; a Universal Resource Identifier (URI), which identifies the file or resource the client is querying; and the HTTP version number. The following lines of a client request contain header information, which provides information about the client and any data it is sending the server. The third part of a client request is the entity body, which is data sent to the server (for the POST method). The following is a sample HTTP request:

GET /index.html HTTP/1.0
User-Agent: Mozilla/1.1N (Macintosh; I; 68K)
Accept: */*
Accept: image/gif
Accept: image/jpeg

LWP::UserAgent->request forms this message from an HTTP::Request object. A request object requires a method for the first argument. The GET method asks for a file, while the POST method supplies information such as form data to a server application. There are other methods, but these two are most commonly used.

The second argument is the URL for the request. The URL must contain the server name because this is how the UserAgent knows where to connect. The URL argument can be represented as a string or as a URI::URL object, which allows more complex URLs to be formed and managed. Optional parameters for an HTTP::Request include your own headers, in the form of an HTTP::Headers object, and any POST data for the message. The following example creates a request object:

use HTTP::Request;

$req = HTTP::Request->new(GET, $url, $hdrs);

The URL object is created like this:

use URI::URL;

$url = URI::URL->new('www.ora.com/index.html');

And a header object can be created like this:

use HTTP::Headers;

$hdrs = HTTP::Headers->new(Accept => 'text/plain',
                          User-Agent => 'MegaBrowser/1.0');

Then you can put them all together to make a request:

use LWP::UserAgent;  # This will cover all of them!

$hdrs = HTTP::Headers->new(Accept => 'text/plain',
                          User-Agent => 'MegaBrowser/1.0');

$url = URI::URL->new('www.ora.com/index.html');
$req = HTTP::Request->new(GET, $url, $hdrs);
$ua = LWP::UserAgent->new( );
$resp = $ua->request($req);
if ($resp->is_success) {
        print $resp->content;}
else {
        print $resp->message;}

Once the request has been made by the user agent, the response from the server is returned as another object, described by HTTP::Response. This object contains the status code of the request, returned headers, and the content you requested, if successful. In the example, is_success checks to see if the request was fulfilled without problems, thus outputting the content. If unsuccessful, a message describing the server's response code is printed.

There are other modules and classes that create useful objects for web clients in LWP, but the above examples show the most basic ones. For server applications, many of the objects used above become pieces of a server transaction, which you either create yourself (such as response objects) or receive from a client (such as request objects).

Additional functionality for both client and server applications is provided by the HTML module. This module provides many classes for both the creation and interpretation of HTML documents.

The rest of this chapter provides information for the LWP, HTTP, HTML, and URI modules.

Previous | Home | Next
VIII. LWP | Book Index | 20.2. The LWP Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.2. The LWP Modules

The LWP modules provide the core of functionality for web programming in Perl. It contains the foundations for networking applications, protocol implementations, media type definitions, and debugging ability.

The modules LWP::Simple and LWP::UserAgent define client applications that implement network connections, send requests, and receive response data from servers. LWP::RobotUA is another client application used to build automated web searchers following a specified set of guidelines.

LWP::UserAgent is the primary module used in applications built with LWP. With it, you can build your own robust web client. It is also the base class for the Simple and RobotUA modules. These two modules provide a specialized set of functions for creating clients.

Additional LWP modules provide the building blocks required for web communications, but you often don't need to use them directly in your applications. LWP::Protocol implements the actual socket connections with the appropriate protocol. The most common protocol is HTTP, but mail protocols (such as SMTP), FTP for file transfers, and others can be used across networks.

LWP::MediaTypes implements the MIME definitions for media type identification and mapping to file extensions. The LWP::Debug module provides functions to help you debug your LWP applications.

The following sections describe the RobotUA, Simple, and UserAgent modules of LWP.

20.2.1. LWP::RobotUA Sections

The Robot User Agent (LWP::RobotUA) is a subclass of LWP::UserAgent and is used to create robot client applications. A robot application requests resources in an automated fashion. Robots perform such activities as searching, mirroring, and surveying. Some robots collect statistics, while others wander the Web and summarize their findings for a search engine.

The LWP::RobotUA module defines methods to help program robot applications and observes the Robot Exclusion Standards, which web server administrators can define on their web site to keep robots away from certain (or all) areas of the site.

The constructor for an LWP::RobotUA object looks like this:

$rob = LWP::RobotUA->new(agent_name, email, [$rules]);

The first parameter, agent_name, is the user agent identifier used for the value of the User-Agent header in the request. The second parameter is the email address of the person using the robot, and the optional third parameter is a reference to a WWW::RobotRules object, which is used to store the robot rules for a server. If you omit the third parameter, the LWP::RobotUA module requests the robots.txt file from every server it contacts and generates its own WWW::RobotRules object.

Since LWP::RobotUA is a subclass of LWP::UserAgent, the LWP::UserAgent methods are used to perform the basic client activities. The following methods are defined by LWP::RobotUA for robot-related functionality.

as_string
$rob->as_string( )

Returns a human-readable string that describes the robot's status.

delay
$rob->delay ([time])

Sets or returns the specified time (in minutes) to wait between requests. The default value is 1.

host_wait
$rob->host_wait(netloc)

Returns the number of seconds the robot must wait before it can request another resource from the server identified by netloc.

no_visits
$rob->no_visits(netloc)

Returns the number of visits to a given server. netloc is of the form user:password@host:port. The user, password, and port are optional.

rules
$rob->rules([$rules])

Sets or returns the WWW:RobotRules object $rules, which is used when determining if the module is allowed access to a particular resource.

use_sleep
$rob->use_sleep ([boolean])

Determines whether the user agent should sleep( ) if requests arrive too fast. The default is true. If set to false, an internal SERVICE_UNAVAILABLE response is generated, with a Retry-After header indicating when it is permissable to send another request to this server. With no arguments, returns the current value of this flag.

20.2.2. LWP::Simple

LWP::Simple provides an easy-to-use interface for creating a web client, although it is only capable of performing basic retrieving functions. An object constructor is not used for this class; it defines functions for retrieving information from a specified URL and interpreting the status codes from the requests.

This module isn't named Simple for nothing. The following shows how to use it to get a web page and save it to a file:

use LWP::Simple;

$homepage = 'oreilly_com.html';
$status = getstore('http:www.oreilly.com/', $homepage);
print("hooray") if is_success($status);

The retrieving functions get and head return the URL's contents and header contents, respectively. The other retrieving functions return the HTTP status code of the request. The status codes are returned as the constants from the HTTP::Status module, which is also where the is_success and is_failure methods are obtained. See Section 20.3.4, "HTTP::Status" for a listing of the response codes.

The user agent identifier produced by LWP::Simple is LWP::Simple/n.nn, in which n.nn is the version number of LWP being used.

The following are the functions exported by LWP::Simple.

get
get (url)

Returns the contents of the specified url. Upon failure, get returns undef. Other than returning undef, there is no way of accessing the HTTP status code or headers returned by the server.

getprint
getprint (url)

Prints the contents of url on standard output and returns the HTTP status code given by the server.

getstore
getstore (url, file)

Stores the contents of the specified url into file and returns the HTTP status code given by the server.

head
head (url)

Returns header information about the specified url in the form of: ($content_type, $document_length, $modified_time, $expires, $server). Upon failure, head returns an empty list.

is_error
is_error (code)

Given a status code from getprint, getstore, or mirror, returns true if the request was not successful.

is_success
is_success (code)

Given a status code from getprint, getstore, or mirror, returns true if the request was successful.

mirror
mirror (url, file)

Copies the contents of the specified url into file, when the modification time or length of the online version is different from that of the named file.

20.2.3. LWP::UserAgent

Requests over the network are performed with LWP::UserAgent objects. To create an LWP::UserAgent object, use:

$ua = LWP::UserAgent->new( );

You give the object a request, which it uses to contact the server, and the information you requested is returned. The most often used method in this module is request, which contacts a server and returns the result of your query. Other methods in this module change the way request behaves. You can change the timeout value, customize the value of the User-Agent header, or use a proxy server.

The following methods are supplied by LWP::UserAgent.

new
$ua->new(%options)

Constructs a new LWP::UserAgent object and returns a reference to it. Key/value arguments may be provided to set up the initial state of the user agent. new accepts several options that correspond to the following attribute methods:

Key | Default
agent | "libwww-perl/#.##"
from | undef
timeout | 180
use_eval | 1
parse_head | 1
max_size | undef
cookie_jar | undef
conn_cache | undef
protocols_allowed | undef
protocols_forbidden | undef
requests_redirectable | ["GET", "HEAD"]

The options are:

env_proxy
If set to true, proxy settings are read from environment variables.

keep_alive
A number that will be passed on as the total_capacity for the connection. A LWP::ConnCache is set up (see the conn_cache method), and the HTTP/1.1 protocol module is enabled.

agent
$ua->agent([string])

When invoked with no arguments, this method returns the current value of the identifier used in the User-Agent HTTP header. If invoked with an argument, the User-Agent header will use string as its identifier in the future.

_agent
$ua->_agent(  )

Returns the default agent identifier. This is a string of the form "libwww-perl/#.##", in which #.## is substituted with the version number of this library.

clone
$ua->clone(  )

Returns a copy of the LWP::UserAgent object.

conn_cache
$ua->conn_cache([$cache_object])

Defines the LWP::ConnCache object to use. With no arguments, returns the current LWP::ConnCache object.

cookie_jar
$ua->cookie_jar([$cjar])

Specifies the "cookie jar" object to use with the UserAgent object, or returns it if invoked with no argument. $cjar is a reference to an HTTP::Cookies object that contains client cookie data. See the HTTP::Cookies section for more information.

credentials
$ua->credentials(netloc, realm, uname, pass)

Uses the given username and password for authentication at the given network location and realm. This method sets the parameters for either the WWW-Authenticate or Proxy-Authenticate headers in a request. The get_basic_credentials method is called by request to retrieve the username and passwords, if they exist. The arguments are:

netloc
The network location (usually a URL string) to which the username and password apply.

realm
The name of the server-defined range of URLs that this data applies to.

uname
The username for authentication.

pass
The password for authentication. By default, the password will be transmitted with MIME base-64 encoding.

env_proxy
$ua->env_proxy(  )

Defines a scheme/proxy URL mapping by looking at environment variables. For example, to define the HTTP proxy, one would define the HTTP_PROXY environment variable with the proxy's URL. To define a domain to avoid the proxy, one would define the NO_PROXY environment variable with the domain that doesn't need a proxy.

from
$ua->from([email])

When invoked with no arguments, this method returns the current value of the email address used in the From header. If invoked with an argument, the From header will use that email address in the future. (The From header tells the web server the email address of the person running the client software.)

get
$ua->get($url, [Header => Value])

Shortcut for $ua->request(HTTP::Request::Common::GET( $url, Header => Value,... )).

get_basic_credentials
$ua->get_basic_credentials(realm, url)

Returns the list containing the username and password for the given realm and urlwhen authentication is required by the server. This function is usually called internally by request. This method becomes useful when creating a subclass of LWP::UserAgent with its own version of get_basic_credentials. From there, you can rewrite get_basic_credentials to do more flexible things, such as asking the user for the account information, or referring to authentication information in a file. All you need to do is return a list in which the first element is a username and the second element is a password.

head
$ua->head($url, [Header => Value])

Shortcut for $ua->request(HTTP::Request::Common::HEAD( $url, Header => Value,...)).

is_protocol_supported
$ua->is_protocol_supported(proto)

Given a scheme, this method returns a true or false (nonzero or zero) value. A true value means that LWP knows how to handle a URL with the specified protocol. If it returns a false value, LWP does not know how to handle the URL.

max_size
$ua->max_size([size])

Sets or returns the maximum size (in bytes) for response content. The default is undef, which means that there is no limit. If the returned content is partial because the size limit was exceeded, then an X-Content-Range header will be added to the response.

mirror
$ua->mirror(url, file)

Given a URL and file path, this method copies the contents of url into the file when the length or modification date headers are different from any previous retrieval. If the file does not exist, it is created. This method returns an HTTP::Response object, in which the response code indicates what happened.

no_proxy
$ua->no_proxy(domains)

Does not use a proxy server for the specified domains.

parse_head
$ua->parse_head([boolean])

Sets or returns a true or false value indicating whether response headers from the <head> sections of HTML documents are initialized. The default is true.

post
$ua->post($url, \%formref, [Header => Value])

Shortcut for $ua->request(HTTP::Request::Common::POST( $url, \%formref, Header => Value,... )). The form reference is optional and can be either a hashref or an arrayref.

protocols_allowed
$ua->protocols_allowed([\@protocols])

Assigns the list of protocols that $ua->request and $ua->simple_request will exclusively allow. With no arguments, returns a list of the protocols currently allowed. Assigning to a value of undef deletes the list.

protocols_forbidden
$ua->protocols_forbidden([\@protocols])

Assigns the list of procotols that $ua->request and $ua->simple_request will not allow. With no arguments, returns a list of the protocols currently prohibited. Assigning to a value of undef deletes the list.

proxy
$ua->proxy(prot, proxy_url)

Defines a URL (proxy_url) to use with the specified protocols, prot. The first parameter can be a reference to a list of protocol names or a scalar that contains a single protocol. The second argument defines a proxy URL to use with the protocol.

put
$ua->put($url, [Header => Value])
$ua -- >gt;put($url, Header ==>gt; Value,...)

Shortcut for $ua->request(HTTP::Request::Common::PUT( $url, Header => Value,...)).

redirect_ok
$ua->redirect_ok($this_request)

This method is called by request before it tries to follow a redirection to the request in $this_request. This should return a true value if this redirection is permissible.

request
$ua->request($request, [file | $sub, size])

Performs a request for the resource specified by $request, which is an HTTP::Request object. Returns the information received from the server as an HTTP::Response object. Normally, doing a $ua->request($request) is enough. You can also specify a subroutine to process the data as it comes in or provide a filename in which to store the entity body of the response. The arguments are:

$request
An HTTP::Request object. The object must contain the method and URL of the site to be queried. This object must exist before request is called.

file
Name of the file in which to store the response's entity body. When this option is used on request, the entity body of the returned response object will be empty.

$sub
A reference to a subroutine that will process the data of the response. If you use the optional third argument, size, the subroutine will be called any time that number of bytes is received as response data. The subroutine should expect each chunk of the entity body data as a scalar in the first argument, an HTTP::Response object as the second argument, and an LWP::Protocol object as the third argument.

size
Optional argument specifying the number of bytes of the entity body received before the sub callback is called to process response data.

requests_redirectable
$ua->requests_redirectable([\@requests])

Assigns the list of request names that $ua->redirect_ok will allow to be redirected. With no arguments, returns the current list of request names. By default, GET and HEAD requests are allowed; to include POST requests, enter:

push @{ $ua->requests_redirectable }, 'POST';
timeout
$ua->timeout([secs])

When invoked with no arguments, timeout returns the timeout value of a request. By default, this value is three minutes. Therefore, if the client software doesn't hear back from the server within three minutes, it will stop the transaction and indicate that a timeout occurred in the HTTP response code. If invoked with an argument, the timeout value is redefined to be that value.

use_alarm
$ua->use_alarm([boolean])

Retrieves or defines the ability to use alarm for timeouts. By default, timeouts with alarm are enabled. If you plan on using alarm for your own purposes, or it isn't supported on your system, it is recommended that you disable alarm by calling this method with a value of 0.

Previous | Home | Next
20. The LWP Library | Book Index | 20.3. The HTTP Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.3. The HTTP Modules

The HTTP modules implement an interface to the HTTP messaging protocol used in web transactions. Its most useful modules are HTTP::Request and HTTP::Response, which create objects for client requests and server responses. Other modules provide means for manipulating headers, interpreting server response codes, managing cookies, converting date formats, and creating basic server applications.

Client applications created with LWP::UserAgent use HTTP::Request objects to create and send requests to servers. The information returned from a server is saved as an HTTP::Response object. Both of these objects are subclasses of HTTP::Message, which provides general methods of creating and modifying HTTP messages. The header information included in HTTP messages can be represented by objects of the HTTP::Headers class.

HTTP::Status includes functions to classify response codes into the categories of informational, successful, redirection, error, client error, or server error. It also exports symbolic aliases of HTTP response codes; one could refer to the status code of 200 as RC_OK and refer to 404 as RC_NOT_FOUND.

The HTTP::Date module converts date strings from and to machine time. The HTTP::Daemon module can be used to create web server applications, utilizing the functionality of the rest of the LWP modules to communicate with clients.

20.3.1. HTTP::Request

This module summarizes a web client's request. For a simple GET request, you define an object with the GET method and assign a URL to apply it to. Basic headers would be filled in automatically by LWP. For a POST or PUT request, you might want to specify a custom HTTP::Headers object for the request, or use the contents of a file for an entity body. Since HTTP::Request inherits everything in HTTP::Message, you can use the header and entity body manipulation methods from HTTP::Message in HTTP::Request objects.

The constructor for HTTP::Request looks like this:

$req = http::Request->new (method, url, [$header, [content]]);

The method and URL values for the request are required parameters. The header and content arguments are not required, nor even necessary for all requests. The parameters are defined as follows:

method
A string specifying the HTTP request method. GET, HEAD, and POST are the most commonly used. Other methods defined in the HTTP specification such as PUT and DELETE are not supported by most servers.

url
The address and resource name of the information you are requesting. This argument may be either a string containing an absolute URL (the hostname is required), or a URI::URL object that stores all the information about the URL.

$header
A reference to an HTTP::Headers object.

content
A scalar that specifies the entity body of the request. If omitted, the entity body is empty.

The following methods can be used on HTTP::Request objects.

as_string
$req->as_string

Returns a text version of the request object as a string with \n placed after each line. Information about the object reference is also included in the first line. The returned string looks like this:

-- HTTP::Request=HASH(0x68148) --
PUT http:www.ora.com/example/hi.text
Content-Length: 2
Content-Type: text/plain
hi
------------------
method
$req->method ([method])

Sets or retrieves the HTTP method for an HTTP::Request object. Without an argument, method returns the object's current method.

url
$req->url ([url])

Sets or retrieves the URL for the request object. Without an argument, this method retrieves the current URL for the object. url is a string containing the new URL to set for the request or a URI::URL object.

20.3.2. HTTP::Response

Responses from a web server are described by HTTP::Response objects. An HTTP response message contains a status line, headers, and any content data that was requested by the client (such as an HTML file). The status line is the minimum requirement for a response. It contains the version of HTTP that the server is running, a status code indicating the success, failure, or other condition the request received from the server, and a short message describing the status code.

If LWP has problems fulfilling your request, it internally generates an HTTP::Response object and fills in an appropriate response code. In the context of web client programming, you'll usually get an HTTP::Response object from LWP::UserAgent and LWP::RobotUA.

If you plan to write extensions to LWP or to a web server or proxy server, you might use HTTP::Response to generate your own responses.

The constructor for HTTP::Response looks like this:

$resp = HTTP::Response->new (rc, [msg, [header, [content]]]);

In its simplest form, an HTTP::Response object can contain just a response code. If you would like to specify a more detailed message than "OK" or "Not found," you can specify a text description of the response code as the second parameter. As a third parameter, you can pass a reference to an HTTP::Headers object to specify the response headers. Finally, you can also include an entity body in the fourth parameter as a scalar.

For client applications, it is unlikely that you will build your own response object with the constructor for this class. You receive a client object when you use the request method on an LWP::UserAgent object. For example:

$ua = LWP::UserAgent->new;
$req = HTTP::Request->new(GET, $url)
$resp = $ua->request($req);

The server's response is contained in the object $resp. When you have this object, you can use the HTTP::Response methods to get the information about the response. Since HTTP::Response is a subclass of HTTP::Message, you can also use methods from that class on response objects. See Section 20.3.8, "HTTP::Message" for a description of its methods.

The following methods can be used on objects created by HTTP::Response.

as_string
$resp->as_string(  )

Returns a string version of the response with lines separated by \n. For example, this method would return a response string that looks like this:

-- HTTP::Response=HASH(0xc8548) --
RC: 200 (OK)
Message: all is fine

Content-Length: 2
Content-Type: text/plain

hi
------------------
base
$resp->base(  )

Returns the base URL of the response. If the response was hypertext, any links from the hypertext should be relative to the location returned by this method. LWP looks for the BASE tag in HTML and Content-Base/Content-Location HTTP headers for a base specification. If a base was not explicitly defined by the server, LWP uses the requesting URL as the base.

code
$resp->code ([code])

When invoked without any parameters, this method returns the object's response code. Sets the status code of the object when invoked with an argument.

current_age
$resp->current_age(  )

Returns the number of seconds since the response was generated by the original server.

error_as_HTML
$resp->error_as_HTML(  )

When is_error is true, this method returns an HTML explanation of what happened.

freshness_lifetime
$resp->freshness_lifetime(  )

Returns the number of seconds until the response expires. If expiration was not specified by the server, LWP will make an informed guess based on the Last-Modified header of the response.

fresh_until
$resp->fresh_until(  )

Returns the time when the response expires. The time is based on the number of seconds since January 1, 1970, UTC.

is_error
$resp->is_error(  )

Returns true when the response code is 400 through 599. When an error occurs, you might want to use error_as_HTML to generate an HTML explanation of the error.

is_fresh
$resp->is_fresh(  )

Returns true if the response has not yet expired.

is_info
$resp->is_info(  )

Returns true when the response code is 100 through 199.

is_redirect
$resp->is_redirect(  )

Returns true when the response code is 300 through 399.

is_success
$resp->is_success(  )

Returns true when the response code is 200 through 299.

message
$resp->message ([msg])

When invoked without any parameters, message returns the object's status code message (the short string describing the response code). When invoked with a scalar msg argument, this method defines the object's message.

status_line
$resp->status_line(  )

Returns a string with the HTTP status code and message. If the message attribute is unspecified, the official message associated with code is used.

20.3.3. HTTP::Headers

This module deals with HTTP header definition and manipulation. You can use these methods on HTTP::Request and HTTP::Response objects to retrieve headers they contain, or to set new headers and values for new objects you are building.

The constructor for an HTTP::Headers object looks like this:

$h = HTTP::Headers->new([name => val],...);

This code creates a new headers object. You can set headers in the constructor by providing a header name and its value. Multiple name=>valpairs can be used to set multiple headers.

The following methods can be used by objects in the HTTP::Headers class. These methods can also be used on objects from HTTP::Request and HTTP::Response, since they inherit from HTTP::Headers. In fact, most header manipulation will occur on the request and response objects in LWP applications.

clone
$h->clone(  )

Creates a copy of the current object, $h, and returns a reference to it.

header
$h->header(field [=> $val],...)

When called with just an HTTP header as a parameter, this method returns the current value for the header. For example, $myobject->('content-type') would return the value for the object's Content-Type header. To define a new header value, invoke header with a hash of header=>value pairs, in which the value is a scalar or reference to an array. For example, to define the Content-Type header, you would do this:

$h->header('content-type' => 'text/plain');
init_header
$h->init_header($field, $value)

Sets the specified header to the given value, but only if no previous value for that field is set. The header field name is not case-sensitive, and _ can be used as a replacement for -. The $value argument may be a scalar or a reference to a list of scalars. Previous values of the field are not removed.

push_header
$h->push_header(field => val)

Adds a new header field and value to the object. Previous values of the field are not removed.

$h->push_header(Accept => 'image/jpeg');
remove_header
$h->remove_header(field,...)

Removes the header specified in the parameter(s) and the header's associated value.

scan
$h->scan($sub)

Invokes the subroutine referenced by $sub for each header field in the object. The subroutine is passed the name of the header and its value as a pair of arguments. For header fields with more than one value, the subroutine will be called once for each value.

The HTTP::Headers class allows you to use a number of convenience methods on header objects to set (or read) common field values. If you supply a value for an argument, that value will be set for the field. The previous value for the header is always returned. The following methods are available:

date
expires
if_modified_since
if_unmodified_since
last_modified
content_type
content_encoding
content_length
content_language
title
user_agent
server
from
referrer
www_authenticate
proxy_authenticate
authorization
proxy_authorization
authorization_basic
proxy_authorization_basic

20.3.4. HTTP::Status

This module provides methods to determine the type of a response code. It also exports a list of mnemonics that can be used by the programmer to refer to a status code.

The following methods are used on response objects:

is_info
Returns true when the response code is 100-199.

is_success
Returns true when the response code is 200-299.

is_redirect
Returns true when the response code is 300-399.

is_client_error
Returns true when the response code is 400-499.

is_server_error
Returns true when the response code is 500-599.

is_error
Returns true when the response code is 400-599. When an error occurs, you might want to use error_as_HTML to generate an HTML explanation of the error.

HTTP::Status exports the following constant functions to use as mnemonic substitutes for status codes. For example, you could do something like:

if ($rc = RC_OK) {....}

Here are the mnemonics, followed by the status codes they represent:

RC_CONTINUE (100)
RC_SWITCHING_PROTOCOLS (101)
RC_OK (200)
RC_CREATED (201)
RC_ACCEPTED (202)
RC_NON_AUTHORITATIVE_INFORMATION (203)
RC_NO_CONTENT (204)
RC_RESET_CONTENT (205)
RC_PARTIAL_CONTENT (206)
RC_MULTIPLE_CHOICES (300)
RC_MOVED_PERMANENTLY (301)
RC_MOVED_TEMPORARILY (302)
RC_SEE_OTHER (303)
RC_NOT_MODIFIED (304)
RC_USE_PROXY (305)
RC_BAD_REQUEST (400)
RC_UNAUTHORIZED (401)
RC_PAYMENT_REQUIRED (402)
RC_FORBIDDEN (403)
RC_NOT_FOUND (404)
RC_METHOD_NOT_ALLOWED (405)
RC_NOT_ACCEPTABLE (406)
RC_PROXY_AUTHENTICATION_REQUIRED (407)
RC_REQUEST_TIMEOUT (408)
RC_CONFLICT (409)
RC_GONE (410)
RC_LENGTH_REQUIRED (411)
RC_PRECONDITION_FAILED (412)
RC_REQUEST_ENTITY_TOO_LARGE (413)
RC_REQUEST_URI_TOO_LARGE (414)
RC_UNSUPPORTED_MEDIA_TYPE (415)
RC_REQUEST_RANGE_NOT_SATISFIABLE (416)
RC_INTERNAL_SERVER_ERROR (500)
RC_NOT_IMPLEMENTED (501)
RC_BAD_GATEWAY (502)
RC_SERVICE_UNAVAILABLE (503)
RC_GATEWAY_TIMEOUT (504)
RC_HTTP_VERSION_NOT_SUPPORTED (505)

20.3.5. HTTP::Date

The HTTP::Date module is useful when you want to process a date string. It exports two functions that convert date strings to and from standard time formats.

parse_date
parse_date($str)

Parses a date string and returns it as a list of numerical values followed by a time zone specification. If the date is unrecognized, then the empty list is returned.

str2time
str2time(str [, zone])

Converts the time specified as a string in the first parameter into the number of seconds since epoch. This function recognizes a wide variety of formats, including RFC 1123 (standard HTTP), RFC 850, ANSI C asctime, common log file format, Unix ls -l, and Windows dir, among others. When a time zone is not implicit in the first parameter, this function will use an optional time zone specified as the second parameter, such as -0800, +0500, or GMT. If the second parameter is omitted, and the time zone is ambiguous, the local time zone is used.

time2iso
time2iso([$time])

Same as time2str( ), but returns a "YYYY-MM-DD hh:mm:ss"-formatted string representing time in the local time zone.

time2isoz
time2isoz([$time])

Same as time2str( ), but returns a "YYYY-MM-DD hh:mm:ssZ"-formatted string representing Universal Time.

time2str
time2str([time])

Given the number of seconds since machine epoch, this function generates the equivalent time as specified in RFC 1123, which is the recommended time format used in HTTP. When invoked with no parameter, the current time is used.

20.3.6. HTTP::Cookies

HTTP cookies provide a mechanism for preserving information about a client or user across several different visits to a site or page. The "cookie" is a name/value pair sent to the client on its initial visit to a page. This cookie is stored by the client and sent back in the request upon revisit to the same page.

A server initializes a cookie with the Set-Cookie header. Set-Cookie sets the name and value of a cookie, as well as other parameters such as how long the cookie is valid and the range of URLs to which the cookie applies. Each cookie (a single name/value pair) is sent in its own Set-Cookie header, so if there is more than one cookie sent to a client, multiple Set-Cookie headers are sent in the response. Two Set-Cookie headers may be used in server responses: Set-Cookie is defined in the original Netscape cookie specification, and Set-Cookie2 is the latest, IETF-defined header. Both header styles are supported by HTTP::Cookies. The latest browsers also support both styles.

If a client visits a page for which it has a valid cookie stored, the client sends the cookie in the request with the Cookie header. This header's value contains any name/value pairs that apply to the URL. Multiple cookies are separated by semicolons in the header.

The HTTP::Cookies module is used to retrieve, return, and manage the cookies used by an LWP::UserAgent client application. Setting cookies from an LWP-created server requires only the coding of the proper response headers sent by an HTTP::Daemon server application. HTTP::Cookies is not designed to be used in setting cookies on the server side, although you may find use for it in managing sent cookies.

The new constructor for HTTP::Cookies creates an object called a cookie jar, which represents a collection of saved cookies usually read from a file. Methods on the cookie jar object allow you to add new cookies or send cookie information in a client request to a specific URL. The constructor may take optional parameters, as shown in the following example:

$cjar = HTTP::Cookies->new( file => 'cookies.txt',
                            autosave => 1,
                            ignore_discard => 0 );

The cookie jar object $cjar created here contains any cookie information stored in the file cookies.txt. The autosave parameter takes a Boolean value that determines if the state of the cookie jar is saved to the file upon destruction of the object. ignore_discard also takes a Boolean value to determine if cookies marked to be discarded are still saved to the file.

Cookies received by a client are added to the cookie jar with the extract_cookies method. This method searches an HTTP::Response object for Set-Cookie and Set-Cookie2 headers and adds them to the cookie jar. Cookies are sent in a client request using the add-cookie-header method. This method takes an HTTP::Request object with the URL component already set, and if the URL matches any entries in the cookie jar, adds the appropriate Cookie headers to the request.

These methods can be used on a cookie jar object created by HTTP::Cookies.

add_cookie_header
$cjar->add_cookie_header($request)

Adds appropriate Cookie headers to an HTTP::Request object $request. $request must already be created with a valid URL address. This method will search the cookie jar for any cookies matching the request URL. If the cookies are valid (i.e., have not expired), they are used to create Cookie headers and are added to the request.

as_string
$cjar->as_string([discard])

Returns the current contents of the cookie jar as a string. Each cookie is output as a Set-Cookie3 header line followed by "0". If discard is given and is true, cookies marked to be discarded will not be output. Set-Cookie3 is a special LWP format used to store cookie information in the save file.

clear
$cjar->clear( [domain, [path, [key] ] ])

Without arguments, this method clears the entire contents of the cookie jar. Given arguments, cookies belonging to a specific domain, path, or with a name, key, will be cleared. The arguments are ordered for increasing specificity. If only one argument is given, all cookies for that domain will be deleted. A second argument specifies a distinct path within the domain. To remove a cookie by keyname, you must use all three arguments.

extract_cookies
$cjar->extract_cookies($response)

Searches an HTTP::Response object $response for any Set-Cookie and Set-Cookie2 headers and stores the cookie information in the cookie jar.

load
$cjar->load( [file] )

Loads cookie information into the cookie jar from the file specified during construction (default) or from the named file. The file must be in the format produced by the save method.

revert
$cjar->revert

Restores the cookie jar to its state before the last save.

save
$cjar->save( [file] )

Saves the state of the cookie jar to the file specified during construction (by default) or to the named file. The cookies are saved in a special LWP format as Set-Cookie3 header lines. This format is not compatible with the standard Set-Cookie and Set-Cookie2 headers, but you are not likely to use this file to set new cookies in response headers.

set_cookie
$cjar->set_cookie(version, key, val, path, domain, port, path_spec, secure, maxages, discard, \%misc)

Sets a cookie in the cookie jar with the information given in the arguments. The number and order of arguments represent the structure of elements in the Set-Cookie3 header lines used to save the cookies in a file.

version
A string containing the cookie-spec version number.

key
The name of the cookie.

val
The value of the cookie.

path
The pathname of the URL for which the cookie is set.

domain
The domain name for which the cookie is set.

port
The port number of the URL for which the cookie is set.

path_spec
A Boolean value indicating if the cookie is valid for the specific URL path or all the URLs in the domain. The path is used if true; otherwise, the cookie is valid for the entire domain.

secure
A Boolean value indicating that the cookie should only be sent over a secure connection for true, or over any connection for false.

maxage
The number of seconds that the cookie will be valid from the time it was received. Adding the maxage to the current time will yield a value that can be used for an expiration date.

discard
A Boolean value indicating that the cookie should not be sent in any future requests and should be discarded upon saving the cookie jar, unless the ignore_discard parameter was set to true in the constructor.

%misc
The final argument is a reference to a hash, %misc, that contains any additional parameters from the Set-Cookie headers such as Comment and URLComment, in key/value pairs.

scan
$cjar->scan( \&callback )

Invokes the callback subroutine for each cookie in the cookie jar. The subroutine is called with the same arguments given to the save method, described above. Any undefined arguments will be given the value undef.

20.3.6.1. HTTP::Cookies::Netscape

The HTTP::Cookies class contains one subclass that supports Netscape-style cookies within a cookie jar object. Netscape-style cookies were defined in the original cookie specification for Navigator 1.1, which outlined the syntax for the Cookie and Set-Cookie HTTP headers. Netscape cookie headers are different from the newer Set-Cookie2-style cookies in that they don't support as many additional parameters when a cookie is set. The Cookie header also does not use a version-number attribute. Many browsers and servers still use the original Netscape cookies, and the Netscape subclass of HTTP::Cookies can be used to support this style.

The new constructor for this subclass creates a Netscape-compatible cookie jar object like this:

$njar = HTTP::Cookies::Netscape->new(
                  File     => "$ENV{HOME}/.netscape/cookies",
                  AutoSave => 1 );

The methods described above can be used on this object, although many of the parameters used in Set-Cookie2 headers will simply be lost when cookies are saved to the cookie jar.

20.3.7. HTTP::Daemon

The HTTP::Daemon module creates HTTP server applications. The module provides objects based on the IO::Socket::INET class that can listen on a socket for client requests and send server responses. The objects implemented by the module are HTTP 1.1 servers. Client requests are stored as HTTP::Request objects, and all the methods for that class can be used to obtain information about the request. HTTP::Response objects can be used to send information back to the client.

An HTTP::Daemon object is created by using the new constructor. Since the base class for this object is IO::Socket::INET, the parameters used in that class's constructor are the same here. For example:

$d = HTTP::Daemon->new ( LocalAddr => 'maude.oreilly.com',
                         LocalPort => 8888,
                         Listen => 5 );

The HTTP::Daemon object is a server socket that automatically listens for requests on the specified port (or on the default port if none is given). When a client request is received, the object uses the accept method to create a connection with the client on the network.

$d = HTTP::Daemon->new;
while ( $c = $d->accept ) {
     $req = $c->get_request;
     # Process request and send response here
     }
$c = undef;   # Don't forget to close the socket

The accept method returns a reference to a new object of the HTTP::Daemon::ClientConn class. This class is also based on IO::Socket::INET and is used to extract the request message and send the response and any requested file content.

The sockets created by both HTTP::Daemon and HTTP::Daemon::ClientConn work the same way as those in IO::Socket::INET. The methods are also the same except for some slight variations in usage. The methods for the HTTP::Daemon classes are listed in the sections below and include the adjusted IO::Socket::INET methods. For more detailed information about sockets and the IO::Socket classes and methods, see Chapter 13, "XML and Perl".

The following methods can be used on HTTP::Daemon objects.

accept
$d->accept ([pkg])

Accepts a client request on a socket object and creates a connection with the client. This method is the same as IO::Socket->accept, except it will return a reference to a new HTTP::Daemon::ClientConn object. If an argument is given, the connection object will be created in the package named by pkg. If no connection is made before a specified timeout, the method will return undef.

product_tokens
$d->product_tokens

Returns the string that the server uses to identify itself in the Server response header.

url
$d->url

Returns the URL string that gives access to the server root.

20.3.7.1. HTTP::Daemon::ClientConn methods

The following methods can be used on HTTP::Daemon::ClientConn objects.

antique_client
$c->antique_client

Returns true if the client uses the HTTP/0.9 protocol (i.e., no status code or headers should be returned).

crlf
$c->crlf(  )

Sends the CRLF sequence to the client.

daemon
$c->daemon

Returns a reference to the HTTP::Daemon object from which the current ClientConn object was generated.

force_last_request
$c->force_last_request(  )

Ensures that $c->get_request will not try to read more requests off this connection. If you generate a response that is not self-delimiting, then you should signal this fact by calling this method. This attribute is turned on automatically if the client announces protocol HTTP/1.0 or worse and does not include a Connection: Keep-Alive header. It is also turned on automatically when HTTP/1.1 or better clients send the Connection: Close request header

get_request
$c->get_request

Reads information from the client request and returns a reference to an HTTP::Request object. Returns undef if the request failed.

proto_ge
$c->proto_ge ( [$new_value] )

Returns true if the client announced a protocol with version number greater or equal to the given argument. The $proto argument can be a string such as "HTTP/1.1", or just "1.1".

read_buffer
$c->read_buffer ( [$new_value] )

Bytes read, but not used, by $c->get_reques t are placed in the read buffer. The next time $c->get_request is called, it will consume the bytes in this buffer before reading more data from the network connection itself.

reason
$c->reason(  )

Returns a short string describing what happened if $c->get_request returns undef.

send_basic_header
$c->send_basic_header ( [code, [msg, [proto]]] )

Sends status line composed of the specified parameters and the Date and Server headers to the client. If no arguments are given, the default status line HTTP/1.1 200 OK is used.

send_error
$c->send_error ( [code, [msg]] )

Returns an error response to the client. code can contain one of the error response codes; the default is 400 Bad Request. msg is a string describing the error displayed in the HTML entity body.

send_file
$c->send_file (filename)

Copies contents of the file filename to the client as the response. filename can be a string that is interpreted as a filename, or a reference to a glob.

send_file_response
$c->send_file_response (filename)

Sends a response with the file filename as content. If filename is a directory, an index listing will be generated and sent as HTML.

send_redirect
$c->send_redirect ( url, [code, [entity_body]] )

Sends a redirect response to the client, with the location url, an absolute or a relative URL. The optional code argument should be one of the redirect status codes; the default is 301 Moved Permanently. An entity_bodystring can be sent as HTML that informs the user of the redirection.

send_response
$c->send_response ( [$resp | @resplist] )

Sends a response to the client created from the HTTP::Response object, $resp, or the list of parameters, @resplist. The resplist parameters are the same as those used in the constructor for HTTP::Response and must at least contain a status code. If no argument is given, the default OK response is sent.

send_status_line
$c->send_status_line ( [code, [msg, [proto]]] )

Sends the status line composed of the given arguments back to the client. If the arguments are given, the default status line is sent as HTTP/1.1 200 OK. The arguments are:

code
The numeric code indicating the status of the request, e.g., 200 for an OK request or 404 for a request for a resource that doesn't exist

msg
A short string describing the status code

proto
A string indicating the protocol and version number used by the server, e.g., HTTP/1.1.

20.3.8. HTTP::Message

HTTP::Message is the generic base class for HTTP::Request and HTTP::Response. It provides a couple of methods used on both classes. The constructor for this class is used internally by the Request and Response classes, so you will probably not need to use it. Methods defined by the HTTP::Headers class will also work on Message objects.

add_content
$r->add_content(data)

Appends data to the end of the object's current entity body.

clone
$r->clone(  )

Creates a copy of the current object, $r, and returns a reference to it.

content
$r->content ([content])

Without an argument, content returns the entity body of the object. With a scalar argument, the entity body will be set to content.

content_ref
$r->content_ref(  )

Returns a reference to the string containing the content body. This reference can be used to manage large content data.

headers
$r->headers(  )

Returns the embedded HTTP::Headers object from the message object.

protocol
$r->protocol([string])

Sets or retrieves the HTTP protocol string for the message object. This string looks like HTTP/1.1.

Previous | Home | Next
20.2. The LWP Modules | Book Index | 20.4. The HTML Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.4. The HTML Modules

HTML modules provide an interface to parse HTML documents. After you parse the document, you can print or display it according to the markup tags or extract specific information such as hyperlinks.

The HTML::parser module provides methods for, literally, parsing HTML. It can handle HTML text from a string or file and can separate out the syntactic structures and data. You shouldn't use HTML::Parser directly, however, since its interface hasn't been designed to make your life easy when you parse HTML. It's merely a base class from which you can build your own parser to deal with HTML in any way you want. And if you don't want to roll your own HTML parser or parser class, then there's always HTML::TokeParser and HTML::TreeBuilder, both of which are covered in this chapter.

HTML::TreeBuilder is a class that parses HTML into a syntax tree. In a syntax tree, each element of the HTML, such as container elements with beginning and end tags, is stored relative to other elements. This preserves the nested structure and behavior of HTML and its hierarchy.

A syntax tree of the TreeBuilder class is formed of connected nodes that represent each element of the HTML document. These nodes are saved as objects from the HTML::Element class. An HTML::Element object stores all the information from an HTML tag: the start tag, end tag, attributes, plain text, and pointers to any nested elements.

The remaining classes of the HTML modules use the syntax trees and its nodes of element objects to output useful information from the HTML documents. The format classes, such as HTML::FormatText and HTML::FormatPS, allow you to produce text and PostScript from HTML. The HTML::LinkExtor class extracts all of the links from a document. Additional modules provide means for replacing HTML character entities and implementing HTML tags as subroutines.

20.4.1. HTML::Parser

This module implements the base class for the other HTML modules. A parser object is created with the new constructor:

$p = HTML::Parser->new( );

The constructor takes no arguments.

The parser object takes methods that read in HTML from a string or a file. The string-reading method can take data in several smaller chunks if the HTML is too big. Each chunk of HTML will be appended to the object, and the eof method indicates the end of the document. These basic methods are described below.

eof
$p->eof(  )

Indicates the end of a document and flushes any buffered text. Returns the parser object.

parse
$p->parse(string)

Reads HTML into the parser object from a given string. Performance problems occur if the string is too large, so the HTML can be broken up into smaller pieces, which will be appended to the data already contained in the object. The parse can be terminated with a call to the eof method.

parse_file
$p->parse_file(file)

Reads HTML into the parser object from the given file, which can be a filename or an open filehandle.

When the parse or parse_file method is called, it parses the incoming HTML with a few internal methods. In HTML::Parser, these methods are defined, but empty. Additional HTML parsing classes (included in the HTML modules or ones you write yourself) override these methods for their own purposes. For example:

package HTML::MyParser;
require HTML::Parser;
@ISA=qw(HTML::MyParser);

sub start {
     your subroutine defined here
     }

The following list shows the internal methods contained in HTML::Parser.

comment
comment(comment)

Invoked on comments from HTML (text between <!- and ->). The text of the comment (without the tags) is given to the method as the string comment.

end
end(tag, origtext)

Invoked on end tags (those with the </tag> form). The first argument, tag, is the tag name in lowercase, and the second argument, origtext, is the original HTML text of the tag.

start
start(tag, $attr, attrseq, origtext)

Invoked on start tags. The first argument, tag, is the name of the tag in lowercase. The second argument is a reference to a hash, attr. This hash contains all the attributes and their values in key/value pairs. The keys are the names of the attributes in lowercase. The third argument, attrseq, is a reference to an array that contains the names of all the attributes in the order they appeared in the tag. The fourth argument, origtext, is a string that contains the original text of the tag.

text
text(text)

Invoked on plain text in the document. The text is passed unmodified and may contain newlines. Character entities in the text are not expanded.

xml_mode
xml_mode(bool)

Enabling this attribute changes the parser to allow some XML constructs such as empty element tags and XML processing instructions. It also disables forcing tag and attribute names to lowercase when they are reported by the tagname and attr arguments, and suppresses special treatment of elements parsed as CDATA for HTML.

20.4.2. HTML::TokeParser

As we said, you should use a subclassed HTML parser if you want a better interface to HTML parsing features than what HTML::Parser gives you. HTML::TokeParser by Gisle Aas is one such example. While HTML::TokeParser is actually a subclass of HTML::PullParser, it can help you do many useful things, such as link extraction and HTML checking.

In short, HTML::TokeParser breaks an HTML document into tokens, attributes, and content, in which the HTML <a href="http://url">link</a> would break down as:

token: a
    attrib: href
content: http://url
content: link
token /a

For example, you can use HTML::TokeParser to extract links from a string that contains HTML:

#!/usr/local/bin/perl -w

require HTML::TokeParser;

# Our string that turns out to be HTML!
my $html = '<p>Some text. <a href="http://blah"My name is Nate!</a></p>';
my $parser = HTML::TokeParser->new(\$html);

get_tag( ) tells TokeParser to match a tag by name
while (my $token = $parser->get_tag("a")) {
    my $url = $token->[1]{href} || "-";
    my $text = $parser->get_trimmed_text("/a");
    print "URL is: $url.\nURL text is: $text.\n";
}

20.4.2.1. HTML::TokeParser methods

new
new(  )

Constructor. Takes a filename, filehandle, or reference to a scalar as arguments. Each argument represents the content that will be parsed. If a scalar is present, new looks for a filename $scalar. If a reference to a scalar is present, new looks for HTML in \$scalar. new will read filehandles until end-of-file. Returns undef on failure.

get_tag
get_tag(  )

Returns the next start or end tag in a document. If there are no remaining start or end tags, get_tag returns undef. get_tag is useful because it skips unwanted tokens and matches only the tag that you want—if it exists. When a tag is found, it is returned as an array reference, like so: [$tag, $attr, $attrseq, $text]. If an end tag is found, is is returned—e.g., "/$tag".

get_text
get_text(  )

Returns all text found at the current position. If the next token is not text, get_text returns a zero-length string. You can pass an "$end_tag" option to get_text to return all of the text before "end_tag".

get_token
get_token(  )

Returns the next token found in the HTML document, or undef if no next token exists. Each token is returned as an array reference. The array reference's first and last items refer to start and end tags concurrently. The rest of the items in the array include text, comments, declarations, and process instructions. get_token uses the following labels for the tokens:

S
Start tag

E
End tag

T
Text

C
Comment

D
Declaration

PI
Process instructions

Consider the following code:

#!/usr/local/bin/perl -w

require HTML::TokeParser;

my $html = '<a href="http://blah">My name is
Nate!</a></p>';
my $p = HTML::TokeParser->new(\$html);

while (my $token = $p->get_token) {
    my $i = 0;
    foreach my $tk (@{$token}) {
        print "token[$i]: $tk\n";
                    $i++;
    }
}

The items in each token (in the HTML) are displayed as follows:

token[0]: S
token[1]: a
token[2]: HASH(0x8146d3c)
token[3]: ARRAY(0x814a380)
token[4]: <a href="http://blah">
token[0]: T
token[1]: My name is Nate!
token[2]:
token[0]: E
token[1]: a
token[2]: </a>
token[0]: E
token[1]: p
token[2]: </p>
get_trimmed_text
get_trimmed_text(  )

Works the same as get_text, but reduces all instances of multiple spaces to a single space and removes leading and trailing whitespace.

unget_token
unget_token(  )

Useful for pushing tokens back to the parser so they can be reused the next time you call get_token.

20.4.3. HTML::Element

The HTML::Element module provides methods for dealing with nodes in an HTML syntax tree. You can get or set the contents of each node, traverse the tree, and delete a node.

HTML::Element objects are used to represent elements of HTML. These elements include start and end tags, attributes, contained plain text, and other nested elements.

The constructor for this class requires the name of the tag for its first argument. You may optionally specify initial attributes and values as hash elements in the constructor. For example:

$h = HTML::Element->new('a', 'href' => 'http:www.oreilly.com');

The new element is created for the anchor tag, <a>, which links to the URL through its href attribute.

The following methods are provided for objects of the HTML::Element class.

as_HTML
$h->as_HTML(  )

Returns the HTML string that represents the element and its children.

attr
$h->attr(name [,value])

Sets or retrieves the value of attribute name in the current element.

content
$h->content(  )

Returns the content contained in this element as a reference to an array that contains plain-text segments and references to nested element objects.

delete
$h->delete(  )

Deletes the current element and all of its child elements.

delete_content
$h->delete_content(  )

Removes the content from the current element.

dump
$h->dump(  )

Prints the tag name of the element and all its children to STDOUT. Useful for debugging. The structure of the document is shown by indentation.

endtag
$h->endtag(  )

Returns the original text of the end tag, including the </ and >.

extract_links
$h->extract_links([types])

Retrieves the links contained within an element and all of its child elements. This method returns a reference to an array in which each element is a reference to an array with two values: the value of the link and a reference to the element in which it was found. You may specify the tags from which you want to extract links by providing their names in a list of types.

implicit
$h->implicit([boolean])

Indicates whether the element was contained in the original document (false) or whether it was assumed to be implicit (true) by the parser. Implicit tags are elements that the parser included to conform to proper HTML structure, such as an ending paragraph tag (</p>). You may also set this attribute by providing a boolean argument.

insert_element
$h->insert_element($element, implicit)

Inserts the object $element at the current position relative to the root object $h and updates the position (indicated by pos) to the inserted element. Returns the new $element. The implicit argument is a Boolean indicating whether the element is an implicit tag (true) or the original HTML (false).

is_empty
$h->is_empty(  )

Returns true if the current object has no content.

is_inside
$h->is_inside(tag1 [,tag2, ...])

Returns true if the tag for this element is contained inside one of the tags listed as arguments.

parent
$h->parent([$new])

Without an argument, returns the parent object for this element. If given a reference to another element object, this element is set as the new parent object and is returned.

pos
$h->pos([$element])

Sets or retrieves the current position in the syntax tree of the current object. The returned value is a reference to the element object that holds the current position. The "position" object is an element contained within the tree that has the current object ($h) at its root.

push_content
$h->push_content(content)

Inserts the specified content into the current element. content can be either a scalar containing plain text or a reference to another element. Multiple arguments can be supplied.

starttag
$h->starttag(  )

Returns the original text of the start tag for the element. This includes the < and > and all attributes.

tag
$h->tag([name])

Sets or retrieves the tag name for the element. Tag names are always converted to lowercase.

traverse
$h->traverse(sub, [ignoretext])

Traverses the current element and all of its children, invoking the callback routine sub for each element. The callback routine is called with a reference to the current element (the node), a startflag, and the depth as arguments. The start flag is 1 when entering a node and 0 when leaving (returning to a parent element). If the ignoretext parameter is true (the default), then the callback routine will not be invoked for text content. If the callback routine returns false, the method will not traverse any child elements of that node.

20.4.4. HTML::TreeBuilder

The HTML::TreeBuilder class provides a parser that creates an HTML syntax tree. Each node of the tree is an HTML::Element object. This class inherits both HTML::Parser and HTML::Elements, so methods from both of those classes can be used on its objects.

The methods provided by HTML::TreeBuilder control how the parsing is performed. Values for these methods are set by providing a Boolean value for their arguments.

ignore_text
$p->ignore_text(boolean)

If set to true, text content of elements will not be included in elements of the parse tree. The default is false.

ignore_unknown
$p->ignore_unknown(boolean)

If set to true, unknown tags in the HTML will be represented as elements in the parse tree.

implicit_tags
$p->implicit_tags(boolean)

If set to true, the parser will try to deduce implicit tags such as missing elements or end tags that are required to conform to proper HTML structure. If false, the parse tree will reflect the HTML as is.

warn
$p->warn(boolean)

If set to true, the parser will make calls to warn with messages describing syntax errors when they occur. Error messages are off by default.

20.4.5. HTML::FormatPS

The HTML::FormatPS module converts an HTML parse tree into PostScript. The formatter object is created with the new constructor, which can take parameters that assign PostScript attributes. For example:

$formatter = HTML::FormatPS->new('papersize' => 'Letter');

You can now give parsed HTML to the formatter and produce PostScript output for printing. HTML::FormatPS does not handle table or form elements at this time.

The method for this class is format. format takes a reference to an HTML TreeBuilder object, representing a parsed HTML document. It returns a scalar containing the document formatted in PostScript. The following example shows how to use this module to print a file in PostScript:

use HTML::FormatPS;

$html = HTML::TreeBuilder->parse_file(somefile);
$formatter = HTML::FormatPS->new( );
print $formatter->format($html);

The following list describes the attributes that can be set in the constructor:

PaperSize
Possible values are 3, A4, A5, B4, B5, Letter, Legal, Executive, Tabloid, Statement, Folio, 10x14, and Quarto. The default is A4.

PaperWidth
Width of the paper in points.

PaperHeight
Height of the paper in points.

LeftMargin
Left margin in points.

RightMargin
Right margin in points.

HorizontalMargin
Left and right margin. Default is 4 cm.

TopMargin
Top margin in points.

BottomMargin
Bottom margin in points.

VerticalMargin
Top and bottom margin. Default is 2 cm.

PageNo
Boolean value to display page numbers. Default is 0 (off).

FontFamily
Font family to use on the page. Possible values are Courier, Helvetica, and Times. Default is Times.

FontScale
Scale factor for the font.

Leading
Space between lines, as a factor of the font size. Default is 0.1.

20.4.6. HTML::FormatText

The HTML::FormatText module takes a parsed HTML file and outputs a plain-text version of it. None of the character attributes will be usable, i.e., bold or italic fonts, font sizes, etc.

This module is similar to FormatPS in that the constructor takes attributes for formatting, and the format method produces the output. A formatter object can be constructed like this:

$formatter = HTML::FormatText->new(leftmargin => 10, rightmargin => 80);

The constructor can take two parameters: leftmargin and rightmargin. The value for the margins is given in column numbers. The aliases lm and rm can also be used.

The format method takes an HTML::TreeBuilder object and returns a scalar containing the formatted text. You can print it with:

print $formatter->format($html);
Previous | Home | Next
20.3. The HTTP Modules | Book Index | 20.5. The URI Module
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.5. The URI Module

The URI module contains functions and modules to specify and convert URIs. (URLs are a type of URI.) In addition to the URL module itself, there are also: URI::URL, URI::Escape, and URI::Heuristic. Of primary importance to many LWP applications is the URI::URL class, which creates the objects used by LWP::UserAgent to determine protocols, server locations, and resource names.

The URI::Escape module replaces unsafe characters in URL strings with their appropriate escape sequences. URI::Heuristic provides convenience methods for creating proper URLs out of short strings and incomplete addresses.

20.5.1. URI

The URI module is a successor to URI::URL and was written by Gisle Aas. While not clearly stated in the LWP documentation, you should use the URI module whenever possible, since URI.pm has essentially deprecated URI::URL.

The URI module implements the URI class. Objects created from the URI class represent Uniform Resource Identifiers (URIs). With the URI module, you can identify the key parts of a URI: scheme, scheme-specific parts, and fragment identifiers, which may be referred to respectfully as authority, path, and query components. For example, as shown in the URI module documentation:

<scheme>:<scheme-specific-part>#<fragment>
<scheme>://<authority><path>?<query>#<fragment>
<path>?<query>#<fragment>

You can break down http://www.oreilly.com/somefile.html as:

scheme: http
authority: www.oreilly.com
path: /somefile.html

In the case of relative URIs, you can use the URI module to deal with only the query component of a URI. With the URI module, you can parse the above URI as follows:

#!/usr/local/bin/perl -w

use URI;

my $url = 'http://www.oreilly.com/somefile.html';
my $u1 = URI->new($url);

print "scheme: ", $u1->scheme, "\n";
print "authority: ", $u1->authority, "\n";
print "path: ", $u1->path, "\n";

20.5.1.1. URI methods

The following methods give you access to components of a URI. These methods will return a string, unless the URI component is invalid, in which case undef is returned. Bear in mind that an empty string ("") is not equivalent to an undefined value.

new
new($uri, [$scheme])

Constructor. $uri is given as an argument with the optional $scheme. new removes additional whitespace, double quotes, and arrows from the URL. $scheme is used only when $str is a relative URI; it is a simple string that denotes the scheme or an absolute URI object. $str will be treated like a generic URI if $scheme isn't defined.

new
URI::file->new($file, [$os])

Constructs a new file URI from a filename.

new_abs
URI::file->new_abs($file, [$os])

Constructs a new absolute file URI from a filename.

abs
abs($base_uri)

Returns an absolute URI reference. If $uri is already absolute, then a reference to $uri is returned. abs returns a new absolute URI that contains $uri and $base_uri if $uri is relative.

as_string
as_string

Returns a URI object as a plain string.

authority
authority([$auth])

Sets and gets the authority component of the $uri. This component will be escaped.

canonical
canonical

Returns a normalized version of the URI. This includes lowercasing the scheme and hostname components, as well as removing an explicit port specification (if it mtaches the default port). canonical will return the original $uri if $uri was already in the correct form.

clone
clone

Returns a copy of the URI.

cwd
URI::file->cwd

Returns the current working directory as a file URI.

default_port
default_port()

Returns the default port of the URI scheme that $uri belongs to. You cannot change the default port for a scheme.

eq
eq()

Compares two URIs.

fragment
fragment([$new_frag])

Returns the fragment identifier of a URI reference as an escaped string.

host
host([$new_host])

Sets and gets the unescaped hostname. To specify a different port:

$new_host = "hostname:port_number"
host_port
host_port([$new_host_port])

Sets and gets the host and port as a single unit. Hostname and port are colon-separated.

new_abs
new_abs($str, $base_uri)

Creates a new absolute URI object. $str represents the absolute URI, and $base_uri represents the relative URI.

opaque
opaque([$new_opaque_value])

Sets and gets the scheme-specific part of $uri.

path
path([$path])

Sets and gets the escaped path component of $uri. Returns empty string ("") if there is no path.

path
path([$new_path])

Gets and sets the same value as opaque, unless the URI supports the generic syntax for heirarchical namespaces. path returns the part of the URI between the hostname and the fragment.

path_query
path_query([$path_here])

Sets and gets the escapted path and query components.

path_segments
path_segments([$seg])

Sets and gets the path. In a scalar content, path_segments is equivalent to path. In a list contents, path_segments returns the unescaped path segments that make up the path.

port
port([$new_port])

Sets and gets the port, which is an integer. If $new_port is not defined, then the default port of the URI scheme will be returned.

query
query([$q])

Sets and gets the escaped query component of $ uri .

query_form
query_form([$key => $val])

Sets and gets query components that use the urlencoded format.

query_keywords
query_keywords([$keywords])

Sets and gets query components that use keywords separated by a +.

rel
rel($base_uri)

Returns a relative URI reference, if one exists. Otherwise, $uri is returned.

scheme
scheme([$some_scheme])

Sets and gets the scheme part of the URI. Such values include: data, file, ftp, gopher, http, https, ldap, mailto, news, nntp, pop, rlogin, rsync, snews, telnet, and ssh. In the case of relative URIs, scheme will return undef; otherwise, scheme will return the scheme in lowercase. With $some_scheme, scheme will set the scheme of the current URI. scheme will die if the scheme isn't supported, or if it contains non-US-ASCII characters.

userinfo
userinfo([$new_userinfo])

Sets and gets the escaped "userinfo" part of the authority component (of the URI). Often, the userinfo will appear as a username and password separated by a colon. Bear in mind that sending a password in the clear is a bad idea.

20.5.2. URI::Escape

This module escapes or unescapes "unsafe" characters within a URL string. Unsafe characters in URLs are described by RFC 1738. Before you form URI::URL objects and use that class's methods, you should make sure your strings are properly escaped. This module does not create its own objects; it exports the following functions:

uri_escape
uri_escape uri, [regexp]

Given a URI as the first parameter, returns the equivalent URI with certain characters replaced with % followed by two hexadecimal digits. The first parameter can be a text string, such as "http:www.oreilly.com", or an object of type URI::URL. When invoked without a second parameter, uri_escape escapes characters specified by RFC 1738. Otherwise, you can pass in a regular expression (in the context of [ ]) of characters to escape as the second parameter. For example:

$escaped_uri = uri_escape($uri, 'aeiou')

This code escapes all lowercase vowels in $uri and returns the escaped version.

uri_unescape
uri_unescape uri

Substitutes any instance of % followed by two hexadecimal digits back into its original form and returns the entire URI in unescaped form.

20.5.3. URI::URL

This module creates URL objects that store all the elements of a URL. These objects are used by the request method of LWP::UserAgent for server addresses, port numbers, filenames, protocol, and many other elements that can be loaded into a URL.

The new constructor is used to make a URI::URL object:

$url = URI::URL->new($url_string [, $base_url])

This method creates a new URI::URL object with the URL given as the first parameter. An optional base URL can be specified as the second parameter and is useful for generating an absolute URL from a relative URL.

The following methods are for the URI::URL class.

abs
$url->abs([base, [scheme]])

Returns the absolute URL, given a base. If invoked with no parameters, any previous definition of the base is used. The second parameter is a Boolean that modifies abs's behavior. When the second parameter is nonzero, abs will accept a relative URL with a scheme but no host, such as http:index.html.

as_string
$url->as_string(  )

Returns the URL as a scalar string. All defined components of the URL are included in the string.

base
$url->base([base])

Gets or sets the base URL associated with the URL in this URI::URL object. The base URL is useful for converting a relative URL into an absolute URL.

crack
$url->crack(  )

Returns an array with the following data: (scheme, user, password, host, port, epath, eparams, equery, frag).

default_port
$url->default_port([port])

When invoked with no parameters, this method returns the default port for the URL defined in the object. The default port is based on the scheme used. Even if the port for the URL is explicitly changed by the user with the port method, the default port is always the same.

eparams
$url->eparams([param])

When invoked with no arguments, this method returns the escaped parameter of the URL defined in the object. When invoked with an argument, the object's escaped parameter is assigned to that value.

epath
$url->epath(  )

When invoked with no parameters, this method returns the escaped path of the URL defined in the object. When invoked with a parameter, the object's escaped path is assigned to that value.

eq
$url->eq(other_url)

Returns true when the object's URL is equal to the URL specified.

equery
$url->equery([string])

When invoked with no arguments, this method returns the escaped query string of the URL defined in the object. When invoked with an argument, the object's escaped query string is assigned to that value.

frag
$url->frag([frag])

When invoked with no arguments, this method returns the fragment of the URL defined in the object. When invoked with an argument, the object's fragment is assigned to that value.

full_path
$url->full_path(  )

Returns a string consisting of the escaped path, escaped parameters, and escaped query string.

host
$url->host([hostname])

When invoked with no parameters, this method returns the hostname in the URL defined in the object. When invoked with a parameter, the object's hostname is assigned to that value.

netloc
$url->netloc([netloc])

When invoked with no parameters, this method returns the network location for the URL defined in the object. The network location is a string composed of "user:password@host:port", in which the user, password, and port may be omitted when not defined. When netloc is invoked with a parameter, the object's network location is defined to that value. Changes to the network location are reflected in the user, password, host, and port methods.

params
$url->params([param])

Same as eparams, except that the parameter that is set/returned is not escaped.

password
$url->password([passwd])

When invoked with no parameters, this method returns the password in the URL defined in the object. When invoked with a parameter, the object's password is assigned to that value.

path
$url->path([pathname])

Same as epath, except that the path that is set/returned is not escaped.

port
$url->port([port])

When invoked with no parameters, this method returns the port for the URL defined in the object. If a port wasn't explicitly defined in the URL, a default port is assumed. When invoked with a parameter, the object's port is assigned to that value.

query
$url->query([param])

Same as equery, except that the parameter that is set/returned is not escaped.

rel
$url->rel(base)

Given a base as a first parameter or a previous definition of the base, returns the current object's URL relative to the base URL.

scheme
$url->scheme([scheme])

When invoked with no parameters, this method returns the scheme in the URL defined in the object. When invoked with a parameter, the object's scheme is assigned to that value.

strict
URI::URL::strict(bool)

When set, the URI::URL module calls croak upon encountering an error. When disabled, the URI::URL module may behave more gracefully. The function returns the previous value of strict. This function is not exported explicitly by the module.

user
$url->user([username])

When invoked with no parameters, this method returns the user for the URL defined in the object. When invoked with a parameter, the object's user is assigned to that value.

Previous | Home | Next
20.4. The HTML Modules | Book Index | IX. Perl/Tk
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part IX. Perl/Tk

Chapter 21, "Perl/Tk"

Previous | Home | Next
20.5. The URI Module | Book Index | 21. Perl/Tk
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 21. Perl/Tk

Contents:

Widgets
Geometry Managers
Common Widget Configuration Options
The Button Widget
The Checkbutton Widget
The Radiobutton Widget
The Label Widget
The Entry Widget
The Scrollbar Widget
The Listbox Widget
The Text Widget
The Canvas Widget
The Scale Widget
The Menubutton Widget
The Menu Widget
The Optionmenu Widget
The Frame Widget
The Toplevel Widget

Perl/Tk is an extension for writing Perl programs with a graphical user interface (GUI) on both Unix and Windows 95/NT. Tk was originally developed as an extension to the Tcl language, for use with the X Window System on Unix. With its port to Perl, Tk gives Perl programmers the same control over the graphical desktop that Tcl programmers have taken for granted.

The Tk extension makes it easy to draw a window, put widgets into it (such as buttons, checkboxes, entry fields, menus, etc.), and have them perform certain actions based on user input. A simple "Hello World" program would look like this:

#!/usr/bin/perl -w
use Tk;
my $mw = MainWindow->new;
$mw->Button(-text => "Hello World!", -command =>sub{exit})->pack;
MainLoop;

When you run it, it would look like Figure 21-1.

Figure 21-1. A simple Perl/Tk program

Clicking on the Hello World button exits the program, and your window disappears.

Let's walk through these few lines of code. After calling the Perl interpreter, the program calls the Tk module. It then proceeds to build a generic, standard window (MainWindow) to act as a parent for any other widgets you create. Line 4 of the program creates a button and displays it using the pack geometry manager. It also gives the button something to do when pushed (in this case, exit the program).

The last line tells the program to "go do it." MainLoop starts the event handler for the graphical interface, and the program draws windows until it reaches the MainLoop statement. Everything up to that point is preparation; until you reach the MainLoop statement, the program simply prepares its windows and defines what to do when certain events happen (such as a mouse click on the Hello World! button). Nothing is drawn until the MainLoop statement is reached.

21.1. Widgets

Widgets in Perl/Tk are created with widget creation commands, which include Button, Canvas, CheckButton, Entry, Frame, Label, Listbox, Menu, Menubutton, Message, Radiobutton, Scale, Scrollbar, Text, and Toplevel, among many, many others.

Positioning widgets is done with geometry managers. In the "Hello World" example shown earlier, the pack command is the geometry manager. Geometry managers determine where in the window (or frame) the widget will sit. We'll talk more about the Perl/Tk geometry managers later in this chapter.

21.1.1. Widget Methods

Widgets can be configured, queried, or manipulated via various widget methods. For example, all widgets support the configure widget method for changing widget properties after the widget is created. In addition, most widgets have specialized methods associated with them for manipulating the widget as needed throughout the program. For example, widgets that scroll support the xview and yview methods for determining the viewable portion of the content when the scrollbar is moved. The Entry and Text widgets have methods for inserting and deleting values. The Canvas widget has a whole series of methods for drawing shapes and inserting text into the canvas. And so on.

Widget methods are listed in the discussion of each widget later in this chapter. However, since all widgets support the configure and cget methods, we will cover them now.

21.1.1.1. The configure method

The configure method can be used to set and retrieve widget configuration values. For example, to change the width of a button:

$button->configure(-width => 100);

To get the value for a current widget, just supply it without a value:

$button->configure(-width);

The result is an array of scalars; the important values are the last two, which represent the default value and its current value, respectively.

You can also call configure without any options at all, which will give you a listing of all options and their values.

21.1.1.2. The cget method

For simply retrieving the value of an option, configure returns more information than you generally want. The cget method returns just the current value.

21.1.2. Scrollbars

Many widgets have scrollbars associated with them. Scrollbars can be added to a widget in two ways: with an independent Scrollbar widget or with the Scrolled method when creating a widget. For simple scrollbars, the Scrolled method is much easier and therefore preferable.

21.1.2.1. Using the Scrolled method

Use the Scrolled method to create both the widget and the scrollbar in a single command. For example:

$mainwindow->Scrolled('Entry', -scrollbars => 'os'
        -textvariable => \$address)->pack;

This creates an Entry widget with an "optional" scrollbar on the bottom. The first argument to Scrolled is the type of widget (in this case, an Entry widget). Then use the -scrollbars option to list the location of the scrollbar ("s" for the south, or bottom, edge of the widget). Here, we specify an "optional" scrollbar with "o", meaning that the scrollbar will appear only if needed.

Any additional options to the Scrolled method are taken as options to the widget itself. In this case, we're setting the -textvariable option to the Entry widget.

21.1.2.2. The Scrollbar widget

For more flexibility with a scrollbar, you can use the Scrollbar widget. To do so, you need to create the target widget to scroll. Set the -xscrollcommand or -yscrollcommand option as appropriate, configure the scrollbar to talk to the widget, and position the scrollbar and target widget next to one another. For example:

$scrollbar = $mainwindow->Scrollbar(-orient => 'vertical');
$listbox = $mainwindow->Entry(-yscrollcommand => ['set' => $scrollbar]);
$scrollbar->configure(-command => ['yview' => $listbox]);
$scrollbar->pack(-side => 'right', -fill => 'y');
$listbox->pack(-side => 'left', -fill => 'both');

First, we create the scrollbar with vertical orientation (which is actually the default). Next, we create the Listbox widget with the -yscrollcommand option to define a callback when the widget is scrolled vertically. The scrollbar is then configured with a callback that says to inform the Listbox widget when it is clicked vertically. Finally, the Scrollbar and Listbox widgets are packed side-by-side. See further discussion of the Scrollbar widget later in this chapter for more information.

21.1.3. Callbacks

Many widgets allow you to define a callback, which is a command to execute when the widget is selected. For example, when you press an exit button, the callback might be to a routine that cleans up and quits the program. When you click on a radio button, you might want to change the window to reflect the new preferences.

Widgets that support callbacks have a -command option to provide the callback function. In the "Hello World" example shown previously, the callback is to sub {exit}. In that example, the callback is called as an anonymous subroutine. You could also use a reference to a subroutine (e.g., \&routine). If you want to provide arguments to a subroutine, you can call it as an anonymous list (e.g., [ \&routine, $arg, $arg, ... ]).

21.1.4. Colors and Fonts

Tk was originally created for the X Window System and is still primarily used in that environment. For this reason, it has inherited the font and color scheme used for the X Window System.

Colors that can be used with Tk widgets are identified either by an RGB value or by a name that has been associated with an RGB value. In general, it is easier to use a color name than an explicit RGB value. For a listing of the color names that are supported, see the rgb.txt file in your X distribution or use the showrgb command. (Most common color names are supported, so you can say things such as "red," "pink," "green," and even "chartreuse" with confidence.)

Fonts are another matter. Under the X Window System, fonts are named things such as -adobe-helvetica-medium-o-normal -- 12-120-75-75-p-67-iso8859-1. Wildcards can make the fonts easier to use, but they're still a mouthful. For a listing of fonts available for a particular X server, use the xlsfonts command. There are a few font "aliases" that have been defined for your convenience (such as fixed, 6x10, 9x15, etc.), and you might prefer to just stick to those.

Previous | Home | Next
IX. Perl/Tk | Book Index | 21.2. Geometry Managers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.2. Geometry Managers

Creating widgets and determining how to display them are done with separate commands. You can create a widget with one of the widget creation methods (such as Button, Canvas, etc.), but you display them using a geometry manager. The three geometry managers are pack, grid, place, and form. pack is by far the most commonly used.

You can either pack a widget as you create it or create the widget object and pack it separately. For example, the previous "Hello World" example might have read:

#!/usr/bin/perl -w
use Tk;
my $mw = MainWindow->new;
$button = $mw->Button(-text => "Hello World!", -command =>sub{exit});
$button->pack;
MainLoop;

21.2.1. The pack Geometry Manager

With the pack geometry manager, widgets cannot overlap or cover each other, either partially or completely. Once a widget is packed into a window, the next widget is packed in the remaining space around it. pack sets up an "allocation rectangle" for each widget, determined by the dimensions of the parent window and the positioning of the widgets already packed into it. This means that the order in which you pack your widgets is very important.

By default, pack places widgets at the top center of the allocation rectangle. However, you can use options to pack to control where a widget is placed and how much padding is placed around it. Options for pack are:

-side => side
Puts the widget against the specified side of the window. Values for side are left, right, top, and bottom. The default is top.

-fill => direction
Causes the widget to fill the allocation rectangle in the specified direction. Values for direction are none, x, y, and both. The default is none.

-expand => boolean
Causes the allocation rectangle to fill the remaining space available in the window. Values are yes, no, 1, and 0. The default is 0 (no).

-anchor => position
Anchors the widget inside the allocation rectangle. Values for positionare n, ne, e, se, s, sw, w, nw, and center. The default is center.

-after => $widget
Puts the widget after another widget in packing order.

-before => $widget
Puts the widget before another widget in packing order.

-in => $window
Packs the widget inside another window rather than inside its parent.

-ipadx => amount
Increases the size of the widget horizontally by amount x 2. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-ipady => amount
Increases the size of the widget vertically by amount x 2. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-padx => amount
Places padding on the left and right of the widget. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-pady amount
Places padding on the top and bottom of the widget. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

21.2.1.1. pack methods

The following methods are associated with widgets managed with pack:

packForget
Causes a widget to be removed from view:

$widget->packForget;

The widget is not destroyed, but it is no longer managed by pack. The widget is removed from the packing order, so if it was repacked later, it would appear at the end of the packing order.

packInfo
Returns a list containing all pack information about that widget:

$info = $widget->packInfo;
packPropagate
Enables or suppresses automatic resizing of a Toplevel or Frame widget to accommodate items packed inside of it. Automatic resizing is on by default; the following line turns off automatic resizing:

$widget->packPropagate(0);
packSlaves
Returns an ordered list of all the widgets packed into the parent widget:

$children = $widget->packSlaves;

21.2.2. The grid Geometry Manager

The grid geometry manager divides the window into a grid composed of columns and rows starting at 0,0 in the upper lefthand corner. The resulting grid resembles a spreadsheet, with each widget assigned a cell according to the options to grid. To create a grid, create a frame packed inside the parent window and then grid the widgets within the frame.

You can specify explicit rows and columns using options to grid. However, if several widgets are meant to appear in the same row, you can use a single grid command with a list of widgets rather than calling grid for each one. The first widget invokes the grid command, and all other widgets for that column are specified as options to grid. Any subsequent grid commands increment the row by one and start again.

You can use special characters as placeholders:

- (minus sign)
The previous widget should span this column as well. May not follow ^ or x.

x
Leaves a blank space.

^
The widget above this one (same column, previous row) should span this row.

Options to grid are:

-column => n
The column in which to place the widget. n is any integer >= 0.

-row => m
The row in which to place the widget. m is any integer >= 0.

-columnspan => n
The number of columns for the widget to span, beginning with the column specified with -column. n is any integer > 0.

-rowspan => m
The number of rows for the widget to span, beginning with the row specified with -row. mis any integer > 0.

-sticky => sides
Sticks widget to specified side(s). sides contains characters n, s, e, or w.

-in => $window
Grids widget inside another window instead of its parent.

-ipadx => amount
Increases the size of the widget horizontally by amount x 2. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-ipady => amount
Increases the size of the widget vertically by amount x 2. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-padx => amount
Places padding on the left and right of the widget. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-pady amount
Places padding on the top and bottom of the widget. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

21.2.2.1. grid methods

The following methods are associated with widgets managed by grid:

gridColumnconfigure
Configures the column specified by the first argument using -weight and -minsize arguments. The -weight argument determines the amount of space to allocate to that column, and the -minsize argument sets the minimum size in pixels. For example:

$widget->gridColumnconfigure(3, -weight => 1);
gridRowconfigure
Configures the row specified by the first argument using -weight and -minsize arguments. The -weight argument determines the amount of space to allocate to that row, and the -minsize argument sets the minimum size in pixels. For example:

$widget->gridRowconfigure(3, -weight => 1);
gridRemove
Removes each of the $slaves from grid for its master and unmaps their windows. The slaves will no longer be managed by the grid geometry manager. gridRemove remembers the previous configuration options for the window. So, if $slave is managed once more by the grid geometry manager, the previous values will be retained.

gridBbox
Returns the bounding box in pixels for the space occupied by the specified grid position (in the order of column, row). For example:

$widget->gridBbox(3,2);
gridForget
Causes the widget(s) to be removed from view. Additional widgets can be specified as arguments.

$widget1->gridForget($widget2, widget3, ...);
gridInfo
Returns information about the widget in list format:

$widget->gridInfo;
gridLocation
Returns the column and row of the widget nearest the specified x,y coordinates (in pixels):

$widget->gridLocation(120, 32);
gridPropagate
Turns off automatic resizing of the widget:

$widget->gridPropagate;
gridSize
Returns the size of the grid, i.e., the number of columns and rows:

$widget->gridSize;
gridSlaves
Returns a list of all widgets contained within a master widget. Optional -row and -column arguments restrict the response to the widget(s) within that row or column:

@children = $widget->gridSlaves(-row => 2);

21.2.3. The place Geometry Manager

The place geometry manager lets you position a window at explicit x,y coordinates. With place, you can overlap widgets, which isn't allowed with grid or pack. For example, to position a button widget at the upper-left corner of a window:

$button->place(-x => 0, -y => 0);

Options to place are:

-anchor => position
The position in the widget that will be placed at the coordinates specified. Values for position are n, ne, e, se, s, sw, w, nw, and center. Default is nw.

-bordermode => location
Determines whether the border portion of the widget is included in the coordinate system. Values for location are inside, outside, and ignore.

-height => amount
Absolute height of the widget. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-in => $window
The child widget will be packed inside the specified window instead of the parent that created it. Any relative coordinates or sizes will still refer to the parent.

-relheight => ratio
The height of the widget relates to the parent widget's height by the specified ratio.

-relwidth => ratio
The width of the widget relates to the parent widget's width by the specified ratio.

-relx => xratio
The widget will be placed relative to its parent by the specified ratio. xratiois a floating point number from 0.0 to 1.0, with 0.0 representing the left side of the parent widget and 1.0 representing the right side.

-rely => yratio
The widget will be placed relative to its parent by the specified ratio. yratio is a floating point number from 0.0 to 1.0, with 0.0 representing the top of the parent widget and 1.0 representing the bottom.

-width => amount
The width of the widget will be the specified amount. amount can be represented as a number followed by c (centimeters), i (inches), m (millimeters), and p (printer points). Pixels are the default units.

-x => xcoord
The widget will be placed at the specified x coordinate.

-y => ycoord
The widget will be placed at the specified y coordinate.

The following methods are associated with widgets managed by place:

placeForget
Causes the widget to be removed from view.

placeInfo
Returns information about the widget.

placeSlaves
Returns a list of widgets managed by the specified parent widget.

21.2.4. The form Geometry Manager

The form geometry manager arranges the geometry of children in the parent window according to attachment rules. In addition, form can be used as a replacement for the existing Tk pack and place geometry managers. For example, to position a widget $top_w on top of $bot_w, you'd do this:

$bot_w->form(-top=>[$topw_w, 0]);

Options to form are:

-b => attachment
Abbreviation for the -bottom option.

-bottom => attachment
Specifies an attachment for the bottom edge of the slave window.

-bottomspring => attachment
Specifies the weight of the spring at the bottom edge of the slave window.

-bp => value
Abbrevation for the -padbottom option.

-bs => weight
Abbrevation for the -bottomspring option.

-fill => style
Specifies the fillings when springs are used for this widget. The value must be x, y, both, or none.

-in => $master
Places the slave window into the specified $master window. If the slave was originally in $another_master, all attachment values with respect to $original_master are discarded. The attachment values will need to be specified again. If you use -in, it must be used first in the options list.

-l => attachment
Abbreviation for the -left option.

-left => attachment
Specifies an attachment for the left edge of slave window, $slave.

-leftspring => weight
Specifies the weight of the spring at the edge of the slave window, $slave.

-lp => value
Abbreviation for the -padleft option.

-ls => weight
Abbreviation for the -leftspring option.

-padbottom => value
Specifies the amount of external padding to leave on the bottom side of the slave.

-padleft => value
Specifies the amount of external padding to leave on the left side of the slave.

-padright => value
Specifies the amount of external padding to leave on the right side of the slave.

-padtop => value
Specifies the amount of external padding to leave on the top side of the slave.

-padx => value
Specifies the amount of external padding to leave on both the left and right sides of the slave.

-pady => value
Specifies the amount of external padding to leave on both the top and bottom sides of the slave.

-r => attachment
Abbreviation for the -right option.

-right => attachment
Specifies an attachment for the right edge of the slave window.

-rightspring => weight
Specifies the weight of the spring at the right edge of the slave window.

-rp => value
Abbreviation for the -padright option.

-rs => weight
Abbreviation for the -rightspring option.

-t => attachment
Abbreviation for the -top option.

-top => attachment
Specifies an attachment for the top edge of the slave window.

-topspring => weight
Specifies the weight of the spring at the top edge of the slave window.

-tp => value
Abbreviation for the -padtop option.

-ts => weight
Abbreviation for the -topspring option.

The following methods are associated with widgets managed by form:

formCheck
Checks whether this is a circular dependancy between the master's slaves. It returns true if the dependancy exists and false otherwise.

formForget
Removes the slave from its master and unmaps its window. The slave will no longer be managed by form. All attachment values with respect to $master are discarded.

formGrid($size_x, $size_y)
Returns the number of grids to $master as integers in the form $size_x, $size_y. You may change the number of grids on the master window by passing $size_x and $size_y to formGrid.

formInfo(-option)
Queries the attachment options of a slave window. -option can be any of the options accepted by form. With no options, formInfo returns the current configuration values.

formSlaves
Returns a list of all the slaves for the master window.

Previous | Home | Next
21. Perl/Tk | Book Index | 21.3. Common Widget Configuration Options
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.3. Common Widget Configuration Options

In the remainder of this chapter, we'll discuss each widget, the commands used to create each widget, the options used to configure them, and the methods for manipulating them.

You'll find that there are many, many configuration options shared by multiple widgets. We could list them individually for each widget, but in the interest of saving a tree or two, we will instead list the shared options up front rather than repeating them over and over. That way, we can concentrate on the options that are crucial to the behavior of each particular widget and save the reader from being lost in a sea of options.

The following options are supported by the widgets noted:

-activebackground => color
Sets the background color when the mouse cursor is over the widget. Applicable widgets: Button, Checkbutton, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar.

-activeborderwidth => borderwidth
Sets a 3-D border around active elements. Applicable widgets: Menu, Menubutton, Optionmenu.

-activeforeground => color
Sets the text color when the mouse cursor is over the widget. Applicable widgets: Button, Checkbutton, Menu, Menubutton, Optionmenu, Radiobutton.

-anchor => position
Causes the text to stick to that position in the widget. Values for position are n, ne, e, se, s, sw, w, nw, and center. Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton.

-background => color
-bg => color
Sets the background of the widget to the specified color. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-bitmap => 'bitmapname'
Uses a bitmap instead of text in the widget. You can specify either a default bitmap or the location of a bitmap file (with @ in front of the path). Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton.

-borderwidth => amount
-bd => amount
Changes the width of the edge drawn around the widget. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-cursor => 'cursorname'
Mouse cursor will change to specified cursor when over the widget. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-disabledforeground => color
Sets the color of the text when the widget is disabled. Applicable widgets: Button, Checkbutton, Menu, Menubutton, Optionmenu, Radiobutton.

-exportselection => boolean
Determines whether selected text is exported to the window system's clipboard. (For a listbox, the default of -exportselection => 1 means two listboxes cannot have selections at the same time.) Applicable widgets: Entry, Listbox, Text.

-font => 'fontname'
Changes the font of all the text on the widget to fontname. Applicable widgets: Button, Checkbutton, Entry, Label, Listbox, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Text.

-foreground => color
-fg => color
Changes the text color to color. Applicable widgets: Button, Checkbutton, Entry, Label, Listbox, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Text.

-height => amount
Specifies the height of the widget. amountrepresents a number of characters if text is displayed, or a screen distance if an image or bitmap is displayed. Applicable widgets: Button, Canvas, Checkbutton, Frame, Label, Listbox, Menubutton, Optionmenu, Radiobutton, Text, Toplevel.

-highlightbackground => color
Sets the color of a non-focus rectangle. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-highlightcolor => color
Sets the color of the focus rectangle. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-highlightthickness => amount
Sets the thickness of the black box around the widget that indicates focus. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-image => $imgptr
Uses an image instead of text. $imgptr is a pointer to a Photo or Image object made using a GIF or PPM file. For example:

$arrow = $mainwindow->Photo(-file => "image.gif");
$mainwindow->Button(-image => $arrow,
                  -command => sub {exit})->pack;

Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton.

-insertbackground => color
Sets the color of the insert cursor. Applicable widgets: Canvas, Entry, Text.

-insertborderwidth => amount
Sets the width of the insert cursor's border. Applicable widgets: Canvas, Entry, Text.

-insertofftime => milliseconds
Defines the amount of time the insert cursor is "off." Applicable widgets: Canvas, Entry, Text.

-insertontime => milliseconds
Defines the amount of time the insert cursor is "on." Applicable widgets: Canvas, Entry, Text.

-insertwidth => amount
The width of the insert corner (default = 2 pixels). Applicable widgets: Canvas, Entry, Text.

-justify => side
Justifies text against the specified side. side can be left, right, or center. Applicable widgets: Button, Checkbutton, Entry, Label, Menubutton, Optionmenu, Radiobutton.

-padx => amount
Adds extra space to left and right of the widget inside the widget edge. Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton, Text.

-pady => amount
Adds extra space to top and bottom of the widget inside the widget edge. Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton, Text.

-relief => type
Changes the type of edges drawn around the widget. Values for type are flat, groove, raised, ridge, and sunken. Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-selectbackground => color
Determines the background color of selected text in the entry widget. Applicable widgets: Canvas, Entry, Listbox, Text.

-selectborderwidth => amount
Determines the width of the selection highlight's border. Applicable widgets: Canvas, Entry, Listbox, Text.

-selectforeground => color
Determines the text color of selected text in the entry widget. Applicable widgets: Canvas, Entry, Listbox, Text.

-state => state
Sets the state of responsiveness of the widget. Values for state are normal, disabled, and active. (disabled makes it not respond.) Applicable widgets: Button, Checkbutton, Entry, Menubutton, Optionmenu, Scale, Text.

-takefocus => focus
Determines whether the widget gets focus. Values for focus are 0 (the widget will never get the focus), 1 (the widget always gets the focus), and the null string ("") (which lets the application decide). Applicable widgets: Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Menubutton, Optionmenu, Scale, Scrollbar, Text, Toplevel.

-underline => n
Underlines the nth character in the text string. Allows keyboard input via that character when the widget has the focus. Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton.

-width => amount
Width of the widget, represented in characters if text is displayed, or as a screen distance if an image or bitmap is displayed. Applicable widgets: Button, Canvas, Checkbutton, Frame, Label, Listbox, Menubutton, Optionmenu, Radiobutton, Scale, Scrollbar, Text, Toplevel.

-wraplength => amount
Defines the maximum amount of text to be displayed on one line. Applicable widgets: Button, Checkbutton, Label, Menubutton, Optionmenu, Radiobutton.

-xscrollcommand => callback
Assigns a callback to use when scrolling back and forth. Applicable widgets: Canvas, Entry, Listbox, Text.

-yscrollcommand => callback
Determines a command to run when scrolled in the vertical direction. Applicable widgets: Canvas, Listbox, Text.

Previous | Home | Next
21.2. Geometry Managers | Book Index | 21.4. The Button Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.4. The Button Widget

Create a simple button with the Button method:

$parentwidget->Button (options)

The standard configuration options that apply to Button are: -activebackground, -activeforeground, -anchor, -background, -bg, -bitmap, -borderwidth, -bd, -cursor, -default, -disabledforeground, -font, -foreground, -fg, -height, -highlight-background, -highlightcolor, -highlightthickness, -image, -justify, -padx, -pady, -relief, -state, -takefocus, -underline, -width, and -wraplength.

Other options are:

-command => callback
Pointer to a function that will be called when the button is pressed.

-text => 'text'
Defines the text string displayed on the button. See also -textvariable.

-textvariable => \$variable
Points to the variable containing text to be displayed in the button. Button text will change as $variable does.

21.4.1. Button Methods

In addition to configure and cget, the following methods can be used for Button:

flash
Causes the button to flash from the normal to active state colors.

invoke
Invokes the callback command as if the button was clicked.

Previous | Home | Next
21.3. Common Widget Configuration Options | Book Index | 21.5. The Checkbutton Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.5. The Checkbutton Widget

Create a checkbutton with the Checkbutton command. A checkbutton has an indicator to the left of the label indicating whether the button is selected. The boolean status of the button (0, 1, or values as specified by the -onvalue and -offvalue options) is stored in the variable specified with the -variable option.

$parentwidget->Checkbutton (options)

The standard configuration options that apply to Checkbutton are: -activeback-ground, -activeforeground, -anchor, -background, -bg, -bitmap, -borderwidth, -bd, -cursor, -disabledforeground, -font, -foreground, -fg, -height, -highlight-background, -highlightcolor, -highlightthickness, -image, -justify, -padx, -pady, -relief, -state, -takefocus, -underline, -width, and -wraplength.

Other options are:

-command => callback
Pointer to a function that will be called when the checkbutton is pressed.

-indicatoron => boolean
Determines whether to display the indicator. Default is on (1).

-offvalue => newvalue
Specifies the value used when the checkbutton is off. Must be a scalar. Default is 0.

-onvalue => newvalue
Specifies the value used when the checkbutton is on. Must be a scalar. Default is 1.

-selectcolor => color
Color of the indicator when the checkbutton is on.

-selectimage => imgptr
Defines the image to be displayed instead of text when the checkbutton is on. Ignored if -image is not used.

-text => 'text'
Defines the text string displayed in the checkbutton. See also -textvariable.

-textvariable => \$variable
Points to the variable containing text to be displayed in the checkbutton. Button text will change as $variable does.

-variable => \$variable
Associates the on/off value of the indicator with the specified variable.

21.5.1. Checkbutton Methods

In addition to configure and cget, the following methods are supported by Checkbutton:

deselect
Sets the indicator to off.

select
Sets the indicator to on.

flash
Causes the button to flash from the normal to active state colors.

invoke
Invokes the callback command as if the checkbuttons were clicked.

toggle
Toggles the indicator from on to off, or from off to on.

Previous | Home | Next
21.4. The Button Widget | Book Index | 21.6. The Radiobutton Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.6. The Radiobutton Widget

Create a radiobutton with the Radiobutton method. A radiobutton has an indicator to the left of the label indicating whether the button is selected. It differs from a checkbutton in that only one button may be selected at a time. Each button in a group of radiobuttons uses the same variable specified with the -variable option; when selected, the button assigns that variable the value specified by the -value option.

$parentwidget->Radiobutton (options)

The standard configuration options that apply to Radiobutton are: -activeback-ground, -activeforeground, -anchor, -background, -bg, -bitmap, -borderwidth, -bd, -cursor, -disabledforeground, -font, -foreground, -fg, -height, -highlight-background, -highlightcolor, -highlightthickness, -image, -justify, -padx, -pady, -relief, -state, -underline, -width, and -wraplength.

Other options are:

-command => callback
Pointer to a function that will be called when the radiobutton is pressed.

-indicatoron => boolean
Determines whether to display the indicator. Default is on (1).

-selectcolor => color
Color of the indicator when the radiobutton is on.

-selectimage => imgptr
Defines the image to be displayed instead of text when the radiobutton is on. Ignored if -image is not used.

-text => 'text'
Defines the text string displayed in the radiobutton. See also -textvariable.

-textvariable => \$variable
Points to the variable containing text to be displayed in the radiobutton. Button text will change as $variable does.

-value => value
Sets $variable to the specified value when the radiobutton is selected. Default is 1.

-variable => \$variable
Associates the on/off value of the indicator with the specified variable.

21.6.1. Radiobutton Methods

In addition to configure and cget, the following methods are supported by Radiobutton:

deselect
Deselects the button and sets the variable to the empty string.

select
Sets the radio button.

flash
Causes the button to flash from the normal to active state colors.

invoke
Selects the button and invokes the callback command as if the radiobutton was clicked.

Previous | Home | Next
21.5. The Checkbutton Widget | Book Index | 21.7. The Label Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.7. The Label Widget

Create a noninteractive label with the Label command. A label is used to display text or an image.

$parentwidget->Label (options)

The standard configuration options that apply to Label are: -anchor, -background, -bg, -bitmap, -borderwidth, -bd, -cursor, -font, -foreground, -fg, -height, -high-lightbackground, -highlightcolor, -highlightthickness, -image, -justify, -padx, -pady, -relief, -takefocus, -underline, -width, and -wraplength.

Other options are:

-text => 'text'
Defines the text string displayed in the label. See also -textvariable.

-textvariable => \$variable
Points to the variable containing text to be displayed in the label. Button text will change as $variable does.

Previous | Home | Next
21.6. The Radiobutton Widget | Book Index | 21.8. The Entry Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.8. The Entry Widget

Create an Entry widget with the Entry method. An entry widget is a space for the user to enter text. The value that the user has typed into the widget is stored in the variable pointed to by the -textvariable option.

$parent->Entry (options)

The standard configuration options that apply to Entry are: -background, -bg, -borderwidth, -bd, -cursor, -exportselection, -font, -foreground, -fg, -high-lightbackground, -highlightcolor, -highlightthickness, -insertbackground, -in-sertborderwidth, -insertofftime, -insertontime, -insertwidth, -justify, -relief, -selectbackground, -selectborderwidth, -selectforeground, -state, -takefocus, and -xscrollcommand.

Other options are:

-show => x
Defines a character to be displayed in place of actual typed text (for use with passwords).

-textvariable => \$variable
Points to the variable containing text to be displayed in the Entry widget. Button text will change as $variable does.

21.8.1. Text Indexes

In an Entry widget, several indexes are defined to identify positions in the entry text. These are used by the methods that retrieve and manipulate entry text.

n
An integer representing a character position, with 0 as the first character in the string.

insert
The character directly after the insert cursor.

sel.first
The first character in the selection block.

sel.last
The character after the last character in the selection block.

anchor
The anchored position.

end
The position just after the last character in the entry string.

@x
The character containing the specified xcoordinate.

21.8.2. Entry Methods

In addition to configure and cget, the following methods are supported for the Entry widget:

delete
Deletes text from the widget. For example, to delete the selected text:

$entry->delete('sel.first', 'sel.last');
get
Gets the contents of the Entry widget. For example:

$input = $entry->get;
icursor
Places the cursor at the specified index. For example, to move the cursor to the end of the entry string:

$entry->icursor('end');
index
Converts a named index into a numeric one:

$length = $entry->index('end');
insert
Inserts text at the specified index. For example, to append the ".txt" string to the end of the entry string:

$entry -> insert('end', '.txt');
selection
Manipulates the selected block. The first argument can be any of:

adjust
Extends selected text to the index specified in the second argument:

$entry->selection('adjust', 'end');
clear
Clears the selection block:

$entry->selection('clear');
from
Resets the anchor index to the index specified in the second argument:

$entry->selection('from',0);
present
Determines if any text is currently selected:

if ($entry->selection('present')) {
        $entry->delete('sel.first','sel.last');
}
range
Changes the selection range to the indexes specified in the second and third arguments. For example, to change the selection to include the entire entry string:

$entry->selection('range',0,'end');
to
Extends the selection from the current anchor position to the specified index:

$entry->selection('to','insert');
xview
Manipulates the text in view. With no arguments, returns a list of two numbers between 0 and 1, defining the portion of the entry text that is currently hidden on the left and right sides, respectively. With arguments, the function of xview changes:

index
If the first argument is an index, that position becomes the leftmost position in view. For example, to reset the visible portion to the beginning of the string:

$entry->xview(0);
moveto
Moves the specified fraction of the entry text to the left of the visible portion. For example, to hide the first 10% of the entry text:

$entry->xview('moveto',0.1);
scroll
Scrolls the text left or right by the specified number of units (characters, in this context) or pages. Used mainly as a callback to a scrollbar; pressing on an arrow moves by units (characters), and pressing on the trough moves by pages. The number is either 1 or -1, to move forwards or backwards, respectively. For example:

$entry->xview('scroll',1,'units');
Previous | Home | Next
21.7. The Label Widget | Book Index | 21.9. The Scrollbar Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.9. The Scrollbar Widget

Create a scrollbar with the Scrollbar method:

$parentwidget->Scrollbar (options)

The standard configuration options that apply to Scrollbar are: -ac-tivebackground, -background, -bg, -borderwidth, -bd, -cursor, -highlightback-ground, -highlightcolor, -highlightthickness, -relief, -takefocus, and -width.

Other options are:

-activerelief => type
Changes how active elements (arrow1, arrow2, and slider) in the scrollbar are drawn. Values for type are flat, groove, raised, ridge, and sunken. The default is raised.

-command => callback
Pointer to a function that will be called when the scrollbar is clicked on.

-elementborderwidth => amount
The width of the borders of the arrow1, arrow2, and slider elements.

-jump => boolean
Determines whether the scrollbar will jump scroll. Default is 0 (jump scroll disabled).

-orient => orientation
Determines the orientation of the scrollbar. Possible orientations are horizontal and vertical (default).

-repeatdelay => milliseconds
Determines the number of milliseconds to hold down an arrow before it will auto-repeat. Default is 300.

-repeatinterval => milliseconds
Determines the number of milliseconds between auto-repeats once it is started. Default is 100.

-troughcolor => color
Changes the color of the trough.

21.9.1. Scrollbar Methods

In addition to configure and cget, the following methods are supported by the Scrollbar widget:

set
Changes the viewable portion of the data, with the two arguments being numbers between 0 and 1 representing the portions of the data that will be visible.

$scrollbar->set(0.2,0.6);
get
Returns the latest arguments to set.

activate
With no arguments, returns the name of the current active element. With an argument of arrow1, arrow2, or slider, changes the color of the specified element to the active foreground color and relief type.

delta
Given a number of pixels in the first argument, returns the fractional change needed to move the slider that amount.

fraction
Given an x,y coordinate as the first and second arguments, returns a number between 0 and 1 representing the fraction of the scrollbar that the coordinate would fall under.

identify
Given an x,y coordinate as the first and second arguments, returns the name of the element at those coordinates.

Previous | Home | Next
21.8. The Entry Widget | Book Index | 21.10. The Listbox Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.10. The Listbox Widget

Create a listbox with the Listbox method. You can then insert items into the listbox using the insert method.

$parentwidget->Listbox (options)

The standard configuration options that apply to Listbox are: -background, -bg, -borderwidth, -bd, -cursor, -exportselection, -font, -foreground, -fg, -height, -highlightbackground, -highlightcolor, -highlightthickness, -relief, -select-background, -selectborderwidth, -selectforeground, -takefocus, -width, -xscroll-command, and -yscrollcommand.

Other options are:

-selectmode => mode
Determines the number of items that can be selected at once, as well as key/mouse bindings. mode can be any of:

single
Only one item can be selected at a time.

browse
Only one item can be selected at a time (default).

multiple
Multiple items can be selected at a time.

extended
Multiple items can be selected at a time.

-setgrid => boolean
Turns on gridding for the listbox. If the widget is resized, only complete lines and characters are displayed. Default is 0 (off).

21.10.1. Listbox Indexes

In a Listbox widget, several indexes are defined to identify positions in the listbox. These are used by the methods that retrieve and manipulate listbox entries.

n
An integer representing a position in the list, with 0 as the first item.

active
The item with the keyboard focus.

anchor
The anchored position.

end
The last element in the listbox.

@x,y
The listbox item containing the specified x,y coordinate.

21.10.2. Listbox Methods

In addition to configure and cget, the following methods are supported by Listbox:

insert
Adds items to a listbox at the specified index. For example, to insert items at the end of a list:

$listbox->insert('end', "Puerto Rico", "Virgin Islands", "Guam");
delete
Deletes items from a listbox. To delete all items:

$listbox->delete(0,'end');
get
Returns a list of elements within the specified range of indexes. For a list of all elements:

@items = $listbox->get(0,'end');
curselection
Returns a list of all currently selected elements in the listbox.

activate
Sets the specified item to be the active element.

bbox
Returns the location and dimensions of the bounding box surrounding the specified listbox element. The returned list contains four numbers representing (respectively) the x coordinate of the upper-left corner, the y coordinate of the upper-left corner, the width of the text in pixels, and the height of the text in pixels.

index
Converts a named index into a numeric one.

nearest
Gets the index of the listbox item nearest a given y coordinate.

see
Pages the listbox up or down to display the specified item.

selection
Manipulates the selected block of list items. The first argument can be any of:

anchor
Sets the anchor index to the specified index.

clear
Clears any selected list items in the specified range. For example, to clear all selections:

$listbox->selection('clear', 0, 'end');
includes
Returns 0 or 1 depending on whether the specified item is already selected:

$listbox->selection('includes', 'end');
set
Selects a range of items in the listbox:

$listbox->selection('set', 0, 'end');
size
Returns the total number of items in the listbox.

xview
Manipulates the text in view. With no arguments, returns a list of two numbers between 0 and 1, defining the portion of the list text that is currently hidden on the left and right sides, respectively. With arguments, the function of xview changes:

index
If the first argument is an index, that position becomes the leftmost position in view.

moveto
Moves the specified fraction of the listbox to the left of the visible portion.

scroll
Scrolls the text left or right by the specified number of units (characters, in this context) or pages. Used primarily as a callback to a scrollbar; pressing on an arrow would move by units (characters), and pressing on the trough would move by pages. The number is either 1 or -1, to move forwards or backwards, respectively.

yview
Manipulates the text in view. With no arguments, returns a list of two numbers between 0 and 1, defining the portion of the list text that is currently hidden on the top and bottom, respectively. With arguments, the function of yview changes:

index
If the first argument is an index, that position becomes the topmost position in view.

moveto
Moves the specified fraction of the listbox to the top of the visible portion.

scroll
Scrolls the text up or down by the specified number of units (lines, in this context) or pages. Used primarily as a callback to a scrollbar; pressing on an arrow would move by units (lines), and pressing on the trough would move by pages. The number is either 1 or -1, to move forwards or backwards, respectively.

Previous | Home | Next
21.9. The Scrollbar Widget | Book Index | 21.11. The Text Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.11. The Text Widget

Create a Text widget with the Text method:

$parentwidget->Text ( options)

The standard configuration options that apply to Text are: -background, -bg, -bor-derwidth, -bd, -cursor, -exportselection, -font, -foreground, -fg, -height, -high-lightbackground, -highlightcolor, -highlightthickness, -insertbackground, -in-sertborderwidth, -insertofftime, -insertontime, -insertwidth, -padx, -pady, -re-lief, -selectbackground, -selectborderwidth, -selectforeground, -state, -takefo-cus, -width, -xscrollcommand, and -yscrollcommand.

Other options are:

-setgrid => boolean
Turns on gridding for the Text widget. Default is 0 (off).

-spacing1 => amount
Defines the amount of space left on the top of a line of text that starts on its own line. Default is 0.

-spacing2 => amount
Defines the amount of space left on the top of a line of text after it has been automatically wrapped by the Text widget. Default is 0.

-spacing3 => amount
Defines the amount of space left after a line of text that has been ended by \n. Default is 0.

-tabs => list
Specifies a list of tab stops to use in the text widget. Default is undefined (no tab stops).

-wrap => mode
Sets the mode for determining automatic line wrapping. Values are none (no wrapping), char (wrap at any character), or word (wrap at a word boundary). Default is char.

21.11.1. Text Indexes and Modifiers

In a Text widget, several indexes are defined to identify positions in the text. These are used by the methods that retrieve and manipulate text.

n.m
Numbers representing character m on line n

@x,y
The character closest to the x,y coordinate

end
The end of the text

insert
The character after the insert cursor

current
The position closest to the mouse cursor

mark
Other marks defined for the widget (see discussion of text marks later in this section)

sel.first
The first selected character

sel.last
The character just after the last selected character

tag.first
The first character in the widget of the specified tag type

tag.last
The character just after the last character of the specified tag type

widget
The location of an embedded widget

There are also several modifiers to use with text indexes. They are:

- n lines
+ n lines
n lines before or after the index

- n chars
+ n chars
n characters before or after the index

linestart
The first character on the line

lineend
The last character on the line (often a newline)

wordstart
The first character in the word

wordend
The character after the last character in the word

21.11.2. Text Methods

In addition to configure and cget, the following methods are defined for the Text widget:

bbox
Returns the location and dimensions of the bounding box surrounding the character at the specified index. The returned list contains four numbers representing (respectively) the x coordinate of the upper-left corner, the y coordinate of the upper-left corner, the width of the text in pixels, and the height of the text in pixels.

compare
Performs a comparison on two indexes. For example:

if ($text->compare('insert', '==', 'end') {
        # we're at the end of the text
}

The valid operators are <, <=, ==, >=, and !=.

debug
Given a Boolean, turns debugging on or off.

delete
Deletes text from the text widget. To delete everything:

$text->delete(0, 'end');
dlineinfo
Returns the location and dimensions of the bounding box surrounding the line at the specified index. The returned list contains five numbers representing (respectively) the x coordinate of the upper-left corner, the y coordinate of the upper-left corner, the width of the text in pixels, the height of the text in pixels, and the baseline position of the line.

get
Returns the text located in the given index range.

index
Given a named index, returns its numeric equivalent in the format line.char.

insert
Inserts text into the widget at the specified location. The second argument is the text to insert, and the third argument is either a single tag or a list reference containing the names of multiple tags to apply to the text. Subsequent arguments alternate between text and tags. For example:

$text->insert('end', 'You want to do ', 'normal',
                     'what?!', ['bold','red']);
search
Returns the index containing a particular string in the Text widget. For example, to search backwards for a case-insensitive hostname starting from the end of the text:

$hostindex = $text->search(-nocase, -backwards, $hostname, 'end');

The search method takes several switches to modify the search, each starting with -. The first argument that does not start with - is taken to be the search string. The switches are:

-forwards
Searches forwards starting at the specified index.

-backwards
Searches backwards starting at the specified index.

-exact
Matches the string exactly (default).

-regexp
Treat the pattern as a regular expression.

-nocase
Ignores case.

-count => $variable
Stores the number of matches into the specified variable.

--
Interprets the next argument as the pattern. (Useful when the pattern starts with a -.)

see
Scrolls the text so that the portion of the text containing the specified index is visible.

window
Embeds widgets within the Text widget. The first argument can be any of: create, names, cget, and configure.

create
Inserts an embedded widget at a specified index. Each widget occupies one character in the Text widget. The widget must have already been created as a child of the Text widget. For example:

$button = $text->Label(-text => "How ya doing?");
$text->window('create','end', -window => $button);

Here, the -window option is used to identify the widget to embed. The list of options to window ('create') is:

-align
Determines the positioning within the line of text. Values are baseline, bottom, top, or center (default).

-padx
Adds padding in the x direction.

-pady
Adds padding in the y direction.

-window
Identifies the widget to embed.

names
Returns a list of widget types embedded into the Text widget.

cget
Returns information on the widget at the specified index:

$text->window('cget',0);
configure
Configures widget at the specified index:

$text->window('configure',0,-background => "green");
xview
Manipulates the text in view. With no arguments, returns a list of two numbers between 0 and 1, defining the portion of the text that is currently hidden on the left and right sides, respectively. With arguments, the function of xview changes:

index
If the first argument is an index, that position becomes the leftmost position in view.

moveto
Moves the specified fraction of the text to the left of the visible portion.

scroll
Scrolls the text left or right by the specified number of units (characters, in this context) or pages. Used primarily as a callback to a scrollbar; pressing on an arrow would move by units (characters), and pressing on the trough would move by pages. The number is either 1 or -1, to move forwards or backwards, respectively.

yview
Manipulates the text in view. With no arguments, returns a list of two numbers between 0 and 1, defining the portion of the text that is currently hidden on the top and bottom, respectively. With arguments, the function of yview changes:

index
If the first argument is an index, that position becomes the topmost position in view.

moveto
Moves the specified fraction of the text to the top of the visible portion.

scroll
Scrolls the text up or down by the specified number of units (lines, in this context) or pages. Used primarily as a callback to a scrollbar; pressing on an arrow would move by units (lines), and pressing on the trough would move by pages. The number is either 1 or -1, to move forwards or backwards, respectively.

21.11.3. Tags

You can associate a distinct set of format properties to a portion of the text using tags. A tag is defined with the tagConfigure method, and text is associated with a tag via an option to the insert or tagAdd method. For example:

$text->Text->pack;
$text->tagConfigure('bold', -font =>
     '-*-Courier-Medium-B-Normal-*-120-*-*-*-*-*-*');
$text->insert('end', "Normal text\n");
$text->insert('end', "Bold text\n", 'bold');

There are several methods defined for manipulating text tags:

tagAdd
Adds a tag to the text within the specified index range. For example, to assign the bold tag defined above to the current selection:

$text->tagAdd('bold','sel.first','sel.last');

You can supply multiple ranges as arguments to tagAdd.

tagBind
Executes a callback when a specified event happens on the tagged text. For example:

$text->tagBind('goto_end', "<Button-1>", sub {shift->see('end');} );
tagConfigure
Creates or changes settings for a text tag. For example:

$text->tagConfigure('link', -foreground => 'red');

Options for configuring text tags are:

-background => color
The color to use behind the text.

-bgstipple => bitmap
A pattern to draw behind the text.

-borderwidth => amount
The width of the edge drawn around the text.

-fgstipple => bitmap
A pattern used to draw the text.

-font => fontname
The font used for the text.

-foreground => color
The color of the text.

-justify => position
The justification of the text (any of left, right, and center). The default is left.

-lmargin1 => amount
The indentation for the first line of a paragraph.

-lmargin2 => amount
The indentation for subsequent lines of a paragraph (for hanging indents).

-offset => amount
The amount the text is raised or lowered from the baseline (for subscripts and superscripts).

-overstrike => boolean
Draws the text with a line through it.

-relief => type
The types of edges drawn around the text. Values for type can be flat, groove, raised, ridge, and sunken. Default is flat.

-rmargin => amount
The right margin.

-spacing1 => amount
The amount of space left on the top of a line of text that starts on its own line.

-spacing2 => amount
The amount of space left on the top of a line of text after it has been automatically wrapped by the Text widget.

-spacing3 => amount
The amount of space left after a line of text ended by \n.

-tabs => list
A list of tab stops to use in the Text widget.

-underline => boolean
Whether to underline the text.

-wrap => mode
Sets the mode for determining automatic line wrapping. Values are none (no wrapping), char (wrap at any character), or word (wrap at a word boundary).

tagCget
Returns configuration settings for a tag.

tagDelete
Deletes the specified tag(s).

tagRemove
Removes the tags from the text in the specified index range. (The tag itself remains defined, but is no longer applied to that text.)

tagRaise
Increases priority for a specified tag. With only one argument, the tag takes highest priority over all others; with a second argument of another tag, the tag's priority is just higher than the second tag. For example:

$text->tagRaise('bold','italic');
tagLower
Decreases priority for a specified tag. With only one argument, the tag takes lowest priority to all others; with a second argument of another tag, the tag's priority is just lower than the second tag. For example:

$text->tagLower('italic','bold');
tagNames
Returns the names of all tags applying to the specified index. With no index specified, returns all tags defined for the Text widget, regardless of whether they have been applied. For example:

@defined_tags = $text->tagNames;
tagRanges
Returns a list of index ranges to which the specified tag is defined. The returned list contains pairs of starting and ending indexes for the ranges. For example:

@bold_indexes = $text->tagRanges('bold');
tagNextrange
Given a tag name and an index, returns the next index range to which the specified tag is defined. For example:

@next_bold = $text->tagRanges('bold', 'insert');

21.11.4. Marks

A mark is a particular position between characters in a Text widget. Once you create a mark, you can use it as an index. The gravity of the mark affects to which side the text is inserted. Right gravity is the default, in which case the text is inserted to the right of the mark.

The two marks that are automatically set are insert and current. The insert mark refers to the position of the insert cursor. The current mark is the position closest to the mouse cursor.

The following methods are defined for marking:

markGravity
Sets the gravity of a mark. For example:

$text->markGravity('insert', 'left');
markNames
Returns a list of all marks defined for the Text widget.

markSet
Creates a mark at a specified index:

$text->markSet('saved', 'insert');
markUnset
Deletes mark(s) from the Text widget:

$text->markUnset('saved');

Note that you cannot delete the insert or current marks.

Previous | Home | Next
21.10. The Listbox Widget | Book Index | 21.12. The Canvas Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.12. The Canvas Widget

Create a canvas for drawing with the Canvas method. The Canvas widget uses a coordinate system with the x coordinate increasing as you move right, and the y coordinate increasing as you move down (i.e., the y coordinate is mathematically upside-down). The x and y coordinates are specified in pixels by default.

$parentwidget->Canvas (options)

The standard configuration options that apply to Canvas are: -background, -bor-derwidth, -cursor, -height, -highlightbackground, -highlightcolor, -highlight-thickness, -insertbackground, -insertborderwidth, -insertofftime, -inserton-time, -insertwidth, -relief, -selectbackground, -selectborderwidth, -selectfore-ground, -state, -takefocus, -width, -xscrollcommand, and -yscrollcommand.

Other options are:

-closeenough => amount
The distance considered "close enough" to an item to be judged to be within it. Default is 1 pixel.

-confine => boolean
Whether to limit the canvas to the scroll region. Default is 1.

-scrollregion => [ x, y, w, h ]
Sets the region that the user is allowed to scroll. The option is a list reference that conveniently corresponds to the return value of the bbox method.

-xscrollincrement => amount
The distance to use for scrolling in the x direction.

-yscrollincrement => amount
The distance to use for scrolling in the y direction.

21.12.1. Canvas Creation Methods

To place graphic elements in a canvas, there are several item creation methods:

createArc
Creates an arc contained within the given bounding box. For example, to create an oval bounded by the box from (0,0) to (40,100):

$canvas->createArc(0,0,40,100, -extent => 360);

The -extent option gives a number between 0 and 360 defining the length of the arc. The default -extent is 90, or 1/4 of an oval; an extent of 360 gives you a full oval. The complete list of options to createArc is:

-extent => degrees
Creates an arc of the specified extent. degrees can be any number between 0 and 360, as described above.

-fill => color
Fills the arc with the specified color.

-outline => color
Draws the arc with the specified color (default is black).

-outlinestipple => bitmap
Draws the outline with the specified bitmap pattern.

-start => degrees
Starts drawing the arc from the specified position, which is represented by a number from 0 to 360. The default is 0, which means to start drawing at the 3 o'clock position.

-stipple => bitmap
Uses the specified bitmap to fill the arc (if -fill is also specified).

-style => type
Draws the arc as specified. Values are:

pieslice
Draws lines from the center to the ends of the arc (the default)

chord
Draws a line connecting the two ends of the arc

arc
Draws the arc with no other lines

-tags => tagnames
Associates the arc with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-width => amount
The width of the outline. Default is 1.

createBitmap
Inserts a bitmap. For example, to place the calculator bitmap at the (0,0) coordinates:

$canvas -> createBitmap(0, 0, -bitmap => 'calculator');

Options are:

-anchor => position
Anchors the bitmap at the specified position. Values are center (default), n, e, s, w, ne, nw, se, and sw.

-background => color
Specifies the color to use for the 0 pixels in the bitmap (default is to be transparent).

-bitmap => bitmap
Specifies the bitmap name. For a built-in bitmap, just specify the name; for a local bitmap file, specify the name with an @ preceding it.

-foreground => color
Specifies the color to use for the 1 pixel in the bitmap (default is black).

-tags => tagnames
Associates the bitmap with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

createImage
Creates an image. For example, to place an image at (0,0):

$canvas->createImage(0,0, -image => $imgptr);

Options are:

-anchor => position
Anchors the image at the specified position. Values are center (default), n, e, s, w, ne, nw, se, and sw.

-image => $imgptr
$imgptr is a pointer to a Photo or Image object made using a GIF or PPM file. For example:

$imgptr = $mainwindow->Photo(-file => "doggie.gif");
-tags => tagnames
Associate the image with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

createLine
Creates a line or several adjoining lines. For example, to create a line from (0,0) to (100,100) and then back to (100,0):

$canvas->createLine (0,0,100,100,100,0);

The first four coordinates are required. Any additional coordinates are taken to represent a continuation of that line. Options are:

-arrow => position
Specifies where to place arrowheads. Values are none (default), first, last, and both.

-arrowshape => [ head, length, flare ]
Specifies the dimensions of the arrow as a three-element anonymous list, describing (in order) the distance from the base to the head of the arrow, the distance from the rear point(s) to the head of the arrow, and the distance from the rear point(s) to the line.

-capstyle => type
Defines the type of arrowhead. Values are butt (the default), projecting, and round.

-fill => color
The color to use to draw the line.

-joinstyle => type
Defines how multiple lines are joined. Values are miter (default), bevel, and round.

-smooth => boolean
Determines whether the lines are drawn with a Bezier spine. Default is 0.

-splinesteps => n
Determines how smooth the Bezier curve is.

-stipple => bitmap
Draws the line with the specified bitmap pattern.

-tags => tagnames
Associates the line with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-width => amount
The width of the line (default is 1 pixel).

createOval
Creates an oval. For example, to create a circle bounded by the box from (50,50) to (150,150):

$canvas->createOval(50,50,150,150);

Options are:

-fill => color
Fills the arc with the specified color.

-outline => color
Specifies the color for the outline (default is black).

-stipple => bitmap
Specifies a bitmap to fill the oval with.

-tags => tagnames
Associates the oval with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-width => amount
The width of the outline (default is 1 pixel).

createPolygon
Creates a polygon. At least three sets of coordinates are required; the first point is automatically connected to the last point to complete the polygon.

$canvas -> createPolygon(0,0,130, 20, 90, -35);

Options are:

-fill => color
The color to use to fill the polygon.

-outline => color
Specifies the color of the outline (default is black).

-smooth => boolean
Determines whether the outline is drawn with a Bezier spine. Default is 0.

-splinesteps => n
Determines how smooth the Bezier curve is.

-stipple => bitmap
Fills the polygon with the specified bitmap pattern.

-tags => tagnames
Associates the polygon with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-width => amount
The width of the outline (default is 1 pixel).

createRectangle
Creates a rectangle. For example, to create a square with one corner at (0,0) and another at (100,100):

$canvas->createRectangle(0,0,100,100);

Options are:

-fill => color
The color to use to fill the rectangle.

-outline => color
Specifies the color of the outline (default is black).

-stipple => bitmap
Fills the rectangle with the specified bitmap pattern.

-tags => tagnames
Associates the rectangle with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-width => amount
The width of the outline (default is 1 pixel).

createText
Places text in a canvas widget. For example, to write "Broadway" centered at the position (130,-40):

$canvas->createText(130,-40, -text => "Broadway");

Options are:

-anchor => position
Anchors the text at the specified position. Values are center (default), n, e, s, w, ne, nw, se, and sw.

-fill => color
The color to use for the text.

-font => fontname
The font for the text.

-justify => position
The justification of the text (either left, right, or center). The default is left.

-stipple => bitmap
Fills the text with the specified bitmap pattern.

-tags => tagnames
Associates the text with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-text => string
Specifies the text to display.

-width => amount
The maximum length of each line of text. Default is 0, which means that lines are broken only at explicit newline characters.

There is a set of methods for manipulating text items within a Canvas widget. For each of these methods, the first argument is the tag name or tag ID, and subsequent arguments use text indexes as described for the Text widget.

dchars
Deletes characters from a text item, given the tag name or ID, and indexes of the first and last characters to delete

icursor
Places the insert cursor at the specified index

index
Gets a numerical index from a named one

insert
Adds a string to the text item

createWindow
Embeds another widget inside of a canvas. The widget must have been already created as a child of the canvas or of the canvas's parent. Options are:

-anchor => position
Anchors the widget at the specified position. Values are center (default), n, e, s, w, ne, nw, se, and sw.

-height => amount
Specifies the height of the widget.

-tags => tagnames
Associates the widget with the specified tag(s). Multiple tag names can be supplied as an anonymous list.

-width => amount
The width of the widget.

-window => $widget
Specifies the widget to embed.

21.12.2. Item Tags and IDs

Each item in a Canvas widget is given a unique ID when it is created. This ID is returned from the canvas creation command. In addition, each item can have a tag associated with it, either when created or with the addtag method. You can use either the ID or the tag to refer to an item in the canvas. Unlike IDs, tags do not have to be unique, which makes it possible to configure several items as a group.

Two special tags are created automatically. The "all" tag refers to all items in the canvas. The "current" tag refers to the item that the cursor is currently over, if any.

21.12.3. Canvas Methods

In addition to configure and cget, the following methods are supported by the Canvas widget:

addtag
Defines a tag for an already created canvas item. For example, to assign a tag called "everything" to all items in a canvas:

$canvas->addtag("everything", "all");

To assign the tag origin to the item closest to the coordinates (0,0):

$canvas->addtag("origin", "closest", 0, 0);

The full list of identifiers is:

above
Assigns the tag to the item above the specified item in the display list

all
Assigns the tag to all items in the canvas

below
Assigns the tag to the item below the specified item in the display list

closest
Assigns the tag to the item closest to the specified x,y coordinate

enclosed
Assigns the tag to all items that are completely enclosed within the specified bounding box

overlapping
Assigns the tag to all items that are even partially inside the specified bounding box

withtag
Assigns the tag to all items with the specified tag

bind
Binds a callback to an item. (To bind a callback to the Canvas widget itself, you must specify Tk::bind.)

bbox
Returns the bounding box of an item. For example, to get the bounding box for all items in the canvas:

$canvas->bbox("all");
itemconfigure
Configures one of the items within the canvas. Works just like the configure method for widgets, but the first argument is the tag name or ID for the canvas item.

itemcget
Gets configuration information for one of the items within the canvas. Works just like the cget method for widgets, but the first argument is the tag name or ID for the canvas item.

move
Moves an item on the canvas by adding the specified x and y distances to it:

$canvas->move("circle1", 100, 100);
coords
Gets the current x,y coordinates for an item, or moves an item to an explicit x,y coordinate.

lower
Sets the priority for the item in the display list to be lower than the item identified by the specified tag or ID.

raise
Sets the priority for the item in the display list to be higher than the item identified by the specified tag or ID.

delete
Removes an item from the canvas. You can specify as many tags or IDs in the argument list as you want.

find
Finds the specified items. The first argument can be any of:

above
Finds the item above the specified item in the display list

all
Finds all items in the canvas

below
Finds the item below the specified item in the display list

closest
Finds the item closest to the specified x,y coordinate

enclosed
Finds all items that are completely enclosed within the specified bounding box

overlapping
Finds all items that are even partially inside the specified bounding box

withtag
Finds all items with the specified tag

gettags
Retrieves a list of all tags associated with an item.

type
Determines the type of the specified item.

focus
Assigns the keyboard focus to the specified item.

postscript
Renders the canvas as PostScript. Options are:

-colormap => \@colorcommand
Specifies a PostScript command for setting color values.

-colormode => mode
Sets the mode to color (full color), gray (grayscale), or mono (black and white).

-file => filename
The name of the file to store the PostScript output.

-fontmap => \@fontspec
Specifies a font name and point size.

-height => size
The height of the area to print.

-pageanchor => position
The anchor position of the page. Values are center (default), n, e, s, and w.

-pageheight => height
The height of the printed page.

-pagewidth => width
The width of the printed page.

-pagex => x
The x positioning point.

-pagey => y
The y positioning point.

-rotate => boolean
Whether to rotate to landscape orientation. Default is 0.

-width => size
The width of the area to print.

-x => x
The left edge of the canvas.

-y => y
The top edge of the canvas.

scale
Changes the scaling of the canvas or any individual items. For example, to scale the entire canvas to half its dimensions:

$canvas->scale("all", 0, 0, .5, .5);
xview
Manipulates the canvas area in view. With no arguments, returns a list of two numbers between 0 and 1, defining the portion of the canvas that is currently hidden on the left and right sides, respectively. With arguments, the function of xview changes:

moveto
Moves the specified fraction of the text to the left of the visible portion.

scroll
Scrolls the canvas left or right by the specified number of units or pages. Used primarily as a callback to a scrollbar; pressing on an arrow would move by units (characters), and pressing on the trough would move by pages. The number is either 1 or -1, to move forwards or backwards, respectively.

yview
Manipulates the canvas in view. With no arguments, returns a list of two numbers between 0 and 1, defining that portion of the canvas that is currently hidden on the top and bottom, respectively. With arguments, its function changes:

moveto
Moves the specified fraction of the canvas area to the top of the visible portion.

scroll
Scrolls the canvas up or down by the specified number of units or pages. Used primarily as a callback to a scrollbar; pressing on an arrow would move by units (lines), and pressing on the trough would move by pages. The number is either 1 or -1, to move forwards or backwards, respectively.

Previous | Home | Next
21.11. The Text Widget | Book Index | 21.13. The Scale Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.13. The Scale Widget

Create a "slider" widget representing a numeric value with the Scale method.

$parent->Scale(options);

The standard configuration options that apply to Scale are: -activebackground, -background, -bg, -borderwidth, -bw, -cursor, -font, -foreground, -fg, -highlight-background, -highlightcolor, -highlightthickness, -relief, -state, -takefocus, and -width.

Other options are:

-bigincrement => amount
The amount to change the slider when using large increments. Default is 0, which means 1/10 of the scale.

-command => callback
Pointer to a function that will be called for every incremental change in the slider.

-digits => amount
The number of digits to keep when converting from a number to a string.

-from => n
Low end of the scale (default is 0).

-label => string
The string to use as a label for the slider.

-length => amount
The length of the scale.

-orient => direction
The orientation of the slider. Values can be either vertical (default) or horizontal.

-repeatdelay => milliseconds
Determines the number of milliseconds to hold down an arrow before it auto-repeats. Default is 300.

-repeatinterval => milliseconds
Determines the number of milliseconds between auto-repeats once it is started. Default is 100.

-resolution => value
The increments that the scale will change by (default is 1).

-showvalue => boolean
Whether to show the current value of the slider (default is 1).

-sliderlength => amount
The size of the slider. Default is 25 pixels.

-tickinterval => n
The number of "ticks" to display for the slider (default is 0).

-to => n
The top value of the scale (default is 100).

-troughcolor => color
Changes the color of the trough.

-variable => \$variable
Assigns the value of the slider to the specified variable.

21.13.1. Scale Methods

In addition to configure and cget, the following methods are defined for the Scale widget:

get
Returns the current value if given no arguments. If given x and y coordinates as the first and second arguments, returns the value of the scale at that position.

set
Assigns the value associated with the scale.

coords
Returns the x and y coordinates associated with the value given in the first argument.

identify
Returns "slider", "trough1", "trough2", or "", depending on which part of the scale corresponds to the given x, y coordinates.

Previous | Home | Next
21.12. The Canvas Widget | Book Index | 21.14. The Menubutton Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.14. The Menubutton Widget

Create a menubutton with the Menubutton method. For example:

$mainwindow->Menubutton(-text => "File",
        -menuitems => [ [ command => "New",
                            -command => \&newfile,
                          -underline => 0 ],
                           [ command => "Open",
                            -command => \&openfile,
                          -underline => 0 ],
                        "-",
                           [ command => "Save",
                            -command => \&savefile,
                          -underline => 0 ],
                           [ command => "SaveAs",
                            -command => \&saveasfile,
                          -underline => 4 ] ] );

The -menuitems option takes a list of lists describing the menu items. For each menu item, an embedded anonymous list describes the type of menu item, the label to use, and the action to take when it is selected along with any other options desired to configure the menu item. In this example, each of the menu items is the command type, and we use the -command option for each item to point to the callback to execute when the menu item is selected. We also use the -underline option to enable the user to select a menu item using keystrokes. (\[quotedbl]- represents a separator between menu items.)

In addition to command, other types of menus are:

cascade
Embeds a cascade menu

checkbutton
Treats the menu item as a checkbutton

radiobutton
Treats the menu item as a radiobutton

You can configure both the menu itself and the individual menu items. The configuration options that apply to Menubutton are: -activebackground, -active-foreground, -anchor, -background, -bg, -bitmap, -borderwidth, -bw, -cursor, -disa-bledforeground, -font, -foreground, -fg, -height, -highlightbackground, -high-lightcolor, -highlightthickness, -image, -justify, -padx, -pady, -relief, -state, -takefocus, -underline, -width, and -wraplength.

Other Menubutton options are:

-indicatoron => boolean
Determines whether to display an indicator.

-menu => $menu
Displays the menu associated with $menu.

-menuitems => list
Specifies items to create in the menu as a list of lists. See the description at the beginning of this section.

-tearoff => boolean
Whether to allow the menu to be "torn off." Default is 1.

-text => string
Specifies the text to display as a label for the button.

-textvariable => \$variable
Points to the variable containing text to be displayed in the menubutton. Button text will change as $variable does.

21.14.1. Menu Item Options

In addition to the menu itself, each individual menu item can be configured. The widget configuration options that apply to menu items are: -activebackground, -background, -bg, -bitmap, -font, -foreground, -fg, -image, -state, and -underline. Other options are:

-accelerator
Displays an accelerator key sequence for the menu item. The key sequence must be independently defined with a bind.

-command => callback
Pointer to a function that will be called when the menu item is selected.

-indicatoron => boolean
Determines whether to display an indicator.

-label => string
The string to use as a label for the menu item.

-menu => $submenu
For a cascade menu, points to the menu to embed.

-offvalue => newvalue
For a checkbutton, specifies the value used when the checkbutton is off.

-onvalue => newvalue
For a checkbutton, specifies the value used when the checkbutton is on.

-selectcolor => color
For a checkbutton or radiobutton, color of the indicator when on.

-selectimage => imgptr
For a checkbutton or radiobutton, defines the image to be displayed instead of text when the radiobutton is on. Ignored if -image is not used.

-value => value
For a radiobutton, sets $variable to the specified value when the radiobutton is selected (default is 1).

-variable => \$variable
Associates the value of the menu item to the specified variable.

21.14.2. Menubutton Methods

In addition to configure and cget, the following methods are defined for Menubutton widgets:

AddItems
Adds menu items to the end of the menu. The arguments to AddItems are lists configuring each menu item, similar to the lists defined with the -menuitem option.

$menubutton->AddItems([command => "Print",
                                       -command => \&printscreen ],
                                       [command => "Exit",
                                       -command => \&exitclean ]);
command
Adds a command item to the end of the menu. The above example could have read:

$menubutton->command(-label => "Print", -command => \&printscreen);
$menubutton->command(-label => "Exit", -command => \&exitclean);
checkbutton
Adds a checkbutton item to the end of the menu:

$menubutton->checkbutton(-label => "Show Toolbar",
           -variable => \$toolbar);
radiobutton
Adds a radiobutton item to the end of the menu:

$menubutton->radiobutton(-label => "Red", -variable => \$color);
$menubutton->radiobutton(-label => "Blue", -variable => \$color);
separator
Adds a separator line to the end of a menu.

cascade
Adds a cascade item to the end of the menu.

menu
Returns a reference to the menu.

entrycget
Gets information on a menu entry given an index and option to query.

entryconfigure
Changes information on a specific menu item given an index.

Previous | Home | Next
21.13. The Scale Widget | Book Index | 21.15. The Menu Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.15. The Menu Widget

Create a menu with the Menu method, to be displayed later with the post method.

$menu = $parent->Menu(options)

The standard configuration options that apply to Menu are: -activebackground, -activeforeground, -background, -bg, -borderwidth, -bw, -cursor, -disabledfore-ground, -font, -foreground, -fg, -relief, and -takefocus.

Other options are:

-activeborderwidth => amount
Sets the width of the edges for the active menu item.

-menuitems => list
Specifies items to create in the menu as a list of lists.

-postcommand => callback
The command to invoke before the menu is posted. For example, to update the state of the menu items.

-tearoff => boolean
Whether to allow the menu to be "torn off." Default is 1.

-selectcolor => color
Color of the selection box for checkbuttons or radiobuttons.

21.15.1. Menu Indexes

Menus have indexes for manipulating individual menu items. They are:

n
Menu item n, with 0 representing the first item

active
The current menu item

end or last
The last menu item

none
No menu item

@n
The menu item closest to the y coordinate specified by n

pattern
The first menu item with text that matches the pattern

21.15.2. Menu Methods

In addition to configure and cget, the following methods are defined for the Menu widget:

add
Adds items to the end of a menu. The first argument is the type of menu item to add, and additional arguments are options to the menu item. For example:

$menu = $mainwindow->Menu;
$menu->add( 'command', -label => "New", "-command" => \&newfile );
entrycget
Gets information on a specific menu item given an index.

entryconfigure
Changes information on a specific menu item given an index.

post
Displays the menu widget.

unpost
Removes the menu widget from display.

postcascade
Unposts a submenu and posts the cascade menu associated with the menu item at the specified index.

delete
Removes menu items from the menu.

index
Given a named index, returns the numerical index for that menu item.

insert
Inserts a menu item at the specified index. Same as add, except that it takes an index as the first argument.

invoke
Invokes the menu item at the specified index as if it was selected.

type
Returns the type of menu item at the specified index.

yposition
Returns the y coordinate of the topmost pixel of the menu item.

Previous | Home | Next
21.14. The Menubutton Widget | Book Index | 21.16. The Optionmenu Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.16. The Optionmenu Widget

Use the Optionmenu method to create an option menu, in which the selected item is the value displayed. For example:

$mainwindow->OptionMenu(-textvariable => \$platform,
        -options => [ [ "UNIX", "unix" ],
                      [ "Windows NT", "winnt" ],
                      [ "Macintosh", "mac" ] ]) -> pack;

The -options argument takes a list of menu items. If the descriptions of the menu items displayed are different from those of the values stored, the menu items are themselves written as two-item lists.

The standard configuration options that apply to Optionmenu are: -activeback-ground, -activeforeground, -background, -bg, -bitmap, -borderwidth, -bw, -cursor, -disabledforeground, -font, -foreground, -fg, -highlightbackground, -highlight-color, -highlightthickness, -image, -justify, -relief, -state, -takefocus, -un-derline, -width, and -wraplength.

Other options are:

-command => callback
The command to execute when a selection is made. Its arguments are the values of the -textvariable and -variable options.

-indicatoron => boolean
Determines whether to display an indicator.

-menu => $menu
Displays the menu associated with $menu.

-options => list
Lists the menu options, as described above.

-tearoff => boolean
Whether to allow the menu to be "torn off." Default is 1.

-text => string
Specifies the text to display as a label for the option menu.

-textvariable => \$variable
Points to the variable containing text to be displayed in the option menu.

-variable => \$variable
Points to a variable containing a stored value, distinct from the value shown in the option menu.

Previous | Home | Next
21.15. The Menu Widget | Book Index | 21.17. The Frame Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.17. The Frame Widget

Create a frame for enclosing other widgets using the Frame method. For example:

$parent->Frame( options )

The standard configuration options that apply to Frame are: -background, -bg, -borderwidth, -bw, -cursor, -height, -highlightbackground, -highlightcolor, -highlightthickness, -relief, -takefocus, and -width.

Other options are:

-class => name
The class associated with the frame.

-colormap => \$window
Specifies another window to share the colormap with. You can point to another window or use the value new to specify a new colormap. Default is undef.

-label => string
The string to use as a label for the frame.

-labelPack
Specifies options for the pack command.

-labelVariable => \$variable
Specifies a variable containing the text for the label.

-visual => type n
For the X Window System, changes the depth of colors.

Previous | Home | Next
21.16. The Optionmenu Widget | Book Index | 21.18. The Toplevel Widget
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.18. The Toplevel Widget

Create a toplevel widget, displayed independently from the main window with the same decoration as the window system, using the Toplevel method.

The standard configuration options that apply to Toplevel are: -background, -bg, -borderwidth, -bw, -cursor, -height, -highlightbackground, -highlightcolor, -highlightthickness, -relief, -takefocus, and -width.

Other options are:

-class => name
The class associated with the Toplevel widget.

-colormap => \$window
Specifies another window to share the colormap with. You can point to another window or use the value new to specify a new colormap. Default is undef.

-screen => screen
The screen to place the toplevel widget on.

-visual => type n
For the X Window System, changes the depth of colors.

21.18.1. Toplevel Methods

In addition to cget and configure, the following methods are supported by the Toplevel widget. Note that since the MainWindow is a Toplevel widget, each of these methods applies to the MainWindow as well.

aspect
Returns the constraints to the aspect of the window. The four-item list returned corresponds to the minimum width, the minimum height, the maximum width, and the maximum height.

client
Assigns a name to the toplevel window.

colormapwindows
For the X Window System, passes a list of windows to the window manager that have private colormaps. Controls the WM_COLORMAP_WINDOWS property.

command
For the X Window System, returns the command used to start the application.

deiconify
Displays an iconified window.

focusmodel
Gives up the keyboard focus to another window.

frame
Returns the ID of the parent widget as a hexadecimal string.

geometry
For the X Window System, gets the geometry of the Toplevel widget.

grid
Changes the size of the Toplevel's grid.

group
Makes the widget the group leader of a set of related windows.

iconbitmap
Identifies a bitmap to use as an icon when the window is iconified.

iconify
Iconifies the window.

iconmask
Specifies a mask for the icon bitmap.

iconname
Assigns text to be associated with the icon.

iconposition
Specifies a position for the icon on the desktop.

iconwindow
Specifies a widget to use in place of an icon when iconified.

maxsize
Specifies the largest size for the window.

minsize
Specifies the smallest size for the window.

overrideredirect
Removes window decorations from the window.

positionfrom
Returns either program or user to tell you whether the user or window manager requested its current position.

protocol
Given one of the window managers WM_DELETE_WINDOW, WM_SAVE_YOURSELF, or WM_TAKE_FOCUS, allows you to define a callback to execute when an associated event is detected.

resizable
Takes Boolean values representing whether the window can be resized in width and height, respectively.

sizefrom
Returns either program or user to tell you whether the user or window manager requested its current size.

state
Returns normal, iconic, or withdrawn, indicating the current state of the window.

title
Changes the title at the top of the window.

transient
Indicates to the window manager that the window is transient.

withdraw
Makes the window nonvisible.

Previous | Home | Next
21.17. The Frame Widget | Book Index | X. Win32
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part X. Win32

Chapter 22, "Win32 Modules and Extensions"

Chapter 23, "OLE Automation"

Chapter 24, "ODBC Extension for Win32"

Previous | Home | Next
21.18. The Toplevel Widget | Book Index | 22. Win32 Modules and Extensions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 22. Win32 Modules and Extensions

Contents:

Win32::Clipboard
Win32::Console
Win32::ChangeNotify
Win32::Eventlog
Win32::File
Win32::FileSecurity
Win32::Internet
Win32::IPC
Win32::Mutex
Win32::NetAdmin
Win32::NetResource
Win32::PerfLib
Win32::Pipe
Win32::Process
Win32::Registry
Win32::Semaphore
Win32::Service
Win32::Shortcut
Win32 Extensions

If you use Perl on a Win32 system, a number of extension modules are available to provide Windows-specific functionality. Extension modules consist of a regular module written in Perl and a library written in C or C++ that can implement native Windows calls. The core of available modules is bundled together as lib-win32 on CPAN, and with ActivePerl, Activestate's version of Perl for Win32. They provide such functionality as managing Windows processes, NT user administration, registry modification, and OLE automation.

The Win32 modules were originally written for Windows NT systems, so much of the functionality of the Win32 library is applicable only to Perl running on Windows NT. Many modules check to see which system they are on before installing. Many of the NT-specific modules such as NetAdmin and EventLog do not install at all on Windows 95. Modules such as Registry do their best to work on both systems, despite the differences in their registries.

This chapter covers most of the modules and extensions included in lib-win32 and distributed with ActivePerl. Additional Windows modules are available at CPAN.

The following modules are described in this chapter:

Win32::Clipboard
Provides Windows clipboard interaction

Win32::Console
Provides Windows console interaction

Win32::ChangeNotify
Creates and uses ChangeNotify objects

Win32::EventLog
Reads from and writes to the Windows NT event log

Win32::File
Manages file attributes (read-only, system, hidden, etc.)

Win32::FileSecurity
Manages ACLs in Perl

Win32::Internet
Provides extensions for Internet services

Win32::IPC
Waits for objects (processes, mutexes, semaphores)

Win32::Mutex
Creates and uses mutexes

Win32::NetAdmin
Administers users and groups

Win32::NetResource
Manages resources (servers, file shares, printers)

Win32::PerfLib
Accesses the Windows NT Performance Counter

Win32::Pipe
Creates a named pipe under Win32

Win32::Process
Starts and stops Win32 processes

Win32::Registry
Reads and manages the Win32 Registry

Win32::Semaphore
Creates and uses semaphores

Win32::Service
Manages Windows NT services

Win32::Shortcut
Provides shell link interface

In addition to this chapter, Chapter 23, "OLE Automation" covers the Win32::OLE modules, and Chapter 24, "ODBC Extension for Win32" covers the ODBC extension for Win32.

The reference material for the Clipboard, Console, Internet, and Shortcut modules was graciously provided by Aldo Capini, author and maintainer of many Win32 modules (http://dada.perl.it/).

22.1. Win32::Clipboard

The Win32::Clipboard module allows you to manipulate the Windows clipboard. You can use the clipboard as an object with the following syntax:

$clip = Win32::Clipboard( );

This functions as an implicit constructor. If you include a text string as an argument, that text will be placed on the clipboard. You can use the package-qualified method names instead of the object syntax, since the clipboard is a single entity:

$text = Win32::Clipboard::Get( );
Win32::Clipboard::Set("blah blah blah");
Win32::Clipboard::Empty( );

Alternatively, you can use the clipboard as an object with this syntax:

$Clip = Win32::Clipboard( );
$text = $Clip->Get( );
$Clip->Set("blah blah blah");
$Clip->Empty( );
Previous | Home | Next
X. Win32 | Book Index | 22.2. Win32::Console
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.2. Win32::Console

Win32::Console implements the Win32 console and character mode functions. They give you full control on the console input and output, including support of offscreen console buffers (e.g., multiple screen pages); reading and writing of characters, attributes, and whole portions of the screen; and complete processing of keyboard and mouse events.

The new constructor is used to create a console object. It can take two forms:

$con = Win32::Console->new(standard_handle);
$con = Win32::Console->new(accessmode, sharemode);

The first form creates a handle to a standard channel. standard_handle can be one of STD_OUTPUT_HANDLE, STD_ERROR_HANDLE, or STD_INPUT_HANDLE.

The second form creates a console screen buffer in memory, which you can access for reading and writing as a normal console, and then redirect on the standard output (the screen) with Display. In this case, you can specify accessmode to be GENERIC_READ, GENERIC_WRITE, or both, determining the permissions you will have on the created buffer.

sharemode affects how the console can be shared. It can be specified as either FILE_SHARE_READ, FILE_SHARE_WRITE, or both. If you don't specify any of those parameters, all four flags will be used.

The following methods are supported by the Win32::Console module.

Alloc
$cons->Alloc

Allocates a new console for the process. Returns undef on error or a nonzero value on success. A process cannot be associated with more than one console, so this method will fail if there is already an allocated console. Use Free to detach the process from the console, and then call Alloc to create a new console.

Attr
$cons->Attr([attr])

Gets or sets the current console attribute. This attribute is used by the Write method.

Cls
$cons->Cls([attr])

Clears the console with the specified attr, if given. Uses ATTR_NORMAL otherwise.

Cursor
$cons->Cursor([x, y, size, visible])

Gets or sets cursor position and appearance. Returns undef on error, or a four-element list containing x, y, size, and visible. x and y give the current cursor position.

Display
$cons->Display

Displays the specified console on the screen. Returns undef on error or a nonzero value on success.

FillAttr
$cons->FillAttr([value, number, col, row])

Fills the specified number of consecutive attributes, beginning at col, row, with the value specified. Returns the number of attributes filled, or undef on error.

FillChar
$cons->FillChar(char, number, col, row)

Fills the specified number of consecutive characters, beginning at col, row, with the character specified in char. Returns the number of characters filled, or undef on error.

Flush
$cons->Flush

Flushes the console input buffer. All the events in the buffer are discarded. Returns undef on error, a nonzero value on success.

Free
$cons->Free

Detaches the process from the console. Returns undef on error, a nonzero value on success.

GenerateCtrlEvent
$cons->GenerateCtrlEvent([type, processgroup])

Sends a break signal of the specified type to the specified process group. type can be one of CTRL_BREAK_EVENT or CTRL_C_EVENT, signaling, respectively, the pressing of Ctrl + Break and Ctrl-C. If not specified, type defaults to CTRL_C_EVENT. processgroup is the PID of a process sharing the same console. If omitted, it defaults to 0 (the current process), which is also the only meaningful value that you can pass to this function. Returns undef on error, a nonzero value on success.

GetEvents
$cons->GetEvents

Returns the number of unread input events in the console's input buffer, or undef on error.

Info
$cons->Info

Returns an array of information about the console, which contains:

  • Number of columns (X size) of the console buffer

  • Number of rows (Y size) of the console buffer

  • Current column (X position) of the cursor

  • Current row (Y position) of the cursor

  • Current attribute used for Write

  • Left column (X of the starting point) of the current console window

  • Top row (Y of the starting point) of the current console window

  • Right column (X of the final point) of the current console window

  • Bottom row (Y of the final point) of the current console window

  • Maximum number of columns for the console window, given the current buffer size, font, and screen size

  • Maximum number of rows for the console window, given the current buffer size, font, and screen size

This example prints the cursor's current position:

@info = $CONSOLE->Info( );
print "Cursor at $info[3], $info[4].0";
Input
$cons->Input

Reads an event from the input buffer. Returns a list of values, determined by the type of event. A keyboard event will contain the following values, in order:

  • Event type (1 for keyboard)

  • Key state—true if the key is being pressed, false if the key is being released

  • Repeat count—the number of times the key is held down

  • Virtual keycode of the key

  • Virtual scancode of the key

  • ASCII code of the character (if the key is a character key, 0 otherwise)

  • State of the control keys (Shifts, Ctrls, Alts, etc.)

A mouse event will return the following values, in order:

  • Event type (2 for mouse)

  • X coordinate (column) of the mouse location

  • Y coordinate (row) of the mouse location

  • Button state—the mouse button(s) that are pressed

  • State of the control keys (Shifts, Ctrls, Alts, etc.)

  • Event flags for the type of the mouse event

This method will return undef on error.

Note that the events returned depend on the input mode of the console; for example, mouse events are not intercepted unless ENABLE_MOUSE_INPUT is specified.

InputChar
$cons->InputChar(number)

Reads and returns number characters from the console input buffer, or returns undef on error.

InputCP
$cons->InputCP([codepage])

Gets or sets the input code page used by the console. Note that this doesn't apply to a console object, but to the standard input console. This attribute is used by the Write method.

MaxWindow
$cons->MaxWindow

Returns the size of the largest possible console window, based on the current font and the size of the display. The result is undef on error; otherwise, a two-element list containing the number of columns and rows is returned.

Mode
$cons->Mode([flags])

Gets or sets the input or output mode of a console. flags can be a combination of the following constants:

ENABLE_LINE_INPUT
ENABLE_ECHO_INPUT
ENABLE_PROCESSED_INPUT
ENABLE_WINDOW_INPUT
ENABLE_MOUSE_INPUT
ENABLE_PROCESSED_OUTPUT
ENABLE_WRAP_AT_EOL_OUTPUT
MouseButtons
$cons->MouseButtons

Returns the number of the buttons on your mouse, or undef on error.

OutputCP
$cons->OutputCP([codepage])

Gets or sets the output code page used by the console. Note that this doesn't apply to a console object, but to the standard output console. You may want to use the noninstantiated form to avoid confusion:

$codepage = Win32::Console::OutputCP( );
Win32::Console::OutputCP(437);
PeekInput
$cons->PeekInput

Does exactly the same as Input, except that the event read is not removed from the input buffer.

ReadAttr
$cons->ReadAttr([number, col, row])

Reads the specified number of consecutive attributes from the console, beginning at col, row. Returns the attributes read (a variable containing one character for each attribute), or undef on error. You can then pass the returned variable to WriteAttr to restore the saved attributes on screen.

ReadChar
$cons->ReadChar([number, col, row])

Reads the specified number of consecutive characters from the console, beginning at col, row. Returns a string containing the characters read, or undef on error. You can then pass the returned variable to WriteChar to restore the saved characters on screen.

ReadRect
$cons->ReadRect(left, top, right, bottom)

Reads the content (characters and attributes) of the rectangle specified by left, top, right, and bottom from the console. Returns a string containing the rectangle read, or undef on error. You can then pass the returned variable to WriteRect to restore the saved rectangle on screen (or on another console).

Scroll
$cons->Scroll(left, top, right, bottom, col, row, char, attr, [cleft, ctop, cright, cbottom])

Moves a block of data in a console buffer; the block is identified by the left, top, right, and bottom positions.

row and colidentify the new location of the block. The cells left empty as a result of the move are filled with the character char and attribute attr.

Optionally, you can specify a clipping region with cleft, ctop, cright, and cbottom so that the contents of the console outside this rectangle are unchanged. Returns undef on error or a nonzero value on success.

# Scrolls the screen 10 lines down, filling with black spaces
$CONSOLE->Scroll(0, 0, 80, 25, 0, 10, " ", $FG_BLACK | $BG_BLACK);
Select
$cons->Select(standard_handle)

Redirects a standard handle to the specified console. standard_handlecan have one of the following values:

STD_INPUT_HANDLE
STD_OUTPUT_HANDLE
STD_ERROR_HANDLE

Returns undef on error or a nonzero value on success.

Size
$cons->Size([col, row])

Gets or sets the console buffer size.

Title
$cons->Title([title])

Gets or sets the title bar string of the current console window.

Window
$cons->Window([flag, left, top, right, bottom])

Gets or sets the current console window size. If called without arguments, returns a four-element list containing the current window coordinates in the form of (left, top, right, bottom). To set the window size, you have to specify an additional flag parameter. If it is 0, coordinates are considered relative to the current coordinates; if it is nonzero, coordinates are absolute.

Write
$cons->Write(string)

Writes stringon the console, using the current attribute, which you can set with Attr, and advances the cursor as needed. This isn't that different from Perl's print statement. Returns the number of characters written, or undef on error.

WriteAttr
$cons->WriteAttr(attrs, col, row)

Writes the attributes contained in the string <attrs>, beginning at col, row, without affecting the characters that are on screen. The string attrs can be the result of a ReadAttr function, or you can build your own attribute string; in this case, keep in mind that every attribute is treated as a character, not a number (see example). Returns the number of attributes written, or undef on error.

$CONSOLE->WriteAttr($attrs, 0, 0);
# note the use of chr( )...
$attrs = chr($FG_BLACK | $BG_WHITE) x 80;
$CONSOLE->WriteAttr($attrs, 0, 0);
WriteChar
$cons->WriteChar(chars, col, row)

Writes the characters in the string attr, beginning at col, row, without affecting the attributes that are onscreen. The string characters can be the result of a ReadChar function or a normal string. Returns the number of characters written, or undef on error.

WriteInput
$cons->WriteInput(event)

Pushes data in the console input buffer. event is a list of values (for more information, see Input). The string characters can be the result of a ReadChar function or a normal string. Returns the number of characters written, or undef on error.

WriteRect
$cons->WriteRect(rect, left, top, right, bottom)

Writes a rectangle of characters and attributes (contained in rect) on the console at the coordinates specified by left, top, right, and bottom. rectcan be the result of a ReadRect function. Returns undef on error; otherwise, returns a four-element list containing the coordinates of the affected rectangle, in the format (left, top, right, bottom).

22.2.1. Constants

The following constants are exported in the main namespace of your script using Win32::Console:

BACKGROUND_BLUE                 BACKGROUND_GREEN
BACKGROUND_INTENSITY            BACKGROUND_RED
CAPSLOCK_ON                     CONSOLE_TEXTMODE_BUFFER
ENABLE_ECHO_INPUT               ENABLE_LINE_INPUT
ENABLE_MOUSE_INPUT              ENABLE_PROCESSED_INPUT
ENABLE_PROCESSED_OUTPUT         ENABLE_WINDOW_INPUT
ENABLE_WRAP_AT_EOL_OUTPUT       ENHANCED_KEY
FILE_SHARE_READ                 FILE_SHARE_WRITE
FOREGROUND_BLUE                 FOREGROUND_GREEN
FOREGROUND_INTENSITY            FOREGROUND_RED
LEFT_ALT_PRESSED                LEFT_CTRL_PRESSED
NUMLOCK_ON                      GENERIC_READ
GENERIC_WRITE                   RIGHT_ALT_PRESSED
RIGHT_CTRL_PRESSED              SCROLLLOCK_ON
SHIFT_PRESSED                   STD_INPUT_HANDLE
STD_OUTPUT_HANDLE               STD_ERROR_HANDLE

Additionally, the following variables can be used:

$FG_BLACK                       $FG_BLUE
$FG_LIGHTBLUE                   $FG_RED
$FG_LIGHTRED                    $FG_GREEN
$FG_LIGHTGREEN                  $FG_MAGENTA
$FG_LIGHTMAGENTA                $FG_CYAN
$FG_LIGHTCYAN                   $FG_BROWN
$FG_YELLOW                      $FG_GRAY
$FG_WHITE                       $BG_BLACK
$BG_BLUE                        $BG_LIGHTBLUE
$BG_RED                         $BG_LIGHTRED
$BG_GREEN                       $BG_LIGHTGREEN
$BG_MAGENTA                     $BG_LIGHTMAGENTA
$BG_CYAN                        $BG_LIGHTCYAN
$BG_BROWN                       $BG_YELLOW
$BG_GRAY                        $BG_WHITE
$ATTR_NORMAL                    $ATTR_INVERSE

ATTR_NORMAL is set to gray foreground on black background (DOS's standard colors).

Previous | Home | Next
22. Win32 Modules and Extensions | Book Index | 22.3. Win32::ChangeNotify
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.3. Win32::ChangeNotify

This module provides access to Win32 change-notification objects, letting you monitor events relating to files and directory trees. The constructor for this class is new, which creates a ChangeNotify object for a specified path and indicates how it should be monitored:

$ntfy = Win32::ChangeNotify->new(path, subtree, events);
$ntfy->wait or warn "Something has failed: $!");

The function returns a reference to the object as $ntfy. path is the pathname of the directory to monitor. subtree is a Boolean value that, if true, forces the object to monitor all subdirectories of the object's path. The eventsparameter indicates the type of events that will trigger a notification. It can be one of the following string values:

Value | Description
ATTRIBUTES | Any attribute change
DIR_NAME | Any directory name change
FILE_NAME | Any filename change (creating/deleting/renaming)
LAST_WRITE | Any change to a file's last write time
SECURITY | Any security descriptor change
SIZE | Any change in a file's size

The following methods are used on notification objects created by new.

close
$ntfy->close(  )

Stops the monitoring done by the notification object and destroys the object. This happens automatically when the program exits.

reset
$ntfy->reset(  )

Resets the object to begin monitoring again after a change has occurred.

wait
$ntfy->wait([timeout])

The wait method is inherited from the Win32::IPC package. It waits for the notification object to signal when it detects a change. timeout is the maximum time to wait (in milliseconds). If timeout is omitted, the method waits forever. If timeout is 0, the function returns immediately. The function returns the following values:

+1
The object is signaled.

0
Timed out.

undef
An error occurred.

Use reset on the object after wait if you wish to continue monitoring.

Previous | Home | Next
22.2. Win32::Console | Book Index | 22.4. Win32::Eventlog
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.4. Win32::Eventlog

This module makes the Windows NT event log accessible to your Perl programs. It allows you to create new records, read records, and create backup logfiles. The new constructor opens a server's event log as an object:

$log = Win32::EventLog->new(source, [server]);

This function opens an event log and returns an object reference. source specifies the name of the source event, and server specifies the name of the server (local is assumed if no server name is given).

Many of the methods for this module require a reference to an empty variable as an argument. This is how the return value of the method will be placed, whether it is a hash or a scalar. The following methods can be used on event log objects.

Backup
$log->Backup(filename)

Saves the current open event log to a file named by filename.

Clear
$log->Clear([filename])

Writes the current event log to the file filename (if supplied) and clears the event log.

GetNumber
$log->GetNumber(\$number)

Returns the number of events as the value of the scalar variable number.

GetOldest
$log->GetOldest(\$record)

Returns the record number of the oldest record in the event log to the scalar $record.

Read
$log->Read(flags, offset, \%eventinfo)

Reads an entry from the event log and returns the information in the eventinfo hash. offset specifies the record number you want to start at in the log. flags sets options for how you want to read the log, which can be any combination of the following:

EVENTLOG_FORWARDS_READ
Eventlog is read in forward chronological order.

EVENTLOG_BACKWARDS_READ
Eventlog is read in reverse chronological order.

EVENTLOG_SEEK_READ
The read begins at the record specified by the $RecordOffset parameter. Must also specify EVENT_LOG_FORWARDS_READ or EVENTLOG_BACKWARDS_READ.

EVENTLOG_SEQUENTIAL_READ
The read continues sequentially from the last read call.

The final argument is the output object for the event read. eventinfo is a reference to a hash that contains keys for each part of the event description. This same structure is used when you report new events to the event log using the Report method. The eventinfo hash looks like this:

%event = (
    EventID             => val,
    EventType           => val,
    Category            => val,
    ClosingRecordNumber => val,
    Source              => val,
    Computer            => val,
    Strings             => val,
    Data                => val,
);
Report
$log->Report(\%eventinfo)

Reports an event to the event log. The information for the event to be recorded is given in a hash, %eventinfo, which should contain values for at least the following keys:

EventType
A string describing the type of event to be reported. The options for EventType are:

EVENTLOG_ERROR_TYPE          Error event
EVENTLOG_WARNING_TYPE        Warning event
EVENTLOG_INFORMATION_TYPE    Information event
EVENTLOG_AUDIT_SUCCESS_TYPE  Success Audit event
EVENTLOG_AUDIT_FAILURE_TYPE  Failure Audit event
Category
An integer value for the category of the event, defined by the application.

EventID
Source-specific ID for the event.

Data
Raw binary data for the event.

Strings
Any text strings to merge that provide a description of the event.

Previous | Home | Next
22.3. Win32::ChangeNotify | Book Index | 22.5. Win32::File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.5. Win32::File

The Win32::File module allows you to view or set the attributes for files. There are two functions that allow you to do this, which must be explicitly imported to your namespace:

use Win32::File qw/GetAttributes SetAttributes/;

The constant values for the attributes are exported by default.

GetAttributes
GetAttributes (filename, \$atts)

Returns the attribute settings for file filename and saves them as the variable referenced by $atts, which will contain an ORed combination of one or more of the following values:

ARCHIVE
DIRECTORY
HIDDEN
NORMAL
READONLY
SYSTEM
SetAttributes
SetAttributes (filename, atts)

Sets the attributes for the file filename to the values contained in atts. The attributes are given as an ORed combination of one or more of the attribute values shown above.

Previous | Home | Next
22.4. Win32::Eventlog | Book Index | 22.6. Win32::FileSecurity
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.6. Win32::FileSecurity

The Win32::FileSecurity module allows you to work with NT File System (NTFS) file permissions. File permissions are stored as Discretionary Access Control Lists (DACLs) for each file or directory. These lists contain a bitmask specifying the permission rights for users on the file or directory. This module implements a DACL as a permissions hash in which each key is a username, and the value is the bitmask for the permissions.

The FileSecurity module exports the following constants to describe user permissions:

ACCESS_SYSTEM_SECURITY     READ or R
CHANGE or C                SPECIFIC_RIGHTS_ALL
DELETE                     STANDARD_RIGHTS_ALL
FULL or F                  STANDARD_RIGHTS_EXECUTE
GENERIC_ALL                STANDARD_RIGHTS_READ
GENERIC_EXECUTE            STANDARD_RIGHTS_REQUIRED
GENERIC_READ               STANDARD_RIGHTS_WRITE
GENERIC_WRITE              SYNCHRONIZE
MAXIMUM_ALLOWED            WRITE_DAC
READ_CONTROL               WRITE_OWNER

Using the constant function on one of these constants gives its value, and bitmasks or multiple permissions settings can be made by supplying a list of these constants to the MakeMask function.

The following functions are exported by the Win32::FileSecurity module.

constant
constant (name $val)

Takes the name of a permission constant and saves its value in the variable val.

EnumerateRights
EnumerateRights (mask, \@rights)

Takes a permissions bitmask (as returned by MakeMask or constant) and saves the corresponding list of string constants in rights.

Get
Get (filename, \%permissions)

Gets the access control list for filename (or directory) and saves in the specified permissions hash.

MakeMask
MakeMask (stringlist)

Takes a list of permission string constants and returns the bitmask.

Set
Set (filename, \%permissions)

Sets the access control list for the given filename (or directory) to the settings in the specified permissionshash.

Previous | Home | Next
22.5. Win32::File | Book Index | 22.7. Win32::Internet
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.7. Win32::Internet

The Win32::Internet extension implements the Win32 Internet APIs (found in WININET.DLL), providing support for HTTP, FTP, and Gopher connections.

All types of connections start as a basic Internet connection that must be opened with the following command:

use Win32::Internet;
$Connection = Win32::Internet->new( );

This creates an Internet object in Perl on which you use the functions provided in this module to create more specific connection objects. The objects and functions that create them are:

  • Internet connections (the main object, with new)

  • URLs (with OpenURL)

  • FTP sessions (with FTP)

  • HTTP sessions (with HTTP)

  • HTTP requests (with OpenRequest)

This module provides different levels of implementation of the Win32 Internet functions. Some routines use several Win32 API functions to perform a complex task in a single call; they are simpler to use, but less powerful. Other functions implement nothing more and nothing less than the corresponding API function, so you can use all of their power, but with some additional programming steps.

For example, the function FetchURL fetches the contents of any HTTP, FTP, or Gopher URL with a simple command:

$inet = new Win32::Internet( );
$file = $inet->FetchURL("http://www.yahoo.com");

You can achieve the same result with this series of commands, which is what FetchURL actually does:

$inet = new Win32::Internet( );
$url = $inet->OpenURL("http://www.yahoo.com");
$file = $url->ReadFile( );
$url->Close( );

22.7.1. General Internet Methods

The methods described in this section are used on Internet connection objects created with new:

$inet = Win32::Internet->new( );

You can supply new with an optional list of arguments (or a reference to a hash containing them) that looks like this:

Win32::Internet->new [useragent, opentype, proxy, proxybypass, flags]
Win32::Internet->new [$hashref]

The parameters and their values are:

useragent
The user agent string passed to HTTP requests. Default is Perl-Win32Internet/version.

opentype
How to access the Internet (e.g., directly or using a proxy). Default is INTERNET_OPEN_TYPE_DIRECT.

proxy
Name of the proxy server (or servers) to use. Default is none.

proxybypass
Optional list of hostnames or IP addresses that are known locally. Default is none.

flags
Additional flags affecting the behavior of the function. Default is none.

If you pass a hash reference to the function, the following values are taken from the hash:

%hash=(
  "useragent"   => "useragent",
  "opentype"    => "opentype",
  "proxy"       => "proxy",
  "proxybypass" => "proxybypass",
  "flags"       => flags,
);

The following methods can be used on Internet connection objects.

CanonicalizeURL
$inet->CanonicalizeURL(URL, [flags])

Converts a URL to a canonical format, which includes converting unsafe characters to escape sequences. Returns the canonicalized URL, or undef on error. For the possible values of flags, refer to the Microsoft Win32 Internet Functions documentation.

Close
$inet->Close([$obj])

Closes an Internet connection. This can be applied to any Win32::Internet object. Note that it is not strictly required to close the connections you create, since the Win32::Internet objects are automatically closed when the program ends (or when such an object is destroyed by other means).

CombineURL
$inet->CombineURL(baseURL, relativeURL, [flags])

Combines a base and relative URL into a single URL. Returns the (canonicalized) combined URL, or undef on error. For the possible values of flags, refer to the Microsoft Win32 Internet Functions documentation.

ConnectBackoff
$inet->ConnectBackoff([value])

Reads or sets the delay value, in milliseconds, to wait between connection retries. If no value parameter is specified, the current value is returned; otherwise, the delay between retries is set.

ConnectionRetries
$inet->ConnectRetries([value])

Reads or sets the number of times a connection is retried before considering it failed. If no value parameter is specified, the current value is returned; otherwise, the number of retries is set. The default value is 5.

ConnectTimeout
$inet->ConnectTimeout([value])

Reads or sets the timeout value (in milliseconds) before a connection is considered failed. If no value parameter is specified, the current value is returned; otherwise, the timeout is set to value. The default value is infinity.

ControlReceiveTimeout
$inet->ControlReceiveTimeout([value])

Reads or sets the timeout value (in milliseconds) to use for non-data (control) receive requests before they are canceled. Currently, this value has meaning only for FTP sessions. If no value parameter is specified, the current value is returned; otherwise, the timeout is set. The default value is infinity.

ControlSendTimeout
$inet->ControlSendTimeout([value])

Reads or sets the timeout value (in milliseconds) to use for non-data (control) send requests before they are canceled. Currently, this value has meaning only for FTP sessions. If no value parameter is specified, the current value is returned; otherwise, the timeout is set. The default value is infinity.

CrackURL
$inet->CrackURL(URL, [flags])

Splits a URL into its component parts and returns them in an array. Returns undef on error. The array will contain the following values: (scheme, host, port, username, password, path, extrainfo). For example, the URL http://www.divinf.it/index.html#top can be split into:

http, www.divinf.it, 80, anonymous, dada@divinf.it, /index.html, #top

If you don't specify a flags parameter, ICU_ESCAPE will be used by default; for the possible values of flags, refer to the Microsoft Win32 Internet Functions documentation.

CreateURL
$inet->CreateURL(scheme, hostname, port, username, password, path, extrainfo, [flags])
$inet->CreateURL($hashref, [flags])

Creates a URL from its component parts. Returns undef on error and the created URL if successful. If you pass a hash reference, the following values are taken from the array:

%hash=(
  "scheme"    => "scheme",
  "hostname"  => "hostname",
  "port"      => port,
  "username"  => "username",
  "password"  => "password",
  "path"      => "path",
  "extrainfo" => "extrainfo",
);

If you don't specify a flags parameter, ICU_ESCAPE will be used by default; for the other possible values of flags, refer to the Microsoft Win32 Internet Functions documentation.

DataReceiveTimeout
$inet->DataReceiveTimeout([value])

Reads or sets the timeout value (in milliseconds) to use for data receive requests before they are canceled. If no value parameter is specified, the current value is returned; otherwise, the timeout is set. The default value is infinity.

DataSendTimeout
$inet->DataSendTimeout([value])

Reads or sets the timeout value (in milliseconds) to use for data send requests before they are canceled. If no value parameter is specified, the current value is returned; otherwise, the timeout is set. The default value is infinity.

Error
$inet->Error(  )

Returns the last recorded error in the form of an array or string (depending on the context) containing the error number and an error description. Can be applied on any Win32::Internet object (FTP sessions, etc.). There are three types of errors you can encounter, recognizable by the error number returned:

-1
A "trivial" error has occurred in the package. For example, you tried to use a method on the wrong type of object.

1-11,999
A generic error has occurred, and the Win32::GetLastError error message is returned.

12,000 and higher
An Internet error has occurred, and the extended Win32 Internet API error message is returned.

FetchURL
$inet->FetchURL(URL)

Fetches the content of an HTTP, FTP, or Gopher URL. Returns the contents of the file read (or undef if there was an error and nothing was read).

FTP
$inet->FTP($ftpobject, server, username, pwd, [port, pasv, context])
$inet->FTP($ftpobject, $hashref)

Opens an FTP connection to server, logging in with the given username and password. The new connection object is saved to ftpobject. The parameters and their values are:

server
The server to connect to.

username
The username used to log in to the server. Default is anonymous.

pwd
The password used to log in to the server. Default is none.

port
The port of the FTP service on the server. Default is 21.

pasv
If it is a value other than 0, use passive transfer mode. Otherwise, it is taken from the parent Internet connection object; you can set this value with the Pasv method.

context
A number to identify this operation if it is asynchronous. See SetStatusCallback and GetStatusCallback for more info on asynchronous operations.

If you pass a hash reference, the following values are taken from the hash:

%hash=(
  "server"   => "server",
  "username" => "username",
  "password" => "password",
  "port"     => port,
  "pasv"     => pasv,
  "context"  => context,
);

The FTP method returns undef if the connection failed, a number otherwise. You can then call any of the FTP functions as methods of the newly created FTP object.

GetResponse
$inet->GetResponse(  )

Returns the text sent by a remote server in response to the last function executed. It applies to any Win32::Internet object, particularly FTP sessions.

GetStatusCallback
$inet->GetStatusCallback(context)

Returns information about the progress of the asynchronous operation identified by context; this information consists of two values: a status code (one of the INTERNET_STATUS_* constants) and an additional value depending on the status code. For example, if the status code returned is INTERNET_STATUS_HANDLE_CREATED, the second value will hold the handle just created. For more information on these values, refer to the Microsoft Win32 Internet Functions documentation.

HTTP
$inet->HTTP(httpobject, server, username, password, [port, flags, context])
$inet->HTTP($httpobject, $hashref)

Opens an HTTP connection to server, logging in with the given username and password. The new connection object is saved as httpobject. The parameters and their values are:

server
The server to connect to.

username
The username used to log in to the server. Default is anonymous.

password
The password used to log in to the server. Default is none.

port
The port of the HTTP service on the server. Default is 80.

flags
Additional flags affecting the behavior of the function.

context
A number to identify this operation if it is asynchronous.

If you pass a hash reference, the following values are taken from the hash:

%hash=(
  "server"   => "server",
  "username" => "username",
  "password" => "password",
  "port"     => port,
  "flags"    => flags,
  "context"  => context,
);

The HTTP method returns undef if the connection failed, a number otherwise. You can then call any of the HTTP functions as methods of the newly created httpobject.

OpenURL
$inet->OpenURL(urlobject, URL)

Opens a connection to an HTTP, FTP, or Gopher URL. Returns undef on error, or a number if the connection was successful. You can then retrieve the URL content by applying the methods QueryDataAvailable and ReadFile on the newly created urlobject. See also FetchURL.

Password
$inet->Password([password])

Reads or sets the password used for an FTP or HTTP connection. If no password parameter is specified, the current value is returned.

QueryDataAvailable
$inet->QueryDataAvailable(  )

Returns the number of bytes of data available to be read immediately by a subsequent call to ReadFile (or undef on error). Can be applied to URL or HTTP request objects.

QueryOption
$inet->QueryOption(option)

Queries an Internet option. For the possible values of option, refer to the Microsoft Win32 Internet Functions documentation.

ReadEntireFile
$inet->ReadEntireFile(  )

Reads all the data available from an opened URL or HTTP request object. Returns what has been read, or undef on error.

ReadFile
$inet->ReadFile(bytes)

Reads and returns the specified number of bytes of data from an opened URL or HTTP request object. Returns undef on error. Be careful to keep bytes to an acceptable value.

SetOption
$inet->SetOption(option, value)

Sets an Internet option. For the possible values of option, refer to the Microsoft Win32 Internet Functions documentation.

SetStatusCallback
$inet->SetStatusCallback(  )

Initializes the callback routine used to return data about the progress of an asynchronous operation. This is one of the steps required to perform asynchronous operations; the complete procedure is:

# Use the INTERNET_FLAG_ASYNC when initializing
$params{'flags'}=INTERNET_FLAG_ASYNC;
$inet = new Win32::Internet(params);

# Initialize the callback routine
$inet->SetStatusCallback( );

# Specify the context parameter (the last 1 in this case)
$inet->HTTP($http, "www.yahoo.com", "anonymous", "dada\@divinf.it",
            80, 0, 1);

At this point, control returns immediately to Perl, and $inet->Error( ) will return 997, which means an asynchronous I/O operation is pending. Now, you can call:

$http->GetStatusCallback(1);

in a loop to verify what's happening; see also GetStatusCallback.

TimeConvert
$inet->TimeConvert(time)

Takes an HTTP date/time string and returns the date/time converted in the following array: (seconds, minutes, hours, day, month, year, day_of_week).

UserAgent
$inet->UserAgent([name])

Reads or sets the user agent name used for HTTP requests. If no name is specified, the current value is returned.

Username
$inet->Username([name])

Reads or sets the username used for an FTP or HTTP connection. If no name parameter is specified, the current value is returned.

Version
$inet->Version(  )

Returns the version numbers for the Win32::Internet package and the WININET.DLL version, as an array or string, depending on the context. The string returned will contain package_version/DLL_version, while the array will contain: package_version, DLL_version. For example:

$version = $inet->Version( );
# Should return "0.06/4.70.1215"
@version = $inet->Version( );
# Should return ("0.06", "4.70.1215")

22.7.2. FTP Functions

The methods described in this section are used to control FTP sessions. They apply to FTP session objects created by the FTP method on an Internet connection object. FTP creates an open FTP session and assigns it to an object ($FTP):

use Win32::Internet;
$inet = new Win32::Internet( );
$inet->FTP($FTP, "hostname", "username", "password");

The following methods are used on FTP session objects.

Ascii
$FTP->Ascii(  )
$FTP->Asc(  )

Sets the ASCII transfer mode for this FTP session. It will be applied to subsequent Get functions.

Binary
$FTP->Binary(  )
$FTP->Bin(  )

Sets the binary transfer mode for this FTP session. It will be applied to subsequent Get functions.

Cd
$FTP->Cd(path)
$FTP->Cwd(path)
$FTP->Chdir(path)

Changes the current directory on the FTP remote host. Returns path, or undef on error.

Delete
$FTP->Delete(file)
$FTP->Del(file)

Deletes fileon the FTP remote host. Returns undef on error.

Get
$FTP->Get(file, [local, overwrite, flags, context])

Gets the remote FTP file and saves it locally in local. If localis not specified, it will be the same name as file. Returns undef on error. The parameters and their values are:

file
The name of the remote file on the FTP server.

local
The name of the local file to create.

overwrite
If 0, overwrites localif it exists. With any other value, the function fails if the local file already exists. Default is 0.

flags
Additional flags affecting the behavior of the function. None by default.

context
A number to identify this operation if it is asynchronous. (See SetStatusCallback and GetStatusCallback for more information on asynchronous operations.) None by default.

List
$FTP->List([pattern, listmode])
$FTP->Ls([pattern, listmode])
$FTP->Dir([pattern, listmode])

Returns a list containing the files found in the current directory, matching the given pattern, if specified. The content of the returned list depends on the listmodeparameter, which can have the following values:

1 (default)
The list contains the names of the files found.

2
The list contains seven values for each file:

  • The filename

  • The DOS short filename, a.k.a. 8.3

  • The size

  • The attributes

  • The creation time

  • The last access time

  • The last modified time

3
The list contains a reference to a hash for each found file. Each hash contains the following key/value pairs:

name => filename
altname => DOS short filename, a.k.a. 8.3
size => size
attr => attributes
ctime => creation time
atime => last access time
mtime => last modified time

All times are reported as strings of the following format: second, hour, minute, day, month, year. For example:

$file->{'mtime'} == "0,10,58,9,12,1996"
# Stands for 09 Dec 1996 at 10:58:00
Mkdir
$FTP->Mkdir(name)
$FTP->Md(name)

Creates the directory name on the FTP remote host. Returns undef on error.

Mode
$FTP->Mode([mode])

If called with no arguments, returns the current transfer mode for this FTP session (asc for ASCII or bin for binary). The mode argument can be asc or bin, in which case the appropriate transfer mode is selected. Returns undef on error.

Pasv
$FTP->Pasv([mode])

If called with no arguments, returns 1 if the current FTP session has passive transfer mode enabled; 0 if not. You can call it with a mode parameter (0/1) only as a method of a Internet object, in which case it will set the default value for the next FTP object you create (i.e., set it before, because you can't change this value once you open the FTP session).

Put
$FTP->Put(file, [remote, context])

Uploads the local file to the FTP server, saving it under the name remote, which, if omitted, is the same name as file. Returns undef on error. contextis a number to identify this operation if it is asynchronous. See SetStatusCallback and GetStatusCallback for more information on asynchronous operations.

Pwd
$FTP->Pwd(  )

Returns the current directory on the FTP server, or undef on error.

Rename
$FTP->Rename(oldfile, newfile)
$FTP->Ren(oldfile, newfile)

Renames a file on the FTP remote host. Returns undef on error.

Rmdir
$FTP->Rmdir(name)
$FTP->Rd(name)

Removes the directory name on the FTP remote host. Returns undef on error.

22.7.3. HTTP Functions

The methods described in this section are used to create and control an HTTP session. Open an HTTP session using the HTTP method on an Internet connection object:

use Win32::Internet;
$inet = new Win32::Internet( );
$inet->HTTP($http, "hostname", "username", "password");

This opens the session and creates the HTTP session object $http. The following methods can be used on HTTP session objects.

AddHeader
$request->AddHeader(header, [flags])

Adds HTTP request headers to an HTTP request object created with OpenRequest. For the possible values of flags, refer to the Microsoft Win32 Internet Functions documentation.

OpenRequest
$http->OpenRequest(requestobject, [path, method, version,
referer, accept, flags, context])
$http->OpenRequest($requestobject, hashref)

Opens an HTTP request and saves it as $requestobject. Returns undef on error, or a number if the connection was successful. You can then use one of the AddHeader, SendRequest, QueryInfo, QueryDataAvailable, and ReadFile methods on the newly created requestobject. The optional parameters and their values are:

path
The object to request. This is generally a filename, an executable module, etc. The default is /.

method
The method to use, which can be GET, POST, HEAD, or PUT. Default is GET.

version
The HTTP version. Default is HTTP/1.0.

referer
The URL of the document from which the URL in the request was obtained.

accept
The content types accepted. They must be separated by a \0 (ASCII zero). Default types are text/* image/gif image/jpeg.

flags
Additional flags affecting the behavior of the function.

context
A number to identify this operation if it is asynchronous. See SetStatusCallback and GetStatusCallback for more information on asynchronous operations.

A reference to a hash containing the previous list of parameters can also be supplied to this method:

%hash=(
  "path"        => "path",
  "method"      => "method",
  "version"     => "version",
  "referer"     => "referer",
  "accept"      => "accept",
  "flags"       => flags,
  "context"     => context,
);
QueryInfo
$request->QueryInfo(header, [flags])

Queries information about an HTTP request object ($request) created with OpenRequest. You can specify a header (for example, Content-type) and/or one or more flags. If you don't specify flags, HTTP_QUERY_CUSTOM will be used by default; this means that the header should contain a valid HTTP header name. For the possible values of flags, refer to the Microsoft Win32 Internet Functions documentation.

Request
$http->Request([path, method, version, referer, accept, flags])
$http->Request(hashref)

Performs an HTTP request and returns an array containing the status code, the headers, and the content of the file. It is a one-step procedure that executes OpenRequest, SendRequest, QueryInfo, ReadFile, and finally, Close. For a description of the parameters, see OpenRequest.

SendRequest
$request->SendRequest([postdata])

Sends an HTTP request to the destination server. postdata contains any optional data to send immediately after the request header; this is generally used for POST or PUT requests. Your request object must contain the following content header for post data to be processed. You can add the header with AddHeader:

...
$request->AddHeader("Content-Type: application/x-www-form-urlencoded");
$request->SendRequest("key1=value1&key2=value2&key3=value3");
Previous | Home | Next
22.6. Win32::FileSecurity | Book Index | 22.8. Win32::IPC
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.8. Win32::IPC

The Win32::IPC module provides synchronization for multiple objects created from the Semaphore, Mutex, Process, and ChangeNotify classes. The wait method of this class is inherited by objects of the preceding modules, as well as the functions wait_all and wait_any. You should not need to call Win32::IPC directly.

wait
$obj->wait([timeout])

This method is used on any synchronization object. It waits for the object to become signaled. It returns 1 if the object is signaled, -1 if the object is an abandoned mutex, 0 if the call times out, and undef on error. timeoutis the time to wait (in milliseconds). If no timeout is specified, the method waits indefinitely.

Win32::IPC also defines the two functions wait_all and wait_any.

wait_all
wait_all(@objects, [timeout])

Waits for all the synchronization objects contained in @objects to be signaled. The optional timeout parameter is the same as described for wait. The return value will be an integer that identifies the last object to be signaled (the nth object in the list, starting from 1). A negative integer (-n) indicates that the nth object was an abandoned mutex. A return of 0 means that the function timed out; undef is returned on error.

wait_any
wait_any(@objects, [timeout])

Waits for at least one of the objects contained in @objects to be signaled. Return values are the same as for wait_all, above, indicating which object signaled.

Previous | Home | Next
22.7. Win32::Internet | Book Index | 22.9. Win32::Mutex
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.9. Win32::Mutex

This module provides access to Win32 mutex objects, which control access to common resources. The new constructor creates the mutex and determines its initial availability. It has the following syntax:

$mut = Win32::Mutex->new(init, [name]);

The first argument determines the initial status of the mutex. If init is nonzero, the calling process has immediate ownership of the mutex object. A 0 value means that the mutex is available. The second argument assigns a name to the mutex that allows this object to be referenced by others via the open function.

Another object constructor for Win32::Mutex is open:

$mut = Win32::Mutex->open(name);

This call creates a new mutex object to access an existing mutex identified by name.

The following methods can be used on Win32::Mutex objects.

release
$mut->Release(  )

Releases ownership of the mutex from the calling process, allowing anyone waiting on the mutex to take ownership.

wait
$mut->wait([timeout])

The Win32::IPC method inherited by this module. Makes the calling process wait for ownership of the mutex object for the number of milliseconds specified by timeout. If the mutex doesn't become available before the timeout, the call returns 0.

Previous | Home | Next
22.8. Win32::IPC | Book Index | 22.10. Win32::NetAdmin
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.10. Win32::NetAdmin

The Win32::NetAdmin module provides extensive functionality for administering users and groups on Windows NT servers. This module does not implement an object interface for administration; it exports several functions that execute administrative commands. (This module does not load on Windows 95 systems.)

The following functions are provided by the Win32::NetAdmin module. The server argument of each function is optional; however, a placeholder for the argument must be used if you don't supply a name. An empty string ("") will work, indicating that the local machine should be used.

GetDomainController
GetDomainController (server, domain, $name)

Returns the name of the domain controller for the specified server and domain to the variable $name.

GroupAddUsers
GroupAddUsers (server, name, users)

Adds users to group name on server. userscan be a list of usernames or a list variable containing multiple usernames.

GroupCreate
GroupCreate (server, name, comment)

Creates a group with the specified name on server. commentis a string used to provide a description about the group.

GroupDelete
GroupDelete (server, name)

Deletes a group named name from server.

GroupDeleteUsers
GroupDeleteUsers (server, name, users)

Deletes a list of users from the group name on server.

GroupGetAttributes
GroupGetAttributes (server, name, comment)

Returns the comment for group name on server to the variable comment.

GroupGetMembers
GroupGetMembers (server, name, $users)

Returns the usernames that are members of group name on serverto the array referenced by users.

GroupIsMember
GroupIsMember (server, name, user)

Queries group name on server to see if user is a member. Returns true if user is a member, false if not.

GroupSetAttributes
GroupSetAttributes (server, name, comment)

Sets the comment for group name on server to the string provided in comment.

LocalGroupAddUsers
LocalGroupAddUsers (server, name, users)

Adds users to local group name on server. userscan be a list of usernames or a list variable containing multiple usernames.

LocalGroupCreate
LocalGroupCreate (server, name, comment)

Creates a local group with the specified name on server. comment is a string used to provide a description about the group.

LocalGroupDelete
LocalGroupDelete (server, name)

Deletes a local group named name from server.

LocalGroupDeleteUsers
LocalGroupDeleteUsers (server, name, users)

Deletes a list of users from the local group name on server.

LocalGroupGetAttributes
LocalGroupGetAttributes (server, name, $comment)

Returns the comment for local group nameon server to the variable $comment.

LocalGroupGetMembers
LocalGroupGetMembers (server, name, \@users)

Returns the usernames that are members of local group name on serverto the array referenced by users.

LocalGroupIsMember
LocalGroupIsMember (server, name, user)

Queries local group name on server to see if user is a member. Returns true if user is a member, false if not.

LocalGroupSetAttributes
LocalGroupSetAttributes (server, name, comment)

Sets the comment for local group name on server to the string provided in comment.

UserCreate
UserCreate (server, username, password, passwordage, privilege,
homedir, comment, flags, scriptpath)

Creates a new user with the specified settings:

server
Name of the server

username
Name of new user

password
The user's password

passwordage
Amount of time before password expires

privilege
Privilege settings of the new user, which can be one of the following:

USER_PRIV_MASK
USER_PRIV_GUEST
USER_PRIV_USER
USER_PRIV_ADMIN
homedir
Pathname of the user's home directory

comment
A string containing a comment about the user

flag
A flag containing user creation settings, which can be one of the following:

UF_TEMP_DUPLICATE_ACCOUNT
UF_NORMAL_ACCOUNT
UF_INTERDOMAIN_TRUST_ACCOUNT
UF_WORKSTATION_TRUST_ACCOUNT
UF_SERVER_TRUST_ACCOUNT
UF_MACHINE_ACCOUNT_MASK
UF_ACCOUNT_TYPE_MASK
UF_DONT_EXPIRE_PASSWD
UF_SETTABLE_BITS
UF_SCRIPT
UF_ACCOUNTDISABLE
UF_HOMEDIR_REQUIRED
UF_LOCKOUT
UF_PASSWD_NOTREQD
UF_PASSWD_CANT_CHANGE
scriptpath
Pathname for the user's login script

UserDelete
UserDelete (server, username)

Deletes a user with username from server.

UserGetAttributes
UserGetAttributes (server, username, $password, $passwordage, $privilege, $homedir, $comment, $flags, $scriptpath)

Retrieves information from a user profile for the user identified by username on server and stores each piece in the corresponding variables you provide as arguments. The elements and order of user information are the same as described in the UserCreate function.

UserSetAttributes
UserSetAttributes (server, username, password, passwordage, privilege, homedir, comment, flags, scriptpath)

Sets attributes for user username on server. The attributes are those described for the UserCreate function.

Previous | Home | Next
22.9. Win32::Mutex | Book Index | 22.11. Win32::NetResource
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.11. Win32::NetResource

The Win32::NetResource module allows you to manage shared resources on a network, such as printers, disks, etc. Two data structures are used to provide or store information for many of the NetResource functions. The first is the share_info hash. This hash contains parameters for setting up a share, using the following structure:

%share_info = (
      netname       => "name of share",
      type          => "type of share",
      remark        => "a string comment",
      permissions   => "permissions value",
      maxusers      => "the max number of users",
      current-users => "the current number of users",
      path          => "the path of the share",
      passwd        => "password, if required"
);

A netresource data structure contains information about the shared resource or device. It has the following structure:

%netresource = (
      'Scope'       => "Scope of a resource connection (see list below for
                        values)",
      'Type'        => "The type of resource (see list below)",
      'DisplayType' => "How the resource should be displayed (see list
                        below)",
      'Usage'       => "How the resource should be used",
      'LocalName'   => "Name of the local device the resource is connected
                        to",
      'RemoteName'  => "Network name of the resource",
      'Comment'     => "Comment string",
      'Provider'    => "Provider of the resource"
);

The first three elements of the netresource hash contain values described in the following lists. The Scope value can be one of the following:

RESOURCE_CONNECTED
Resource is already connected

RESOURCE_REMEMBERED
Resource is reconnected each time the user logs on

RESOURCE_GLOBALNET
Resource is available to the entire network

The Type element takes one of the following values:

RESOURCETYPE_ANY
All resources

RESOURCETYPE_DISK
Disk resources

RESOURCETYPE_PRINT
Print resources

The Display element can be one of these values:

RESOURCEDISPLAYTYPE_DOMAIN
Object is displayed as a domain

RESOURCEDISPLAYTYPE_SERVER
Object is displayed as a server

RESOURCEDISPLAYTYPE_SHARE
Object is displayed as a sharepoint

RESOURCEUSAGE_CONNECTABLE
Resource can be connected to a local device

RESOURCEUSAGE_CONTAINER
Resource contains more resources

The functions in Win32::NetResource use the share_info and netresource structures as input and output arguments. These arguments are used in the description of the functions below; you should name them whatever you want.

AddConnection
AddConnection (\%netresource, password, username, connection)

Connects to the resource described in %netresource, with the password and username of the user. The <connection> flag indicates whether the connection should be remembered for the user for all logins.

CancelConnection
CancelConnection (name, connection, force)

Cancels a connection to a resource connected to the local device specified by name. connection indicates the type of connection, with 1 being a persistent connection and 0 being nonpersistent. The force value is a Boolean indicating whether to force the connection.

GetError
GetError ($code)

Gets the last error caused by a Win32 network call and saves it in the variable named by code.

GetSharedResources
GetSharedResources (\@resources, type)

Gets a list of all network resources and saves the list as references to %netresource hashes in @resources. type is the type of enumeration.

GetUNCName
GetUNCName ($uncname, path)

Gets the UNC name of the share connected to the local path and saves it to the variable specified by uncname.

NetShareAdd
NetShareAdd (\%shareinfo, $error, [server])

Makes a disk resource described by shareinfo available for sharing on the network. server is the name of the server for the shared resource (local is assumed if not specified). Any error that occurs is saved in the variable named by error.

NetShareCheck
NetShareCheck (device, $type, [server])

Returns true if a share on device is available for connection. The type of share is saved in the variable named by type (if the function returns true).

NetShareDel
NetShareDel (name, [server])

Removes the share named name on optional server from a machine's list of shares.

NetShareGetInfo
NetShareGetInfo (name, \%shareinfo, [server])

Gets the share information for the share name on optional server and saves it in the specified shareinfo variable.

NetShareSetInfo
NetShareSetInfo (name, \%shareinfo, $error, [server])

Sets the information for the share name on server to the parameters given by shareinfo. The error status is saved to the variable named by error.

WNetGetLastError
WNetGetLastError ($code, $description, $name)

Gets the extended network error and saves its information to the variables named by code, description, and name. An extended network error is given only when Win32::GetLastError returns ERROR_EXTENDED_ERROR.

Previous | Home | Next
22.10. Win32::NetAdmin | Book Index | 22.12. Win32::PerfLib
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.12. Win32::PerfLib

The Win32::PerfLib module allows you to retrieve the performance counter of any computer running Windows NT in the network. All of the functions return false if they fail, unless otherwise noted. If the $server argument is undef, the local machine is assumed.

new
$perflib->new($server)

Creates a connection to the performance counters of the given server.

Close
$perflib->Close($hashref)

Closes the connection to the performance counters.

GetCounterHelp
GetCounterHelp($server, $hashref)

Retrieves the counter help strings and their indices from the registry and stores them in the hash reference.

GetCounterNames
GetCounterNames($server, $hashref)

Retrieves the counter names and their indices from the registry and stores them in the hash reference.

GetCounterType
GetCounterType(countertype)

Converts the counter type to a readable string.

GetObjectList
$perflib->GetObjectList($objectid, $hashref)

Retrieves the object and counter list of the given performance object.

Previous | Home | Next
22.11. Win32::NetResource | Book Index | 22.13. Win32::Pipe
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.13. Win32::Pipe

This module gives Win32 Perl the ability to use named pipes. Under Windows NT, named pipes are used for processes to communicate with one another, and are not limited to the local machine.

Named pipes are created with new, which makes a new Win32::Pipe object and returns true on success. new has the following syntax:

my $named_pipe = Win32::Pipe->new($pipe_name);

22.13.1. Win32::Pipe Methods

The following methods are provided for objects of created by Win32::Pipe.

BufferSize
$named_pipe->BufferSize(  )

Returns the size of the instance of the buffer of the named pipe.

Close
$named_pipe->Close

Closes the named pipe.

Connect
$named_pipe->Connect

Tells the named pipe to create an instance of the named pipe and wait until a client connects. Returns true on success, false on failure.

Disconnect
$named_pipe->Disconnect

Disconnects (and destroys) the instance of the named pipe from the client. Returns true on success, false on failure.

Error
$named_pipe->Error

Returns the last error messages pertaining to the named pipe, if used in context to the package. Returns a list containing ERROR_NUMBER and ERROR_TEXT.

Read
$named_pipe->Read

Reads from the named pipe. Returns data read from the pipe on success, undef on failure.

ResizeBuffer
$named_pipe->ResizeBuffer(SIZE)

Sets the size of the buffer of the instance of the named pipe to SIZE. Returns the size of the buffer on success, false on failure.

Write
$named_pipe->Write(DATA)

Writes DATA to the named pipe. Returns true on success, false on failure.

Previous | Home | Next
22.12. Win32::PerfLib | Book Index | 22.14. Win32::Process
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.14. Win32::Process

This module provides access to extended Win32 process creation and management abilities. Process objects are created with the Create method (the constructor). Additional methods can be used on objects to kill, suspend, resume, and set the priorities of processes.

The Create constructor has the following syntax:

Win32::Process->Create($Proc, app, cmnd, hndls, opts, dir)

The arguments to Create are as follows:

$Proc
Name of the reference for the created process object.

app
Full pathname of the executable.

cmnd
Command line for executable.

hndls
Determines handle inheritance. A value of 1 turns on inheritance; a 0 value turns it off.

opts
Sets options to implement when the process is created. The available options for this argument are listed below.

dir
The working directory for the executable.

The process is created by passing the command line in cmnd to the executable named in app. For example, a process object for a text file running in Notepad is created like this:

use Win32::Process;
Win32::Process->Create($proc, 'C:\\windows\\Notepad.exe',
                       "Notepad perlnut.txt", 1,
                       DETACHED_PROCESS, ".");

The process creation options given by the opts argument to Create are:

CREATE_DEFAULT_ERROR_MODE
Gives the process the default error mode.

CREATE_NEW_CONSOLE
Creates a new console for the process. Can't be used with DETACHED_PROCESS.

CREATE_NO_CONSOLE
Creates a new process, but without running the process in a new and visible window. That is, a new process will be created, but in the background.

CREATE_NEW_PROCESS_GROUP
Creates process as root of a new process group.

CREATE_SEPARATE_WOW_VDM
Runs process in its own Virtual DOS Machine (VDM). Only applicable to 16-bit applications.

CREATE_SUSPENDED
Starts process in a suspended state. The process can be started with the Resume method.

CREATE_UNICODE_ENVIRONMENT
Uses Unicode characters in the environment block of the new process.

DEBUG_PROCESS
Debugs the new process with the calling process.

DEBUG_ONLY_THIS_PROCESS
Doesn't debug the new process if calling process is being debugged.

DETACHED_PROCESS
Creates a process with no access to the console of the calling process.

22.14.1. Win32::Process Methods

The following methods are provided for objects of created by Win32::Process.

GetExitCode
$proc->GetExitCode($ref)

Gets the exit code of a process and saves it to $ref.

GetPriorityClass
$proc->GetPriorityClass($ref)

Gets the priority class of the process and stores it in $ref.

Kill
$proc->Kill(exitcode)

Kills the process with the given exitcode, which is returned by the process.

Resume
$proc->Resume

Resumes a suspended process. This method can also be used on processes created with the CREATE_SUSPENDED flag.

SetPriorityClass
$proc->SetPriorityClass($priority)

Sets the priority class of the object to $priority. The priority can be one of the following:

IDLE_PRIORITY_CLASS
A process whith threads that run only when the system is idle

NORMAL_PRIORITY_CLASS
A process with normal scheduling

HIGH_PRIORITY_CLASS
A process that performs time-critical tasks that must be executed immediately

REALTIME_PRIORITY_CLASS
The highest-priority process, even preempts operating-system threads

Suspend
$proc->Suspend

Suspends the process.

Wait
$proc->Wait(n)

Waits n milliseconds for the process to exit. If the process times out, the method returns false and sets $! to WAIT_FAILED. For no timeout, sets n to INFINITE.

Previous | Home | Next
22.13. Win32::Pipe | Book Index | 22.15. Win32::Registry
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.15. Win32::Registry

This module provides access to the Windows Registry, the database that stores information about all parts of your system and software. Many operating-system and application behaviors are controlled by Registry data. The Win32::Registry module gives you a way to access and update registry information with Perl.

WARNING: Always be careful when making changes to the registry. If vital system information gets changed by mistake, your system could become inoperable. Always make certain you have a backup of your registry before you start making modifications.

The Registry module automatically creates objects for the top-level registry trees. These objects are created in the main:: namespace, and each key that you open or create is accessed via one of these root objects. The top-level objects are:

$HKEY_CLASSES_ROOT
$HKEY_CURRENT_USER
$HKEY_LOCAL_MACHINE
$HKEY_USERS
$HKEY_PERFORMANCE_DATA
$HKEY_CURRENT_CONFIG
$HKEY_DYN_DATA

If you are outside of the main (default) namespace, you should package declare the keys, e.g., $main::HKEY_USERS.

The Open method creates new key objects for subtrees or subkeys under another open key object. Initially, a new key is opened from one of the main key objects. For example:

use Win32::Registry;
$p = "SOFTWARE\Microsoft\Windows NT\CurrentVersion";
$HKEY_LOCAL_MACHINE->Open($p, $CurrVer) || die "Open $!";

This example creates a key object $CurrVer for the CurrentVersion key for Windows NT. This key contains several values for the current version of the operating system. With the new key open, you can read or change the values it contains (every key has at least one unnamed, default value), or open and create subkeys. The Open method can create key objects only for existing keys.

Registry values are represented in Win32::Registry functions by three elements: the name of the value, the data type of the value, and the value itself. There are several different data types for the values. Win32::Registry defines the following constants for these types:

REG_SZ
String data

REG_DWORD
Unsigned four-byte integer

REG_MULTI_SZ
Multiple strings delimited with NULL

REG_EXPAND_SZ
Strings that expand (e.g., based on environment variables)

REG_BINARY
Binary data (no particular format is assumed)

22.15.1. Win32::Registry Methods

The following methods can be used on key objects, either on the preopened main keys or subkeys that you have already opened.

Create
$key->Create($newkey, name)

Creates a new key identified by name and saves it as the object reference named by $newkey. If the key already exists, this function simply opens the key. New keys can only be created one level below the key on which Create is used.

DeleteKey
$key->DeleteKey(subkey)

Deletes a subkey of the current key. This function will delete all values in the subkey and the subkey itself. A key cannot be deleted if it contains any subkeys.

DeleteValue
$key->DeleteValue(name)

Deletes a value identified by name from the current key.

GetKeys
$key->GetKeys($listref)

Returns the names of the subkeys of the current key to the list referenced by listref.

GetValues
$key->GetValues($hashref)

Returns the values contained in the current key to the hash referenced by hashref. Each registry value name is a hash key, while the hash value is a reference to a three-element list containing the name of the value, the data type, and the value.

Load
$key->Load(subkey, filename)

Loads a registry file to the named subkey from file filename.

Open
$parent->Open(keyname, $key)

Opens a registry key named in keyname and saves it as the object reference named by $key. keyname is the name of a key relative to the object on which Open is used ($parent).

QueryKey
$key->QueryKey($class, $subs, $vals)

Retrieves information about the current key and returns it to the named scalar variables. The key class is saved in the class variable (it will be the null string "" on Win95 since it doesn't use key classes). The number of subkeys is saved in the $subs variable, and the number of values in the current key is saved in $vals.

QueryValue
$key->QueryValue(name, $var)

Returns the value of the registry value specified by name and saves it in the scalar variable $var.

Save
$key->Save(filename)

Saves the registry tree root and the current key to a file, filename.

SetValue
$key->SetValue(subkey, type, value)

Sets the default (unnamed) value for the specified subkey of the key object on which SetValue is used. The arguments are:

subkey
Name of the subkey

type
One of the type constants (listed above) describing the value

value
Value of the key

SetValueEx
$key->SetValueEx(name, res, type, value)

Sets a value specified by name in the current key (or creates the value if it doesn't already exist). The arguments are:

res
A reserved argument for future use (use 0 as a placeholder)

type
The data type constant (listed above) describing the value

value
The value of the key

Previous | Home | Next
22.14. Win32::Process | Book Index | 22.16. Win32::Semaphore
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.16. Win32::Semaphore

The Win32::Semaphore module implements semaphores, synchronizing access to shared resources. The constructor new creates a new semaphore object and sets the initial count and the maximum count of the semaphore. The constructor has the following syntax:

$sem = Win32::Semaphore->new(init, max, [name]);

The arguments are defined as follows:

init
The initial count of the semaphore

max
The maximum count of the semaphore

name
A string containing a name of the semaphore

The open constructor opens an existing semaphore object specified by name:

$sem = Win32::Semaphore->open(name);

The following methods can be used on Win32::Semaphore objects.

release
$sem->release(inc, [$var])

Releases a semaphore and increments the count by the amount specified in inc. The last count (before the increment) is returned in the $var variable, if provided.

wait
$sem->wait([timeout])

The inherited Win32::IPC call. Waits for the semaphore's count to be nonzero, then decrements it. Optional timeout is given in milliseconds.

Previous | Home | Next
22.15. Win32::Registry | Book Index | 22.17. Win32::Service
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.17. Win32::Service

The Win32::Service module provides a service control interface. It allows you to start, pause, resume, and stop Windows NT system services from Perl scripts.

The following functions are exported by this module. The host argument in each function gives the hostname of the machine a service is running (or will run) on. If you supply a null string (""), the local machine will be assumed.

GetServices
GetServices (host, \%hash)

Returns a list of services on host to the hash referenced by hash.

GetStatus
GetStatus (host, service, \%status)

Returns the status of service as a hash referenced by status. The keys for this hash are:

ServiceType
CurrentState
ControlsAccepted
Win32ExitCode
ServiceSpecificExitCode
CheckPoint
WaitHint
PauseService
PauseService (host, service)

Pauses the named service on machine host (only if the service is able to pause).

ResumeService
ResumeService (host, service)

Resumes a paused service on host.

StartService
StartService (host, service)

Starts the named service on the machine host. The specified service must be registered with the Service Control Manager.

StopService
StopService (host, service)

Stops the named service on machine host.

Previous | Home | Next
22.16. Win32::Semaphore | Book Index | 22.18. Win32::Shortcut
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.18. Win32::Shortcut

This module allows you to create and manipulate Windows shortcut files (.lnk files) through Perl. The methods and properties of this module apply to shortcut objects created by new:

use Win32::Shortcut;
$link = Win32::Shortcut->new( );

This creates the shortcut object $link, on which you can set properties and save into a file. If you supply a filename as an argument to new, the file will be loaded into the shortcut object.

The object can also be accessed as if it was a normal hash reference. The following properties (hash keys) are available:

$link->{'File'}
$link->{'Path'}
$link->{'ShortPath'}
$link->{'WorkingDirectory'}
$link->{'Arguments'}
$link->{'Description'}
$link->{'ShowCmd'}
$link->{'Hotkey'}
$link->{'IconLocation'}
$link->{'IconNumber'}

See Section 22.18.1, "Shortcut Properties" for a description of each property.

The following example assumes you have a shortcut file named test.lnk in your current directory. This simple script will tell you where this shortcut points to:

use Win32::Shortcut;
$link=new Win32::Shortcut( );
$link->Load("test.lnk");
print "Shortcut to: $link->{'Path'} $link->{'Arguments'} \n";
$link->Close( );

But you can also modify its values:

use Win32::Shortcut;
$link=new Win32::Shortcut( );
$link->Load("test.lnk");
$link->{'Path'}=~s/C:/D:/i;   # Move the target from C: to D:
$link->{'ShowCmd'}=SW_NORMAL; # Runs in a normal window

The methods provided by Win32::Shortcut are as follows.

new
new Win32::Shortcut [file]

Creates a new shortcut object. If a filename is passed in file, automatically Load s this file also. Returns the object created, or undef on error.

Close
$link->Close(  )

Closes a shortcut object. It is not strictly required to close the objects you created, since the Win32::Shortcut objects are automatically closed when the program ends (or when you otherwise destroy such an object).

Also note that a shortcut is not automatically saved when it is closed, even if you modified it. You have to call Save in order to apply modifications to a shortcut file.

Load
$link->Load(file)

Loads the content of the shortcut file named file in a shortcut object and fills the properties of the object with its values. Returns undef on error, or true if everything was successful.

Resolve
$link->Resolve([flag])

Attempts to automatically resolve a shortcut and returns the resolved path, or undef on error; if there is no resolution, the path is returned unchanged. Note that the path is automatically updated in the Path property of the shortcut.

By default, this method acts quietly, but if you pass a value of 0 in the flagparameter, it will eventually post a dialog box prompting the user for more information. For example:

# If the target doesn't exist...
if(! -f $link->Path) {

    # Save the actual target for comparison
    $oldpath = $link->Path;

    # Try to resolve it (with dialog box)
    $newpath = $link->Resolve(0);

    die "Not resolved..." if $newpath == $oldpath;
}
Save
$link->Save([file])

Saves the content of the shortcut object into the file named file. If file is omitted, the filename is taken from the File property of the object (which, if not changed, is the name of the last Load ed file).

If no file was loaded, and the File property doesn't contain a valid filename, the method returns undef, which is also returned on error. A true value is returned if everything was successful.

Set
$link->Set(path, arguments, workingdirectory, description,
showcmd, hotkey, iconlocation, iconnumber)

Sets all the properties of the shortcut object with a single command. This method is supplied for convenience only; you can also set these values by changing the values of the properties. For example:

$link->Set("C:\PERL5\BIN\PERL.EXE",
           "-v",
           "C:\PERL5\BIN",
           "Prints out the version of Perl",
           SW_SHOWMAXIMIZED,
           hex('0x0337'),
           "C:\WINDOWS\SYSTEM\COOL.DLL",
           1);

This is the same as:

$link->Path("C:\PERL5\BIN\PERL.EXE");
$link->Arguments("-v");
$link->WorkingDirectory("C:\PERL5\BIN");
$link->Description("Prints out the version of Perl");
$link->ShowCmd(SW_SHOWMAXIMIZED);
$link->Hotkey(hex('0x0337'));
$link->IconLocation("C:\WINDOWS\SYSTEM\COOL.DLL");
$link->IconNumber(1);</PRE>

22.18.1. Shortcut Properties

The properties of a shortcut object can be accessed as:

$link->{'property'}

For example, assuming that you have created a shortcut object with:

$link=new Win32::Shortcut( );

you can see its description with:

print $link->{'Description'};

You can, of course, also set it like this:

$link->{'Description'}="This is a description";

The shortcut properties also have corresponding methods that can also set or read their values.

The properties of a shortcut reflect the content of the Shortcut Properties dialog box, which can be obtained by right-clicking on a shortcut file in the Windows 95 (or NT 4.0) Explorer and choosing "Properties." Shortcut properties are:

Arguments
The arguments associated with the shell link object. They are passed to the targeted program (see Path) when it gets executed. In fact, joined with Path, this parameter forms the "Target" field of a Shortcut Properties dialog box.

Description
An optional description given to the shortcut. Not implemented in Shortcut Properties dialog box.

File
The filename of the shortcut file opened with Load and/or the filename under which the shortcut will be saved with Save (if the fileargument is not specified).

Hotkey
The hotkey associated with the shortcut, in the form of a two-byte number, of which the first byte identifies the modifiers (Ctrl, Alt, Shift, etc.), and the second is the ASCII code of the character key. Corresponds to the "Shortcut key" field of a Shortcut Properties dialog box.

IconLocation
The file that contains the icon for the shortcut.

IconNumber
The number of the icon for the shortcut in the file pointed to by IconLocation, in case more that one icon is contained in that file.

Path
The target of the shortcut. This (joined with Arguments) is the content of the "Target" field in a Shortcut Properties dialog box.

ShortPath
Same as Path, but expressed in a DOS-readable format (8.3-character filenames). It is available as read-only (well, you can change it, but it has no effect on the shortcut; change Path instead) once you Load a shortcut file.

ShowCmd
The condition of the window in which the program will be executed (can be Normal, Minimized, or Maximized). Corresponds to the "Run" field of a Shortcut Properties dialog box. Allowed values are:

Value

Meaning

Constant

1

Normal window

SW_SHOWNORMAL

3

Maximized

SW_SHOWMAXIMIZED

7

Minimized

SW_SHOWMINNOACTIVE

WorkingDirectory
The directory in which the targeted program will be executed. Corresponds to the "Start in" field of a Shortcut Properties dialog box.

Previous | Home | Next
22.17. Win32::Service | Book Index | 22.19. Win32 Extensions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.19. Win32 Extensions

In addition to the modules listed previously, Perl for Win32 can use an additional set of functions from the Win32 extension. These functions provide useful tools for some Windows-specific tasks that don't require their own modules. They are exported from the Win32 package with:

use Win32;

Many of these functions do not take arguments and return the value (or values) of the requested information, unless otherwise noted.

Win32::CopyFile(from, to, overwrite)
Copies an existing file to a new file, while preserving all attributes of the original file, except the security information. If to exists, overwriting will take place only if overwrite is true. Read-only files will never be overwritten; they will need to be unlink ed first.

Win32::FreeLibrary(handle)
Unloads a previously loaded DLL. handle is no longer valid after FreeLibrary( ) is called.

Win32::GetArchName( )
Has been deprecated in favor of $ENV{PROCESSOR_ARCHITECTURE}.

Win32::GetChipName( )
Returns the processor type of the machine under which the perl process is running. This string will be represented as 386, 486, 586, etc.

Win32::GetFullPathName(filename)
Combines filename with drive number and directory name. In a list context, GetFulllPathName( ) returns path and file.

Win32::GetLastError( )
Returns the last error value generated by a call to a Win32 API function.

Win32::GetLongPathName(pathname)
Returns pathname as composed of longname components.

Win32::GetProcAddress(instance, procname)
Returns the address of a function inside of a loaded library. Since GetProcAddress( ) is deprecated, you should use Win32::API instead.

Win32::LoadLibrary(libname)
Loads a DLL into memory and returns its module handle. You can then use the returned module handle with Win32::GetProcAddress and Win32::FreeLibrary.

Win32::MsgBox(message, [, flags, [, title]])
Creates a dialog box that contains message. title specifies an optional window title. FLAGS specifies the required icons according to the following:

0 = OK
1 = OK and Cancel
2 = Abort, Retry, and Ignore
3 = Yes, No and Cancel
4 = Yes and No
5 = Retry and Cancel
MB_ICONSTOP creates an "X" in a red circle
MB_ICONQUESTION creates a question mark in a bubble
MB_ICONEXCLAMATION creates an exclamation mark in a yellow triangle
MB_ICONINFORMATION creates an "i" in a bubble

MsgBox( ) returns the menu ID of the selected pushbutton:

0  Error
1  OK
2  Cancel
3  Abort
4  Retry
5  Ignore
6  Yes
7  No
Win32::OLELastError( )
Returns the last error value generated by a call to a Win32 OLE API function.

Win32::BuildNumber( )
Returns the build number of Perl for Win32.

Win32::LoginName( )
Returns the username of the owner of the current Perl process.

Win32::NodeName( )
Returns the Microsoft network node name of the current machine.

Win32::DomainName( )
Returns the name of the Microsoft network domain that the owner of the current Perl process is logged into.

Win32::FsType( )
Returns a string naming the filesystem type of the currently active drive.

Win32::GetCwd( )
Returns the current active drive and directory. This function does not return a UNC path, since the functionality required for such a feature is not available under Windows 95.

Win32::SetCwd(newdir)
Sets the current active drive and directory to newdir. This function does not work with UNC paths, since the functionality required for such a feature is not available under Windows 95.

Win32::SetLastError(error)
Sets the value of the last error encountered to error. Does not work under Windows 95.

Win32::GetOSVersion( )
Returns a list of elements describing the version of the operating system. The elements of the list are an arbitrary descriptive string; the major version number of the operating system; the minor version number; the build number; and a digit indicating the actual operating system, which will be 0 for Win32s, 1 for Windows 95, and 2 for Windows NT. For example:

use Win32;
($string, $major, $minor, $build, $id) = Win32::GetOSVersion( );
Win32::FormatMessage(error)
Converts the Win32 error number supplied by errorinto a descriptive string. The error number can be retrieved using Win32::GetLastError or Win32::OLELastError.

Win32::Spawn(command, args, $pid)
Spawns a new process for the given command, passing the arguments in args. The ID of the new process is saved in the variable named by pid.

Win32::LookupAccountName(sys, acct, $domain, $sid, $type)
Returns the domain name, SID, and SID type to the specified variables for the account acct on system sys.

Win32::LookupAccountSID(sys, sid, $acct, $domain, $type)
Returns the account name, domain name, and SID type to the specified variables for the SID sid on system sys.

Win32::InitiateSystemShutdown(machine, message, timeout, forceclose, reboot)
Shuts down the specified machine in the specified timeout interval. message is broadcast to all users. If forceclose is true, all documents are closed (forcefully) without prompting the user. If reboot is true, the machine is rebooted.

Win32::AbortSystemShutdown(machine)
Aborts a shutdown on the specified machine.

Win32::GetTickCount( )
Returns the Win32 tick count.

Win32::IsWinNT( )
Returns true (nonzero) if the Win32 subsystem is Windows NT.

Win32::IsWin95( )
Returns true (nonzero) if the Win32 subsystem is Windows 95.

Win32::ExpandEnvironmentStrings(envstring)
Returns a string in which any environment variables in the given envstring are replaced with their values.

Win32::GetShortPathName(longpathname)
Returns the short (8.3) pathname of longpathname.

Win32::GetNextAvailDrive( )
Returns a string in the form of d:\, in which d is the first available drive letter.

Win32::RegisterServer(libraryname)
Loads the DLL libraryname and calls the function DllRegisterServer.

Win32::UnregisterServer(libraryname)
Loads the DLL libraryname and calls the function DllUnregisterServer.

Win32::Sleep(time)
Pauses for the number of milliseconds specified by time.

Previous | Home | Next
22.18. Win32::Shortcut | Book Index | 23. OLE Automation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 23. OLE Automation

Contents:

Creating Objects
Automation Methods and Properties
Win32::OLE::Enum
Win32::OLE::Variant
Win32::OLE::Const

The Win32::OLE modules give Perl support for OLE automation. OLE automation is a Microsoft technology based on COM that allows objects created by another application to be used and manipulated by a program through a common interface.

The application (or DLL) that implements the automation interface is called the automation server. The application that creates and uses the interface is called the automation controller or automation client. Many popular applications expose their objects through automation. Microsoft Word, Excel, and other Office applications can be used as automation servers. Automation is widely used by Active Server Pages (ASP) and CGI scripts to access data repositories, perhaps via ActiveX Data Objects (ADO). You can even use automation to control many development environments and editors.

To create an automation object, the server needs to be registered on the system. This is typically done by the server's installation program, but can be done manually using a utility such as regsvr32.exe. This involves adding entries to the system registry to tell COM how to find the component, the types of interfaces it provides, the type of server it is, etc. You should be able to find the object model, available methods, and properties of the interface in the documentation provided by the application. This object model can be used via Perl's object syntax to create and control objects in your programs.

Four modules provide automation functionality to Perl:

Win32::OLE
Provides the main interface for OLE automation. You can create or open automation objects, use their methods, and set their properties.

Win32::OLE::Enum
Creates objects for collections and defines an interface for enumerating them.

Win32::OLE::Variant
Allows you to convert the Variant data type used in OLE.

Win32::OLE::Const
Imports constants from an automation object into your script.

Note that there are a few limitations to Win32::OLE. There is currently no support for OCXs or OLE events (notifications generated by the automation server). Win32::OLE implements the IDispatch interface only, and therefore cannot access a custom OLE interface.

23.1. Creating Objects

Automation objects are represented in Perl as instances of Win32::OLE objects. The module provides three constructors for creating objects from a registered automation server.

new
Win32::OLE->new(progid, [destructor])

Creates a new automation object. This method always creates a new instance of the server, even if a previous instance of the server is running. If the object cannot be created, new returns undef.

progid, the program identifier (ProgID), is a string that uniquely identifies an automation object. progid is used to look up the object's class ID (CLSID), which is stored in the registry.

The second, optional argument to the new method describes a way to destroy the object in case the Perl program dies unexpectedly. destructor can be either a string with the name of the defined OLE destructor method, or a code reference that will destroy the object. You should use some form of destructor to close out all your objects, for they can be extremely expensive in terms of system resources. You can explicitly destroy an object using the undef function. If you don't explicitly destroy the object, Perl takes care of it for you when the last reference to the object goes away.

Here is what new would look like with the destructor arguments:

# Quit is the OLE-defined destructor method
$x1 = Win32::OLE->new("Excel.Application", 'Quit');

# The object reference is the first argument ($_[0]) passed to new
# The code reference will undef it to destroy the object
$x2 = Win32::OLE->new("Excel.Application", sub{undef $_[0];})

Notice that we're supplying Excel.Application as the ProgID. Excel supports several different automation objects, including an Application object, WorkBook objects, and several more. You don't necessarily have to create the top-level object (Application, in this case) when dealing with automation objects (this is determined by the automation server). In Excel's case, we could have directly created a WorkSheet object (e.g., Excel.Sheet) or a Chart object, for example.

GetActiveObject
Win32::OLE->GetActiveObject(progid)

Creates an object for a currently active instance of a server, if one exists. If the server is registered, but no instance of it is running, the method returns undef. If the server is not registered, the method will croak.

You should probably call GetActiveObject inside an eval so that you can do exception handling in the event that the server is unregistered or is not currently running. If the method returns undef, you can just create a new instance of the server and the object with new.

GetObject
Win32::OLE->GetObject(filename)

Creates an automation object based on a document. filename is the full pathname of the document, which can be optionally followed by additional item subcomponents separated by exclamation marks (!). For example:

$doc = 'c:\test\test.xls';
$x1 = Win32::OLE->GetObject($doc);

This code creates an Excel instance based on an Excel file. It is not always clear what type of object GetObject will return from a document since applications may register for more than one document type (e.g., worksheets, charts, macro files, etc. for Excel). You can use QueryObjectType on an object to get the class name of the object.

Previous | Home | Next
22.19. Win32 Extensions | Book Index | 23.2. Automation Methods and Properties
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


23.2. Automation Methods and Properties

Once you have created an automation object, you can use its methods or adjust its properties as you require. Automation methods are implemented as you'd expect with the Perl object syntax:

$obj->some_method(args);

Automation methods can often take a number of optional parameters. You can pass undef for any unwanted parameters in the arguments list. For example, you can save a WorkBook in Excel with SaveAs. Additional settings allow you to add the WorkBook to the MRU list and create a backup copy:

$xl->WorkBooks(1)->SaveAs($f, undef, undef, undef, undef, 1, undef, undef, 1);

For simplification, you can also use just the named parameters you want to set by passing a reference to a hash containing them. You can do this right in the argument list by creating an anonymous hash reference with {}. The previous example can therefore be written like this:

$xl->WorkBooks(1)->SaveAs($f, {AddtoMru => 1, CreateBackup => 1});

Properties of automation objects are accessed via hash reference notation on the object. For example:

$val = $obj->{"property"};         # Get a property value
$obj->{"property"} = $val;         # Set a property value

Be aware that properties may not be writable (or even readable). Many automation objects have read-only properties and will generate an exception if you try to write to them. You'll need to consult the documentation for the object to find out which properties you can safely set.

You can enumerate the properties of an automation object using the normal methods for enumerating hashes, which are keys and each. Here's how you can print the properties and values contained within an object:

$xl = Win32::OLE->new('Excel.Application', 'Quit');
while( ($key,$value) = each %$xl ) {
    print "$key=$value\n";
}

23.2.1. Win32::OLE Methods

Win32::OLE defines a couple of its own methods for dealing with the automation interface. These are not automation-defined methods, although they look the same. If a given method is not defined in Win32::OLE, the method call is dispatched to the automation object. If the method doesn't exist there, you will get an OLE error.

The following methods are defined by Win32::OLE.

Invoke
$obj->Invoke(method, args)

This object method calls the given method for $obj with args as arguments. It is useful for invoking methods that would interfere with predefined names in Perl, or methods that contain characters that Perl can't recognize. You can also use Invoke to call an object's default method by using either undef or an empty string ("") as the first argument.

LastError
Win32::OLE->LastError(  )

This class method returns the last OLE error. In a numeric context, the error number is returned, while in a string context, the error message is returned.

QueryObjectType
Win32::OLE->QueryObjectType($obj)

This class method returns the type of object queried ($obj). In list context, a two-element list of the type library name and the class name of the object is returned. In scalar context, just the class name is returned.

23.2.2. Win32::OLE Functions

The following functions are defined by Win32::OLE. They are not exported by default.

in
in($coll)

Returns a list of all the members of a collection referenced by the collection object $coll. Same as Win32::OLE::Enum->All( ).

valof
valof($obj)

Dereferences an automation object ($obj), calls the default method of the object, and returns the value.

with
with($obj, property1 => value1, ...)

Sets the values of multiple properties on an object ($obj). The function calls $obj->{property}=valuefor each property/value pair.

23.2.3. Win32::OLE Class Variables

The Win32::OLE module defines certain class variables that set default behavior for automation usage:

$Win32::OLE::CP
Determines the codepage used by all translations between Perl strings and Unicode strings used by the OLE interface. The default value is CP_ACP, which is the default ANSI codepage. It can also be set to CP_OEMCP, which is the default OEM codepage. Both constants are not exported by default.

$Win32::OLE::LCID
Controls the locale identifier used for all OLE calls. It is set to LOCALE_NEUTRAL by default. Check the Win32 module for other locale-related information.

$Win32::OLE::Warn
Determines the behavior of the Win32::OLE module when an error happens. Valid values are:

0
Ignores error, returns undef.

1
Uses Carp::carp if $^W is set (-w option).

2
Always uses Carp::carp.

3
Uses Carp::croak.

The error number and message (without Carp line/module info) are also available through the Win32::OLE->LastError method.

Previous | Home | Next
23. OLE Automation | Book Index | 23.3. Win32::OLE::Enum
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


23.3. Win32::OLE::Enum

The Win32::OLE::Enum module provides special support for collections. Collections are special automation data types that contain an array of objects or data. A collection supports enumeration; you can iterate through each item through a standard interface.

Collection objects should always provide a Count property (the number of items in the collection) and an Item method. The Item method is used to access a particular collection item using a subscript, which may be an integer or a string, depending on the server. Collection objects may also optionally contain an Add and a Remove method.

Collection objects also support a standard COM interface (IEnumVARIANT) that allows you to enumerate each item in a collection. It defines methods that let you advance the iteration to the next item, skip a given item, restart the enumeration, and create a new copy of the iterator. While all servers are supposed to provide this interface, some servers don't implement all of the methods (often Reset and Clone are not implemented).

Win32::OLE::Enum defines these methods for enumerating collections. The collection object should provide the Count and Item methods, which are often all you need to use on collections. For example:

$cnt = $coll->Count( );
if( $cnt) {
    $obj = $coll->Item(0);
    $obj->do_something( );
}

Count will tell you the number of items in the collection, and Item will return the desired item as a Win32::OLE object.

For the enumeration methods, you need to create an enumeration object for the collection object:

$coll = $obj->some_coll( );
$enum = Win32::OLE::Enum->new($coll);

Now you can use the enumeration methods on the object.

23.3.1. Win32::OLE::Enum Methods

The following methods are defined in Win32::OLE::Enum.

new
Win32::OLE::Enum->new($obj)

Creates a new Win32::OLE::Enum object. Provides it with a collection object or an existing Enum object, in which case it calls Clone.

All
$Enum->All(  )

Returns a list of all objects in the collection. Note that to use All again, you need to first call Reset.

Clone
$Enum->Clone(  )

Returns a copy of the current iterator. This method is supposed to maintain the same iteration position, if possible, but may be unimplemented.

Next
$Enum->Next([count])

Returns the next item in the collection. You can optionally provide Next with a count (which must be greater than zero), in which case it returns a list of the next count items. Note that if you provide a scalar context in conjunction with a count, you'll get only the last item in the list of returned items. Next returns undef if it is currently on the last item in the collection.

Reset
$Enum->Reset(  )

Restarts the enumeration with the first item in the collection. Reset returns true if it succeeds, false if it fails. Note that this method may be unimplemented.

Skip
$Enum->Skip([count])

Skips the next count number of items of the enumeration (again, count must be positive and defaults to 1). Skip returns false if there are not at least countitems left.

Previous | Home | Next
23.2. Automation Methods and Properties | Book Index | 23.4. Win32::OLE::Variant
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


23.4. Win32::OLE::Variant

All automation data has to be coerced into a special type called a Variant. Most of the time, you don't need to worry about explicit type coercion. You just provide your scalar data, and the magic of automation takes care of the rest. However, there are times when you want to control the exact type of data you're sending to the automation server. The Win32::OLE::Variant module provides access to the Variant data type and lets you control exactly how the data is represented.

A Variant is an OLE data structure that contains a type field and a data field. The flags are implemented in Perl (as are many constants) as subroutines that return an integer value. The following table lists the Variant type flags, along with a brief description of each:

Type | Description
VT_EMPTY | No value specified. Incidentally, automation does not use VT_EMPTY for empty optional parameters. Rather, it uses VT_ERROR with a value of DISP_E_PARAMNOTFOUND (which isn't exported by Perl: the value in current Win32 SDK headers is 0x80020004).
VT_NULL | A propagating NULL value was specified (not to be confused with a null pointer). This is used for things like the NULL in SQL.
VT_I2 | A two-byte integer value.
VT_I4 | A four-byte integer value.
VT_R4 | An IEEE four-byte real value.
VT_R8 | An IEEE eight-byte real value.
VT_CY | An automation currency value.
VT_DATE | An automation date value.
VT_BSTR | A string value.
VT_DISPATCH | The value contains another automation object.
VT_ERROR | An error code was specified. The type of the error is determined by the actual value. As mentioned earlier, this is used to implement empty optional parameters.
VT_BOOL | A Boolean (true/false) value. If all bits are 1, it's true; if all bits are 0, it's false. Any other value is invalid.
VT_VARIANT | The value contains another Variant.
VT_UNKNOWN | The value contains an IUnknown pointer (the base class of COM objects).
VT_UI1 | An unsigned one-byte character.
VT_BYREF | Can be combined with some fields to indicate that the data is being passed by reference, rather than by value.
VT_ARRAY | The value contains an OLE SAFEARRAY (this flag is not currently exported by Perl).

To convert data to a specific Variant type, create a variant object with either the new constructor method or the convenience function Variant:

$vnt = Win32::OLE::Variant->new(type, data);
$vnt = Variant(type, data);

For example, to force a string to be interpreted as a date, create a Variant object and set it to the VT_DATE type:

$dt = Variant(VT_DATE, "August 24, 1970");   # Create an explicit data type
$sheet->Cells(1,1)->{Value} = $dt;           # Set it to a spreadsheet cell

23.4.1. Win32::OLE::Variant Methods

The following methods are defined by Win32::OLE::Variant for working with Variant data types.

As
$vnt->As(type)

Takes a type flag argument and converts the Variant object to the supplied type before converting it to a Perl value.

ChangeType
$vnt->ChangeType(type)

Takes a type flag argument and converts the Variant object (in place) to the supplied type.

Type
$vnt->Type(  )

Returns the type of the variant $vnt.

Value
$vnt->Value(  )

Returns the value of the variant $vnt as a Perl value. The conversion is performed in the same manner as all return values of Win32::OLE method calls are converted.

Previous | Home | Next
23.3. Win32::OLE::Enum | Book Index | 23.5. Win32::OLE::Const
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


23.5. Win32::OLE::Const

While browsing through the documentation for an automation object, you may have come across references to constant values. For example, if you're trying to save an Excel workbook to a different file format, you need to provide a file for- mat constant. Since the server documentation typically provides symbolic con- stants (e.g., xlExcel5 or xlTemplate), we need a way to access those from Perl. This is the purpose of Win32::OLE::Const, which imports the constants from an automation object into your script.

You can either import the constants directly into your namespace as subs that return the constant value, or you can have them returned as a hash reference with the constant name as the key and its value as the value. Here's an example of the former:

use Win32::OLE::Const ("Microsoft Excel");
print "xlExcel5 = ", xlExcel5, "\n";

This produces something like:

xlExcel5 = 39

Here's an example using the Load method to return a hash reference populated with the constants and their values (this produces the same output as the previ- ous example, of course):

use Win32::OLE::Const;

my $constants = Win32::OLE::Const->Load("Microsoft Excel");
print "xlExcel5 = $constants->{xlExcel5}\n";

Notice that, in both cases, we're supplying a regular expression for the name of the type library from which we want to import. Win32::OLE::Const searches the registry for matching type libraries and loads the one with the highest version number (you can override this by supplying the version you want). You can also specify the language you'd like. The parameters (for either Load or Win32::OLE::Const) are the typelib regular expression, the major version number, the minor version number, and the locale (LCID).

You can also provide the Load method with an automation object, which is then queried for its type library. Interestingly, the documentation notes that this seems to be slower than searching the Registry (though neither is really speedy with a large automation server like Excel). Here's an example of that:

use Win32::OLE;
use Win32::OLE::Const;

# Create an Excel application object
my $xl = Win32::OLE->new('Excel.Application', 'Quit') ||
  die "Can't create Excel: ", Win32::OLE->LastError;

# Import the constants from it
my $constants = Win32::OLE::Const->Load($xl);

Using Load (to get a hash reference for the constants) may be preferable to importing all of the constants into your namespace. Some automation servers pro- vide a large number of constants (the current version of Excel has some 900+), so importing them into your namespace can clutter things considerably.

Previous | Home | Next
23.4. Win32::OLE::Variant | Book Index | 24. ODBC Extension for Win32
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 24. ODBC Extension for Win32

Contents:

ODBC Methods and Properties

Win32::ODBC allows you to make a connection to a database that supports ODBC under both Win32 and Unix. Win32::ODBC allows you to support as many ODBC connections as are allowed by memory and ODBC.

Generally, you'll use Win32::ODBC to access databases such as those created under Microsoft Access, but there's also an ODBC driver available for MySQL if you want to connect to MySQL via ODBC and aren't able to use DBI and a DBD.

To get started, you'll need to use new( ) to create a new Win32::ODBC object. As arguments, new( ) takes a connection string (DSN) or an open ODBC object if one is given. new( ) returns a database handle on success and undef on failure. For example:

use Win32::ODBC;

my $dsn = "DSN=Name of Database;UID=Your UID Here;PWD=dbpasswd;"
my $DB  = Win32::ODBC->new($dsn);

24.1. ODBC Methods and Properties

Once you have created an ODBC object, you can use its methods or adjust its properties as you require. ODBC methods are implemented as you'd expect with the Perl object syntax.

The following methods are defined by Win32::ODBC.

Catalog
$obj->Catalog(qualifier, owner, name, type)

Tells ODBC to create a data set that contains table information about the DSN. Use Fetch and Data or DataHash to retrieve the data. The returned format is:

[qualifier] [owner] [name] [type]

Returns true on error.

ColAttributes
Win32::ODBC->ColAttributes(attributes, [field_names])

Returns the attributes attributes on each of the fields in the list field_names in the current record set. If field_names is empty, then all fields are assumed. The attributes are returned as an associative array.

ConfigDSN
Win32::ODBC->ConfigDSN(option, driver, attribute1 [, attribute2, attribute3, ... ])

Configures a DSN. option takes on one of the following values:

ODBC_ADD_DSN
Adds a new DSN

ODBC_MODIFY_DSN
Modifies an existing DSN

ODBC_REMOVE_DSN
Removes an existing DSN

ODBC_ADD_SYS_DSN
Adds a new System DSN

ODBC_MODIFY_SYS_DSN
Modifies an existing System DSN

ODBC_REMOVE_SYS_DSN
Removes an existing System DSN

driver is a required argument. attribute1 is the DSN, whose format is shown earlier. ConfigDSN( ) returns true on success and false on failure.

Connection
Win32::ODBC->Connection(  )

Returns the connection number associated with the ODBC connection.

Close
Win32::ODBC->Close(  )

Closes the ODBC connection. No return value.

Data
Win32::ODBC->Data([field_name])

Returns the contents of column name field_name or the current row (if nothing is specified).

DataHash
Win32::ODBC->DataHash([field1, field2, ...])

Returns the contents for field1, field2, ..., or the entire row (if nothing is specified) as an associative array consisting of:

{Field Name} => Field Data
DataSources
Win32::ODBC->DataSources(  )

Returns an associative array of data sources and ODBC remarks about them. They are returned in the form of:

$ArrayName{'DSN'}=Driver
Debug
Win32::ODBC->Debug( [ 0 | 1 ] )

Sets the debug option to on or off. If nothing is specified, then nothing is changed. Returns the debugging value (1 or 0).

Drivers
Win32::ODBC->Drivers(  )

Returns an associative array of ODBC Drivers and their attributes. They are returned in the form of:

$ArrayName{'driver'}=Attrib1;Attrib2;Attrib3;...

in which driver is the ODBC driver name, and AttribX are the driver-defined attributes.

DropCursor
Win32::ODBC->DropCursor([close_type])

Drops the cursor associated with the ODBC object. This forces the cursor to be deallocated. This overrides SetStmtCloseType, but the ODBC object does not lose the StmtCloseType setting. close_type can be any valid SmtpCloseType and will perform a close on the statement using the specified close type. Returns true on success, false on failure.

DumpData
Win32::ODBC->DumpData(  )

Dumps to the screen the fieldnames and all records of the current data set. Used primarily for debugging. No return value.

Error
Win32::ODBC->Error(  )

Returns the last encountered error. The returned value is context-dependent.

If called in a scalar context, then a three-element array is returned:

( error_number, error_text, connection_number )

If called in a string context, then a string is returned:

"[error_number] [connection_number] [error_text]"

If debugging is on, then two more variables are returned:

( ..., function, level )

function is the name of the function in which the error occurred, and levelrepresents extra information about the error (usually the location of the error).

FetchRow
Win32::ODBC->FetchRow(row, [type])

Retrieves the next record from the keyset. When row and/or type are specified, the call is made using SQLExtendedFetch instead of SQLFetch. Returns true when another record is available to read and false when there are no more records.

FieldNames
Win32::ODBC->FieldNames(  )

Returns an array of fieldnames found in the current data set. The order isn't specified.

GetConnections
Win32::ODBC->GetConnections(  )

Returns an array of connection numbers showing which connections are currently open.

GetConnectOption
Win32::ODBC->GetConnectOption(option)

Returns the value of the specified connect option option. (Refer to ODBC documentation for more information on the options and values.) Returns a string or scalar depending upon the option specified.

GetCursorName
Win32::ODBC->GetCursorName(  )

Returns the name of the current cursor as a string or undef.

GetData
Win32::ODBC->GetData(  )

Retrieves the current row from the dataset. This is not generally used by users; it is used internally. Returns an array of field data in which the first element is either false (if successful) or true (if not successful).

getDSN
Win32::ODBC->getDSN([dsn])

Returns an associative array indicating the configuration for the specified dsn. If no dsnis specified, then the current connection is used. The returned associative array consists of:

keys=DSN keyword; values=Keyword value.
$Data{$Keyword}=Value
GetFunctions
Win32::ODBC->GetFunctions([function1, function2])

Returns an associative array indicating the ability of the ODBC Driver to support the specified functions. If no functions are specified, then a 100-element associative array is returned containing all possible functions and their values. function must be in the form of an ODBC API constant such as SQL_API_SQLTRANSACT. The returned array will contain the results:

$Results{SQL_API_SQLTRANSACT}=Value

For example:

$Results = $O->GetFunctions(
    $O->SQL_API_SQLTRANSACT,
    SQL_API_SQLSETCONNECTOPTION
);
$ConnectOption = $Results{SQL_API_SQLSETCONNECTOPTION};
$Transact = $Results{SQL_API_SQLTRANSACT};
GetInfo
Win32::ODBC->GetInfo([option])

Returns a string indicating the value of the particular option specified.

GetMaxBufSize
Win32::ODBC->GetMaxBufSize(  )

Returns the current allocated limit for MaxBufSize. For more info, see SetMaxBufSize.

GetSQLState
Win32::ODBC->GetSQLState(  )

Returns a string indicating the SQL state as reported by ODBC. The SQL state is a code that the ODBC Manager or ODBC Driver returns after the execution of a SQL function. This is helpful for debugging purposes.

GetStmtCloseType
Win32::ODBC->GetStmtCloseType([connection])

Returns a string indicating the type of closure that will be used every time the hstmt is freed. (See SetStmtCloseType for details.) By default, the connection of the current object will be used. If connection is a valid connection number, then it will be used.

GetStmtOption
Win32::ODBC->GetStmtOption([option])

Returns the value of the specified statement option option. (Refer to ODBC documentation for more information on the options and values.) Returns a string or scalar depending on the option specified.

MoreResults
Win32::ODBC->MoreResults([connection])

Reports whether there is data yet to be retrieved from the query. This can happen if the query was a multiple select:

"SELECT * FROM [foo] SELECT * FROM [bar]"

Returns 1 if there is more data, undef otherwise.

RowCount
Win32::ODBC->RowCount([connection])

For UPDATE, INSERT, and DELETE statements, the returned value is the number of rows affected by the request, or -1 if the number of affected rows is not available. Returns the number of affected rows, or -1 if not supported by the driver in the current context.

Run
Win32::ODBC->Run(sql)

Executes the SQL command sql and dumps to the screen info about it. Used primarily for debugging. No return value.

SetConnectOption
Win32::ODBC->SetConnectOption(option)

Sets the value of the specified connect option option. (Refer to ODBC documentation for more information on the options and values.) Returns true on success, false otherwise.

SetCursorName
Win32::ODBC->SetCursorName(name)

Sets the name of the current cursor. Returns true on success, false otherwise.

SetPos
Win32::ODBC->SetPos(row, [option, lock])

Moves the cursor to the row row within the current keyset (not the current data/result set). Returns true on success, false otherwise.

SetMaxBufSize
Win32::ODBC->SetMaxBufSize(size)

Sets the MaxBufSize for a particular connection. The amount of memory allocated to retrieve the field data of a record is dynamic and changes when it needs to be larger. Returns the maximum number of bytes.

SetStmtCloseType
Win32::ODBC->SetStmtCloseType(type, [connection])

Sets a particular hstmt close type for the connection. This is the same as ODBCFreeStmt(hstmt, type). By default, the connection of the current object will be used. If connection is a valid connection number, then it will be used. type may be one of:

SQL_CLOSE
SQL_DROP
SQL_UNBIND
SQL_RESET_PARAMS

Returns a string indicating the newly set type.

SetStmtOption
Win32::ODBC->SetStmtOption(option)

Sets the value of the specified statement option option. (Refer to ODBC documentation for more information on the options and values.) Returns true on success, false otherwise.

Shutdown
Win32::ODBC->Shutdown(  )

Closes the ODBC connection and dumps to the screen info about it. Used primarily for debugging. No return value.

Sql
Win32::ODBC->Sql(SQL_STRING)

Executes the SQL command SQL_STRING on the current connection. Returns ? on success, or an error number on failure.

TableList
Win32::ODBC->TableList(qualifier, owner, name, type)

Returns the catalog of tables available in the DSN. For an unknown parameter, just specify the empty string "". Returns an array of table names.

Transact
Win32::ODBC->Transact(type)

Forces the ODBC connection to perform a rollback or commit transaction. type may be one of:

SQL_COMMIT
SQL_ROLLBACK

Returns true on success, false otherwise.

Version
Win32::ODBC->Version(packages)

Returns an array of version numbers for the requested packages (ODBC.pm or ODBC.PLL). If the list packages is empty, then all version numbers are returned.

Previous | Home | Next
23.5. Win32::OLE::Const | Book Index | Index
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Perl in a Nutshell: Index

Perl in a Nutshell
Previous Next

Index

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Symbols & Numbers

Symbols

& (ampersand)
AND bitwise operator: 4.5.10. Bitwise Operators
calling subroutines: 4.7.1. Calling Subroutines
in encoded URLs: 9.2. URL Encoding
prototype symbol: 4.7.5. Prototypes
&&= (assignment) operator: 4.5.6. Assignment Operators
&= (assignment) operator: 4.5.6. Assignment Operators
<> (angle brackets)
<=> (comparison) operator: 4.5.4.2. Equality operators
<...> (line-input) operator: 4.9. Filehandles
<<= (assignment) operator: 4.5.6. Assignment Operators
<< debugger commands, and: 6.2. Debugger Commands
< (less-than) operator: 4.5.4.1. Relational operators
<= (less-than-or-equal) operator: 4.5.4.1. Relational operators
>>= (assignment) operator: 4.5.6. Assignment Operators
> (greater-than) operator: 4.5.4.1. Relational operators
>= (greater-than-or-equal) operator: 4.5.4.1. Relational operators
>> (to open file for appending): 4.9. Filehandles
* (asterisk)
multiplication operator: 4.5.3. Arithmetic Operators
prototype symbol (typeglob): 4.7.5. Prototypes
regular expression metacharacter: 4.6.2. Regular Expression Syntax
** (exponentiation) operator: 4.5.3. Arithmetic Operators
*= (assignment) operator: 4.5.6. Assignment Operators
@ (at sign)
@_ array: 4.7.2. Passing Arguments
dereferencing with: 4.8.2. Dereferencing
format fieldholders: 4.12. Formats
prototype symbol (list): 4.7.5. Prototypes
signifying arrays: 4.2.5.1. Arrays
(backslash)
creating references: 4.8.1. Creating References
reference creation operator: 4.5.2. Unary Operators
! (bang)
!= (not equal to) operator: 4.5.4.2. Equality operators
CPAN.pm eval command: 2.4.4. Installing Modules with the CPAN Module
logical negation operator: 4.5.2. Unary Operators
Perl debugger command: 6.2. Debugger Commands
!! Perl debugger command: 6.2. Debugger Commands
{} (braces)
delimiting statement blocks: 4.3. Statements
regular expression quantifiers: 4.6.6. Quantifiers
{{ Perl debugger command: 6.2. Debugger Commands
{ Perl debugger command: 6.2. Debugger Commands
[] (brackets)
Perl debugger command: 6.2. Debugger Commands
regular expression metacharacter: 4.6.4. Character Classes
^ (caret)
in [...] construct: 4.6.4. Character Classes
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager
regular expression metacharacter: 4.6.2. Regular Expression Syntax
XOR bitwise operator: 4.5.10. Bitwise Operators
^= (assignment) operator: 4.5.6. Assignment Operators
: (colon), in package names: 7.1. Namespaces and Packages
, (comma)
number legibility without: 4.2.1. Numbers
operator: 4.5.11.3. Comma operator
$ (dollar sign)
dereferencing with: 4.8.2. Dereferencing
prototype symbol (scalar): 4.7.5. Prototypes
regular expression metacharacter: 4.6.2. Regular Expression Syntax
signifying scalar variables: 4.2.5. Variables
$ variables
$' variable: 4.4.5. Regular Expression Special Variables
$1, $2, $3, ...: 4.4.5. Regular Expression Special Variables
4.6.7. Pattern Match Variables
$& variable: 4.4.5. Regular Expression Special Variables
$< variable: 4.4.1. Global Special Variables
$> variable: 4.4.1. Global Special Variables
$@ variable: 4.4.1. Global Special Variables
$ variable: 4.4.1. Global Special Variables
$` variable: 4.4.5. Regular Expression Special Variables
$! variable: 4.4.1. Global Special Variables
$[ variable: 4.4.1. Global Special Variables
$] variable: 4.4.1. Global Special Variables
$^ variable: 4.4.6. Filehandle Special Variables
$^A variable: 4.4.1. Global Special Variables
$^D variable: 4.4.1. Global Special Variables
$^E variable: 4.4.1. Global Special Variables
$^F variable: 4.4.1. Global Special Variables
$^H variable: 4.4.1. Global Special Variables
$^I variable: 4.4.1. Global Special Variables
$^L variable: 4.4.1. Global Special Variables
$^M variable: 4.4.1. Global Special Variables
$^N variable: 4.4.5. Regular Expression Special Variables
$^O variable: 4.4.1. Global Special Variables
$^P variable: 4.4.1. Global Special Variables
$: variable: 4.4.1. Global Special Variables
$, variable: 4.4.1. Global Special Variables
$$ variable: 4.4.1. Global Special Variables
$. variable: 4.4.1. Global Special Variables
$= variable: 4.4.6. Filehandle Special Variables
$# variable: 4.4.1. Global Special Variables
$- variable: 4.4.6. Filehandle Special Variables
$( variable: 4.4.1. Global Special Variables
$) variable: 4.4.1. Global Special Variables
$% variable: 4.4.6. Filehandle Special Variables
$+ variable: 4.4.5. Regular Expression Special Variables
$? variable: 4.4.1. Global Special Variables
$" variable: 4.4.1. Global Special Variables
$; variable: 4.4.1. Global Special Variables
$/ variable: 4.4.1. Global Special Variables
$~ variable: 4.4.6. Filehandle Special Variables
$_ ($ARG) variable: 4.4.1. Global Special Variables
$0 variable: 4.4.1. Global Special Variables
$| variable: 4.4.6. Filehandle Special Variables
$^T variable: 4.4.1. Global Special Variables
$^W variable: 4.4.1. Global Special Variables
$^X variable: 4.4.1. Global Special Variables
. (dot)
concatenation operator: 4.5.11.4. String operator
Perl debugger command: 6.2. Debugger Commands
regular expression metacharacter: 4.6.2. Regular Expression Syntax
.. (range) operator: 4.5.11.1. Range operator
... (range) operator: 4.5.11.1. Range operator
.= (assignment) operator: 4.5.6. Assignment Operators
= (equal sign)
== (equal to) operator: 4.5.4.2. Equality operators
assignment operator: 4.2.5. Variables
4.5.6. Assignment Operators
for embedded documentation (pod): 4.1. Program Structure
in hash name/value pairs: 4.2.5.2. Hashes
for pod commands: 4.13. Pod
=> operator, defining key/value pairs: 4.2.5.2. Hashes
4.5.11.3. Comma operator
/ (forward slash): 2.4.4. Installing Modules with the CPAN Module
# (hash mark)
#! (shebang) line: 3. The Perl Executable
for comments: 4.1. Program Structure
format fieldholder: 4.12. Formats
- (hyphen)
arithmetic negation operator: 4.5.2. Unary Operators
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager
Perl debugger command: 6.2. Debugger Commands
in [...] construct: 4.6.4. Character Classes
-> (arrow) operator: 4.5.1. The Arrow Operator
dereferencing with: 4.8.2.1. Arrow dereferencing
-- (autodecrement) operator: 4.5.5. Autoincrement and Autodecrement
( ) (parentheses)
around function arguments: 5. Function Reference
operator precedence and: 4.5. Operators
regular expression metacharacter: 4.6.2. Regular Expression Syntax
(?...) extended regular expression syntax: 4.6.8. Extended Regular Expressions
% (percent sign)
%SIG: 4.10. Signals
dereferencing with: 4.8.2. Dereferencing
modulus operator: 4.5.3. Arithmetic Operators
prototype symbol (hash): 4.7.5. Prototypes
signifying variable type: 4.2.5.2. Hashes
%= (assignment) operator: 4.5.6. Assignment Operators
+ (plus)
1: 4.5.5. Autoincrement and Autodecrement
regular expression metacharacter: 4.6.2. Regular Expression Syntax
unary operator: 4.5.2. Unary Operators
+= (assignment) operator: 4.5.6. Assignment Operators
? (question mark)
regular expression metacharacter: 4.6.2. Regular Expression Syntax
?: (conditional) operator: 4.5.11.2. Conditional operator
?...? pattern match operator: 4.6.1. Pattern-Matching Operators
?...? Perl debugger command: 6.2. Debugger Commands
; (semicolon)
ending Perl statements: 4.1. Program Structure
in prototype declarations: 4.7.5. Prototypes
/ (slash)
division operator: 4.5.3. Arithmetic Operators
encoding in URLs: 9.2. URL Encoding
/= (assignment) operator: 4.5.6. Assignment Operators
/.../ pattern match operator: 4.6. Regular Expressions
/.../ Perl debugger command: 6.2. Debugger Commands
~ (tilde)
bitwise negation operator: 4.5.2. Unary Operators
suppressing output whitespace: 4.12. Formats
~~ to print strings in fields: 4.12. Formats
_ (underscore)
_ _END_ _ constant: 4.4.4. Global Special Constants
_ _END_ _ marker: 8.5. AutoLoader
_ _FILE_ _ constant: 4.4.4. Global Special Constants
filehandle: 4.4.3. Global Special Filehandles
improving number legibility: 4.2.1. Numbers
_ _LINE_ _ constant: 4.4.4. Global Special Constants
_ _PACKAGE_ _ constant: 4.4.4. Global Special Constants
| (vertical bar)
format fieldholders: 4.12. Formats
OR bitwise operator: 4.5.10. Bitwise Operators
Perl debugger command: 6.2. Debugger Commands
regular expression metacharacter: 4.6.2. Regular Expression Syntax
|= (assignment) operator: 4.5.6. Assignment Operators
|| Perl debugger command: 6.2. Debugger Commands
||= (assignment) operator: 4.5.6. Assignment Operators

Numbers

038 (octal value) sequence: 4.6.3. Escaped Sequences

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

a command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
a command (Perl debugger): 6.2. Debugger Commands
-A file test operator: 4.5.8. File Test Operators
-a option (dprofpp): 6.5. The Perl Profiler
-a option (perlbug): 6.6. The perlbug Program
a (alarm) sequence: 4.6.3. Escaped Sequences
abandon( ) (Net::LDAP): 19.4. Net::LDAP Methods
abort( ) (Net::FTP): 18.2. Net::FTP
abs( )
Perl built-in: 5. Function Reference
URI::URL module: 20.5.3. URI::URL
-accelerator option (Menubutton): 21.14.1. Menu Item Options
accept( )
CGI.pm module: 10.7. CGI.pm Reference
HTTP::Daemon module: 20.3.7. HTTP::Daemon
IO::Socket module: 15.2. The IO::Socket Module
15.2.2. Server-Side Sockets
15.2.3. IO::Socket Methods
Perl built-in: 5. Function Reference
socket function: 15.1. Built-in Socket Functions
15.1.3. Server Connections
account entries (.netrc): 18.3. FTP Configuration with Net::Netrc
account( ) (Net::Netrc): 18.3. FTP Configuration with Net::Netrc
$ACCUMULATOR ($^A) variable: 4.4.1. Global Special Variables
activate( )
Listbox widget: 21.10.2. Listbox Methods
Scrollbar widget: 21.9.1. Scrollbar Methods
active( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
active index
Listbox widget: 21.10.1. Listbox Indexes
Menu widget: 21.15.1. Menu Indexes
-activebackground option (widgets): 21.3. Common Widget Configuration Options
-activeborderwidth option (Menu): 21.15. The Menu Widget
-activeborderwidth option (widgets): 21.3. Common Widget Configuration Options
-activeforeground option (widgets): 21.3. Common Widget Configuration Options
ActivePerl distribution: 2.3.2.1. ActivePerl
2.4.3. Installing Modules with ActiveState Perl
-activerelief option (Scrollbar): 21.9. The Scrollbar Widget
ActiveState Perl
installing documentation: 2.5.1. Installing the Documentation
installing modules with: 2.4.3. Installing Modules with ActiveState Perl
active_times( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
add( )
Digest modules: 8.57. Digest
Digest::MD5 module: 8.58. Digest::MD5
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
16.2.2. Better Header Control with Mail::Send
Menu widget: 21.15.2. Menu Methods
Net::LDAP: 19.3. Adding an Entry to the Directory with Net::LDAP
19.4. Net::LDAP Methods
AddConnection( ) (Win32::NetResource): 22.11. Win32::NetResource
add_content( ) (HTTP::Message): 20.3.8. HTTP::Message
add_cookie_header( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies
addfile( )
Digest modules: 8.57. Digest
Digest::MD5 module: 8.58. Digest::MD5
add_group( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
AddHeader( ), Win32::Internet module: 22.7.3. HTTP Functions
AddItems( ) (Menubutton): 21.14.2. Menubutton Methods
add_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
address( ) (Mail::Address): 16.2.7. Mail::Address Reference
addresses (email), parsing: 16.2.6. Parse Email Addresses with Mail::Address
add_signature( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
addTag( ) (Canvas): 21.12.3. Canvas Methods
administering network servers: 22.10. Win32::NetAdmin
-after option (pack geometry manager): 21.2.1. The pack Geometry Manager
_agent( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
20.2.3. LWP::UserAgent
.al file extension: 8.5. AutoLoader
alarm( ): 5. Function Reference
:all method group: 10.2. Importing Method Groups
All( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods
Alloc( ) (Win32::Console): 22.2. Win32::Console
alternate quoting schemes: 4.2.2. String Interpolation
ampersand (&)
AND bitwise operator: 4.5.10. Bitwise Operators
calling subroutines: 4.7.1. Calling Subroutines
in encoded URLs: 9.2. URL Encoding
prototype symbol: 4.7.5. Prototypes
&& (logical AND) operator: 4.5.9. Logical Operators
&&= (assignment) operator: 4.5.6. Assignment Operators
&= (assignment) operator: 4.5.6. Assignment Operators
anchor index
Entry widget: 21.8.1. Text Indexes
Listbox widget: 21.10.1. Listbox Indexes
-anchor option
pack geometry manager: 21.2.1. The pack Geometry Manager
place geometry manager: 21.2.3. The place Geometry Manager
widgets: 21.3. Common Widget Configuration Options
anchors in regular expressions: 4.6.5. Anchors
and (logical AND) operator: 4.5.9. Logical Operators
AND (&) operator, bitwise: 4.5.10. Bitwise Operators
AND (&&) operator, logical: 4.5.9. Logical Operators
angle brackets (<>)
<=> (comparison) operator: 4.5.4.2. Equality operators
<...> (line-input) operator: 4.9. Filehandles
<<= (assignment) operator: 4.5.6. Assignment Operators
<< debugger commands, and: 6.2. Debugger Commands
< (less-than) operator: 4.5.4.1. Relational operators
<= (less-than-or-equal) operator: 4.5.4.1. Relational operators
>>= (assignment) operator: 4.5.6. Assignment Operators
> (greater-than) operator: 4.5.4.1. Relational operators
>= (greater-than-or-equal) operator: 4.5.4.1. Relational operators
>> to open file for appending: 4.9. Filehandles
anonymous data, referencing: 4.8.1.1. Referencing anonymous data
anonymous FTP: 2.1. The CPAN Architecture
18.1. The FTP Protocol
anonymous subroutines: 4.7. Subroutines
antique_client( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
AnyDBM_File module: 8.1. AnyDBM_File
Apache modules: 11.7. Apache:: Modules
Apache::DumpHeaders module: 11.3. mod_perl Handlers
Apache::Include module: 11.5. Server-Side Includes with mod_perl
Apache server, mod_perl with: 11. Web Server Programmingwith mod_perl
apop( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3
appe( ) (Net::FTP): 18.2. Net::FTP
append( )
CGI.pm module: 10.7. CGI.pm Reference
Net::FTP module: 18.2. Net::FTP
append_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
$ARG ($_) variable: 4.4.1. Global Special Variables
arguments, passing to subroutines: 4.7.2. Passing Arguments
@ARGV array: 4.4.2. Global Special Arrays and Hashes
ARGV filehandle: 4.4.3. Global Special Filehandles
4.9. Filehandles
-argv option (perlcc): 3.4. The Perl Compiler
$ARGV variable: 4.4.1. Global Special Variables
arithmetic operators: 4.5.3. Arithmetic Operators
arrays: 4.2. Data Types and Variables
4.2.5.1. Arrays
functions for processing: 5.1. Perl Functions by Category
special (predefined): 4.4.2. Global Special Arrays and Hashes
arrow (->) operator: 4.5.1. The Arrow Operator
dereferencing with: 4.8.2.1. Arrow dereferencing
article command (NNTP): 17.1. The NNTP Protocol
article( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
articles, news: 17.1. The NNTP Protocol
As( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods
ascii( ) (Net::FTP module): 18.2. Net::FTP
Ascii( ) (Win32::Internet): 22.7.2. FTP Functions
as_HTML( ) (HTML::Parser): 20.4.3. HTML::Element
aspect( ) (Frame widget): 21.18.1. Toplevel Methods
assign function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
assignment operators: 4.5.6. Assignment Operators
as_something method: 14.4. SOAP::Serializer
as_string( )
HTTP::Cookies module: 20.3.6. HTTP::Cookies
HTTP::Request module: 20.3.1. HTTP::Request
HTTP::Response module: 20.3.2. HTTP::Response
LWP::RobotUA module: 20.2.1. LWP::RobotUA Sections
URI::URL module: 20.5.3. URI::URL
asterisk (*)
multiplication operator: 4.5.3. Arithmetic Operators
prototype symbol (typeglob): 4.7.5. Prototypes
regular expression metacharacter: 4.6.2. Regular Expression Syntax
** (exponentiation) operator: 4.5.3. Arithmetic Operators
**= (assignment) operator: 4.5.6. Assignment Operators
*= (assignment) operator: 4.5.6. Assignment Operators
at sign (@)
@_ array: 4.7.2. Passing Arguments
dereferencing with: 4.8.2. Dereferencing
format fieldholders: 4.12. Formats
prototype symbol (list): 4.7.5. Prototypes
signifying arrays: 4.2.5.1. Arrays
atan2( ): 5. Function Reference
Attlist handler (Expat): 13.3. Expat Handlers
attr( ) (HTML::Parser): 20.4.3. HTML::Element
Attr( ) (Win32::Console): 22.2. Win32::Console
Attribute::Handlers module: 8.2. Attribute::Handlers
diagnostics: 8.2. Attribute::Handlers
attributes module: 8.3. attributes
attrs module: 8.4. attrs
attrs.pm (see attributes module)
authentication, POP3: 16.1.3. Retrieving Email with Net::POP3
authinfo( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
authorize( ) (Net::FTP): 18.2. Net::FTP
auth_type( ) (CGI.pm): 10.7. CGI.pm Reference
autobundle command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
AutoCommit attribute (DBI): 12.2.3. Database Handles and Statement Handles
autodecrement (--) operator: 4.5.5. Autoincrement and Autodecrement
autoEscape( ) (CGI.pm): 10.7. CGI.pm Reference
autoincrement (++) operator: 4.5.5. Autoincrement and Autodecrement
autoload function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
AutoLoader module: 8.5. AutoLoader
automation client: 23. OLE Automation
automation controller: 23. OLE Automation
automation modules: 23. OLE Automation
automation objects, creation of: 23. OLE Automation
automation server: 23. OLE Automation
AutoSplit module: 8.6. AutoSplit
autotype( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
autouse module: 8.7. autouse
available_drivers( ) (DBI): 12.3. DBI Methods

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

b command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
b command (Perl debugger): 6.2. Debugger Commands
-b file test operator: 4.5.8. File Test Operators
B<> interior sequence (pod): 4.13.2. Interior Sequences
B module: 8.8. B
-b option
form geometry manager: 21.2.4. The form Geometry Manager
perlbug: 6.6. The perlbug Program
B::Asmdata module: 8.9. B::Asmdata
B::Assembler module: 8.10. B::Assembler
B::Bytecode module: 8.12. B::Bytecode
B::C module: 8.13. B::C
B::CC module: 8.14. B::CC
B::Concise module: 8.15. B::Concise
B::Debug module: 8.16. B::Debug
B::Deparse module: 8.17. B::Deparse
B::Disassembler module: 8.18. B::Disassembler
B::Lint module: 8.19. B::Lint
B::Showlex module: 8.20. B::Showlex
B::Stackobj module: 8.21. B::Stackobj
B::Terse module: 8.22. B::Terse
B::Xref module: 8.23. B::Xref
=back command (pod): 4.13.1. Paragraph Tags
-background option (widgets): 21.3. Common Widget Configuration Options
backreferences: 4.6.7. Pattern Match Variables
backslash ( )
creating references: 4.8.1. Creating References
reference creation operator: 4.5.2. Unary Operators
1, 2, ... pattern match variables: 4.6.7. Pattern Match Variables
Backup( ) (Win32::EventLog): 22.4. Win32::Eventlog
bang (!)
!= (not equal to) operator: 4.5.4.2. Equality operators
CPAN.pm eval command: 2.4.4. Installing Modules with the CPAN Module
logical negation operator: 4.5.2. Unary Operators
Perl debugger command: 6.2. Debugger Commands
!! Perl debugger command: 6.2. Debugger Commands
!~ (pattern match) operator: 4.5.7. Pattern Match Operators
banner( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
Barber, Stan: 17. Usenet News
Barr, Graham: 16. Email Connectivity
base( )
HTTP::Response module: 20.3.2. HTTP::Response
URI::URL module: 20.5.3. URI::URL
base module: 8.24. base
$BASETIME ($^T) variable: 4.4.1. Global Special Variables
bbox( )
Canvas widget: 21.12.3. Canvas Methods
Listbox widget: 21.10.2. Listbox Methods
Text widget: 21.11.2. Text Methods
bcc( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send
-bd option (widgets): 21.3. Common Widget Configuration Options
b64digest( ) (Digest modules): 8.57. Digest
b64digest (Digest::MD5 module): 8.58. Digest::MD5
-before option (pack geometry manager): 21.2.1. The pack Geometry Manager
=begin command (pod): 4.13.1. Paragraph Tags
Benchmark module: 8.25. Benchmark
-bg option (widgets): 21.3. Common Widget Configuration Options
-bigincrement option (Scale): 21.13. The Scale Widget
bigint module: 8.26. bigint
bignum module: 8.27. bignum
bigrat module: 8.28. bigrat
binary copies of Perl: 2.3.1. Installing on Unix
binary( ) (Net::FTP): 18.2. Net::FTP
binary Perl distributions: 2.3.1. Installing on Unix
2.3.2.1. ActivePerl
Binary( ) (Win32::Internet): 22.7.2. FTP Functions
bind( ): 5. Function Reference
Canvas module: 21.12.3. Canvas Methods
Socket module: 15.1. Built-in Socket Functions
15.1.3. Server Connections
bind_col( ) (DBI): 12.3. DBI Methods
bind_columns( ) (DBI): 12.3. DBI Methods
bind( ) (Net::LDAP): 19.4. Net::LDAP Methods
bind_param( ) (DBI): 12.3. DBI Methods
binmode( ): 5. Function Reference
-bitmap option (widgets): 21.3. Common Widget Configuration Options
bitwise operators: 4.5.10. Bitwise Operators
bless( ): 5. Function Reference
blib module: 8.29. blib
block of statements: 4.3. Statements
Body( ) (Mail::Internet module): 16.2.5. Mail::Internet Reference
body( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
bookdb.dir, bookdb.pag files: 12.1. DBM Databases and DBM Hashes
books, Perl-related: 1.4.9. Books
-bordermode option (place geometry manager): 21.2.3. The place Geometry Manager
-borderwidth option (widgets): 21.3. Common Widget Configuration Options
-bottom option, form geometry manager: 21.2.4. The form Geometry Manager
-bottomspring option, form geometry manager: 21.2.4. The form Geometry Manager
-bp option, form geometry manager: 21.2.4. The form Geometry Manager
braces {}
delimiting statement blocks: 4.3. Statements
regular expression quantifiers: 4.6.6. Quantifiers
{{ Perl debugger command: 6.2. Debugger Commands
{ Perl debugger command: 6.2. Debugger Commands
brackets []
Perl debugger command: 6.2. Debugger Commands
regular expression metacharacter: 4.6.4. Character Classes
-bs option, form geometry manager: 21.2.4. The form Geometry Manager
bugs in Perl, reporting: 6.6. The perlbug Program
built-in functions: 5. Function Reference
listed alphabetically: 5. Function Reference
listed by category: 5.1. Perl Functions by Category
socket-related: 15.1. Built-in Socket Functions
built-in Perl variables: 4.4. Special Variables
Bundle:: argument: 2.4.4. Installing Modules with the CPAN Module
button( ) (CGI.pm): 10.7. CGI.pm Reference
Button widget (Perl/Tk): 21.4. The Button Widget
byte( ) (Net::FTP): 18.2. Net::FTP
Bytecode backend (Perl compiler): 3.4. The Perl Compiler
ByteLoader module: 8.31. ByteLoader
byteperl interpreter: 3.4. The Perl Compiler
bytes module: 8.30. bytes

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C, CC backends (Perl compiler): 3.4. The Perl Compiler
c command (Perl debugger): 6.2. Debugger Commands
-c file test operator: 4.5.8. File Test Operators
C<> interior sequence (pod): 4.13.2. Interior Sequences
-C option (perlbug): 6.6. The perlbug Program
-C option (perlcc): 3.4. The Perl Compiler
call( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
callbacks, widget (Perl/Tk): 21.1.3. Callbacks
caller( ): 5. Function Reference
Camel image: 1.4.9. Books
cancel( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send
CancelConnection( ) (Win32::NetResource): 22.11. Win32::NetResource
canon( ) (Mail::Address): 16.2.7. Mail::Address Reference
CanonicalizeURL( ) (Win32::Internet): 22.7.1. General Internet Methods
Canvas widget (Perl/Tk): 21.12. The Canvas Widget
Capini, Aldo: 22. Win32 Modules and Extensions
caret (^)
in [...] construct: 4.6.4. Character Classes
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager
regular expression metacharacter: 4.6.2. Regular Expression Syntax
XOR bitwise operator: 4.5.10. Bitwise Operators
^= (assignment) operator: 4.5.6. Assignment Operators
Carp module: 8.32. Carp
cascade( ) (Menubutton): 21.14.2. Menubutton Methods
cc( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send
C_constant function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
Cd( ) (Win32::Internet): 22.7.2. FTP Functions
CdataEnd handler (Expat): 13.3. Expat Handlers
CdataStart handler (Expat): 13.3. Expat Handlers
cdup( ) (Net::FTP): 18.2. Net::FTP
cget( ) (Perl/Tk): 21.1.1.2. The cget method
:cgi, :cgi-lib method groups: 10.2. Importing Method Groups
CGI modules: 8.33. CGI
CGI::Apache module: 8.34. CGI::Apache
CGI::Carp module: 8.35. CGI::Carp
CGI::Cookie module: 8.36. CGI::Cookie
CGI::Fast module: 8.37. CGI::Fast
CGI::Pretty: 8.38. CGI::Pretty
CGI::Push module: 8.39. CGI::Push
CGI::Switch module: 8.40. CGI::Switch
CGI programs: 9. CGI Overview
debugging: 10.6. Debugging
environment variables for: 9.4. CGI Environment Variables
extra path information: 9.3. Extra Path Information
maintaining state: 10.3. Maintaining State
named parameters: 10.4. Named Parameters
running with mod_perl: 11.4. Running CGI Scripts with mod_perl
URL encoding: 9.2. URL Encoding
CGI.pm module: 9. CGI Overview
10. The CGI.pm Module
debugging scripts: 10.6. Debugging
generating HTML tags: 10.1. HTML Tag Generation
importing method groups: 10.2. Importing Method Groups
JavaScript features with: 10.5. Using JavaScript Features
named parameters: 10.4. Named Parameters
ChangeType( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods
Char handler (Expat): 13.3. Expat Handlers
character classes: 4.6.4. Character Classes
characters
l (lowercase) character: 4.6.4. Character Classes
u (uppercase) character: 4.6.4. Character Classes
charnames: 8.41. charnames
chdir( ): 5. Function Reference
checkbox( ) (CGI.pm): 10.7. CGI.pm Reference
checkbox_group( ) (CGI.pm): 10.7. CGI.pm Reference
checkbutton( ) (Menubutton): 21.14.2. Menubutton Methods
Checkbutton widget (Perl/Tk): 21.5. The Checkbutton Widget
$CHILD_ERROR ($?) variable: 4.4.1. Global Special Variables
children method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
chmod( ): 5. Function Reference
chomp( ): 5. Function Reference
chop( ): 5. Function Reference
chown( ): 5. Function Reference
chr( ): 5. Function Reference
Christiansen, Tom: 1.4.5. www.perl.com
chroot( ): 5. Function Reference
Clark, James: 13.1. XML Parsing and Validation
Class::ISA module: 8.42. Class::ISA
class methods: 7.4. Object Syntax
-class option
Frame widget: 21.17. The Frame Widget
toplevel widget: 21.18. The Toplevel Widget
classes, functions for: 5.1. Perl Functions by Category
Class::Struct module: 8.43. Class::Struct
Class::Template module: 8.43. Class::Struct
clean command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
Clear( ), Win32::EventLog module: 22.4. Win32::Eventlog
clear( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies
clear_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
client( ) (Frame widget): 21.18.1. Toplevel Methods
client-side socket connections: 15.1.2. Client Connections
15.2.1. Client-Side Sockets
clipboard, manipulating: 22.1. Win32::Clipboard
clone( )
HTTP::Headers module: 20.3.3. HTTP::Headers
HTTP::Message module: 20.3.8. HTTP::Message
LWP::UserAgent module: 20.2.3. LWP::UserAgent
Clone( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods
Close( )
Win32::Internet module: 22.7.1. General Internet Methods
Win32::ODBC: 24.1. ODBC Methods and Properties
Win32::Shortcut module: 22.18. Win32::Shortcut
closedir( ): 5. Function Reference
-closeenough option (Canvas): 21.12. The Canvas Widget
Resume( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods
Cls( ) (Win32::Console): 22.2. Win32::Console
code( ) (HTTP::Response): 20.3.2. HTTP::Response
ColAttributes( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
collection objects: 23.3. Win32::OLE::Enum
colon (:) in package names: 7.1. Namespaces and Packages
-colormap option
Frame widget: 21.17. The Frame Widget
toplevel widget: 21.18. The Toplevel Widget
colormapwindows( ) (Frame widget): 21.18.1. Toplevel Methods
colors, widget: 21.1.4. Colors and Fonts
-column option (grid manager): 21.2.2. The grid Geometry Manager
-columnspan option (grid manager): 21.2.2. The grid Geometry Manager
CombineURL( ) (Win32::Internet): 22.7.1. General Internet Methods
comma (,)
number legibility without: 4.2.1. Numbers
operator: 4.5.11.3. Comma operator
command( )
Frame widget: 21.18.1. Toplevel Methods
Menubutton widget: 21.14.2. Menubutton Methods
command-line options (perl interpreter): 3.2. Command-Line Options
"Command not found" error: 3. The Perl Executable
-command option: 21.1.3. Callbacks
Button widget: 21.4. The Button Widget
Checkbutton widget: 21.5. The Checkbutton Widget
Menubutton widget: 21.14.1. Menu Item Options
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
command processing on #! line: 3.1. Command Processing
commands, Perl debugger: 6.2. Debugger Commands
Comment handler (Expat): 13.3. Expat Handlers
comment( ) (Mail::Address): 16.2.7. Mail::Address Reference
comments: 4.1. Program Structure
commit( ) (DBI): 12.3. DBI Methods
Common Gateway Interface: 9. CGI Overview
9.4. CGI Environment Variables
(see also CGI)
compare( ) (Net::LDAP): 19.4. Net::LDAP Methods
compare( ) (Text widget): 21.11.2. Text Methods
comparison operators: 4.5.4.1. Relational operators
4.5.4.2. Equality operators
compiler, Perl: 3.4. The Perl Compiler
complex data structures: 4.8. References and Complex Data Structures
concatenation (.) operator: 4.5.11.4. String operator
conditional (?:) operator: 4.5.11.2. Conditional operator
conditional modifiers: 4.3.1.4. Modifiers
conditional statements: 4.3.1. Conditionals and Loops
conferences, Perl-related: 1.4.8. Perl Conferences
Config module: 8.44. Config
ConfigDSN( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
Config.pm file: 2.3.1. Installing on Unix
config_sh( ) (Config module): 8.44. Config
Configure command (Unix): 2.3.1. Installing on Unix
configure( ) (Perl/Tk): 21.1.1.1. The configure method
config_vars( ) (Config module): 8.44. Config
-confine option (Canvas): 21.12. The Canvas Widget
conn_cache( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
connect( ): 5. Function Reference
DBI module: 12.3. DBI Methods
Socket module: 15.1. Built-in Socket Functions
15.1.2. Client Connections
ConnectBackoff( ) (Win32::Internet): 22.7.1. General Internet Methods
Connection( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
ConnectRetries( ) (Win32::Internet): 22.7.1. General Internet Methods
ConnectTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods
console implementation: 22.2. Win32::Console
constant module: 8.45. constant
constant( ) (Win32::FileSecurity): 22.6. Win32::FileSecurity
constants, global special (predefined): 4.4.4. Global Special Constants
constant_types function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
constructors: 7.3. Object-Oriented Perl
content( )
HTML::Parser module: 20.4.3. HTML::Element
HTTP::Message module: 20.3.8. HTTP::Message
content_ref( ) (HTTP::Message): 20.3.8. HTTP::Message
Content-type header: 9.1.2. Creating Virtual Documents
context: 4.2.6. Scalar and List Contexts
continue block: 4.3.1.1. while loops
ControlReceiveTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods
ControlSendTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods
cookie( )
CGI.pm module: 10.7. CGI.pm Reference
LWP::UserAgent module: 20.2.3. LWP::UserAgent
Cookie header: 20.3.6. HTTP::Cookies
cookies: 8.36. CGI::Cookie
10.3. Maintaining State
HTTP::Cookies module: 20.3.6. HTTP::Cookies
HTTP::Cookies::Netscape module: 20.3.6.1. HTTP::Cookies::Netscape
Cooper, Clark: 13.1. XML Parsing and Validation
coords( )
Canvas widget: 21.12.3. Canvas Methods
Scale widget: 21.13.1. Scale Methods
cos( ): 5. Function Reference
Count( )
Win32::OLE::Enum module: 23.3. Win32::OLE::Enum
CPAN (Comprehensive Perl Archive Network): 1.4.4. CPAN
2. Installing Perl
architecture: 2.1. The CPAN Architecture
commands: 2.4.4. Installing Modules with the CPAN Module
finding available modules: 2.4.1. Locating Modules
website: 2.1. The CPAN Architecture
.cpan directory: 2.4.4. Installing Modules with the CPAN Module
CPAN::FirstTime module: 8.47. CPAN::FirstTime
CPAN::Nox module: 8.48. CPAN::Nox
CPAN::Config: 2.4.4. Installing Modules with the CPAN Module
CPAN.pm module: 2.4.4. Installing Modules with the CPAN Module
8.46. CPAN
crack( ) (URI::URL): 20.5.3. URI::URL
CrackURL( ) (Win32::Internet): 22.7.1. General Internet Methods
Create( )
Win32::Process module: 22.14. Win32::Process
Win32::Registry module: 22.15.1. Win32::Registry Methods
Connect( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods
createArc( ) (Canvas): 21.12.1. Canvas Creation Methods
createBitmap( ) (Canvas): 21.12.1. Canvas Creation Methods
createImage( ) (Canvas): 21.12.1. Canvas Creation Methods
createLine( ) (Canvas): 21.12.1. Canvas Creation Methods
createOval( ) (Canvas): 21.12.1. Canvas Creation Methods
createPolygon( ) (Canvas): 21.12.1. Canvas Creation Methods
createRectangle( ) (Canvas): 21.12.1. Canvas Creation Methods
createText( ) (Canvas): 21.12.1. Canvas Creation Methods
CreateURL( ) (Win32::Internet): 22.7.1. General Internet Methods
createWindow( ) (Canvas): 21.12.1. Canvas Creation Methods
credentials( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
crypt( ): 5. Function Reference
C_stringify function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
curly braces: 4.3. Statements
current_age( ) (HTTP::Response): 20.3.2. HTTP::Response
current index (Text widget): 21.11.1. Text Indexes and Modifiers
current_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
curselection( ) (Listbox): 21.10.2. Listbox Methods
-cursor option (widgets): 21.3. Common Widget Configuration Options
Cursor( ) (Win32::Console): 22.2. Win32::Console
customizing Perl debugger: 6.4. Customizing the Debugger
=cut command (pod): 4.13.1. Paragraph Tags
Cwd module: 8.49. Cwd
cwd( ) (Net::FTP): 18.2. Net::FTP
Cygwin: 2.3.2. Installing on Win32

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

d (digit) character class: 4.6.4. Character Classes
d command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
d command (Perl debugger): 6.2. Debugger Commands
-d file test operator: 4.5.8. File Test Operators
-d option (perlbug): 6.6. The perlbug Program
daemon( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
dash: 4.6.4. Character Classes
Data( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
DATA command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session
Data::Dumper module: 8.50. Data::Dumper
DATA filehandle: 4.4.3. Global Special Filehandles
data( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
data_sources( ) (DBI): 12.3. DBI Methods
data types: 4.2. Data Types and Variables
complex data structures: 4.8. References and Complex Data Structures
databases: 12. Databases and Perl
database handles (DBI methods): 12.2.3. Database Handles and Statement Handles
DBDs (database drivers): 12.2.1. Database Drivers (DBDs)
DBI module: 12.2. Design of DBI
DBM (Database Management) facility: 12.1. DBM Databases and DBM Hashes
dataend( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
DataHash( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
DataReceiveTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods
datasend( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
DataSendTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods
DataSources( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
date and time
functions for: 5.1. Perl Functions by Category
HTTP::Date module: 20.3.5. HTTP::Date
date( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
DB module: 8.51. DB
DBDs (database drivers): 12. Databases and Perl
12.2.1. Database Drivers (DBDs)
DB_File module: 8.52. DB_File
DBI_ environment variables: 12.4. DBI Environment Variables
DBI module: 1.1. What's Perl Good For?
12. Databases and Perl
12.2. Design of DBI
database and statement handles: 12.2.3. Database Handles and Statement Handles
environment variables for: 12.4. DBI Environment Variables
methods of: 12.3. DBI Methods
DBM (Database Management) facility: 12.1. DBM Databases and DBM Hashes
dbmclose( ): 5. Function Reference
dbmopen( ): 5. Function Reference
12.1. DBM Databases and DBM Hashes
Debug( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
Debug style (XML::Parser): 13.4. XML::Parser Styles
debugging: 6. Debugging
CGI scripts: 10.6. Debugging
-d, -D options (perl): 6.1. The Perl Debugger
6.5. The Perl Profiler
Perl debugger: 6.1. The Perl Debugger
commands for: 6.2. Debugger Commands
customizing: 6.4. Customizing the Debugger
Perl profiler (DProf): 6.5. The Perl Profiler
perlbug program: 6.6. The perlbug Program
$DEBUGGING ($^D) variable: 4.4.1. Global Special Variables
debug_print( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
declarations: 4.1. Program Structure
packages: 7.1. Namespaces and Packages
private vs. local: 4.7.4. Private and Local Variables
subroutines: 4.7. Subroutines
variables: 4.2.7. Declarations and Scope
Default handler (Expat): 13.3. Expat Handlers
default_port( ) (URI::URL): 20.5.3. URI::URL
defaults( ) (CGI.pm): 10.7. CGI.pm Reference
defined( ): 5. Function Reference
deiconify( ) (Frame widget): 21.18.1. Toplevel Methods
del( ) (DB_File module): 8.52. DB_File
delay( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections
delete( ): 5. Function Reference
Canvas widget: 21.12.3. Canvas Methods
CGI.pm module: 10.7. CGI.pm Reference
Entry widget: 21.8.2. Entry Methods
HTML::Parser module: 20.4.3. HTML::Element
Listbox widget: 21.10.2. Listbox Methods
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
Menu widget: 21.15.2. Menu Methods
Net::FTP module: 18.2. Net::FTP
Net::LDAP: 19.4. Net::LDAP Methods
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
Text widget: 21.11.2. Text Methods
Delete( ) (Win32::Internet module): 22.7.2. FTP Functions
delete_all( ) (CGI.pm): 10.7. CGI.pm Reference
delete_content( ) (HTML::Parser): 20.4.3. HTML::Element
DeleteKey( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
delete_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
delete_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
DeleteValue( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
del_group( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
delta( ) (Scrollbar): 21.9.1. Scrollbar Methods
Deparse backend (Perl compiler): 3.4. The Perl Compiler
dereferencing: 4.8.2. Dereferencing
deselect( )
Checkbutton widget: 21.5.1. Checkbutton Methods
Radiobutton widget: 21.6.1. Radiobutton Methods
DESTROY method: 7.3. Object-Oriented Perl
Devel::DProf module: 8.53. Devel::DProf
Devel::PPPort module: 8.54. Devel::PPPort
Devel::SelfStubber module: 8.55. Devel::SelfStubber
DevelopMentor: 14.1. What Is SOAP?
diagnostics module: 8.56. diagnostics
diamond <...> operator: 4.9. Filehandles
die( ): 4.9. Filehandles
5. Function Reference
digest( )
(Digest modules): 8.57. Digest
(Digest::MD5 module): 8.58. Digest::MD5
Digest modules: 8.57. Digest
Digest::MD5 module: 8.58. Digest::MD5
-digits option (Scale): 21.13. The Scale Widget
dir( ) (Net::FTP): 18.2. Net::FTP
directories
file-related functions: 5.1. Perl Functions by Category
functions for: 5.1. Perl Functions by Category
directory service: 19. Lightweight Directory Access with Net::LDAP
DirHandle module: 8.59. DirHandle
-disabledforeground option (widgets): 21.3. Common Widget Configuration Options
disconnect( ) (DBI): 12.3. DBI Methods
Disconnect( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods
dispatch_from( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
Display( ) (Win32::Console): 22.2. Win32::Console
distributions( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
division (/) operator: 4.5.3. Arithmetic Operators
dlineinfo( ) (Text widget): 21.11.2. Text Methods
DN (distinguished name): 19.1. How Data Is Stored in LDAP
do( ): 5. Function Reference
DBI module: 12.3. DBI Methods
do statement, conditional modifiers with: 4.3.1.4. Modifiers
Doctype handler (Expat): 13.3. Expat Handlers
DoctypeFin handler (Expat): 13.3. Expat Handlers
documentation, Perl: 2.5. Documentation
4.13. Pod
= to signify in programs: 4.1. Program Structure
utilities for: 4.13.3. Pod Utilities
dollar sign ($): 4.6.2. Regular Expression Syntax
dereferencing with: 4.8.2. Dereferencing
prototype symbol (scalar): 4.7.5. Prototypes
signifying scalar variables: 4.2.5. Variables
special variables: 4.6.2. Regular Expression Syntax
domain( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
do_push( ) (CGI::Push module): 8.39. CGI::Push
dot (.)
concatenation operator: 4.5.11.4. String operator
Perl debugger command: 6.2. Debugger Commands
regular expression metacharacter: 4.6.2. Regular Expression Syntax
.. (range) operator: 4.5.11.1. Range operator
... (range) operator: 4.5.11.1. Range operator
.= (assignment) operator: 4.5.6. Assignment Operators
downloading
Perl language source code: 2. Installing Perl
Perl modules source code: 2.2. How Is CPAN Organized?
2.4. Getting and Installing Modules
dprofpp utility: 6.5. The Perl Profiler
Drivers( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
DropCursor( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
dump( ): 5. Function Reference
CGI.pm module: 10.7. CGI.pm Reference
HTML::Parser module: 20.4.3. HTML::Element
Dump( ) (Data::Dumper)): 8.50. Data::Dumper
dump_results( ) (DBI): 12.3. DBI Methods
DumpData( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
Dumper( ) (Data::Dumper): 8.50. Data::Dumper
DumperX( ) (Data::Dumper)): 8.50. Data::Dumper
dump_names function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
Dumpvalue module: 8.60. Dumpvalue
Dumpxs( ) (Data::Dumper)): 8.50. Data::Dumper
dup( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
DynaLoader module: 8.61. DynaLoader
dynamic scoping: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

E (end) character: 4.6.4. Character Classes
-e file test operator: 4.5.8. File Test Operators
E<> interior sequence (pod): 4.13.2. Interior Sequences
-e option
(perlbug): 6.6. The perlbug Program
(perlcc): 3.4. The Perl Compiler
-E option (dprofpp): 6.5. The Perl Profiler
e (escape) sequence: 4.6.3. Escaped Sequences
each( ): 5. Function Reference
ebcdic( ) (Net::FTP): 18.2. Net::FTP
EDI: 14.1. What Is SOAP?
$EFFECTIVE_GROUP_ID ($EGID) variable: 4.4.1. Global Special Variables
$EFFECTIVE_USER_ID ($>) variable: 4.4.1. Global Special Variables
$EGID variable: 4.4.1. Global Special Variables
Element handler (Expat): 13.3. Expat Handlers
-elementborderwidth option (Scrollbar): 21.9. The Scrollbar Widget
email: 16. Email Connectivity
folders for (Mail::Folder module): 16.2.3. Handle Folders with Mail::Folder
handling messages (Mail::Internet module): 16.2.4. Handle Messages with Mail::Internet
header control (Mail::Send module): 16.2.2. Better Header Control with Mail::Send
Mail modules: 16. Email Connectivity
16.2. The Mail Modules
parsing addresses (Mail::Address module): 16.2.6. Parse Email Addresses with Mail::Address
Perl-related mailing lists: 1.4.3. Mailing Lists
reading (Mail::Audit module): 16.2.9. Mail Filtering with Mail::Audit
reading (Mail::RBL module): 16.2.8. Checking Blacklisted Hosts with Mail::RBL
retrieving (Net::POP3 module): 16.1.3. Retrieving Email with Net::POP3
sending (Mail::Mailer module): 16.2.1. Send Email with Mail::Mailer
sending (Net::SMTP module): 16.1.1. Send Email with Net::SMTP
encoding module: 8.62. encoding
encoding( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
encoding URLs: 9.2. URL Encoding
encodingspace( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
=end command (pod): 4.13.1. Paragraph Tags
_ _END_ _ constant: 4.4.4. Global Special Constants
End handler (Expat): 13.3. Expat Handlers
end index
Entry widget: 21.8.1. Text Indexes
Listbox widget: 21.10.1. Listbox Indexes
Menu widget: 21.15.1. Menu Indexes
Text widget: 21.11.1. Text Indexes and Modifiers
_ _END_ _ marker: 8.5. AutoLoader
endgrent( ): 5. Function Reference
endhostent( ): 5. Function Reference
endnetent( ): 5. Function Reference
endpoint( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
endprotoent( ): 5. Function Reference
endpwent( ): 5. Function Reference
<endrange>Win32 modules, Win32::ODBC module: 24.1. ODBC Methods and Properties
endservent( ): 5. Function Reference
endtag( ) (HTML::Parser): 20.4.3. HTML::Element
English module: 8.63. English
Entity handler (Expat): 13.3. Expat Handlers
Entry widget (Perl/Tk): 21.8. The Entry Widget
entrycget( )
Menu widget: 21.15.2. Menu Methods
Menubutton widget: 21.14.2. Menubutton Methods
entryconfigure( )
Menu widget: 21.15.2. Menu Methods
Menubutton widget: 21.14.2. Menubutton Methods
EnumerateRights( ) (Win32::FileSecurity): 22.6. Win32::FileSecurity
enumeration methods: 23.3. Win32::OLE::Enum
%ENV hash: 4.4.2. Global Special Arrays and Hashes
Env module: 8.64. Env
environment variables: 3.3. Environment Variables
CGI-related: 9.4. CGI Environment Variables
DBI-related: 12.4. DBI Environment Variables
env_proxy( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
eof( ): 5. Function Reference
HTML::Parser module: 20.4.1. HTML::Parser
eparams( ) (URI::URL): 20.5.3. URI::URL
epath( ) (URI::URL): 20.5.3. URI::URL
eq (equal to) operator: 4.5.4.2. Equality operators
eq( ) (URI::URL): 20.5.3. URI::URL
equal sign (=)
assignment operator: 4.2.5. Variables
4.5.6. Assignment Operators
for embedded documentation (pod): 4.1. Program Structure
in hash name/value pairs: 4.2.5.2. Hashes
for pod commands: 4.13. Pod
== (equal to) operator: 4.5.4.2. Equality operators
=> operator, defining key/value pairs: 4.2.5.2. Hashes
4.5.11.3. Comma operator
=~ (pattern match) operator: 4.5.7. Pattern Match Operators
equality operators: 4.5.4.2. Equality operators
equery( ) (URI::URL): 20.5.3. URI::URL
err( ) (DBI): 12.3. DBI Methods
Errno module: 8.65. Errno
$ERRNO ($!) variable: 4.4.1. Global Special Variables
Error( )
(Win32::Internet): 22.7.1. General Internet Methods
(Win32::ODBC): 24.1. ODBC Methods and Properties
(Win32::Pipe): 22.13.1. Win32::Pipe Methods
error_as_HTML( ) (HTTP::Response): 20.3.2. HTTP::Response
errstr( ) (DBI): 12.3. DBI Methods
escaped sequences: 4.6.3. Escaped Sequences
escape_from( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
$EUID ($>) variable: 4.4.1. Global Special Variables
eval( ): 5. Function Reference
$EVAL_ERROR ($@) variable: 4.4.1. Global Special Variables
event-based parsing: 13.3. Expat Handlers
example Perl scripts: 2.3.1.1. Perl examples
exclamation point: 2.4.4. Installing Modules with the CPAN Module
exec( ): 5. Function Reference
$EXECUTABLE_NAME ($^X) variable: 4.4.1. Global Special Variables
execute( ) (DBI): 12.3. DBI Methods
exists( ): 5. Function Reference
News::Newsrc module: 17.3.1. News::Newsrc Reference
exit( ): 5. Function Reference
11.4. Running CGI Scripts with mod_perl
exp( ): 5. Function Reference
expand( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
-expand option (pack geometry manager): 21.2.1. The pack Geometry Manager
Expat: 13.1. XML Parsing and Validation
handlers: 13.3. Expat Handlers
exponentiation (**) operator: 4.5.3. Arithmetic Operators
Exporter module: 8.66. Exporter
-exportselection option (widgets): 21.3. Common Widget Configuration Options
extended regular expression syntax: 4.6.8. Extended Regular Expressions
$EXTENDED_OS_ERROR ($^E) variable: 4.4.1. Global Special Variables
ExternEnt handler (Expat): 13.3. Expat Handlers
ExternEntFin handler (Expat): 13.3. Expat Handlers
extra path information: 9.3. Extra Path Information
extract_cookies( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies
extracting Perl source code: 2.3.2.2. Standard Perl distribution
extract_links( ) (HTML::Parser): 20.4.3. HTML::Element
ExtUtils modules: 8.67. ExtUtils::Command
ExtUtils::Command::MM module: 8.68. ExtUtils::Command::MM
ExtUtils::Constant module: 8.69. ExtUtils::Constant
ExtUtils::MM module: 8.79. ExtUtils::MM
ExtUtils::MM_Any module: 8.80. ExtUtils::MM_Any
ExtUtils::MM_BeOS module: 8.81. ExtUtils::MM_BeOS
ExtUtils::MM_DOS: 8.82. ExtUtils::MM_DOS
ExtUtils::MM_NW5: 8.83. ExtUtils::MM_NW5
ExtUtils::MM_UWIN: 8.86. ExtUtils::MM_UWIN
ExtUtils::MY: 8.89. ExtUtils::MY
ExtUtils::Command module: 8.67. ExtUtils::Command
ExtUtils::Embed module: 8.70. ExtUtils::Embed
ExtUtils::Install module: 8.71. ExtUtils::Install
ExtUtils::Installed module: 8.72. ExtUtils::Installed
ExtUtils::Liblist module: 8.73. ExtUtils::Liblist
ExtUtils::MakeMaker module: 8.74. ExtUtils::MakeMaker
ExtUtils::Manifest module: 8.75. ExtUtils::Manifest
ExtUtils::Miniperl module: 8.76. ExtUtils::Miniperl
ExtUtils::Mkbootstrap module: 8.77. ExtUtils::Mkbootstrap
ExtUtils::Mksymlists module: 8.78. ExtUtils::Mksymlists
ExtUtils::MM_OS2 module: 8.84. ExtUtils::MM_OS2
ExtUtils::MM_Unix module: 8.85. ExtUtils::MM_Unix
ExtUtils::MM_VMS module: 8.87. ExtUtils::MM_VMS
ExtUtils::MM_WIN32 module: 8.88. ExtUtils::MM_Win32
ExtUtils::Packlist module: 8.90. ExtUtils::Packlist
ExtUtils::testlib module: 8.91. ExtUtils::testlib

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

@F array: 4.4.2. Global Special Arrays and Hashes
f command (Perl debugger): 6.2. Debugger Commands
-f file test operator: 4.5.8. File Test Operators
F<> interior sequence (pod): 4.13.2. Interior Sequences
-F option (dprofpp): 6.5. The Perl Profiler
-f option (perlbug): 6.6. The perlbug Program
f (formfeed) sequence: 4.6.3. Escaped Sequences
FAQs, Perl-related: 1.4.2. Frequently Asked Questions Lists (FAQs)
FastCGI: 8.37. CGI::Fast
fastcwd (Cwd module): 8.49. Cwd
Fatal module: 8.92. Fatal
fcntl( ): 5. Function Reference
Fcntl module: 8.93. Fcntl
fd (DB_File module): 8.52. DB_File
fetch( ) (DBI): 12.3. DBI Methods
fetchall_arrayref( ) (DBI): 12.3. DBI Methods
FetchRow( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
fetchrow_array( ) (DBI): 12.3. DBI Methods
fetchrow_arrayref( ) (DBI): 12.3. DBI Methods
fetchrow_hashref( ) (DBI): 12.3. DBI Methods
FetchURL( ) (Win32::Internet): 22.7.1. General Internet Methods
-fg option (widgets): 21.3. Common Widget Configuration Options
fieldholders: 4.12. Formats
FieldNames( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
fields module: 8.94. fields
_ _FILE_ _ constant: 4.4.4. Global Special Constants
File modules: 8.95. File::Basename
File::Basename module: 8.95. File::Basename
File::CheckTree module: 8.96. File::CheckTree
File::Compare module: 8.97. File::Compare
File::Copy module: 8.98. File::Copy
File::DosGlob module: 8.99. File::DosGlob
File::Find module: 8.100. File::Find
File::Path module: 8.101. File::Path
File::Spec module: 8.102. File::Spec
File::Spec::Mac module: 8.104. File::Spec::Mac
File::Spec::Os2 module: 8.105. File::Spec::OS2
File::Spec::Unix module: 8.106. File::Spec::Unix
File::Spec::VMS module: 8.107. File::Spec::VMS
File::Spec::Win32 module: 8.108. File::Spec::Win32
File::Stat module: 8.109. File::stat
File::Temp module: 8.110. File::Temp
file test operators: 4.5.8. File Test Operators
FileCache module: 8.111. FileCache
FileHandle module: 8.112. FileHandle
filehandles: 4.9. Filehandles
functions for: 5.1. Perl Functions by Category
special (predefined): 4.4.3. Global Special Filehandles
4.4.6. Filehandle Special Variables
fileno( ): 5. Function Reference
files, functions for: 5.1. Perl Functions by Category
File::Spec modules, File::Spec::Cygwin module: 8.103. File::Spec::Cygwin
-fill option, form geometry manager: 21.2.4. The form Geometry Manager
-fill option (pack geometry manager): 21.2.1. The pack Geometry Manager
FillAttr( ) (Win32::Console): 22.2. Win32::Console
FillChar( ) (Win32::Console): 22.2. Win32::Console
filled field fieldholders: 4.12. Formats
Filter::Simple module: 8.113. Filter::Simple
Filter::Util::Call module: 8.114. Filter::Util::Call
Final handler (Expat): 13.3. Expat Handlers
find( ) (Canvas): 21.12.3. Canvas Methods
FindBin module: 8.115. FindBin
finish( ) (DBI): 12.3. DBI Methods
first_labeled_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
first_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
fixed-length data/records, functions for: 5.1. Perl Functions by Category
fixed-precision numeric fields: 4.12. Formats
flags: 3.2. Command-Line Options
flash( )
Button widget: 21.4.1. Button Methods
Checkbutton widget: 21.5.1. Checkbutton Methods
Radiobutton widget: 21.6.1. Radiobutton Methods
flock( ): 5. Function Reference
flow control functions: 5.1. Perl Functions by Category
Flush( ) (Win32::Console module): 22.2. Win32::Console
focus( ) (Canvas): 21.12.3. Canvas Methods
focusmodel( ) (Frame widget): 21.18.1. Toplevel Methods
foldername( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
folders for email messages: 16.2.3. Handle Folders with Mail::Folder
-font option (widgets): 21.3. Common Widget Configuration Options
fonts, widget: 21.1.4. Colors and Fonts
=for command (pod): 4.13.1. Paragraph Tags
for loops: 4.3.1.2. for loops
force command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
force_last_request( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
foreach loops: 4.3.1.3. foreach loops
-foreground option (widgets): 21.3. Common Widget Configuration Options
fork( ): 5. Function Reference
form geometry manager (Perl/Tk): 21.2.4. The form Geometry Manager
:form method group: 10.2. Importing Method Groups
<form> tag: 9.1. A Typical CGI Interaction
format( )
HTML::FormatPS module: 20.4.5. HTML::FormatPS
HTML::FormatText module: 20.4.6. HTML::FormatText
Mail::Address module: 16.2.7. Mail::Address Reference
format keyword: 4.12. Formats
$FORMAT_FORMFEED ($^L) variable: 4.4.1. Global Special Variables
$FORMAT_LINE_BREAK_CHARACTERS ($:) variable: 4.4.1. Global Special Variables
$FORMAT_LINES_LEFT ($-) variable: 4.4.6. Filehandle Special Variables
$FORMAT_LINES_PER_PAGE ($=) variable: 4.4.6. Filehandle Special Variables
$FORMAT_NAME ($~) variable: 4.4.6. Filehandle Special Variables
$FORMAT_PAGE_NUMBER ($%) variable: 4.4.6. Filehandle Special Variables
formats: 4.12. Formats
$FORMAT_TOP_NAME ($^) variable: 4.4.6. Filehandle Special Variables
formCheck( ) (form geometry manager): 21.2.4. The form Geometry Manager
formForget( ) (form geometry manager): 21.2.4. The form Geometry Manager
formGrid( ) (form geometry manager): 21.2.4. The form Geometry Manager
formInfo( ) (form geometry manager): 21.2.4. The form Geometry Manager
formline( ): 5. Function Reference
formSlaves( ) (form geometry manager): 21.2.4. The form Geometry Manager
fraction( ) (Scrollbar): 21.9.1. Scrollbar Methods
frag( ) (URI::URL): 20.5.3. URI::URL
frame( ) (Frame widget): 21.18.1. Toplevel Methods
Frame widget (Perl/Tk): 21.17. The Frame Widget
FrameMaker, translating pod to: 4.13.3. Pod Utilities
Free( ) (Win32::Console): 22.2. Win32::Console
freshness_lifetime( ) (HTTP::Response): 20.3.2. HTTP::Response
fresh_until( ) (HTTP::Response): 20.3.2. HTTP::Response
from( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
20.2.3. LWP::UserAgent
20.2.3. LWP::UserAgent
-from option (Scale): 21.13. The Scale Widget
FTP (File Transfer Protocol): 18. FTP
Net::FTP module: 18.2. Net::FTP
Net::Netrc module: 18.3. FTP Configuration with Net::Netrc
obtaining Perl: 2.1. The CPAN Architecture
Win32::Internet functions for: 22.7.2. FTP Functions
FTP( ) (Win32::Internet): 22.7.1. General Internet Methods
full_path( ) (URI::URL): 20.5.3. URI::URL
func( ) (DBI): 12.3. DBI Methods
functions, built-in: 5. Function Reference
listed alphabetically: 5. Function Reference
listed by category: 5.1. Perl Functions by Category
socket-related: 15.1. Built-in Socket Functions
functions, loading
AutoLoader module: 8.5. AutoLoader
DynaLoader module: 8.61. DynaLoader
SelfLoader module: 8.184. SelfLoader

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

-g file test operator: 4.5.8. File Test Operators
g pattern match modifier: 4.6.1. Pattern-Matching Operators
GDBM_File module: 8.116. GDBM_File
ge (greater-than-or-equal) operator: 4.5.4.1. Relational operators
-gen option (perlcc): 3.4. The Perl Compiler
GenerateCtrlEvent( ) (Win32::Console): 22.2. Win32::Console
geometry( ) (Frame widget): 21.18.1. Toplevel Methods
geometry managers (Perl/Tk): 21.2. Geometry Managers
get( )
Entry widget: 21.8.2. Entry Methods
Listbox widget: 21.10.2. Listbox Methods
LWP::Simple module: 20.2.2. LWP::Simple
Net::FTP module: 18.2. Net::FTP
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
Scale widget: 21.13.1. Scale Methods
Scrollbar widget: 21.9.1. Scrollbar Methods
Text widget: 21.11.2. Text Methods
get_basic_credentials( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
BufferSize( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods
get( ) (DB_File module): 8.52. DB_File
get( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
GET method (CGI): 20.3.1. HTTP::Request
GetActiveObject( ) (Win32::OLE): 23.1. Creating Objects
GetAttributes( ) (Win32::File): 22.5. Win32::File
getc( ): 5. Function Reference
GetConnections( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
GetConnectOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
GetCursorName( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
getcwd (Cwd module): 8.49. Cwd
GetData( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
GetDomainController( ) (Win32::NetAdmin): 22.10. Win32::NetAdmin
getDSN( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
GetError( ) (Win32::NetResource): 22.11. Win32::NetResource
GetEvents( ) (Win32::Console): 22.2. Win32::Console
GetExitCode( ) (Win32::Process): 22.14.1. Win32::Process Methods
get_fields( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
GetFunctions( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
getgrent( ): 5. Function Reference
getgrgid( ): 5. Function Reference
getgrnam( ): 5. Function Reference
get_header( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
gethostbyaddr( ): 5. Function Reference
gethostbyname( ): 5. Function Reference
gethostest( ): 5. Function Reference
GetInfo( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
24.1. ODBC Methods and Properties
GetKeys( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
getlogin( ): 5. Function Reference
get_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
get_message_file( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
get_mime_header( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
get_mime_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
getnetbyaddr( ): 5. Function Reference
getnetbyname( ): 5. Function Reference
getnetent( ): 5. Function Reference
GetNumber( ) (Win32::EventLog): 22.4. Win32::Eventlog
GetObject( ) (Win32::OLE): 23.1. Creating Objects
GetOldest( ) (Win32::EventLog): 22.4. Win32::Eventlog
Getopt::Long module: 8.117. Getopt::Long
Getopt::Std module: 8.118. Getopt::Std
get_option( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
getpeername( ): 5. Function Reference
getpgrp( ): 5. Function Reference
getppid( ): 5. Function Reference
getprint( ) (LWP::Simple): 20.2.2. LWP::Simple
getpriority( ): 5. Function Reference
GetPriorityClass( ) (Win32::Process): 22.14.1. Win32::Process Methods
getprotobyname( ): 5. Function Reference
15.1.1. Initializing a Socket
getprotobynumber( ): 5. Function Reference
getprotoent( ): 5. Function Reference
getpwent( ): 5. Function Reference
getpwnam( ): 5. Function Reference
getpwuid( ): 5. Function Reference
get_request( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
GetResponse( ) (Win32::Internet): 22.7.1. General Internet Methods
getservbyname( ): 5. Function Reference
getservbyport( ): 5. Function Reference
GetServices( ) (Win32::Service): 22.17. Win32::Service
getservent( ): 5. Function Reference
GetSharedResource( ) (Win32::NetResource): 22.11. Win32::NetResource
getsockname( ): 5. Function Reference
getsockopt( ): 5. Function Reference
GetSQLState( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
GetStatus( ) (Win32::Service): 22.17. Win32::Service
GetStatusCallback( ) (Win32::Internet): 22.7.1. General Internet Methods
GetStmtCloseType( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
GetStmtOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
getstore( ) (LWP::Simple): 20.2.2. LWP::Simple
gettags( ) (Canvas): 21.12.3. Canvas Methods
GetUNCName( ) (Win32::NetResource): 22.11. Win32::NetResource
GetValues( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
$GID ($( ) variable: 4.4.1. Global Special Variables
glob( ): 5. Function Reference
global special variables: 4.4.1. Global Special Variables
gmtime( ): 5. Function Reference
GNU, utilities for Win32: 2.3.2.2. Standard Perl distribution
goto( ): 5. Function Reference
goto command: 4.3.1.6. goto
greater-than (>, gt) operators: 4.5.4.1. Relational operators
greater-than-or-equal (>=, ge) operators: 4.5.4.1. Relational operators
greedy matching: 4.6.6. Quantifiers
grep( ): 5. Function Reference
grid( ) (Frame widget): 21.18.1. Toplevel Methods
grid geometry manager (Perl/Tk): 21.2.2. The grid Geometry Manager
gridBBox( ) (grid manager): 21.2.2.1. grid methods
gridColumnconfigure( ) (grid manager): 21.2.2.1. grid methods
gridForget( ) (grid manager): 21.2.2.1. grid methods
gridInfo( ) (grid manager): 21.2.2.1. grid methods
gridLocation( ) (grid manager): 21.2.2.1. grid methods
gridPropagate( ) (grid manager): 21.2.2.1. grid methods
gridRemove( ) (grid manager): 21.2.2.1. grid methods
gridRowconfigure( ) (grid manager): 21.2.2.1. grid methods
gridSize( ) (grid manager): 21.2.2.1. grid methods
gridSlaves( ) (grid manager): 21.2.2.1. grid methods
group( )
Frame widget: 21.18.1. Toplevel Methods
Net::NNTP module: 17.2.2. Net::NNTP Reference
group command (NNTP): 17.1. The NNTP Protocol
groups, fetching information on: 5.1. Perl Functions by Category
groups( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
gt (greater-than) operator: 4.5.4.1. Relational operators
guestbook (CGI example): 9.1. A Typical CGI Interaction
.gz extension: 2.3.1. Installing on Unix
gzi: 2.3.1. Installing on Unix
gzip for Win32: 2.3.2.2. Standard Perl distribution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

h command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
h command (Perl debugger): 6.2. Debugger Commands
-h option (perlbug): 6.6. The perlbug Program
handlers: 8.2. Attribute::Handlers
hash mark (#)
#! (shebang) line: 3. The Perl Executable
for comments: 4.1. Program Structure
format fieldholders: 4.12. Formats
hash prototype symbol (%): 4.7.5. Prototypes
hashes: 4.2. Data Types and Variables
4.2.5.2. Hashes
functions for processing: 5.1. Perl Functions by Category
special (predefined): 4.4.2. Global Special Arrays and Hashes
Hash::Util module: 8.119. Hash::Util
head( )
LWP::UserAgent: 20.2.3. LWP::UserAgent
LWP::Simple module: 20.2.2. LWP::Simple
20.2.2. LWP::Simple
Mail::Internet module: 16.2.5. Mail::Internet Reference
Net::NNTP module: 17.2.2. Net::NNTP Reference
=head2 command (pod): 4.13.1. Paragraph Tags
header( )
CGI.pm module: 10.7. CGI.pm Reference
HTTP::Headers module: 20.3.3. HTTP::Headers
HTTP::Message module: 20.3.8. HTTP::Message
headers, HTTP: 20.3.3. HTTP::Headers
-height option
place geometry manager: 21.2.3. The place Geometry Manager
widgets: 21.3. Common Widget Configuration Options
hello( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
HELO command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session
help( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
hex( ): 5. Function Reference
hexdigest( )
Digest modules: 8.57. Digest
Digest::MD5 module: 8.58. Digest::MD5
hidden( ) (CGI.pm): 10.7. CGI.pm Reference
Hietaniemi, Jarkko: 2.1. The CPAN Architecture
-highlightbackground option (widgets): 21.3. Common Widget Configuration Options
-highlightcolor option (widgets): 21.3. Common Widget Configuration Options
-highlightthickness option (widgets): 21.3. Common Widget Configuration Options
HOME variable: 3.3. Environment Variables
host( )
Mail::Address module: 16.2.6. Parse Email Addresses with Mail::Address
16.2.7. Mail::Address Reference
URI::URL module: 20.5.3. URI::URL
hostpath (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference
host_wait( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections
HTML (Hypertext Markup Language)
tags, generating with CGI.pm: 10.1. HTML Tag Generation
translating pod to: 4.13.3. Pod Utilities
8.174. Pod::Html
:html method groups: 10.2. Importing Method Groups
HTML modules: 20.4. The HTML Modules
HTML::Element module: 20.4.3. HTML::Element
HTML::FormatPS module: 20.4.5. HTML::FormatPS
HTML::FormatText module: 20.4.6. HTML::FormatText
HTML::Parser module: 20.4. The HTML Modules
20.4.1. HTML::Parser
HTML::TreeBuilder module: 20.4.4. HTML::TreeBuilder
HTTP (Hypertext Transfer Protocol)
request messages: 20.1. LWP Overview
Win32::Internet functions for: 22.7.3. HTTP Functions
HTTP modules
HTTP::Cookies module: 20.3.6. HTTP::Cookies
HTTP::Cookies::Netscape module: 20.3.6.1. HTTP::Cookies::Netscape
HTTP::Daemon module: 20.3.7. HTTP::Daemon
HTTP::Daemon::ClientConn module: 20.3.7.1. HTTP::Daemon::ClientConn methods
HTTP::Date module: 20.3.5. HTTP::Date
HTTP::Headers module: 20.3.3. HTTP::Headers
HTTP::Message module: 20.3.8. HTTP::Message
HTTP::Request module: 20.1. LWP Overview
20.3.1. HTTP::Request
HTTP::Response module: 20.1. LWP Overview
20.3.2. HTTP::Response
HTTP::Status module: 20.3.4. HTTP::Status
HTTP( ) (Win32::Internet): 22.7.1. General Internet Methods
hyphen (-)
in [...] construct: 4.6.4. Character Classes
arithmetic negation operator: 4.5.2. Unary Operators
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager
Perl debugger command: 6.2. Debugger Commands
-> (arrow) operator: 4.5.1. The Arrow Operator
dereferencing with: 4.8.2.1. Arrow dereferencing
-= (assignment) operator: 4.5.6. Assignment Operators
-- (autodecrement) operator: 4.5.5. Autoincrement and Autodecrement

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

i command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
I<> interior sequence (pod): 4.13.2. Interior Sequences
-I option (perlcc): 3.4. The Perl Compiler
i pattern match modifier: 4.6.1. Pattern-Matching Operators
4.6.8. Extended Regular Expressions
iconbitmap( ) (Frame widget): 21.18.1. Toplevel Methods
iconify( ) (Frame widget): 21.18.1. Toplevel Methods
iconmask( ) (Frame widget): 21.18.1. Toplevel Methods
iconname( ) (Frame widget): 21.18.1. Toplevel Methods
iconposition( ) (Frame widget): 21.18.1. Toplevel Methods
iconwindow( ) (Frame widget): 21.18.1. Toplevel Methods
icursor( ) (Entry): 21.8.2. Entry Methods
identify( )
Scale widget: 21.13.1. Scale Methods
Scrollbar widget: 21.9.1. Scrollbar Methods
if modifier: 4.3.1.4. Modifiers
if module: 8.124. if
if statement: 4.3.1. Conditionals and Loops
ignore_text( ) (HTML::Parser): 20.4.4. HTML::TreeBuilder
ignore_unknown( ) (HTML::Parser): 20.4.4. HTML::TreeBuilder
ihave( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
-image option (widgets): 21.3. Common Widget Configuration Options
image_button( ) (CGI.pm): 10.7. CGI.pm Reference
implicit( ) (HTML::Parser): 20.4.3. HTML::Element
implicit_tags( ) (HTML::Parser): 20.4.4. HTML::TreeBuilder
import_names( ) (CGI.pm): 10.7. CGI.pm Reference
I18N modules: 8.120. I18N::Collate
I18N::Collate module: 8.120. I18N::Collate
I18N::Langinfo module: 8.121. I18N::Langinfo
I18N::LangTags module: 8.122. I18N::LangTags
I18N::LangTags::List module: 8.123. I18N::LangTags::List
-in option
form geometry manager: 21.2.4. The form Geometry Manager
grid geometry manager: 21.2.2. The grid Geometry Manager
pack geometry manager: 21.2.1. The pack Geometry Manager
place geometry manager: 21.2.3. The place Geometry Manager
in( ) (Win32::OLE): 23.2.2. Win32::OLE Functions
INADDR_ANY( ) (Socket): 15.1.4. Socket Module Functions
INADDR_BROADCAST( ) (Socket): 15.1.4. Socket Module Functions
INADDR_LOOPBACK( ) (Socket): 15.1.4. Socket Module Functions
INADDR_NONE( ) (Socket)
.25i: 15.1.4. Socket Module Functions
@INC array: 4.4.2. Global Special Arrays and Hashes
%INC hash: 4.4.2. Global Special Arrays and Hashes
index( ): 5. Function Reference
Entry widget: 21.8.2. Entry Methods
Listbox widget: 21.10.2. Listbox Methods
Menu widget: 21.15.2. Menu Methods
Text widget: 21.11.2. Text Methods
-indicatoron option
Checkbutton widget: 21.5. The Checkbutton Widget
Menubutton widget: 21.14. The Menubutton Widget
21.14.1. Menu Item Options
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
inet_aton( ) (Socket): 15.1.4. Socket Module Functions
inet_ntoa( ) (Socket): 15.1.4. Socket Module Functions
infix dereference (-: 7.4. Object Syntax
infix dereference (->) operator: 4.5.1. The Arrow Operator
4.8.2.1. Arrow dereferencing
Info( ) (Win32::Console): 22.2. Win32::Console
Init handler (Expat): 13.3. Expat Handlers
initializing NNTP clients: 17.2.1. Initializing the NNTP Client
initializing sockets: 15.1.1. Initializing a Socket
$INPLACE_EDIT ($^I) variable: 4.4.1. Global Special Variables
input, functions for: 4.4.1. Global Special Variables
5.1. Perl Functions by Category
<input> tag: 9.1. A Typical CGI Interaction
Input( ) (Win32::Console): 22.2. Win32::Console
InputChar( ) (Win32::Console): 22.2. Win32::Console
InputCP( ) (Win32::Console): 22.2. Win32::Console
$INPUT_LINE_NUMBER ($.) variable: 4.4.1. Global Special Variables
$INPUT_RECORD_SEPARATOR ($/) variable: 4.4.1. Global Special Variables
insert( )
Entry widget: 21.8.2. Entry Methods
Listbox widget: 21.10.2. Listbox Methods
Menu widget: 21.15.2. Menu Methods
Text widget: 21.11.2. Text Methods
insert index
Entry widget: 21.8.1. Text Indexes
Text widget: 21.11.1. Text Indexes and Modifiers
-insertbackground option (widgets): 21.3. Common Widget Configuration Options
-insertborderwidth option (widgets): 21.3. Common Widget Configuration Options
insert_element( ) (HTML::Parser): 20.4.3. HTML::Element
-insertofftime option (widgets): 21.3. Common Widget Configuration Options
-insertontime option (widgets): 21.3. Common Widget Configuration Options
-insertwidth option (widgets): 21.3. Common Widget Configuration Options
install command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
installing
mod_perl module: 11.2. Installing mod_perl
Perl documentation: 2.5.1. Installing the Documentation
Perl modules: 2.4.2. Module Installation
Perl source code: 2.3. Installing Perl
instance methods: 7.4. Object Syntax
instances of classes: 7.3. Object-Oriented Perl
InstMsi.exe: 2.3.2.1. ActivePerl
int( ): 5. Function Reference
integer module: 8.125. integer
interior sequences (pod): 4.13.2. Interior Sequences
Internet-domain sockets: 15. Sockets
interpreter, Perl: 3. The Perl Executable
command-line options: 3.2. Command-Line Options
command processing: 3.1. Command Processing
interprocess communication, functions for: 5.1. Perl Functions by Category
inverse_select( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
invoke( )
Button widget: 21.4.1. Button Methods
Checkbutton widget: 21.5.1. Checkbutton Methods
Menu widget: 21.15.2. Menu Methods
Radiobutton widget: 21.6.1. Radiobutton Methods
Win32::OLE module: 23.2.1. Win32::OLE Methods
I/O (input/output): 4.9.1. Perl 5.8 and PerlIO
IO modules: 8.126. IO
IO::File module: 8.127. IO::File
IO::Handle module: 8.128. IO::Handle
IO::Pipe module: 8.129. IO::Pipe
IO::Seekable module: 8.130. IO::Seekable
8.131. IO::Select
IO::Socket module: 8.132. IO::Socket
ioctl( ): 5. Function Reference
IO::Socket module: 15.2. The IO::Socket Module
IO::Socket::INET subclass: 15.2.4. IO::Socket::INET Reference
IO::Socket::UNIX subclass: 15.2.5. IO::Socket::UNIX Reference
-ipadx, -ipady options
grid geometry manager: 21.2.2. The grid Geometry Manager
pack geometry manager: 21.2.1. The pack Geometry Manager
IPC modules: 8.133. IPC::Msg
IPC::Msg module: 8.133. IPC::Msg
IPC::Open3 module: 8.135. IPC::Open3
IPC::Semaphore module: 8.136. IPC::Semaphore
IPC::SysV module: 8.137. IPC::SysV
isany method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
ischoice method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
is_client_error( ) (HTTP::Status: 20.3.4. HTTP::Status
is_empty( ) (HTML::Parser): 20.4.3. HTML::Element
isempty method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
is_error( )
HTTP::Response module: 20.3.2. HTTP::Response
HTTP::Status module: 20.3.4. HTTP::Status
LWP::Simple module: 20.2.2. LWP::Simple
is_fresh( ) (HTTP::Response): 20.3.2. HTTP::Response
20.3.2. HTTP::Response
isindex( ) (CGI.pm): 10.7. CGI.pm Reference
is_info( )
HTTP::Response module: 20.3.2. HTTP::Response
HTTP::Status module: 20.3.4. HTTP::Status
is_inside( ) (HTML::Parser): 20.4.3. HTML::Element
ismixed method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
isname method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
is_protocol_supported( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
is_readonly( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
is_redirect( )
HTTP::Response module: 20.3.2. HTTP::Response
HTTP::Status module: 20.3.4. HTTP::Status
isseq method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
is_server_error( ) (HTTP::Status: 20.3.4. HTTP::Status
is_success( )
HTTP::Response module: 20.3.2. HTTP::Response
HTTP::Status module: 20.3.4. HTTP::Status
LWP::Simple module: 20.2.2. LWP::Simple
=item command (pod): 4.13.1. Paragraph Tags
item tags (Canvas widgets): 21.12.2. Item Tags and IDs
Item( ) (Win32::OLE::Enum): 23.3. Win32::OLE::Enum
itemcget( ) (Canvas): 21.12.3. Canvas Methods
itemconfigure( ) (Canvas): 21.12.3. Canvas Methods

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JavaScript features with CGI.pm: 10.5. Using JavaScript Features
Johnson, Kevin: 16. Email Connectivity
16.2.3. Handle Folders with Mail::Folder
join(): 5. Function Reference
-jump option (Scrollbar): 21.9. The Scrollbar Widget
-justify option (widgets): 21.3. Common Widget Configuration Options

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2000 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

-k file test operator: 4.5.8. File Test Operators
keys(): 5. Function Reference
keywords() (CGI.pm): 10.7. CGI.pm Reference
kill(): 5. Function Reference
Kill() (Win32\:\:Process): 22.14.1. Win32::Process Methods
Koenig, Andreas: 2.1. The CPAN Architecture
Kolinko, Paul: 14.2. SOAP::Lite

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2000 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

L (lowercase) characters: 4.6.4. Character Classes
l command (Perl debugger): 6.2. Debugger Commands
-l file test operator: 4.5.8. File Test Operators
L<> interior sequence (pod): 4.13.2. Interior Sequences
-l option
form geometry manager: 21.2.4. The form Geometry Manager
-l option (dprofpp): 6.5. The Perl Profiler
-L option (perlcc): 3.4. The Perl Compiler
-label option
Frame widget: 21.17. The Frame Widget
Menubutton widget: 21.14.1. Menu Item Options
Scale widget: 21.13. The Scale Widget
Label widget (Perl/Tk): 21.7. The Label Widget
label_exists( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
-labelPack option (Frame): 21.17. The Frame Widget
labels
loops: 4.3.1.5. Loop control
statement blocks: 4.3. Statements
-labelVariable option (Frame): 21.17. The Frame Widget
last( ): 5. Function Reference
Net::NNTP module: 17.2.2. Net::NNTP Reference
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
last command: 4.3.1.5. Loop control
last index (Menu widget): 21.15.1. Menu Indexes
LastError( ) (Win32::OLE): 23.2.1. Win32::OLE Methods
last_labeled_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
last_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
$LAST_PAREN_MATCH ($+) variable: 4.4.5. Regular Expression Special Variables
LaTeX, translating pod to: 4.13.3. Pod Utilities
lc( ): 5. Function Reference
lcfirst( ): 5. Function Reference
LDAP (Lightweight Directory Access Protocol): 19. Lightweight Directory Access with Net::LDAP
Net::LDAP, searching with: 19.2. Searching an LDAP Directory with Net::LDAP
LDAPm (Lightweight Directory Access Protocol)
data structure: 19.1. How Data Is Stored in LDAP
LDIF (LDAP Directory Interchange Format): 19.1. How Data Is Stored in LDAP
le (less-than-or-equal) operator: 4.5.4.1. Relational operators
-left option
form geometry manager: 21.2.4. The form Geometry Manager
-leftspring option
form geometry manager: 21.2.4. The form Geometry Manager
length( ): 5. Function Reference
-length option (Scale): 21.13. The Scale Widget
less module: 8.138. less
less-than (<, lt) operators: 4.5.4.1. Relational operators
less-than-or-equal (<, le) operators: 4.5.4.1. Relational operators
lexical scoping: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables
lib module: 8.139. lib
lib-win32 library: 22. Win32 Modules and Extensions
lib-www-perl file: 20. The LWP Library
libnet modules: 16. Email Connectivity
library modules, functions for: 5.1. Perl Functions by Category
_ _LINE_ _ constant: 4.4.4. Global Special Constants
line-input <...> operator: 4.9. Filehandles
LineInfo option (PERLDB_OPTS): 6.4. Customizing the Debugger
linestart, lineend modifiers (Text widget): 21.11.1. Text Indexes and Modifiers
link( ): 5. Function Reference
Lint backend (Perl compiler): 3.4. The Perl Compiler
Linux, installing Perl and: 2.3.1. Installing on Unix
List( ), Win32::Internet module: 22.7.2. FTP Functions
list active command (NNTP): 17.1. The NNTP Protocol
list context: 4.2.6. Scalar and List Contexts
list operators: 4.5. Operators
list prototype symbol (@): 4.7.5. Prototypes
list_all_labels( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
Listbox widget (Perl/Tk): 21.10. The Listbox Widget
listen( ): 5. Function Reference
Socket module: 15.1. Built-in Socket Functions
15.1.3. Server Connections
Listen option
IO::Socket::INET module: 15.2.4. IO::Socket::INET Reference
IO::Socket::UNIX module: 15.2.5. IO::Socket::UNIX Reference
listgroup( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
list_labels( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
lists: 4.2.3. Here Documents
4.2.4. Lists
functions for processing: 5.1. Perl Functions by Category
passing arguments to subroutines: 4.7.2. Passing Arguments
$LIST_SEPARATOR ($") variable: 4.4.1. Global Special Variables
List::Util module: 8.140. List::Util
.lnk files: 22.18. Win32::Shortcut
Load( )
Win32::OLE::Const module: 23.5. Win32::OLE::Const
Win32::Registry module: 22.15.1. Win32::Registry Methods
Win32::Shortcut module: 22.18. Win32::Shortcut
loading functions
AutoLoader module: 8.5. AutoLoader
DynaLoader module: 8.61. DynaLoader
SelfLoader module: 8.184. SelfLoader
local( ): 5. Function Reference
local( ), signals, and: 4.10. Signals
Local option (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference
local variables: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables
LocalAddr option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
locale module: 8.141. locale
LocalPort option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
localtime( ): 5. Function Reference
locked attribute: 8.3. attributes
log( ): 5. Function Reference
-log option (perlcc): 3.4. The Perl Compiler
LOGDIR variable: 3.3. Environment Variables
logical operators: 4.5.9. Logical Operators
login( )
Net::FTP module: 18.2. Net::FTP
Net::Netrc module: 18.3. FTP Configuration with Net::Netrc
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
16.1.3. Retrieving Email with Net::POP3
login entries (.netrc): 18.3. FTP Configuration with Net::Netrc
look command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
lookup( ) (Net::Netrc): 18.3. FTP Configuration with Net::Netrc
loops: 4.3.1. Conditionals and Loops
low-level socket access functions: 5.1. Perl Functions by Category
lower( ) (Canvas): 21.12.3. Canvas Methods
-lp option, form geometry manager: 21.2.4. The form Geometry Manager
lpa( ) (Net::Netrc): 18.3. FTP Configuration with Net::Netrc
ls( ) (Net::FTP): 18.2. Net::FTP
-ls option, form geometry manager: 21.2.4. The form Geometry Manager
lstat( ): 5. Function Reference
lt (less-than) operator: 4.5.4.1. Relational operators
lvalue attribute: 8.3. attributes
LWP (library for web access in Perl): 20. The LWP Library
HTML modules: 20.4. The HTML Modules
HTML::Element: 20.4.3. HTML::Element
HTML::FormatPS: 20.4.5. HTML::FormatPS
HTML::FormatText: 20.4.6. HTML::FormatText
HTML::Parser: 20.4. The HTML Modules
20.4.1. HTML::Parser
HTML::TreeBuilder: 20.4.4. HTML::TreeBuilder
HTTP modules
HTTP::Cookies: 20.3.6. HTTP::Cookies
HTTP::Cookies::Netscape: 20.3.6.1. HTTP::Cookies::Netscape
HTTP::Daemon: 20.3.7. HTTP::Daemon
HTTP::Daemon::ClientConn: 20.3.7.1. HTTP::Daemon::ClientConn methods
HTTP::Date: 20.3.5. HTTP::Date
HTTP::Headers: 20.3.3. HTTP::Headers
HTTP::Message: 20.3.8. HTTP::Message
HTTP::Request: 20.1. LWP Overview
20.3.1. HTTP::Request
HTTP::Response: 20.1. LWP Overview
20.3.2. HTTP::Response
HTTP::Status: 20.3.4. HTTP::Status
LWP modules
LWP::Debug module: 20.2. The LWP Modules
LWP::MediaTypes module: 20.2. The LWP Modules
LWP::Protocol module: 20.2. The LWP Modules
LWP::RobotUA module: 20.2. The LWP Modules
20.2.1. LWP::RobotUA Sections
LWP::Simple module: 20.2. The LWP Modules
20.2.2. LWP::Simple
LWP::UserAgent module: 20.1. LWP Overview
20.2. The LWP Modules
20.2.3. LWP::UserAgent
URI modules: 20.5. The URI Module
URI::Escape: 20.5. The URI Module
URI::Heuristic: 20.5. The URI Module
URI::URL: 20.5.3. URI::URL

Symbols & Numbers | A Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

m command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
m command (Perl debugger): 6.2. Debugger Commands
-M file test operator: 4.5.8. File Test Operators
m pattern match modifier: 4.6.1. Pattern-Matching Operators
4.6.8. Extended Regular Expressions
macdef entries (.netrc): 18.3. FTP Configuration with Net::Netrc
machine entries (.netrc): 18.3. FTP Configuration with Net::Netrc
MAIL command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session
Mail modules: 16. Email Connectivity
16.2. The Mail Modules
Mail::Address module: 16.2.6. Parse Email Addresses with Mail::Address
Mail::Audit module: 16.2.9. Mail Filtering with Mail::Audit
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder
Mail::Internet module: 16.2.4. Handle Messages with Mail::Internet
Mail::Mailer module: 16.2.1. Send Email with Mail::Mailer
Mail::RBL module: 16.2.8. Checking Blacklisted Hosts with Mail::RBL
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
mail( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
mailing lists, Perl-related: 1.4.3. Mailing Lists
MailTools collection: 16. Email Connectivity
main namespace: 7.1. Namespaces and Packages
MainLoop statement (Perl/Tk): 21. Perl/Tk
maintaining state (CGI): 10.3. Maintaining State
make command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
make utility: 2.4.2. Module Installation
Makefiles: 2.4.2. Module Installation
MakeMaker utility: 2.4.3.1. Using MakeMaker
MakeMask( ) (Win32::FileSecurity): 22.6. Win32::FileSecurity
man pages, translating pod to: 4.13.3. Pod Utilities
manpages, Perl-related: 2.5.2. The Perl Manpages
map( ): 5. Function Reference
mark( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
marked( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
marked_articles( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
markGravity( ) (Text widget): 21.11.4. Marks
mark_list( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
markNames( ) (Text widget): 21.11.4. Marks
mark_range( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
marks, with Text widgets: 21.11.4. Marks
markSet( ) (Text widget): 21.11.4. Marks
markUnset( ) (Text widget): 21.11.4. Marks
$MATCH ($&) variable: 4.4.5. Regular Expression Special Variables
Math modules: 8.142. Math::BigFloat
Math::BigFloat module: 8.142. Math::BigFloat
Math::BigInt module: 8.143. Math::BigInt
Math::BigInt::Calc module: 8.144. Math::BigInt::Calc
Math::BigRat module: 8.145. Math::BigRat
Math::Complex module: 8.146. Math::Complex
Math::Trig module: 8.147. Math::Trig
maxsize( ) (Frame widget): 21.18.1. Toplevel Methods
max_size( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
MaxWindow( ) (Win32::Console): 22.2. Win32::Console
md5( ) (Digest::MD5 module): 8.58. Digest::MD5
md5_base64 (Digest::MD5 module): 8.58. Digest::MD5
md5_hex (Digest::MD5 module): 8.58. Digest::MD5
mdtm( ) (Net::FTP): 18.2. Net::FTP
memEQ_clause function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
memory: 4.2.5. Variables
menu( ) (Menubutton): 21.14.2. Menubutton Methods
-menu option
Menubutton widget: 21.14. The Menubutton Widget
21.14.1. Menu Item Options
Optionmenu widget: 21.16. The Optionmenu Widget
Menu widget (Perl/Tk): 21.15. The Menu Widget
Menubutton widget (Perl/Tk): 21.14. The Menubutton Widget
-menuitems option
Menu widget: 21.15. The Menu Widget
Menubutton widget: 21.14. The Menubutton Widget
21.14. The Menubutton Widget
message_exists( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
message( ) (HTTP::Response): 20.3.2. HTTP::Response
message_list( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
message-oriented protocols: 15. Sockets
metacharacters for regular expressions: 4.6.2. Regular Expression Syntax
anchors: 4.6.5. Anchors
character classes: 4.6.4. Character Classes
escaped sequences: 4.6.3. Escaped Sequences
quantifiers: 4.6.6. Quantifiers
method attribute: 8.3. attributes
<form> tag: 9.1.1. Transferring the Form Data
method( ) (HTTP::Request): 20.3.1. HTTP::Request
methods: 7.3. Object-Oriented Perl
instance vs. class methods: 7.4. Object Syntax
widget (Perl/Tk): 21.1.1. Widget Methods
Microsoft
SOAP, and: 14.1. What Is SOAP?
Windows 95, Perl functionality on: 2.3.2.2. Standard Perl distribution
MIME::Base64 module: 8.148. MIME::Base64
MIME::QuotedPrint module: 8.149. MIME::QuotedPrint
Mingw32: 2.3.2. Installing on Win32
2.3.2.2. Standard Perl distribution
minimal matching: 4.6.6. Quantifiers
minsize( ) (Frame widget): 21.18.1. Toplevel Methods
mirror( )
LWP::Simple module: 20.2.2. LWP::Simple
LWP::UserAgent module: 20.2.3. LWP::UserAgent
mkdir( ): 5. Function Reference
Net::FTP module: 18.2. Net::FTP
Mkdir( ) (Win32::Internet): 22.7.2. FTP Functions
-mod option (perlcc): 3.4. The Perl Compiler
moddn( ) (Net::LDAP): 19.4. Net::LDAP Methods
Mode( )
Win32::Console module: 22.2. Win32::Console
Win32::Internet module: 22.7.2. FTP Functions
modifiers, conditional: 4.3.1.4. Modifiers
modify( ) (Net::LDAP): 19.4. Net::LDAP Methods
mod_include module: 11.5. Server-Side Includes with mod_perl
mod_perl module: 11. Web Server Programmingwith mod_perl
installing: 11.2. Installing mod_perl
running CGI scripts with: 11.4. Running CGI Scripts with mod_perl
SSI with: 11.5. Server-Side Includes with mod_perl
modules, Perl: 1.1. What's Perl Good For?
7. Packages,Modules, and Objects
7.2. Modules
categories: 2.4.1. Locating Modules
compiling into shared objects: 3.4. The Perl Compiler
obtaining and installing: 2.4. Getting and Installing Modules
obtaining from CPAN: 2.2. How Is CPAN Organized?
standard, list of: 8. Standard Modules
modulus (%) operator: 4.5.3. Arithmetic Operators
MoreResults( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
24.1. ODBC Methods and Properties
MouseButtons( ) (Win32::Console): 22.2. Win32::Console
move( ) (Canvas): 21.12.3. Canvas Methods
msgctl( ): 5. Function Reference
msgget( ): 5. Function Reference
msgrcv( ): 5. Function Reference
msgsnd( ): 5. Function Reference
multiline fieldholder: 4.12. Formats
multiplication (*) operator: 4.5.3. Arithmetic Operators
multirefinplace( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
multithreading: 3.5. Threads
Munoz, Luis: 16. Email Connectivity
mutex objects: 22.9. Win32::Mutex
my( ): 4.7.4. Private and Local Variables
5. Function Reference
myconfig (Config module): 8.44. Config
MyConfig.pm: 2.4.4. Installing Modules with the CPAN Module

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

n command (Perl debugger): 6.2. Debugger Commands
n index
Entry widget: 21.8.1. Text Indexes
Listbox widget: 21.10.1. Listbox Indexes
Menu widget: 21.15.1. Menu Indexes
Text widget: 21.11.1. Text Indexes and Modifiers
n (newline) sequence: 4.6.3. Escaped Sequences
name( ) (Mail::Address): 16.2.7. Mail::Address Reference
named parameters (CGI): 10.4. Named Parameters
namespace( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
namespaces: 4.2.5. Variables
7.1. Namespaces and Packages
naming
loop labels: 4.3.1.5. Loop control
packages: 7.1. Namespaces and Packages
statement block labels: 4.3. Statements
variables: 4.2.5.2. Hashes
NDBM_File module: 8.150. NDBM_File
ne (not equal to) operator: 4.5.4.2. Equality operators
nearest( ) (Listbox): 21.10.2. Listbox Methods
neat( ) (DBI): 12.3. DBI Methods
neat_list( ) (DBI): 12.3. DBI Methods
Net modules: 8.151. Net::Cmd
16. Email Connectivity
Net::Cmd module: 8.151. Net::Cmd
Net::Config module: 8.152. Net::Config
Net::Domain module: 8.153. Net::Domain
Net::FTP module: 18.2. Net::FTP
Net::hostent module: 8.155. Net::hostent
Net::netent module: 8.156. Net::netent
Net::Netrc module: 8.157. Net::Netrc
18.3. FTP Configuration with Net::Netrc
Net::News module: 17.2. Net::NNTP
Net::NNTP module: 8.158. Net::NNTP
Net::Ping module: 8.159. Net::Ping
Net::POP3 module: 8.160. Net::POP3
16.1.3. Retrieving Email with Net::POP3
Net::protoent module: 8.161. Net::protoent
Net::servent module: 8.162. Net::servent
Net::SMTP module: 8.163. Net::SMTP
16.1.1. Send Email with Net::SMTP
Net::SNPP and Net::Time modules: 16. Email Connectivity
Net::Time module: 8.164. Net::Time
Net::LDAP: 19. Lightweight Directory Access with Net::LDAP
directory, adding entries to: 19.3. Adding an Entry to the Directory with Net::LDAP
methods: 19.4. Net::LDAP Methods
searching LDAP: 19.2. Searching an LDAP Directory with Net::LDAP
netloc( ) (URI::URL): 20.5.3. URI::URL
.netrc file: 18.3. FTP Configuration with Net::Netrc
netresource data structure: 22.11. Win32::NetResource
:netscape method group: 10.2. Importing Method Groups
NetShareAdd( ) (Win32::NetResource): 22.11. Win32::NetResource
NetShareCheck( ) (Win32::NetResource): 22.11. Win32::NetResource
NetShareDel( ) (Win32::NetResource): 22.11. Win32::NetResource
NetShareGetInfo( ) (Win32::NetResource): 22.11. Win32::NetResource
NetShareSetInfo( ) (Win32::NetResource): 22.11. Win32::NetResource
Network News Transfer Protocol (NNTP): 17. Usenet News
networking
email: 16. Email Connectivity
fetching information, function for: 5.1. Perl Functions by Category
server administration: 22.10. Win32::NetAdmin
sockets: 15. Sockets
built-in functions for: 15.1. Built-in Socket Functions
IO::Socket module: 15.2. The IO::Socket Module
IO::Socket::INET subclass: 15.2.4. IO::Socket::INET Reference
IO::Socket::UNIX subclass: 15.2.5. IO::Socket::UNIX Reference
Usenet news: 17. Usenet News
new( )
Data::Dumper: 8.50. Data::Dumper
Digest::MD5 module: 8.58. Digest::MD5
DirHandle module: 8.59. DirHandle
HTML::Element module: 20.4.3. HTML::Element
HTTP::Cookies module: 20.3.6. HTTP::Cookies
HTTP::Cookies::Netscape module: 20.3.6.1. HTTP::Cookies::Netscape
HTTP::Daemon module: 20.3.7. HTTP::Daemon
HTTP::Headers module: 20.3.3. HTTP::Headers
HTTP::Request module: 20.3.1. HTTP::Request
HTTP::Response module: 20.3.2. HTTP::Response
LWP::RobotUA module: 20.2.1. LWP::RobotUA Sections
Mail::Address module: 16.2.7. Mail::Address Reference
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder
Mail::Internet module: 16.2.5. Mail::Internet Reference
Mail::Mailer module: 16.2.1. Send Email with Mail::Mailer
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
Net::FTP module: 18.2. Net::FTP
Net::LDAP: 19.4. Net::LDAP Methods
Net::NNTP module: 17.2.2. Net::NNTP Reference
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
Net::SMTP module: 16.1.2.1. Net::SMTP methods
News::Newsrc module: 17.3.1. News::Newsrc Reference
SOAP::Lite: 14.2.1. SOAP::Lite Methods
URI::URL module: 20.5.3. URI::URL
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify
Win32::Console module: 22.2. Win32::Console
Win32::Internet module: 22.7. Win32::Internet
22.7.1. General Internet Methods
Win32::OLE module: 23.1. Creating Objects
Win32::OLE::Enum module: 23.3.1. Win32::OLE::Enum Methods
Win32::OLE::Variant module: 23.4. Win32::OLE::Variant
Win32::Pipe module: 22.13. Win32::Pipe
XML::Parser module: 13.2. XML::Parser Methods
newgroups( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
newnews( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
news: 17. Usenet News
Net::News module: 17.2. Net::NNTP
News::Newsrc module: 17.3. The News::Newsrc Module
NNTP protocol: 17.1. The NNTP Protocol
newsgroups
listing available: 17.1. The NNTP Protocol
Perl-related: 1.4.1. The comp.lang.perl.* Newsgroups
newsgroups( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
News::Newsrc module: 17.3. The News::Newsrc Module
.newsrc file: 17.3. The News::Newsrc Module
next( ): 5. Function Reference
Net::NNTP module: 17.2.2. Net::NNTP Reference
next command: 4.3.1.5. Loop control
Next( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods
next_labeled_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
next_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
nlst( ) (Net::FTP): 18.2. Net::FTP
N{name} (named character value) sequence: 4.6.3. Escaped Sequences
NNTP (Network News Transfer Protocol): 17. Usenet News
nntppost( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
nntpstat( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
no( ): 5. Function Reference
non-greedy matching: 4.6.6. Quantifiers
none index (Menu widget): 21.15.1. Menu Indexes
NonStop option (PERLDB_OPTS): 6.4. Customizing the Debugger
no_proxy( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
Notation handler (Expat): 13.3. Expat Handlers
noTTY option (PERLDB_OPTS): 6.4. Customizing the Debugger
no_visits( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections
nph( ) (CGI.pm): 10.7. CGI.pm Reference
$NR variable: 4.4.1. Global Special Variables
NTFS file permissions: 22.6. Win32::FileSecurity
numbers: 4.2.1. Numbers
D (nondigit) character class: 4.6.4. Character Classes
fixed-precision numeric fields: 4.12. Formats
functions for: 5.1. Perl Functions by Category

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

o command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
O command (Perl debugger): 6.2. Debugger Commands
-O file test operator: 4.5.8. File Test Operators
O module: 8.165. O
-O option (dprofpp): 6.5. The Perl Profiler
-o option (perlcc): 3.4. The Perl Compiler
o pattern match modifier: 4.6.1. Pattern-Matching Operators
object-oriented programming: 7.3. Object-Oriented Perl
objects: 7.3. Object-Oriented Perl
functions for: 5.1. Perl Functions by Category
instance vs. class methods: 7.4. Object Syntax
Objects style (XML::Parser): 13.4. XML::Parser Styles
obtaining Perl modules: 2.2. How Is CPAN Organized?
2.4. Getting and Installing Modules
obtaining Perl source code: 2. Installing Perl
oct( ): 5. Function Reference
ODBC Extension: 24. ODBC Extension for Win32
ODBM_File module: 8.166. ODBM_File
-offvalue option
Checkbutton widget: 21.5. The Checkbutton Widget
Menubutton widget: 21.14.1. Menu Item Options
$OFMT ($#) variable: 4.4.1. Global Special Variables
$OFS ($,) variable: 4.4.1. Global Special Variables
-ok option (perlbug): 6.6. The perlbug Program
-okay option (perlbug): 6.6. The perlbug Program
OLE automation: 23. OLE Automation
on_action( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
on_debug( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
on_fault( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
on_nonserialized( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
-onvalue option
Checkbutton widget: 21.5. The Checkbutton Widget
Menubutton widget: 21.14.1. Menu Item Options
Opcode module: 8.167. Opcode
open( ): 5. Function Reference
DirHandle module: 8.59. DirHandle
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder
Mail::Mailer module: 16.2.1. Send Email with Mail::Mailer
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
16.2.2. Better Header Control with Mail::Send
PerlIO: 4.9.1. Perl 5.8 and PerlIO
Win32::Mutex module: 22.9. Win32::Mutex
Win32::Semaphore module: 22.16. Win32::Semaphore
Open( ) (Win32::Registry): 22.15. Win32::Registry
opendir( ): 5. Function Reference
OpenLDAP: 19. Lightweight Directory Access with Net::LDAP
OpenRequest( ) (Win32::Internet): 22.7.3. HTTP Functions
OpenURL( ) (Win32::Internet): 22.7.1. General Internet Methods
operators: 4.5. Operators
ops module: 8.168. ops
Optionmenu widget (Perl/Tk): 21.16. The Optionmenu Widget
-options option (Optionmenu): 21.16. The Optionmenu Widget
OR (|) operator, bitwise: 4.5.10. Bitwise Operators
OR (||) operator, logical: 4.5.9. Logical Operators
or (OR) operator: 4.5.9. Logical Operators
oraperl package: 12.2. Design of DBI
ord( ): 5. Function Reference
-orient option
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
$ORS ($) variable: 4.4.1. Global Special Variables
$OS_ERROR ($!) variable: 4.4.1. Global Special Variables
$OSNAME ($^O) variable: 4.4.1. Global Special Variables
our( ): 5. Function Reference
output: 5.1. Perl Functions by Category
formats for: 4.12. Formats
$OUTPUT_AUTOFLUSH ($|) variable: 4.4.6. Filehandle Special Variables
OutputCP( ) (Win32::Console): 22.2. Win32::Console
$OUTPUT_FIELD_SEPARATOR ($,) variable: 4.4.1. Global Special Variables
$OUTPUT_RECORD_SEPARATOR ($) variable: 4.4.1. Global Special Variables
outputxml( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
=over command (pod): 4.13.1. Paragraph Tags
overload module: 8.169. overload
overridedirect( ) (Frame widget): 21.18.1. Toplevel Methods
overview_fmt( ) (Net::NNTP): 17.2.2. Net::NNTP Reference

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

p command (Perl debugger): 6.2. Debugger Commands
-p file test operator: 4.5.8. File Test Operators
-p option (dprofpp): 6.5. The Perl Profiler
pack( ): 5. Function Reference
Mail::Folder folder: 16.2.3. Handle Folders with Mail::Folder
pack geometry manager (Perl/Tk): 21.2.1. The pack Geometry Manager
package( ): 5. Function Reference
_ _PACKAGE_ _ constant: 4.4.4. Global Special Constants
package statement: 7.1. Namespaces and Packages
packages: 7.1. Namespaces and Packages
packet-oriented communication: 15. Sockets
packForget( ) (pack geometry manager): 21.2.1.1. pack methods
packInfo( ) (pack geometry manager): 21.2.1.1. pack methods
packPropogate( ) (pack geometry manager): 21.2.1.1. pack methods
packSlaves( ) (pack geometry manager): 21.2.1.1. pack methods
-padbottom option, form geometry manager: 21.2.4. The form Geometry Manager
-padleft option, form geometry manager: 21.2.4. The form Geometry Manager
-padright option, form geometry manager: 21.2.4. The form Geometry Manager
-padtop option, form geometry manager: 21.2.4. The form Geometry Manager
-padx option, form geometry manager: 21.2.4. The form Geometry Manager
-padx, -pady options: 21.3. Common Widget Configuration Options
grid geometry manager: 21.2.2. The grid Geometry Manager
pack geometry manager: 21.2.1. The pack Geometry Manager
-pady option, form geometry manager: 21.2.4. The form Geometry Manager
paragraph tags (pod): 4.13.1. Paragraph Tags
param( ) (CGI.pm): 10. The CGI.pm Module
10.7. CGI.pm Reference
params function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
params( ) (URI::URL): 20.5.3. URI::URL
parent( ) (HTML::Parser): 20.4.3. HTML::Element
parentheses ( )
around function arguments: 5. Function Reference
operator precedence and: 4.5. Operators
regular expression metacharacter: 4.6.2. Regular Expression Syntax
(?...) extended regular expression syntax: 4.6.8. Extended Regular Expressions
parse( )
HTML::Parser module: 20.4.1. HTML::Parser
Mail::Address module: 16.2.7. Mail::Address Reference
XML::Parser module: 13.2. XML::Parser Methods
parse_date( ) (HTTP::Date): 20.3.5. HTTP::Date
parse_file( ) (HTML::Parser): 20.4.1. HTML::Parser
parsefile( ) (XML::Parser module): 13.2. XML::Parser Methods
parse_head( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
parse_start( ) (XML::Parser module): 13.2. XML::Parser Methods
parsestring( ) (XML::Parser module): 13.2. XML::Parser Methods
parsing
email addresses: 16.2.6. Parse Email Addresses with Mail::Address
event-based: 13.3. Expat Handlers
pass( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3
16.1.3. Retrieving Email with Net::POP3
PASS command (POP3): 16.1.3. Retrieving Email with Net::POP3
passing arguments to subroutines: 4.7.2. Passing Arguments
passing references to subroutines: 4.7.3. Passing References
password( )
Net::Netrc module: 18.3. FTP Configuration with Net::Netrc
URI::URL module: 20.5.3. URI::URL
password entries (.netrc): 18.3. FTP Configuration with Net::Netrc
Password( ) (Win32::Internet): 22.7.1. General Internet Methods
password_field( ) (CGI.pm): 10.7. CGI.pm Reference
pasv( ) (Net::FTP): 18.2. Net::FTP
pasv_wait( ) (Net::FTP): 18.2. Net::FTP
pasv_xfer( ) (Net::FTP): 18.2. Net::FTP
pasv_xfer_unique( ) (Net::FTP): 18.2. Net::FTP
patches for Perl source code: 2.3.1.2. Patches
path( )
Mail::Address module: 16.2.7. Mail::Address Reference
URI::URL module: 20.5.3. URI::URL
PATH variable: 3.3. Environment Variables
PATHEXT variable: 3.3. Environment Variables
path_info( ) (CGI.pm): 10.7. CGI.pm Reference
PATH_INFO variable: 9.3. Extra Path Information
path_translated( ) (CGI.pm): 10.7. CGI.pm Reference
PATH_TRANSLATED variable: 9.3. Extra Path Information
pattern matching functions: 5.1. Perl Functions by Category
pattern matching operators: 4.5.7. Pattern Match Operators
4.6.1. Pattern-Matching Operators
PauseService( ) (Win32::Service): 22.17. Win32::Service
PeekInput( ) (Win32::Console): 22.2. Win32::Console
Peer option (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference
peeraddr( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods
PeerAddr option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
peerhost( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods
peerpath (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference
peerport( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods
PeerPort option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
percent sign (%)
dereferencing with: 4.8.2. Dereferencing
modulus operator: 4.5.3. Arithmetic Operators
prototype symbol (hash): 4.7.5. Prototypes
%= (assignment) operator: 4.5.6. Assignment Operators
%SIG: 4.10. Signals
performance
CGI programs: 9. CGI Overview
CGI scripts, with mod_perl: 11.4. Running CGI Scripts with mod_perl
period: 4.5.6. Assignment Operators
<Perl>: 11.6. <Perl> Sections
Perl
compiler: 3.4. The Perl Compiler
conferences: 1.4.8. Perl Conferences
debugger: 6.1. The Perl Debugger
commands for: 6.2. Debugger Commands
customizing: 6.4. Customizing the Debugger
Unicode support: 4.11. Unicode
perl-bin directory: 11.4. Running CGI Scripts with mod_perl
PERL_DEBUG_MSTATS variable: 3.3. Environment Variables
PERL_DESTRUCT_LEVEL variable: 3.3. Environment Variables
perl executable: 3. The Perl Executable
Perl Journal: 1.4.7. The Perl Journal
Perl language: 1. Introduction to Perl
bugs in, reporting: 6.6. The perlbug Program
development of: 1.2. Perl Development
documentation: 2.5. Documentation
4.13. Pod
= (equals sign), and: 4.1. Program Structure
utilities for: 4.13.3. Pod Utilities
example scripts: 2.3.1.1. Perl examples
installing source code: 2.3. Installing Perl
multithreading, and: 3.5. Threads
obtaining source from CPAN: 2. Installing Perl
resources: 1.4. Perl Resources
signals, handling: 4.10. Signals
uses of: 1.1. What's Perl Good For?
v. 5.8, I/O: 4.9.1. Perl 5.8 and PerlIO
PERL_MAILERS variable: 16.2.1. Send Email with Mail::Mailer
PERL_MODULE_EXT variable: 3.4. The Perl Compiler
Perl Mongers: 1.4.6. Perl Mongers (www.perl.org)
Perl Package Manager (PPM): 2.4.3.2. Using the Perl Package Manager
perl (Perl interpreter): 3. The Perl Executable
command-line options: 3.2. Command-Line Options
command processing: 3.1. Command Processing
Perl profiler (DProf): 6.5. The Perl Profiler
PERL_SCRIPT_EXT variable: 3.4. The Perl Compiler
perl-script handler: 11.3. mod_perl Handlers
11.4. Running CGI Scripts with mod_perl
$PERL_VERSION ($]) variable: 4.4.1. Global Special Variables
perlbug program: 6.6. The perlbug Program
perlcc utility: 3.4. The Perl Compiler
.perldb file: 6.4. Customizing the Debugger
$PERLDB ($^P) variable: 4.4.1. Global Special Variables
PERLDB_OPTS variable: 6.4. Customizing the Debugger
perldoc command: 4.13.3. Pod Utilities
8. Standard Modules
PerlHandler directive (mod_perl): 11.3. mod_perl Handlers
PerlIO modules: 4.9.1. Perl 5.8 and PerlIO
8.170. PerlIO
PerlIO::Scalar: 8.171. PerlIO::Scalar
PerlIO::Via: 8.172. PerlIO::Via
PERLLIB variable: 3.3. Environment Variables
PerlModule directive (mod_perl): 11.4. Running CGI Scripts with mod_perl
PERL5OPT variable: 3.3. Environment Variables
PERL5SHELL variable: 3.3. Environment Variables
perl_stringify function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
Perl/Tk: 21. Perl/Tk
callbacks: 21.1.3. Callbacks
colors and fonts: 21.1.4. Colors and Fonts
geometry managers: 21.2. Geometry Managers
scrollbars: 21.1.2. Scrollbars
widgets: 21.1. Widgets
Button widget: 21.4. The Button Widget
Canvas widget: 21.12. The Canvas Widget
Checkbutton widget: 21.5. The Checkbutton Widget
common configuration options: 21.3. Common Widget Configuration Options
Entry widget: 21.8. The Entry Widget
Frame widget: 21.17. The Frame Widget
Label widget: 21.7. The Label Widget
Listbox widget: 21.10. The Listbox Widget
Menu widget: 21.15. The Menu Widget
Menubutton widget: 21.14. The Menubutton Widget
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
Text widget: 21.11. The Text Widget
toplevel widget: 21.18. The Toplevel Widget
widgets methods: 21.1.1. Widget Methods
phrase( ) (Mail::Address): 16.2.6. Parse Email Addresses with Mail::Address
16.2.7. Mail::Address Reference
$PID ($$) variable: 4.4.1. Global Special Variables
ping( ) (DBI): 12.3. DBI Methods
pipe( ): 5. Function Reference
place geometry manager (Perl/Tk): 21.2.3. The place Geometry Manager
placeForget( ) (place geometry manager): 21.2.3. The place Geometry Manager
placeholders (DBI): 12.2.4. Placeholders and Statement Handles
placeInfo( ) (place geometry manager): 21.2.3. The place Geometry Manager
placeSlaves( ) (place geometry manager): 21.2.3. The place Geometry Manager
platforms supporting Perl: 1.3. Which Platforms Support Perl?
pl2bat.bat: 3. The Perl Executable
plus (+)
2: 4.5.5. Autoincrement and Autodecrement
regular expression metacharacter: 4.6.2. Regular Expression Syntax
unary operator: 4.5.2. Unary Operators
+= (assignment) operator: 4.5.6. Assignment Operators
=pod command (pod): 4.13.1. Paragraph Tags
pod documentation: 2.5. Documentation
4.13. Pod
= to signify in programs: 4.1. Program Structure
utilities for: 4.13.3. Pod Utilities
Pod::Functions module: 8.173. Pod::Functions
Pod::Html module: 8.174. Pod::Html
Pod::Text module: 8.176. Pod::Text
pod2fm utility: 4.13.3. Pod Utilities
pod2html utility: 4.13.3. Pod Utilities
8.174. Pod::Html
pod2latex utility: 4.13.3. Pod Utilities
pod2man utility: 4.13.3. Pod Utilities
Pod::ParseLink module: 8.175. Pod::ParseLink
pod2text utility: 4.13.3. Pod Utilities
8.176. Pod::Text
pop( ): 5. Function Reference
POP3 protocol, interface to: 16.1.3. Retrieving Email with Net::POP3
16.2.8. Checking Blacklisted Hosts with Mail::RBL
popstat( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3
popup_menu( ) (CGI.pm): 10.7. CGI.pm Reference
port( )
Net::FTP module: 18.2. Net::FTP
URI::URL module: 20.5.3. URI::URL
pos( ): 5. Function Reference
pos( ) (HTML::Parser): 20.4.3. HTML::Element
positionfrom( ) (Frame widget): 21.18.1. Toplevel Methods
POSIX module: 8.177. POSIX
post command (NNTP): 17.1. The NNTP Protocol
post( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
post( ) (Menu widget): 21.15.2. Menu Methods
POST method (CGI): 9.1.1. Transferring the Form Data
20.3.1. HTTP::Request
post( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
Post Office Protocol (POP3): 16.1.3. Retrieving Email with Net::POP3
postcascade( ) (Menu widget): 21.15.2. Menu Methods
-postcommand option (Menu): 21.15. The Menu Widget
posting news articles: 17.1. The NNTP Protocol
$POSTMATCH ($') variable: 4.4.5. Regular Expression Special Variables
postok( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
postscript( ) (Canvas): 21.12.3. Canvas Methods
PostScript, converting HTML parse tree to: 20.4.5. HTML::FormatPS
pound sign: 3. The Perl Executable
PPM (Perl Package Manager): 2.4.3.2. Using the Perl Package Manager
precedence, operator: 4.5. Operators
predefined Perl variables: 4.4. Special Variables
$PREMATCH ($`) variable: 4.4.5. Regular Expression Special Variables
prepare( ) (DBI): 12.2.3. Database Handles and Statement Handles
12.3. DBI Methods
prev_labeled( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
prev_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
print( ): 5. Function Reference
Socket module: 15.1.2. Client Connections
printf( ): 5. Function Reference
print_header( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
private variables: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables
Proc handler (Expat): 13.3. Expat Handlers
process management: 22.13. Win32::Pipe
22.14. Win32::Process
$PROCESS_ID ($$) variable: 4.4.1. Global Special Variables
product_tokens( ) (HTTP::Daemon): 20.3.7. HTTP::Daemon
profiler, Perl (DProf): 6.5. The Perl Profiler
-prog option (perlcc): 3.4. The Perl Compiler
program flow control functions: 5.1. Perl Functions by Category
program structure: 4.1. Program Structure
$PROGRAM_NAME ($0) variable: 4.4.1. Global Special Variables
Proto option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
protocol( )
Frame widget module: 21.18.1. Toplevel Methods
HTTP::Message module: 20.3.8. HTTP::Message
IO::Socket module: 15.2.3. IO::Socket Methods
protocols_allowed( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
rotocols_forbidden( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
proto_ge( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
prototype( ): 5. Function Reference
prototypes for subroutines: 4.7. Subroutines
4.7.5. Prototypes
proxy( )
LWP::UserAgent: 20.2.3. LWP::UserAgent
SOAP::Lite: 14.2. SOAP::Lite
push( ): 5. Function Reference
push_content( ) (HTML::Parser): 20.4.3. HTML::Element
init_header( ) (HTTP::Headers): 20.3.3. HTTP::Headers
Put( ) (Win32::Internet): 22.7.2. FTP Functions
PUT requests (CGI): 20.3.1. HTTP::Request
put_unique( ) (Net::FTP): 18.2. Net::FTP
pwd( ) (Net::FTP): 18.2. Net::FTP
Pwd( ) (Win32::Internet): 22.7.2. FTP Functions

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

` quote (disable) character: 4.6.4. Character Classes
q command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
q command (Perl debugger): 6.2. Debugger Commands
-q option (dprofpp): 6.5. The Perl Profiler
q// pattern match operator: 4.6.1. Pattern-Matching Operators
5. Function Reference
qty( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
quant method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods
quantifiers for regular expressions: 4.6.6. Quantifiers
query( ) (URI::URL): 20.5.3. URI::URL
QueryDataAvailable( ) (Win32::Internet): 22.7.1. General Internet Methods
QueryInfo( ) (Win32::Internet): 22.7.3. HTTP Functions
QueryKey( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
QueryObjectType( ) (Win32::OLE): 23.2.1. Win32::OLE Methods
QueryOption( ) (Win32::Internet): 22.7.1. General Internet Methods
QUERY_STRING variable: 9.1.1. Transferring the Form Data
QueryValue( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
question mark (?)
regular expression metacharacter: 4.6.2. Regular Expression Syntax
?: (conditional) operator: 4.5.11.2. Conditional operator
?...? pattern match operator: 4.6.1. Pattern-Matching Operators
?...? Perl debugger command: 6.2. Debugger Commands
quit( )
Net::FTP module: 18.2. Net::FTP
Net::NNTP module: 17.2.2. Net::NNTP Reference
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
Net::SMTP module: 16.1.2.1. Net::SMTP methods
QUIT command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session
quot( ) (Net::FTP): 18.2. Net::FTP
quote( ) (DBI): 12.3. DBI Methods
quotemeta( ): 5. Function Reference
quoting schemes: 4.2.2. String Interpolation

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

r command
CPAN.pm: 2.4.4. Installing Modules with the CPAN Module
Perl debugger: 6.2. Debugger Commands
R command (Perl debugger): 6.2. Debugger Commands
-R file test operator: 4.5.8. File Test Operators
-r option
dprofpp: 6.5. The Perl Profiler
form geometry manager: 21.2.4. The form Geometry Manager
perlbug: 6.6. The perlbug Program
r (carriage return) sequence: 4.6.3. Escaped Sequences
radiobutton( ) (Menubutton): 21.14.2. Menubutton Methods
Radiobutton widget (Perl/Tk): 21.6. The Radiobutton Widget
radio_group( ) (CGI.pm): 10.7. CGI.pm Reference
raise( ) (Canvas): 21.12.3. Canvas Methods
rand( ): 5. Function Reference
range (..) operator: 4.5.11.1. Range operator
range (...) operator: 4.5.11.1. Range operator
raw_cookie( ) (CGI.pm): 10.7. CGI.pm Reference
RC_ mnemonics (HTTP::Status): 20.3.4. HTTP::Status
RCPT command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session
re module: 8.178. re
read( ): 5. Function Reference
DirHandle module: 8.59. DirHandle
Read( ) (Win32::EventLog): 22.4. Win32::Eventlog
readable( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
ReadAttr( ) (Win32::Console): 22.2. Win32::Console
read_buffer( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
ReadChar( ) (Win32::Console): 22.2. Win32::Console
readdir( ): 5. Function Reference
ReadEntireFile( ) (Win32::Internet): 22.7.1. General Internet Methods
reader( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
ReadFile( ) (Win32::Internet): 22.7.1. General Internet Methods
reading email messages
Mail::Audit: 16.2.9. Mail Filtering with Mail::Audit
Mail::RBL: 16.2.8. Checking Blacklisted Hosts with Mail::RBL
reading news articles: 17.1. The NNTP Protocol
readline( ): 5. Function Reference
ReadLine option (PERLDB_OPTS): 6.4. Customizing the Debugger
readlink( ): 5. Function Reference
readme command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
ReadParse( ) (CGI.pm): 10.7. CGI.pm Reference
readpipe( ): 5. Function Reference
ReadRect( ) (Win32::Console): 22.2. Win32::Console
Read( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods
$REAL_GROUP_ID ($( ) variable: 4.4.1. Global Special Variables
$REAL_USER_ID ($<) variable: 4.4.1. Global Special Variables
reason( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
recipient( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
recompile command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
records, functions for: 5.1. Perl Functions by Category
recv( ): 5. Function Reference
Socket module: 15.1. Built-in Socket Functions
redirect( ) (CGI.pm): 10.7. CGI.pm Reference
redo( ): 5. Function Reference
redo command: 4.3.1.5. Loop control
ref( ): 4.8.2. Dereferencing
5. Function Reference
references: 4.8.1. Creating References
passing to subroutines: 4.7.3. Passing References
referer( ) (CGI.pm): 10.7. CGI.pm Reference
refile( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
-regex option (perlcc): 3.4. The Perl Compiler
Registry access and management: 22.15. Win32::Registry
regular expressions: 4.6. Regular Expressions
anchors: 4.6.5. Anchors
character classes: 4.6.4. Character Classes
escaped sequences: 4.6.3. Escaped Sequences
extended, syntax for: 4.6.8. Extended Regular Expressions
functions for: 5.1. Perl Functions by Category
metacharacters: 4.6.2. Regular Expression Syntax
pattern match variables: 4.6.7. Pattern Match Variables
pattern matching operators: 4.5.7. Pattern Match Operators
4.6.1. Pattern-Matching Operators
quantifiers: 4.6.6. Quantifiers
special (predefined) variables: 4.4.5. Regular Expression Special Variables
rel( ) (URI::URL): 20.5.3. URI::URL
relational operators: 4.5.4.1. Relational operators
release( )
Win32::Mutex module: 22.9. Win32::Mutex
Win32::Semaphore module: 22.16. Win32::Semaphore
-relheight, -relwidth options (place geometry manager): 21.2.3. The place Geometry Manager
-relief option (widgets): 21.3. Common Widget Configuration Options
reload command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
-relx, -rely options (place geometry manager): 21.2.3. The place Geometry Manager
remote_host( ) (CGI.pm): 10.7. CGI.pm Reference
remote_user( ) (CGI.pm): 10.7. CGI.pm Reference
remove_header( ) (HTTP::Headers): 20.3.3. HTTP::Headers
remove_sig( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
rename( ): 5. Function Reference
Net::FTP module: 18.2. Net::FTP
Rename( ) (Win32::Internet): 22.7.2. FTP Functions
-repeatdelay option
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
-repeatinterval option
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
reply( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
Report( ) (Win32::EventLog): 22.4. Win32::Eventlog
reporting bugs in Perl: 6.6. The perlbug Program
request( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
Request( ) (Win32::Internet): 22.7.3. HTTP Functions
request_method( ) (CGI.pm): 10.7. CGI.pm Reference
requests, HTTP
HTTP::Request module: 20.1. LWP Overview
20.3.1. HTTP::Request
UserAgent object for: 20.1. LWP Overview
20.2. The LWP Modules
20.2.3. LWP::UserAgent
require( ): 5. Function Reference
require directives: 7.2. Modules
reset( ): 5. Function Reference
CGI.pm module: 10.7. CGI.pm Reference
Data::Dumper: 8.50. Data::Dumper
Digest modules: 8.57. Digest
Digest::MD5 module: 8.58. Digest::MD5
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3
Net::SMTP module: 16.1.2.1. Net::SMTP methods
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify
resizable( ) (Frame widget): 21.18.1. Toplevel Methods
-resolution option (Scale): 21.13. The Scale Widget
Resolve( ) (Win32::Shortcut): 22.18. Win32::Shortcut
resources for further reading: 1.4. Perl Resources
resources, managing shared: 22.11. Win32::NetResource
responses, HTTP: 20.3.2. HTTP::Response
Resume( ) (Win32::Process): 22.14.1. Win32::Process Methods
ResumeService( ) (Win32::Service): 22.17. Win32::Service
retr( ) (Net::FTP): 18.2. Net::FTP
retrieving email messages: 16.1.3. Retrieving Email with Net::POP3
return( ): 5. Function Reference
return statement: 4.7.2. Passing Arguments
return_clause function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
Reuse option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
reverse( ): 5. Function Reference
revert( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies
rewind( ) (DirHandle module): 8.59. DirHandle
rewinddir( ): 5. Function Reference
RFC 1617, LDAP data storage: 19.1. How Data Is Stored in LDAP
-right option, form geometry manager: 21.2.4. The form Geometry Manager
-rightspring option, form geometry manager: 21.2.4. The form Geometry Manager
rindex( ): 5. Function Reference
rmdir( ): 5. Function Reference
Net::FTP module: 18.2. Net::FTP
Rmdir( ) (Win32::Internet): 22.7.2. FTP Functions
Robot User Agent: 20.2.1. LWP::RobotUA Sections
rollback( ) (DBI): 12.3. DBI Methods
-row option (grid manager): 21.2.2. The grid Geometry Manager
rows( ) (DBI): 12.3. DBI Methods
-rowspan option (grid manager): 21.2.2. The grid Geometry Manager
-rp option, form geometry manager: 21.2.4. The form Geometry Manager
RPCs (remote procedure calls): 14.1. What Is SOAP?
-rs option, form geometry manager: 21.2.4. The form Geometry Manager
rules( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections
-run option (perlcc): 3.4. The Perl Compiler
RunSQL( ) (Win32::ODBC): 24.1. ODBC Methods and Properties

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

s (whitespace) character class: 4.6.4. Character Classes
s command (Perl debugger): 6.2. Debugger Commands
-S file test operator: 4.5.8. File Test Operators
-s option (dprofpp): 6.5. The Perl Profiler
-S option (perlbug): 6.6. The perlbug Program
s pattern match modifier: 4.6.1. Pattern-Matching Operators
4.6.8. Extended Regular Expressions
s/// (substitution) operator: 4.6. Regular Expressions
4.6.1. Pattern-Matching Operators
Safe module: 8.179. Safe
-sav option (perlcc): 3.4. The Perl Compiler
Save( )
Win32::Registry module: 22.15.1. Win32::Registry Methods
Win32::Shortcut module: 22.18. Win32::Shortcut
save_as( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
scalar( ): 4.2.6. Scalar and List Contexts
5. Function Reference
scalar context: 4.2.6. Scalar and List Contexts
scalar prototype symbol ($): 4.7.5. Prototypes
scalars
arrays of: 4.2.5.1. Arrays
functions for manipulating: 5.1. Perl Functions by Category
lists of: 4.2.3. Here Documents
4.2.4. Lists
references: 4.8.1. Creating References
Scalar::Util module: 8.180. Scalar::Util
scale( ) (Canvas): 21.12.3. Canvas Methods
Scale widget (Perl/Tk): 21.13. The Scale Widget
scan( )
HTTP::Cookies module: 20.3.6. HTTP::Cookies
HTTP::Headers module: 20.3.3. HTTP::Headers
scheme( ) (URI::URL): 20.5.3. URI::URL
scope, variable: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables
functions for: 5.1. Perl Functions by Category
-screen option (toplevel): 21.18. The Toplevel Widget
script_name( ) (CGI.pm): 10.7. CGI.pm Reference
scripts, Perl examples, obtaining: 2.3.1.1. Perl examples
Scroll( ) (Win32::Console): 22.2. Win32::Console
Scrollbar widget (Perl/Tk): 21.1.2.2. The Scrollbar widget
21.9. The Scrollbar Widget
scrollbars, widget (Perl/Tk): 21.1.2. Scrollbars
Scrolled( ) (Perl/Tk): 21.1.2.1. Using the Scrolled method
scrolling_list( ) (CGI.pm): 10.7. CGI.pm Reference
-scrollregion option (Canvas): 21.12. The Canvas Widget
SDBM_File module: 8.181. SDBM_File
Search::Dict module: 8.182. Search::Dict
search( ) (Net::LDAP): 19.4. Net::LDAP Methods
search( ) (Text widget): 21.11.2. Text Methods
searching against LDAP: 19.2. Searching an LDAP Directory with Net::LDAP
see( )
Listbox widget: 21.10.2. Listbox Methods
Text widget: 21.11.2. Text Methods
seek( ): 5. Function Reference
seekdir( ): 5. Function Reference
Seen( ) (Data::Dumper)): 8.50. Data::Dumper
select( ): 5. Function Reference
Checkbutton widget: 21.5.1. Checkbutton Methods
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder
Radiobutton widget: 21.6.1. Radiobutton Methods
Select( ) (Win32::Console): 22.2. Win32::Console
-selectbackground option (widgets): 21.3. Common Widget Configuration Options
-selectborderwidth option (widgets): 21.3. Common Widget Configuration Options
-selectcolor option
Checkbutton widget: 21.5. The Checkbutton Widget
Menu widget: 21.15. The Menu Widget
Menubutton widget: 21.14.1. Menu Item Options
Radiobutton widget: 21.6. The Radiobutton Widget
-selectforeground option (widgets): 21.3. Common Widget Configuration Options
-selectimage option
Checkbutton widget: 21.5. The Checkbutton Widget
Menubutton widget: 21.14.1. Menu Item Options
Radiobutton widget: 21.6. The Radiobutton Widget
selection( )
Entry widget: 21.8.2. Entry Methods
Listbox widget: 21.10.2. Listbox Methods
select_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
-selectmode option (Listbox): 21.10. The Listbox Widget
SelectSaver module: 8.183. SelectSaver
self( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
self_and_super_path( ) (Class::ISA module): 8.42. Class::ISA
self_and_super_versions( ) (Class::ISA module): 8.42. Class::ISA
sel.first, sel.last indexes
Entry widget: 21.8.1. Text Indexes
Text widget: 21.11.1. Text Indexes and Modifiers
SelfLoader module: 8.184. SelfLoader
self_url( ) (CGI.pm): 10.7. CGI.pm Reference
semaphores, implementing: 22.16. Win32::Semaphore
semctl( ): 5. Function Reference
semget( ): 5. Function Reference
semicolon (;)
ending Perl statements: 4.1. Program Structure
in prototype declarations: 4.7.5. Prototypes
semop( ): 5. Function Reference
send( ): 5. Function Reference
Socket: 15.1. Built-in Socket Functions
send_basic_header( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
send_crlf( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
send_error( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
send_file( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
sending email messages: 16.1.1. Send Email with Net::SMTP
send_redirect( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
SendRequest( ) (Win32::Internet): 22.7.3. HTTP Functions
send_response( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
send_status_line( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods
separator( ) (Menubutton): 21.14.2. Menubutton Methods
seq( ) (DB_File module): 8.52. DB_File
serializer( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
server-side includes (SSI), mod_perl with: 11.5. Server-Side Includes with mod_perl
server-side socket connections: 15.1.3. Server Connections
15.2.2. Server-Side Sockets
service control interface: 22.17. Win32::Service
set( )
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
16.2.2. Better Header Control with Mail::Send
Scale widget: 21.13.1. Scale Methods
Scrollbar widget: 21.9.1. Scrollbar Methods
Set-Cookie2 header: 20.3.6. HTTP::Cookies
SetAttributes( ) (Win32::File): 22.5. Win32::File
SetConnectOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
set_cookie( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies
SetCursorName( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
setgrent( ): 5. Function Reference
-setgrid option
Listbox widget: 21.10. The Listbox Widget
Text widget: 21.11. The Text Widget
SetHandler directive (mod_perl): 11.3. mod_perl Handlers
setHandlers( )
XML::Parser module: 13.2. XML::Parser Methods
sethostent( ): 5. Function Reference
SetMaxBufSize( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
setnetent( ): 5. Function Reference
set_option( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
SetOption( ) (Win32::Internet): 22.7.1. General Internet Methods
setpgrp( ): 5. Function Reference
SetPos( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
setpriority( ): 5. Function Reference
SetPriorityClass( ) (Win32::Process): 22.14.1. Win32::Process Methods
setprotoent( ): 5. Function Reference
setpwent( ): 5. Function Reference
set_readonly( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
ResizeBuffer(SIZE) (Win32::Pipe): 22.13.1. Win32::Pipe Methods
setservent( ): 5. Function Reference
setsockopt( ): 5. Function Reference
SetStatusCallback( ) (Win32::Internet): 22.7.1. General Internet Methods
SetStmtCloseType( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
SetStmtOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
SetValue( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
SetValueEx( ) (Win32::Registry): 22.15.1. Win32::Registry Methods
shar: 2.3.1. Installing on Unix
shared resources, managing: 22.11. Win32::NetResource
share_info hash: 22.11. Win32::NetResource
shebang (#!): 0.5. Acknowledgments for the Second Edition
3. The Perl Executable
Shell module: 8.185. Shell
shift( ): 5. Function Reference
shmctl( ): 5. Function Reference
shmget( ): 5. Function Reference
shmread( ): 5. Function Reference
shmwrite( ): 5. Function Reference
shortcut files: 22.18. Win32::Shortcut
-show option (Entry): 21.8. The Entry Widget
Showlex backend (Perl compiler): 3.4. The Perl Compiler
-showvalue option (Scale): 21.13. The Scale Widget
Shutdown( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
-side option (pack geometry manager): 21.2.1. The pack Geometry Manager
%SIG hash: 4.4.2. Global Special Arrays and Hashes
signals, handling of: 4.10. Signals
sigtrap module: 8.186. sigtrap
Simple Mail Transport Protocol (SMTP): 16.1.1. Send Email with Net::SMTP
sin( ): 5. Function Reference
size( )
Listbox widget: 21.10.2. Listbox Methods
Net::FTP module: 18.2. Net::FTP
sizefrom( ) (Frame widget): 21.18.1. Toplevel Methods
Skip( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods
slash (/)
division operator: 4.5.3. Arithmetic Operators
encoding in URLs: 9.2. URL Encoding
/= (assignment) operator: 4.5.6. Assignment Operators
/.../ pattern match operator: 4.6. Regular Expressions
/.../ Perl debugger command: 6.2. Debugger Commands
slave( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
sleep( ): 5. Function Reference
slider (Scale) widget: 21.13. The Scale Widget
-sliderlength option (Scale): 21.13. The Scale Widget
SMTP protocol, interface to: 16.1.1. Send Email with Net::SMTP
smtpsend( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
SOAP 1.1 specification: 14.2. SOAP::Lite
SOAP (Simple Object Access Protocol): 14.1. What Is SOAP?
implementations: 14.2. SOAP::Lite
SOAP::Data: 14.3. SOAP::Data
SOAP::Fault: 14.5. SOAP::Fault
SOAP::Lite: 14.2. SOAP::Lite
methods: 14.2.1. SOAP::Lite Methods
SOAP::Serializer: 14.4. SOAP::Serializer
sockaddr( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods
sockaddr_in( ) (Socket): 15.1.3. Server Connections
15.1.4. Socket Module Functions
sockaddr_un( ) (Socket): 15.1.4. Socket Module Functions
sockdomain( ) (IO::Socket): 15.2.3. IO::Socket Methods
socket( ): 5. Function Reference
Socket module: 15.1. Built-in Socket Functions
Socket module: 8.187. Socket
socket( ) (Socket): 15.1.1. Initializing a Socket
socketpair( ): 5. Function Reference
sockets: 15. Sockets
built-in functions for: 15.1. Built-in Socket Functions
client-side connections: 15.1.2. Client Connections
15.2.1. Client-Side Sockets
initializing: 15.1.1. Initializing a Socket
IO::Socket module: 15.2. The IO::Socket Module
IO::Socket::INET subclass: 15.2.4. IO::Socket::INET Reference
IO::Socket::UNIX subclass: 15.2.5. IO::Socket::UNIX Reference
low-level access functions: 5.1. Perl Functions by Category
server-side connections: 15.1.3. Server Connections
15.2.2. Server-Side Sockets
Socket module functions: 15.1.4. Socket Module Functions
sockhost( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods
sockopt( ) (IO::Socket): 15.2.3. IO::Socket Methods
sockport( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods
socktype( ) (IO::Socket): 15.2.3. IO::Socket Methods
sort( ): 5. Function Reference
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder
sort module: 8.188. sort
source code for Perl, obtaining: 2. Installing Perl
-spacing1, -spacing2, -spacing3 options (Text): 21.11. The Text Widget
splain: 8.56. diagnostics
splice( ): 5. Function Reference
split( ): 5. Function Reference
sprintf( ): 5. Function Reference
Sql( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
SQL statement placeholders: 12.2.4. Placeholders and Statement Handles
sqrt( ): 5. Function Reference
srand( ): 5. Function Reference
SSI (server-side includes), mod_perl with: 11.5. Server-Side Includes with mod_perl
:ssl method group: 10.2. Importing Method Groups
:standard method group: 10.2. Importing Method Groups
standard modules, table listing: 8. Standard Modules
Start handler (Expat): 13.3. Expat Handlers
startform( ) (CGI.pm): 10.7. CGI.pm Reference
start_html( ) (CGI.pm): 10.5. Using JavaScript Features
10.7. CGI.pm Reference
start_multipart_form( ) (CGI.pm): 10.7. CGI.pm Reference
StartService( ) (Win32::Service): 22.17. Win32::Service
starttag( ) (HTML::Parser): 20.4.3. HTML::Element
start_tls( ) (Net::LDAP): 19.4. Net::LDAP Methods
stat( ): 5. Function Reference
state( )
DBI module: 12.3. DBI Methods
Frame widget: 21.18.1. Toplevel Methods
state, maintaining (CGI): 10.3. Maintaining State
-state option (widgets): 21.3. Common Widget Configuration Options
statement handles (DBI methods): 12.2.3. Database Handles and Statement Handles
statements: 4.3. Statements
STDERR filehandle: 4.4.3. Global Special Filehandles
4.9. Filehandles
STDIN filehandle: 4.4.3. Global Special Filehandles
4.9. Filehandles
STDOUT filehandle: 4.4.3. Global Special Filehandles
4.9. Filehandles
-sticky option (grid manager): 21.2.2. The grid Geometry Manager
StopService( ) (Win32::Service): 22.17. Win32::Service
stor( ) (Net::FTP): 18.2. Net::FTP
Storable module: 8.189. Storable
stou( ) (Net::FTP): 18.2. Net::FTP
Stream style (XML::Parser): 13.4. XML::Parser Styles
strict module: 8.190. strict
strict( ) (URI::URL): 20.5.3. URI::URL
string literals: 4.2.2. String Interpolation
character classes: 4.6.4. Character Classes
comparing: 4.5.4.1. Relational operators
operators for: 4.5.11.4. String operator
string repetition (x) operator: 4.5.11.4. String operator
strings, alternate schemes for quoting: 4.2.2. String Interpolation
str2time( ) (HTTP::Date): 20.3.5. HTTP::Date
struct( ) (Class::Struct module): 8.43. Class::Struct
structure of Perl programs: 4.1. Program Structure
stub( ) (Devel::SelfStubber module): 8.55. Devel::SelfStubber
study( ): 5. Function Reference
sub( ): 5. Function Reference
sub statement: 4.7. Subroutines
sub_groups( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
subject( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send
submit( ) (CGI.pm): 10.7. CGI.pm Reference
subroutines: 4.7. Subroutines
constructors: 7.3. Object-Oriented Perl
subs module: 8.191. subs
Subs style (XML::Parser): 13.4. XML::Parser Styles
subscribe( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
subscribed( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
subscriptions( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
$SUBSCRIPT_SEPARATOR ($;) variable: 4.4.1. Global Special Variables
$SUBSEP ($;) variable: 4.4.1. Global Special Variables
substitution (s///) operator: 4.6. Regular Expressions
4.6.1. Pattern-Matching Operators
substr( ): 5. Function Reference
success code (NNTP): 17.1. The NNTP Protocol
super_path( ) (Class::ISA module): 8.42. Class::ISA
supported( ) (Net::FTP): 18.2. Net::FTP
Suspend( ) (Win32::Process): 22.14.1. Win32::Process Methods
Switch module: 8.192. Switch
switch_clause function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
switches: 3.2. Command-Line Options
3.2. Command-Line Options
sybperl package: 12.2. Design of DBI
Symbol module: 8.193. Symbol
symlink( ): 5. Function Reference
sync( )
DB_File module: 8.52. DB_File
Mail::Folder: 16.2.3. Handle Folders with Mail::Folder
Sys::Hostname module: 8.194. Sys::Hostname
Sys::Syslog module: 8.195. Sys::Syslog
syscall( ): 5. Function Reference
sysopen( ): 5. Function Reference
sysread( ): 5. Function Reference
sysseek( ): 5. Function Reference
system( ): 5. Function Reference
System V interprocess communication functions: 5.1. Perl Functions by Category
$SYSTEM_FD_MAX ($^F) variable: 4.4.1. Global Special Variables
syswrite( ): 5. Function Reference

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

t command (Perl debugger): 6.2. Debugger Commands
-T file test operator: 4.5.8. File Test Operators
-t option
dprofpp: 6.5. The Perl Profiler
form geometry manager: 21.2.4. The form Geometry Manager
perlbug: 6.6. The perlbug Program
-T option (dprofpp): 6.5. The Perl Profiler
t (tab) sequence: 4.6.3. Escaped Sequences
TableList( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
-tabs option (Text): 21.11. The Text Widget
tag( ) (HTML::Parser): 20.4.3. HTML::Element
tagAdd( ) (Text widget): 21.11.3. Tags
tagBind( ) (Text widget): 21.11.3. Tags
tagCget( ) (Text widget): 21.11.3. Tags
tagConfigure( ) (Text widget): 21.11.3. Tags
tagDelete( ) (Text widget): 21.11.3. Tags
tagLower( ) (Text widget): 21.11.3. Tags
tagNames( ) (Text widget): 21.11.3. Tags
tagNextrange( ): 21.11.3. Tags
tagRaise( ) (Text widget): 21.11.3. Tags
tagRanges( ) (Text widget): 21.11.3. Tags
tagRemove( ) (Text widget): 21.11.3. Tags
tags, with Text widgets: 21.11.3. Tags
-takefocus option (widgets): 21.3. Common Widget Configuration Options
tar: 2.3.1. Installing on Unix
Win32, for: 2.3.2.2. Standard Perl distribution
-tearoff option
Menu widget: 21.15. The Menu Widget
Menubutton widget: 21.14. The Menubutton Widget
Optionmenu widget: 21.16. The Optionmenu Widget
tell( ): 5. Function Reference
telldir( ): 5. Function Reference
templates for outputting data: 4.12. Formats
Term::Cap module: 8.196. Term::Cap
Term::Complete module: 8.197. Term::Complete
Term::ReadLine module: 8.198. Term::ReadLine
test command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
Test modules: 8.199. Test
Test::Builder module: 8.200. Test::Builder
Test::Harness module: 8.201. Test::Harness
Test::More module: 8.202. Test::More
Test::Simple module: 8.203. Test::Simple
text, translating to/from pod: 4.13.3. Pod Utilities
8.176. Pod::Text
text indexes (Entry widgets): 21.8.1. Text Indexes
Text modules: 8.204. Text::Abbrev
Text::Abbrev module: 8.204. Text::Abbrev
Text::Balanced module: 8.205. Text::Balanced
Text::ParseWords module: 8.206. Text::ParseWords
Text::Soundex module: 8.207. Text::Soundex
Text::Tabs module: 8.208. Text::Tabs
Text::Wrap module: 8.209. Text::Wrap
-text option
Button widget: 21.4. The Button Widget
Checkbutton widget: 21.5. The Checkbutton Widget
Label widget: 21.7. The Label Widget
Menubutton widget: 21.14. The Menubutton Widget
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
Text widget (Perl/Tk): 21.11. The Text Widget
textarea( ) (CGI.pm): 10.7. CGI.pm Reference
textfield( ) (CGI.pm): 10.7. CGI.pm Reference
-textvariable option
Button widget: 21.4. The Button Widget
Checkbutton widget: 21.5. The Checkbutton Widget
Entry widget: 21.8. The Entry Widget
Label widget: 21.7. The Label Widget
Menubutton widget: 21.14. The Menubutton Widget
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
Thread module: 8.210. Thread
Thread::Queue module: 8.211. Thread::Queue
Thread::Semaphore module: 8.212. Thread::Semaphore
Thread::Signal module: 8.213. Thread::Signal
Thread::Specific module: 8.214. Thread::Specific
threads: 3.5. Threads
-tickinterval option (Scale): 21.13. The Scale Widget
tidy_body( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
tie( ): 5. Function Reference
Tie modules: 8.215. Tie::Array, Tie::StdArray
Tie::Array module: 8.215. Tie::Array, Tie::StdArray
Tie::Handle module: 8.217. Tie::Handle
Tie::Hash module: 8.218. Tie::Hash
Tie::RefHash module: 8.220. Tie::RefHash
Tie::Scalar module: 8.221. Tie::Scalar
Tie::StdArray module: 8.215. Tie::Array, Tie::StdArray
Tie::SubstrHash module: 8.222. Tie::SubstrHash
tied( ): 5. Function Reference
tilde (~)
bitwise negation operator: 4.5.2. Unary Operators
suppressing output whitespace: 4.12. Formats
~~ to print strings in fields: 4.12. Formats
time( ): 5. Function Reference
Time modules: 8.223. Time::gmtime
Time::gmtime module: 8.223. Time::gmtime
Time::HiRes module: 8.224. Time::HiRes
Time::Local module: 8.225. Time::Local
Time::localtime module: 8.226. Time::localtime
Time::tm module: 8.227. Time::tm
TimeConvert( ) (Win32::Internet): 22.7.1. General Internet Methods
time2iso( ) (HTTP::Date): 20.3.5. HTTP::Date
time2isoz( ) (HTTP::Date): 20.3.5. HTTP::Date
timeout( )
IO::Socket module: 15.2.3. IO::Socket Methods
LWP::UserAgent module: 20.2.3. LWP::UserAgent
Timeout option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference
times( ): 5. Function Reference
time2str( ) (HTTP::Date): 20.3.5. HTTP::Date
title( ) (Frame widget): 21.18.1. Toplevel Methods
Title( ) (Win32::Console): 22.2. Win32::Console
Tk extension to Perl: 21. Perl/Tk
callbacks: 21.1.3. Callbacks
colors and fonts: 21.1.4. Colors and Fonts
geometry managers: 21.2. Geometry Managers
scrollbars: 21.1.2. Scrollbars
widgets: 21.1. Widgets
Button widget: 21.4. The Button Widget
Canvas widget: 21.12. The Canvas Widget
Checkbutton widget: 21.5. The Checkbutton Widget
common configuration options: 21.3. Common Widget Configuration Options
Entry widget: 21.8. The Entry Widget
Frame widget: 21.17. The Frame Widget
Label widget: 21.7. The Label Widget
Listbox widget: 21.10. The Listbox Widget
Menu widget: 21.15. The Menu Widget
Menubutton widget: 21.14. The Menubutton Widget
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
Text widget: 21.11. The Text Widget
toplevel widget: 21.18. The Toplevel Widget
widgets methods: 21.1.1. Widget Methods
to( )
Mail::Send module: 16.2.2. Better Header Control with Mail::Send
Net::SMTP module: 16.1.2.1. Net::SMTP methods
-to option (Scale): 21.13. The Scale Widget
toggle( ) (Checkbutton): 21.5.1. Checkbutton Methods
top( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3
-top option, form geometry manager: 21.2.4. The form Geometry Manager
toplevel widget (Perl/Tk): 21.18. The Toplevel Widget
-topspring option, form geometry manager: 21.2.4. The form Geometry Manager
-tp option, form geometry manager: 21.2.4. The form Geometry Manager
tr// pattern match operator: 4.6.1. Pattern-Matching Operators
trace( ) (DBI): 12.3. DBI Methods
Transact( ) (Win32::ODBC): 24.1. ODBC Methods and Properties
24.1. ODBC Methods and Properties
transient( ) (Frame widget): 21.18.1. Toplevel Methods
transport protocols: 15. Sockets
transport( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods
traverse( ) (HTML::Parser): 20.4.3. HTML::Element
Tree style (XML::Parser): 13.4. XML::Parser Styles
-troughcolor option
Scale widget: 21.13. The Scale Widget
Scrollbar widget: 21.9. The Scrollbar Widget
truncate( ): 5. Function Reference
-ts option, form geometry manager: 21.2.4. The form Geometry Manager
TTY option (PERLDB_OPTS): 6.4. Customizing the Debugger
type( )
Canvas widget: 21.12.3. Canvas Methods
Menu widget: 21.15.2. Menu Methods
Net::FTP module: 18.2. Net::FTP
Type option
IO::Socket::INET module: 15.2.4. IO::Socket::INET Reference
IO::Socket::UNIX module: 15.2.5. IO::Socket::UNIX Reference
Type( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods
typeglob prototype symbol (*): 4.7.5. Prototypes
typelookup( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

U (uppercase) characters: 4.6.4. Character Classes
u command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module
-u file test operator: 4.5.8. File Test Operators
-u option (dprofpp): 6.5. The Perl Profiler
uc( ): 5. Function Reference
ucfirst( ): 5. Function Reference
$UID ($<) variable: 4.4.1. Global Special Variables
uidl( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3
umask( ): 5. Function Reference
unary operators: 4.5.2. Unary Operators
unbind method (Net::LDAP): 19.4. Net::LDAP Methods
uncompress command: 2.3.1. Installing on Unix
uncompressing Perl source code: 2.3.2.2. Standard Perl distribution
undef( ): 5. Function Reference
undef value: 4.2.5. Variables
undelete_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
-underline option (widgets): 21.3. Common Widget Configuration Options
underscore (_)
filehandle: 4.4.3. Global Special Filehandles
improving number legibility: 4.2.1. Numbers
unescape_from( ) (Mail::Internet): 16.2.5. Mail::Internet Reference
unicode: 4.11. Unicode
unique_name( ) (Net::FTP): 18.2. Net::FTP
UNIVERSAL module: 8.228. UNIVERSAL
Unix-domain sockets: 15. Sockets
Unix systems
#! (shebang) line: 3. The Perl Executable
command processing: 3.1. Command Processing
installing Perl on: 2.3.1. Installing on Unix
unless modifier: 4.3.1.4. Modifiers
unless statement: 4.3.1. Conditionals and Loops
unlink( ): 5. Function Reference
unmark( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
unmarked_articles( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
unmark_list( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
unmark_range( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
unpack( ): 5. Function Reference
unpacking Perl source code: 2.3.2.2. Standard Perl distribution
unpack_sockaddr_in( ) (Socket): 15.1.4. Socket Module Functions
unpack_sockaddr_un( ) (Socket): 15.1.4. Socket Module Functions
Unparsed handler (Expat): 13.3. Expat Handlers
unpost( ) (Menu widget): 21.15.2. Menu Methods
unshift( ): 5. Function Reference
unsub_groups( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
unsubscribe( ) (News::Newsrc): 17.3.1. News::Newsrc Reference
untie( ): 5. Function Reference
until modifier: 4.3.1.4. Modifiers
until statement: 4.3.1.1. while loops
update_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder
URI modules: 20.5. The URI Module
URI::Escape: 20.5. The URI Module
URI::Heuristic: 20.5. The URI Module
URI::URL: 20.5.3. URI::URL
URI::URL module: 20.1. LWP Overview
uri( ) (SOAP::Lite): 14.2. SOAP::Lite
URIs (Universal Resource Identifiers): 20.1. LWP Overview
url( )
CGI.pm module: 10.7. CGI.pm Reference
HTTP::Daemon module: 20.3.7. HTTP::Daemon
HTTP::Request module: 20.3.1. HTTP::Request
urllist parameter, CPAN configuration table: 8.46.4. CD-ROM Support
URLs (uniform resource locators): 22.7.1. General Internet Methods
encoding: 9.2. URL Encoding
extra path information: 9.3. Extra Path Information
URI::URL module: 20.1. LWP Overview
20.5.3. URI::URL
use directives: 7. Packages,Modules, and Objects
7.2. Modules
use_alarm( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent
use_named_parameters( ) (CGI.pm): 10.7. CGI.pm Reference
Usenet news: 17. Usenet News
Net::News module: 17.2. Net::NNTP
News::Newsrc module: 17.3. The News::Newsrc Module
Usenet newsgroups, Perl-related: 1.4.1. The comp.lang.perl.* Newsgroups
use( ): 5. Function Reference
USER command (POP3): 16.1.3. Retrieving Email with Net::POP3
User::grent module: 8.229. User::grent
User::pwent module: 8.230. User::pwent
user_agent( ) (CGI.pm): 10.7. CGI.pm Reference
UserAgent object: 20.1. LWP Overview
20.2. The LWP Modules
20.2.3. LWP::UserAgent
UserAgent( ) (Win32::Internet): 22.7.1. General Internet Methods
UserCreate( ) (Win32::NetAdmin): 22.10. Win32::NetAdmin
user_name( ) (CGI.pm): 10.7. CGI.pm Reference
Username( ) (Win32::Internet): 22.7.1. General Internet Methods
users, fetching information on: 5.1. Perl Functions by Category
use_sleep( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections
utf8 module: 8.231. utf8
utime( ): 5. Function Reference

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

v command (Perl debugger): 6.2. Debugger Commands
-V option, dprofpp: 6.5. The Perl Profiler
valof( ) (Win32::OLE): 23.2.2. Win32::OLE Functions
-value option
Menubutton widget: 21.14.1. Menu Item Options
Radiobutton widget: 21.6. The Radiobutton Widget
Value( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods
values( ): 5. Function Reference
Values( ) (Data::Dumper)): 8.50. Data::Dumper
-variable option
Checkbutton widget: 21.5. The Checkbutton Widget
Menubutton widget: 21.14.1. Menu Item Options
Optionmenu widget: 21.16. The Optionmenu Widget
Radiobutton widget: 21.6. The Radiobutton Widget
Scale widget: 21.13. The Scale Widget
variables: 4.2.5. Variables
declaration and scope: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables
scoping functions: 5.1. Perl Functions by Category
local vs. private: 4.2.7. Declarations and Scope
4.7.4. Private and Local Variables
pattern match variables: 4.6.7. Pattern Match Variables
scalar and list context: 4.2.6. Scalar and List Contexts
special (predefined): 4.4. Special Variables
Variant data structure: 23.4. Win32::OLE::Variant
vars module: 8.232. vars
vec( ): 5. Function Reference
verbatim paragraphs (pod): 4.13. Pod
-verbose option (perlcc): 3.4. The Perl Compiler
verify( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods
version method (Net::LDAP): 19.4. Net::LDAP Methods
Version( ) (Win32::Internet): 22.7.1. General Internet Methods
versions of Perl
obtaining current: 2.1. The CPAN Architecture
for Win32 systems: 2.3.2. Installing on Win32
versions of Perl modules: 2.4.1. Locating Modules
vertical bar (|)
format fieldholders: 4.12. Formats
OR bitwise operator: 4.5.10. Bitwise Operators
Perl debugger command: 6.2. Debugger Commands
regular expression metacharacter: 4.6.2. Regular Expression Syntax
|= (assignment) operator: 4.5.6. Assignment Operators
|| Perl debugger command: 6.2. Debugger Commands
||= (assignment) operator: 4.5.6. Assignment Operators
virtual web documents: 9.1.2. Creating Virtual Documents
-visual option
Frame widget: 21.17. The Frame Widget
toplevel widget: 21.18. The Toplevel Widget
vmsish module: 8.233. vmsish

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

w (word) character class: 4.6.4. Character Classes
w command (Perl debugger): 6.2. Debugger Commands
-w file test operator: 4.5.8. File Test Operators
wait( ): 5. Function Reference
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify
Win32::Mutex module: 22.9. Win32::Mutex
Win32::Semaphore module: 22.16. Win32::Semaphore
Wait( ) (Win32::Process): 22.14.1. Win32::Process Methods
waitpid( ): 5. Function Reference
Wall, Larry: 1.2. Perl Development
13.1. XML Parsing and Validation
wantarray( ): 5. Function Reference
warn( ): 4.9. Filehandles
5. Function Reference
HTML::Parser module: 20.4.4. HTML::TreeBuilder
$WARNING ($^W) variable: 4.4.1. Global Special Variables
web access, LWP library for: 20. The LWP Library
web client, creating: 20.2.2. LWP::Simple
web documents, virtual: 9.1.2. Creating Virtual Documents
web server programming: 11. Web Server Programmingwith mod_perl
while loops: 4.3.1.1. while loops
while modifier: 4.3.1.4. Modifiers
whitespace
encoding into URLs: 9.2. URL Encoding
in Perl programs: 4.1. Program Structure
s (whitespace) character class: 4.6.4. Character Classes
suppressing in formatted output: 4.12. Formats
widgets (Perl/Tk): 21.1. Widgets
callbacks: 21.1.3. Callbacks
colors and fonts: 21.1.4. Colors and Fonts
common configuration options: 21.3. Common Widget Configuration Options
geometry managers for: 21.2. Geometry Managers
scrollbars: 21.1.2. Scrollbars
widget methods: 21.1.1. Widget Methods
-width option: 21.3. Common Widget Configuration Options
place geometry manager: 21.2.3. The place Geometry Manager
wildcards for regular expressions: 4.6.2. Regular Expression Syntax
anchors: 4.6.5. Anchors
character classes: 4.6.4. Character Classes
escaped sequences: 4.6.3. Escaped Sequences
quantifiers: 4.6.6. Quantifiers
Win32 modules: 22. Win32 Modules and Extensions
Win32:AbortSystemShutdown( ): 22.19. Win32 Extensions
Win32:BuildNumber( ): 22.19. Win32 Extensions
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify
Win32::Clipboard module: 22.1. Win32::Clipboard
Win32::Console module: 22.2. Win32::Console
Win32::CopyFile( ): 22.19. Win32 Extensions
Win32:DomainName( ): 22.19. Win32 Extensions
Win32::Eventlog module: 22.4. Win32::Eventlog
Win32:ExpandEnvironmentStrings( ): 22.19. Win32 Extensions
Win32::File module: 22.5. Win32::File
Win32::FileSecurity module: 22.6. Win32::FileSecurity
Win32:FormatMessage( ): 22.19. Win32 Extensions
Win32:FreeLibrary( ): 22.19. Win32 Extensions
Win32:FsType( ): 22.19. Win32 Extensions
Win32:GetArchName( ): 22.19. Win32 Extensions
Win32:GetChipName( ): 22.19. Win32 Extensions
Win32:GetCwd( ): 22.19. Win32 Extensions
Win32:GetFullPathName( ): 22.19. Win32 Extensions
Win32:GetLastError( ): 22.19. Win32 Extensions
Win32:GetLongPathName( ): 22.19. Win32 Extensions
Win32:GetNextAvailDrive( ): 22.19. Win32 Extensions
Win32:GetOSVersion( ): 22.19. Win32 Extensions
Win32:GetProcAddress( ): 22.19. Win32 Extensions
Win32:GetShortPathName( ): 22.19. Win32 Extensions
Win32:GetTickCount( ): 22.19. Win32 Extensions
Win32:InitiateSystemShutdown( ): 22.19. Win32 Extensions
Win32::Internet module: 22.7. Win32::Internet
Win32::IPC module: 22.8. Win32::IPC
Win32:IsWin95( ): 22.19. Win32 Extensions
Win32:IsWinNT( ): 22.19. Win32 Extensions
Win32:LoadLibrary( ): 22.19. Win32 Extensions
Win32:LoginName( ): 22.19. Win32 Extensions
Win32:LookupAccountName( ): 22.19. Win32 Extensions
Win32:LookupAccountSID( ): 22.19. Win32 Extensions
Win32:MsgBox( ): 22.19. Win32 Extensions
Win32::Mutex module: 22.9. Win32::Mutex
Win32::NetAdmin module: 22.10. Win32::NetAdmin
Win32::NetResource module: 22.11. Win32::NetResource
Win32:NodeName( ): 22.19. Win32 Extensions
Win32::ODBC module: 24. ODBC Extension for Win32
Win32::OLE modules: 23. OLE Automation
Win32::OLE::Const module: 23.5. Win32::OLE::Const
Win32::OLE::Enum module: 23.3. Win32::OLE::Enum
Win32:OLELastError( ): 22.19. Win32 Extensions
Win32::OLE::Variant module: 23.4. Win32::OLE::Variant
Win32::PerfLib module: 22.12. Win32::PerfLib
Win32::Pipe module: 22.13. Win32::Pipe
Win32::Process module: 22.14. Win32::Process
Win32:RegisterServer( ): 22.19. Win32 Extensions
Win32::Registry module: 22.15. Win32::Registry
Win32::Semaphore module: 22.16. Win32::Semaphore
Win32::Service module: 22.17. Win32::Service
Win32:SetCwd( ): 22.19. Win32 Extensions
Win32:SetLastError( ): 22.19. Win32 Extensions
Win32::Shortcut module: 22.18. Win32::Shortcut
Win32:Sleep( ): 22.19. Win32 Extensions
Win32:Spawn( ): 22.19. Win32 Extensions
Win32:UnregisterServer( ): 22.19. Win32 Extensions
Win32 systems
command processing: 3.1. Command Processing
installing Perl on: 2.3.2. Installing on Win32
pl2bat.bat: 3. The Perl Executable
window( ) (Text widget): 21.11.2. Text Methods
Window( ) (Win32::Console): 22.2. Win32::Console
Windows 95, Perl functionality on: 2.3.2.2. Standard Perl distribution
Windows clipboard: 22.1. Win32::Clipboard
Winer, Dave: 14.1. What Is SOAP?
Win32::OLE: 23. OLE Automation
Win32::OLE::Const: 23. OLE Automation
Win32::OLE::Enum: 23. OLE Automation
Win32::OLE::Variant: 23. OLE Automation
methods: 23.4.1. Win32::OLE::Variant Methods
with( ) (Win32::OLE): 23.2.2. Win32::OLE Functions
withdraw( ) (Frame widget): 21.18.1. Toplevel Methods
WNetGetLastError( ) (Win32::NetResource): 22.11. Win32::NetResource
wordstart, wordend modifiers (Text widget): 21.11.1. Text Indexes and Modifiers
-wrap option (Text): 21.11. The Text Widget
-wraplength option (widgets): 21.3. Common Widget Configuration Options
wrapping text: 8.209. Text::Wrap
write( ): 4.12. Formats
5. Function Reference
Write( ) (Win32::Console module): 22.2. Win32::Console
WriteAttr( ) (Win32::Console): 22.2. Win32::Console
WriteChar( ) (Win32::Console): 22.2. Win32::Console
WriteInput( ) (Win32::Console): 22.2. Win32::Console
WriteRect( ) (Win32::Console): 22.2. Win32::Console
www.perl.com and www.perl.org sites: 1.4.5. www.perl.com

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x command (Perl debugger): 6.2. Debugger Commands
x= (assignment) operator: 4.5.6. Assignment Operators
-X file test operator: 4.5.8. File Test Operators
x (grid geometry manager placeholder): 21.2.2. The grid Geometry Manager
X-headers (news articles): 17.1. The NNTP Protocol
-x option (place geometry manager): 21.2.3. The place Geometry Manager
x pattern match modifier: 4.6.1. Pattern-Matching Operators
4.6.8. Extended Regular Expressions
x (string repetition) operator: 4.5.11.4. String operator
x{263a} (wide hexadecimal value) sequence: 4.6.3. Escaped Sequences
(hexadecimal value) sequence: 4.6.3. Escaped Sequences
xgtitle( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
xhdr command (NNTP): 17.1. The NNTP Protocol
xhdr( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
XML (Extensible Markup Language): 13. XML and Perl
SOAP, and: 14.1. What Is SOAP?
XMLDecl handler (Expat): 13.3. Expat Handlers
XMLin( ): 13.1. XML Parsing and Validation
XML::Parser: 13.1. XML Parsing and Validation
methods: 13.2. XML::Parser Methods
styles: 13.4. XML::Parser Styles
XML::Parser::ContentModel methods: 13.6. XML::Parser::ContentModel Methods
XML::Simple: 13.1. XML Parsing and Validation
XOR (^) operator, bitwise: 4.5.10. Bitwise Operators
xover( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
xpat command (NNTP): 17.1. The NNTP Protocol
xpat( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
xpath( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
Xref backend (Perl compiler): 3.4. The Perl Compiler
xrover( ) (Net::NNTP): 17.2.2. Net::NNTP Reference
XS_constant function (ExtUtils::Constant module): 8.69. ExtUtils::Constant
-xscrollcommand option: 21.3. Common Widget Configuration Options
Scrollbar widget: 21.1.2.2. The Scrollbar widget
-xscrollincrement option (Canvas): 21.12. The Canvas Widget
XS::Typemap module: 8.234. XS::Typemap
xview( )
Canvas widget: 21.12.3. Canvas Methods
Entry widget: 21.8.2. Entry Methods
Listbox widget: 21.10.2. Listbox Methods
Text widget: 21.11.2. Text Methods

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

-y option (place geometry manager): 21.2.3. The place Geometry Manager
y// pattern match operator: 4.6.1. Pattern-Matching Operators
yposition( ) (Menu widget): 21.15.2. Menu Methods
-yscrollcommand option: 21.3. Common Widget Configuration Options
Scrollbar widget: 21.1.2.2. The Scrollbar widget
-yscrollincrement option (Canvas): 21.12. The Canvas Widget
yview( )
Canvas widget: 21.12.3. Canvas Methods
Listbox widget: 21.10.2. Listbox Methods
Text widget: 21.11.2. Text Methods

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

.Z extension: 2.3.1. Installing on Unix
-z file test operator: 4.5.8. File Test Operators
-z option (dprofpp): 6.5. The Perl Profiler

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal on the cover of Perl in a Nutshell, Second Edition, is a camel (one-hump dromedary). Camels are large ruminant mammals, weighing between 1,000 and 1,600 pounds and standing 6 to 7 feet tall at the shoulders. They are well known for their use as draft and saddle animals in the desert regions, especially of Africa and Asia. Camels can go for days without water. If food is scarce, they will eat anything, even their owner's tent. Camels live up to 50 years.

Matt Hutchinson was the production editor and copyeditor for Perl in a Nutshell, Second Edition . Darren Kelly and Jeffrey Holcomb provided quality control. Seth Maislin and John Bickelhaupt wrote the index.

Edie Freedman designed the cover of this book. The cover image is a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

Melanie Wang designed the interior layout based on a series design by David Futato. Mike Sierra converted the files from XML to FrameMaker 5.5.6 using tools he created, as well as tools written in Perl by Erik Ray, Jason McIntosh, and Neil Walls. The text font is Linotype Birka; the heading font is Adobe Myriad Condensed; and the code font is LucasFont's TheSans Mono Condensed. The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand 9 and Adobe Photoshop 6. The tip and warning icons were drawn by Christopher Bing. This colophon was written by Michael Kalantarian.

Previous | Home
Index |
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Table of Contents

Copyright Page
Foreword
Preface
Chapter 1: Strings
Chapter 2: Numbers
Chapter 3: Dates and Times
Chapter 4: Arrays
Chapter 5: Hashes
Chapter 6: Pattern Matching
Chapter 7: File Access
Chapter 8: File Contents
Chapter 9: Directories
Chapter 10: Subroutines
Chapter 11: References and Records
Chapter 12: Packages, Libraries, and Modules
Chapter 13: Classes, Objects, and Ties
Chapter 14: Database Access
Chapter 15: Interactivity
Chapter 16: Process Management and Communication
Chapter 17: Sockets
Chapter 18: Internet Services
Chapter 19: CGI Programming
Chapter 20: Web Automation
Chapter 21: mod_perl
Chapter 22: XML
Index
Colophon
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


(Perl Cookbook, 2nd Edition)

 Perl Cookbook
Previous Next

Copyright © 2003, 1998 O'Reilly & Associates, Inc.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com). For more information, contact our corporate/institutional sales department: (800) 998-9938 or corporate@oreilly.com.

Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The association between the image of a bighorn sheep and the topic of Perl is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | Foreword
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Preface (Perl Cookbook, 2nd Edition)

 Perl Cookbook
Previous Next

Foreword

They say that it's easy to get trapped by a metaphor. But some metaphors are so magnificent that you don't mind getting trapped in them. Perhaps the cooking metaphor is one such, at least in this case. The only problem I have with it is a personal one—I feel a bit like Betty Crocker's mother. The work in question is so monumental that anything I could say here would be either redundant or irrelevant.

However, that never stopped me before.

Cooking is perhaps the humblest of the arts; but to me humility is a strength, not a weakness. Great artists have always had to serve their artistic medium—great cooks just do so literally. And the more humble the medium, the more humble the artist must be in order to lift the medium beyond the mundane. Food and language are both humble media, consisting as they do of an overwhelming profusion of seemingly unrelated and unruly ingredients. And yet, in the hands of someone with a bit of creativity and discipline, things like potatoes, pasta, and Perl are the basis of works of art that "hit the spot" in a most satisfying way, not merely getting the job done, but doing so in a way that makes your journey through life a little more pleasant.

Cooking is also one of the oldest of the arts. Some modern artists would have you believe that so-called ephemeral art is a recent invention, but cooking has always been an ephemeral art. We can try to preserve our art, make it last a little longer, but even the food we bury with our pharoahs gets dug up eventually. So too, much of our Perl programming is ephemeral. This aspect of Perl cuisine has been much maligned. You can call it quick-and-dirty if you like, but there are billions of dollars out there riding on the supposition that fast food is not necessarily dirty food. (We hope.)

Easy things should be easy, and hard things should be possible. For every fast-food recipe, there are countless slow-food recipes. One of the advantages of living in California is that I have ready access to almost every national cuisine ever invented. But even within a given culture, There's More Than One Way To Do It. It's said in Russia that there are more recipes for borscht than there are cooks, and I believe it. My mom's recipe doesn't even have any beets in it! But that's okay, and it's more than okay. Borscht is a cultural differentiator, and different cultures are interesting, and educational, and useful, and exciting.

So you won't always find Tom and Nat doing things in this book the way I would do them. Sometimes they don't even do things the same way as each other. That's okay—again, this is a strength, not a weakness. I have to confess that I learned quite a few things I didn't know before I read this book. What's more, I'm quite confident that I still don't know it all. And I hope I don't any time soon. I often talk about Perl culture as if it were a single, static entity, but there are in fact many healthy Perl subcultures, not to mention sub-subcultures and supercultures and circumcultures in every conceivable combination, all inheriting attributes and methods from each other. It can get confusing. Hey, I'm confused most of the time.

So the essence of a cookbook like this is not to cook for you (it can't), or even to teach you how to cook (though it helps), but rather to pass on various bits of culture that have been found useful, and perhaps to filter out other bits of "culture" that grew in the refrigerator when no one was looking. You in turn will pass on some of these ideas to other people, filtering them through your own experiences and tastes, your creativity and discipline. You'll come up with your own recipes to pass to your children. Just don't be surprised when they in turn cook up some recipes of their own, and ask you what you think. Try not to make a face.

I commend to you these recipes, over which I've made very few faces.

—Larry Wall, June, 1998

Previous | Home | Next
Copyright Page | Book Index | Preface
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Preface

The investment group eyed the entrepreneur with caution, their expressions flickering from scepticism to intrigue and back again.

"Your bold plan holds promise," their spokesman conceded. "But it is costly and entirely speculative. Our mathematicians mistrust your figures. Why should we entrust our money into your hands? What do you know that we do not?"

"For one thing," he replied, "I know how to balance an egg on its point without outside support. Do you?" And with that, the entrepreneur reached into his satchel and delicately withdrew a fresh hen's egg. He handed over the egg to the financial tycoons, who passed it amongst themselves trying to carry out the simple task. At last they gave up. In exasperation they declared, "What you ask is impossible! No man can balance an egg on its point."

So the entrepreneur took back the egg from the annoyed businessmen and placed it upon the fine oak table, holding it so that its point faced down. Lightly but firmly, he pushed down on the egg with just enough force to crush in its bottom about half an inch. When he took his hand away, the egg stood there on its own, somewhat messy, but definitely balanced. "Was that impossible?" he asked.

"It's just a trick," cried the businessmen. "Once you know how, anyone can do it."

"True enough," came the retort. "But the same can be said for anything. Before you know how, it seems an impossibility. Once the way is revealed, it's so simple that you wonder why you never thought of it that way before. Let me show you that easy way, so others may easily follow. Will you trust me?"

Eventually convinced that this entrepreneur might possibly have something to show them, the skeptical venture capitalists funded his project. From the tiny Andalusian port of Palos de Moguer set forth the Niña, the Pinta, and the Santa María, led by an entrepreneur with a slightly broken egg and his own ideas: Christopher Columbus.

Many have since followed.

Approaching a programming problem can be like balancing Columbus's egg. If no one shows you how, you may sit forever perplexed, watching the egg—and your program—fall over again and again, no closer to the Indies than when you began. This is especially true in a language as idiomatic as Perl.

This book isn't meant to be a complete reference book for Perl. Keeping a copy of Programming Perl handy will let you look up exact definitions of operators, keywords, functions, pragmata, or modules. Alternatively, every Perl installation comes with a voluminous collection of searchable, online reference materials. If those aren't where you can easily get at them, see your system administrator if you have one, or consult the documentation section at http://www.perl.com.

Neither is this book meant to be a bare-bones introduction for programmers who have never seen Perl before. That's what Learning Perl, a kinder and gentler introduction to Perl, is designed for. (If you're on a Microsoft system, you might prefer the Learning Perl for Win32 Systems version.)

Instead, this is a book for learning more Perl. Neither a reference book nor a tutorial book, Perl Cookbook serves as a companion book to both. It's for people who already know the basics but are wondering how to mix all those ingredients together into a complete program. Spread across 22 chapters and more than 400 focused topic areas affectionately called recipes, this task-oriented book contains thousands of solutions to everyday challenges encountered by novice and journeyman alike.

We tried hard to make this book useful for both random and sequential access. Each recipe is self-contained, but has a list of references at the end should you need further information on the topic. We've tried to put the simpler, more common recipes toward the front of each chapter and the simpler chapters toward the front of the book. Perl novices should find that these recipes about Perl's basic data types and operators are just what they're looking for. We gradually work our way through topic areas and solutions more geared toward the journeyman Perl programmer. Now and then we include material that should inspire even the master Perl programmer.

Each chapter begins with an overview of that chapter's topic. This introduction is followed by the main body of each chapter, its recipes. In the spirit of the Perl slogan of TMTOWTDI, There's more than one way to do it, most recipes show several different techniques for solving the same or closely related problems. These recipes range from short-but-sweet solutions to in-depth mini-tutorials. Where more than one technique is given, we often show costs and benefits of each approach.

As with a traditional cookbook, we expect you to access this book more or less at random. When you want to learn how to do something, you'll look up its recipe. Even if the exact solutions presented don't fit your problem exactly, they'll give you ideas about possible approaches.

Each chapter concludes with one or more complete programs. Although some recipes already include small programs, these longer applications highlight the chapter's principal focus and combine techniques from other chapters, just as any real-world program would. All are useful, and many are used on a daily basis. Some even helped us put this book together.

0.1. What's in This Book

Spread over five chapters, the first portion of the book addresses Perl's basic data types. Chapter 1, covers matters like accessing substrings, expanding function calls in strings, and parsing comma-separated data; it also covers Unicode strings. Chapter 2, tackles oddities of floating-point representation, placing commas in numbers, and pseudo-random numbers. Chapter 3, demonstrates conversions between numeric and string date formats and using timers. Chapter 4, covers everything relating to list and array manipulation, including finding unique elements in a list, efficiently sorting lists, and randomizing them. Chapter 5, concludes the basics with a demonstration of the most useful data type, the associative array. The chapter shows how to access a hash in insertion order, how to sort a hash by value, how to have multiple values per key, and how to have an immutable hash.

Chapter 6, includes recipes for converting a shell wildcard into a pattern, matching letters or words, matching multiple lines, avoiding greediness, matching nested or recursive patterns, and matching strings that are close to but not exactly what you're looking for. Although this chapter is one of the longest in the book, it could easily have been longer still—every chapter contains uses of regular expressions. It's part of what makes Perl Perl.

The next three chapters cover the filesystem. Chapter 7, shows opening files, locking them for concurrent access, modifying them in place, and storing filehandles in variables. Chapter 8, discusses storing filehandles in variables, managing temporary files, watching the end of a growing file, reading a particular line from a file, handling alternative character encodings like Unicode and Microsoft character sets, and random access binary I/O. Finally, in Chapter 9, we show techniques to copy, move, or delete a file, manipulate a file's timestamps, and recursively process all files in a directory.

Chapter 10 through Chapter 13 focus on making your program flexible and powerful. Chapter 10, includes recipes on creating persistent local variables, passing parameters by reference, calling functions indirectly, crafting a switch statement, and handling exceptions. Chapter 11, is about data structures; basic manipulation of references to data and functions are demonstrated. Later recipes show how to create elaborate data structures and how to save and restore these structures from permanent storage. Chapter 12, concerns breaking up your program into separate files; we discuss how to make variables and functions private to a module, customize warnings for modules, replace built-ins, trap errors loading missing modules, and use the h2ph and h2xs tools to interact with C and C++ code. Lastly, Chapter 13, covers the fundamentals of building your own object-based module to create user-defined types, complete with constructors, destructors, and inheritance. Other recipes show examples of circular data structures, operator overloading, and tied data types.

The next two chapters are about interfaces: one to databases, the other to users. Chapter 14, includes techniques for manipulating DBM files and querying and updating databases with SQL and the DBI module. Chapter 15, covers topics such as clearing the screen, processing command-line switches, single-character input, moving the cursor using termcap and curses, thumbnailing images, and graphing data.

The last portion of the book is devoted to interacting with other programs and services. Chapter 16, is about running other programs and collecting their output, handling zombie processes, named pipes, signal management, and sharing variables between running programs. Chapter 17, shows how to establish stream connections or use datagrams to create low-level networking applications for client-server programming. Chapter 18, is about higher-level protocols such as mail, FTP, Usenet news, XML-RPC, and SOAP. Chapter 19, contains recipes for processing web forms, trapping their errors, avoiding shell escapes for security, managing cookies, shopping cart techniques, and saving forms to files or pipes. Chapter 20, covers non-interactive uses of the Web, such as fetching web pages, automating form submissions in a script, extracting URLs from a web page, removing HTML tags, finding fresh or stale links, and parsing HTML. Chapter 21, introduces mod_perl, the Perl interpreter embedded in Apache. It covers fetching form parameters, issuing redirections, customizing Apache's logging, handling authentication, and advanced templating with Mason and the Template Toolkit. Finally, Chapter 22 is about the ubiquitous data format XML and includes recipes such as validating XML, parsing XML into events and trees, and transforming XML into other formats.

Previous | Home | Next
Foreword | Book Index | 0.2. What's New in This Edition
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.2. What's New in This Edition

The book you're holding is thicker than its previous edition of five years ago—about 200 pages thicker. New material is spread across more than 80 entirely new recipes plus over 100 existing recipes that were substantially updated since the first edition. You'll also find two new chapters: one on mod_perl, Perl's interface to the popular Apache web server; the other on XML, an increasingly important standard for exchanging structured data.

Growth in this book reflects growth in Perl itself, from Version 5.004 in the first edition to v5.8.1 in this one. Syntactic changes to the core language are nevertheless comparatively few. Some include the spiffy our keyword to replace the crufty use vars construct for declaring global variables, fancier forms of open to disambiguate filenames with strange characters in them, and automatic allocation of anonymous filehandles into undefined scalar variables. We've updated our solutions and code examples to reflect these changes where it made sense to make use of the new features.

Several of Perl's major subsystems have been completely overhauled for improved functionality, stability, and portability. Some of these are relatively isolated, like the subsystems for threading (see Recipe 17.14) and for safe signals (see Recipe 16.17). Their applications are usually confined to systems programming.

More sweeping are the changes to Perl and to this book that stem from integrated support for Unicode characters. The areas most profoundly affected are strings (now with multibyte characters) and I/O (now with stackable encoding layers), so Chapter 1 and Chapter 8 include new introductory material to orient you to these sometimes confusing topics. These chapters also provide the bulk of recipes dealing with those specific topics, but this fundamental shift touches many more recipes throughout the book.

Another growth area for this book and Perl has been the welcome proliferation of many highly used and highly useful modules now released standard with the Perl core. Previously, these modules had to be separately located, downloaded, configured, built, tested, and installed. Now that they're included in the standard distribution, that's all taken care of when installing Perl itself.

Some new core modules are really pragmas that alter Perl's compilation or runtime environment, as demonstrated in Recipe 1.21, Recipe 12.3, and Recipe 12.15. Some are programmer tools to aid code development and debugging, like modules shown in Recipe 11.11, Recipe 11.13, Recipe 11.15, and Recipe 22.2. Others augment basic operations available on core data types, like those shown in Recipe 2.1, Recipe 4.13, Recipe 4.18, Recipe 5.3, Recipe 8.7, and Recipe 11.15. Finally, the networking modules have at last made their way into the core distribution, as seen throughout Chapter 18. We've probably not seen the last of this inward migration of modules.

Previous | Home | Next
Preface | Book Index | 0.3. Platform Notes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.3. Platform Notes

This book was developed using Perl release v5.8.1. That means major release 5, minor release 8, and patch level 1. We tested most programs and examples under BSD, Linux, and SunOS, but that doesn't mean they'll work only on those systems. Perl was designed for platform independence. When you use Perl as a general-purpose programming language, employing basic operations like variables, patterns, subroutines, and high-level I/O, your program should work the same everywhere that Perl runs—which is just about everywhere. The first two-thirds of this book uses Perl for general-purpose programming.

Perl was originally conceived as a high-level, cross-platform language for systems programming. Although it has long since expanded beyond its original domain, Perl continues to be heavily used for systems programming, both on its native Unix systems and elsewhere. Most recipes in Chapter 14 through Chapter 18 deal with classic systems programming. For maximum portability in this area, we've mainly focused on open systems as defined by the Portable Operating System Interface (POSIX), which includes nearly every form of Unix and numerous other systems as well. Most recipes should run with little or no modification on any POSIX system.

You can still use Perl for systems programming work even on non-POSIX systems by using vendor-specific modules, but these are not covered in this book. That's because they're not portable—and to be perfectly forward, because we have no such systems at our disposal. Consult the documentation that came with your port of Perl for any proprietary modules that may have been included. The perlport(1) manpage is a good start; its SEE ALSO section points to per-platform documentation, such as perlmacos(1) and perlvms(1).

But don't worry. Many recipes for systems programming should work on non-POSIX systems as well, especially those dealing with databases, networking, and web interaction. That's because the modules used for those areas hide platform dependencies. The principal exception is those few recipes and programs that rely upon multitasking constructs, notably the powerful fork function, standard on POSIX systems, but seldom on others. Mac OS X now supports fork natively, however, and even on Windows systems Perl now emulates that syscall remarkably well.

When we needed structured files, we picked the convenient Unix /etc/passwd database; when we needed a text file to read, we picked /etc/motd; and when we needed a program to produce output, we picked who(1). These were merely chosen to illustrate the principles—the principles work whether or not your system has these files and programs.

Previous | Home | Next
0.2. What's New in This Edition | Book Index | 0.4. Other Books
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.4. Other Books

If you'd like to learn more about Perl, here are some related publications that we (somewhat sheepishly) recommend:

Programming Perl, by Larry Wall, Tom Christiansen, and Jon Orwant; O'Reilly & Associates (Third Edition, 2000). This book is indispensable for every Perl programmer. Coauthored by Perl's creator, this classic reference is the authoritative guide to Perl's syntax, functions, modules, references, invocation options, and much more.

Mastering Algorithms with Perl, by Jon Orwant, Jarkko Hietaniemi, and John Macdonald; O'Reilly & Associates (2000). All the useful techniques from a CS algorithms course, but without the painful proofs. This book covers fundamental and useful algorithms in the fields of graphs, text, sets, and more.

Mastering Regular Expressions, by Jeffrey Friedl; O'Reilly & Associates (Second Edition, 2002). This book is dedicated to explaining regular expressions from a practical perspective. It not only covers general regular expressions and Perl patterns well, it also compares and contrasts these with those used in other popular languages.

Object Oriented Perl, by Damian Conway; Manning (1999). For beginning as well as advanced OO programmers, this book explains common and esoteric techniques for writing powerful object systems in Perl.

Learning Perl, by Randal Schwartz and Tom Phoenix; O'Reilly & Associates (Third Edition, 2001). A tutorial introduction to Perl for folks who are already programmers and who are interested in learning Perl from scratch. It's a good starting point if this book is over your head. Erik Olson refurbished this book for Windows systems, called Learning Perl for Win32 Systems.

Programming the Perl DBI, by Tim Bunce and Alligator Descartes; O'Reilly & Associates (2000). The only book on Perl's relational database interface, by the author of the DBI module.

CGI Programming with Perl, by Scott Guelich, Shishir Gundavaram, and Gunther Birznieks; O'Reilly & Associates (Second Edition, 2000). This is a solid introduction to the world of CGI programming.

Writing Apache Modules with Perl and C, by Lincoln Stein and Doug MacEachern; O'Reilly & Associates (1999). This guide to web programming teaches you how to extend the capabilities of the Apache web server, especially using the turbo-charged mod_perl for fast CGI scripts and via the Perl-accessible Apache API.

Practical mod_perl, by Stas Bekman and Eric Cholet; O'Reilly & Associates (2003). A comprehensive guide to installing, configuring, and developing with mod_perl. This book goes into corners of mod_perl programming that no other book dares to touch.

The mod_perl Developer's Cookbook, by Geoff Young, Paul Lindner, and Randy Kobes; SAMS (2002). Written in a similar style to the Cookbook you hold in your hand, this book belongs on every mod_perl developer's desk. It covers almost every task a mod_perl developer might want to perform.

Beyond the Perl-related publications listed here, the following books came in handy when writing this book. They were used for reference, consultation, and inspiration.

The Art of Computer Programming, by Donald Knuth, Volumes I-III: "Fundamental Algorithms," "Seminumerical Algorithms," and "Sorting and Searching"; Addison-Wesley (Third Edition, 1998).

Introduction to Algorithms, by Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest; MIT Press and McGraw-Hill (1990).

Algorithms in C, by Robert Sedgewick; Addison-Wesley (1992).

The Art of Mathematics, by Jerry P. King; Plenum (1992).

The Elements of Programming Style, by Brian W. Kernighan and P.J. Plauger; McGraw-Hill (1988).

The UNIX Programming Environment, by Brian W. Kernighan and Rob Pike; Prentice-Hall (1984).

POSIX Programmer's Guide, by Donald Lewine; O'Reilly & Associates (1991).

Advanced Programming in the UNIX Environment, by W. Richard Stevens; Addison-Wesley (1992).

TCP/IP Illustrated, by W. Richard Stevens, et al., Volumes I-III; Addison-Wesley (1992-1996).

HTML: The Definitive Guide, by Chuck Musciano and Bill Kennedy; O'Reilly & Associates (Third Edition, 1998).

Official Guide to Programming with CGI.pm, by Lincoln Stein; John Wiley & Sons (1997).

Web Client Programming with Perl, by Clinton Wong; O'Reilly & Associates (1997).

The New Fowler's Modern English Usage, edited by R.W. Burchfield; Oxford (Third Edition, 1996).

Previous | Home | Next
0.3. Platform Notes | Book Index | 0.5. Conventions Used in This Book
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.5. Conventions Used in This Book

0.5.1. Programming Conventions

We give lots of examples, most of which are pieces of code that should go into a larger program. Some examples are complete programs, which you can recognize because they begin with a #! line. We start nearly all of our longer programs with:

#!/usr/bin/perl -w
use strict;

or else the newer:

#!/usr/bin/perl
use strict;
use warnings;

Still other examples are things to be typed on a command line. We've used % to show the shell prompt:

% perl -e 'print "Hello, world.\n"'
Hello, world.

This style represents a standard Unix command line, where single quotes represent the "most quoted" form. Quoting and wildcard conventions on other systems vary. For example, many command-line interpreters under MS-DOS and VMS require double quotes instead of single ones to group arguments with spaces or wildcards in them.

0.5.2. Typesetting Conventions

The following typographic conventions are used in this book:

Bold
is used exclusively for command-line switches. This allows one to distinguish for example, between the -w warnings switch and the -w filetest operator.

Italic
is used for URLs, manpages, pathnames, and programs. New terms are also italicized when they first appear in the text.

Constant Width
is used for function and method names and their arguments; in examples to show text that you enter verbatim; and in regular text to show literal code.

Constant Width Bold Italic
is used in examples to show output produced.

WARNING:
Indicates a warning or caution.

0.5.3. Documentation Conventions

The most up-to-date and complete documentation about Perl is included with Perl itself. If typeset and printed, this massive anthology would use more than a thousand pages of printed paper, greatly contributing to global deforestation. Fortunately, you don't have to print it out, because it's available in a convenient and searchable electronic form.

When we refer to a "manpage" in this book, we're talking about this set of online manuals. The name is purely a convention; you don't need a Unix-style man program to read them. The perldoc command distributed with Perl also works, and you may even have the manpages installed as HTML pages, especially on non-Unix systems. Plus, once you know where they're installed, you can grep them directly.[1] The HTML version of the manpages is available on the Web at http://www.perl.com/CPAN/doc/manual/html/.

[1]If your system doesn't have grep, use the tcgrep program supplied at the end of Chapter 6.

When we refer to non-Perl documentation, as in "See kill(2) in your system manual," this refers to the kill manpage from section 2 of the Unix Programmer's Manual (system calls). These won't be available on non-Unix systems, but that's probably okay, because you couldn't use them there anyway. If you really do need the documentation for a system call or library function, many organizations have put their manpages on the Web; a quick search of Google for crypt(3) manual will find many copies.

Previous | Home | Next
0.4. Other Books | Book Index | 0.6. We'd Like to Hear from You
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.6. We'd Like to Hear from You

We have tested and verified the information in this book to the best of our ability, but you may find that features have changed (which may in fact resemble bugs). Please let us know about any errors you find, as well as your suggestions for future editions, by writing to:

O'Reilly & Associates, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
(800) 998-9938 (in the U.S.or Canada)
(707) 829-0515 (international or local)
(707) 829-0104 (FAX)

You can also send us messages electronically. To be put on the mailing list or request a catalog, send email to:

info@oreilly.com

To ask technical questions or comment on the book, send email to:

bookquestions@oreilly.com

There is a web site for the book, where we'll list errata and plans for future editions. Here you'll also find source code for the book's examples available for download so you don't have to type them in yourself. You can access this page at:

http://www.oreilly.com/catalog/perlckbk2/

For more information about this book and others, see the O'Reilly web site:

http://www.oreilly.com/
Previous | Home | Next
0.5. Conventions Used in This Book | Book Index | 0.7. Acknowledgments for the First Edition
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.7. Acknowledgments for the First Edition

This book wouldn't exist but for a legion of people standing, knowing and unknowing, behind the authors. At the head of this legion would have to be our editor, Linda Mui, carrot on a stick in one hand and a hot poker in the other. She was great.

As the author of Perl, Larry Wall was our ultimate reality check. He made sure we weren't documenting things he was planning to change and helped out on wording and style.[2] If now and then you think you're hearing Larry's voice in this book, you probably are.

[2]And footnotes.

Larry's wife, Gloria, a literary critic by trade, shocked us by reading through every single word—and actually liking most of them. Together with Sharon Hopkins, resident Perl Poetess, she helped us rein in our admittedly nearly insatiable tendency to produce pretty prose sentences that could only be charitably described as lying somewhere between the inscrutably complex and the hopelessly arcane, eventually rendering the meandering muddle into something legible even to those whose native tongues were neither PDP-11 assembler nor Mediæval Spanish.

Our three most assiduous reviewers, Mark-Jason Dominus, Jon Orwant, and Abigail, have worked with us on this book nearly as long as we've been writing it. Their rigorous standards, fearsome intellects, and practical experience in Perl applications have been of invaluable assistance. Doug Edwards methodically stress-tested every piece of code from the first seven chapters of the book, finding subtle border cases no one else ever thought about. Other major reviewers include Andy Dougherty, Andy Oram, Brent Halsey, Bryan Buus, Gisle Aas, Graham Barr, Jeff Haemer, Jeffrey Friedl, Lincoln Stein, Mark Mielke, Martin Brech, Matthias Neeracher, Mike Stok, Nate Patwardhan, Paul Grassie, Peter Prymmer, Raphaël Manfredi, and Rod Whitby.

And this is just the beginning. Part of what makes Perl fun is the sense of community and sharing it seems to engender. Many selfless individuals lent us their technical expertise. Some read through complete chapters in formal review. Others provided insightful answers to brief technical questions when we were stuck on something outside our own domain. A few even sent us code. Here's a partial list of these helpful people: Aaron Harsh, Ali Rayl, Alligator Descartes, Andrew Hume, Andrew Strebkov, Andy Wardley, Ashton MacAndrews, Ben Gertzfield, Benjamin Holzman, Brad Hughes, Chaim Frenkel, Charles Bailey, Chris Nandor, Clinton Wong, Dan Klein, Dan Sugalski, Daniel Grisinger, Dennis Taylor, Doug MacEachern, Douglas Davenport, Drew Eckhardt, Dylan Northrup, Eric Eisenhart, Eric Watt Forste, Greg Bacon, Gurusamy Sarathy, Henry Spencer, Jason Ornstein, Jason Stewart, Joel Noble, Jonathan Cohen, Jonathan Scott Duff, Josh Purinton, Julian Anderson, Keith Winstein, Ken Lunde, Kirby Hughes, Larry Rosler, Les Peters, Mark Hess, Mark James, Martin Brech, Mary Koutsky, Michael Parker, Nick Ing-Simmons, Paul Marquess, Peter Collinson, Peter Osel, Phil Beauchamp, Piers Cawley, Randal Schwartz, Rich Rauenzahn, Richard Allan, Rocco Caputo, Roderick Schertler, Roland Walker, Ronan Waide, Stephen Lidie, Steven Owens, Sullivan Beck, Tim Bunce, Todd Miller, Troy Denkinger, and Willy Grimm.

And let's not forget Perl itself, without which this book could never have been written. Appropriately enough, we used Perl to build endless small tools to help produce this book. Perl tools converted our text in pod format into troff for displaying and review and into FrameMaker for production. Another Perl program ran syntax checks on every piece of code in the book. The Tk extension to Perl was used to build a graphical tool to shuffle around recipes using drag-and-drop. Beyond these, we also built innumerable smaller tools for tasks like checking RCS locks, finding duplicate words, detecting certain kinds of grammatical errors, managing mail folders with feedback from reviewers, creating program indices and tables of contents, and running text searches that crossed line boundaries or were restricted to certain sections—just to name a few. Some of these tools found their way into the same book they were used on.

0.7.1. Tom

Thanks first of all to Larry and Gloria for sacrificing some of their European vacation to groom the many nits out of this manuscript, and to my other friends and family—Bryan, Sharon, Brent, Todd, and Drew—for putting up with me over the last couple of years and being subjected to incessant proofreadings.

I'd like to thank Nathan for holding up despite the stress of his weekly drives, my piquant vegetarian cooking and wit, and his getting stuck researching the topics I so diligently avoided.

I'd like to thank those largely unsung titans in our field—Dennis, Linus, Kirk, Eric, and Rich—who were all willing to take the time to answer my niggling operating system and troff questions. Their wonderful advice and anecdotes aside, without their tremendous work in the field, this book could never have been written.

Thanks also to my instructors who sacrificed themselves to travel to perilous places like New Jersey to teach Perl in my stead. I'd like to thank Tim O'Reilly and Frank Willison first for being talked into publishing this book, and second for letting time-to-market take a back seat to time-to-quality. Thanks also to Linda, our shamelessly honest editor, for shepherding dangerously rabid sheep through the eye of a release needle.

Most of all, I want to thank my mother, Mary, for tearing herself away from her work in prairie restoration and teaching high school computer and biological sciences to keep both my business and domestic life in smooth working order long enough for me to research and write this book.

Finally, I'd like to thank Johann Sebastian Bach, who was for me a boundless font of perspective, poise, and inspiration—a therapy both mental and physical. I am certain that forevermore the Cookbook will evoke for me the sounds of BWV 849, now indelibly etched into the wetware of head and hand.

0.7.2. Nat

Without my family's love and patience, I'd be baiting hooks in a 10-foot swell instead of mowing my lawn in suburban America. Thank you! My friends have taught me much: Jules, Amy, Raj, Mike, Kef, Sai, Robert, Ewan, Pondy, Mark, and Andy. I owe a debt of gratitude to the denizens of Nerdsholm, who gave sound technical advice and introduced me to my wife (they didn't give me sound technical advice on her, though). Thanks also to my employer, Front Range Internet, for a day job I don't want to quit.

Tom was a great co-author. Without him, this book would be nasty, brutish, and short. Finally, I have to thank Jenine. We'd been married a year when I accepted the offer to write, and we've barely seen each other since then. Nobody will savour the final full-stop in this sentence more than she.

Previous | Home | Next
0.6. We'd Like to Hear from You | Book Index | 0.8. Acknowledgments for the Second Edition
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.8. Acknowledgments for the Second Edition

We would like to thank our many tech reviewers, who gave generously of their time and knowledge so that we might look better. Some were formal reviewers who painstakingly plodded through endless drafts and revisions, while others were casual comrades roped into reading small excerpts related to their own particular expertise or interest. The bugs you don't find in this book are thanks to them. Those you do find were probably introduced after they reviewed it.

Just a few of these selfless people were Adam Maccabee Trachtenberg, Rafael Garcia-Suarez, Ask Björn Hansen, Mark-Jason Dominus, Abhijit Menon-Sen, Jarkko Hietaniemi, Benjamin Goldberg, Aaron Straup Cope, Tony Stubblebine, Michel Rodriguez, Nick Ing-Simmons, Geoffrey Young, Douglas Wilson, Paul Kulchenko, Jeffrey Friedl, Arthur Bergman, Autrijus Tang, Matt Sergeant, Steve Marvell, Damian Conway, Sean M. Burke, Elaine Ashton, Steve Lidie, Ken Williams, Robert Spier, Chris Nandor, Brent Halsey, Matthew Free, Rocco Caputo, Robin Berjon, Adam Turoff, Chip Turner, David Sklar, Mike Sierra, Dave Rolsky, Kip Hampton, Chris Fedde, Graham Barr, Jon Orwant, Rich Bowen, Mike Stok, Tim Bunce, Rob Brown, Dan Brian, Gisle Aas, and Abigail.

We'd also like to thank our patient and persistent editor, Linda Mui, who ran serious risk of getting herself committed as she tried to wrestle "the final edits" from us.

0.8.1. Tom

I would like to thank Larry Wall for making the programming world (and several others) a better place for all of us, Nathan for documenting the undocumented, and our editor, Linda Mui, for her indefatigable patience at herding her author cats of the Schrödinger clan ever onward. This book would not exist but for all three of them.

I would especially like to thank someone who is no longer here to read these words in print, words he would otherwise himself have shepherded: O'Reilly's longtime editor-in-chief and my friend, Frank Willison, gone from us two years now. His many erudite epistles are a thing of legend, carefully crafted treasures more dear to any writer than finest gold. Over our years of working together, Frank was a constant source of personal inspiration and encouragement. His easygoing cheer and charm, his broad learning and interests, and his sparkling wit—sometimes subtle, sometimes hilarious, and often both—made him more deserving of being called avuncular than anyone else I have ever known, and as such do I miss him. Thank you, Frank, wherever you are.

0.8.2. Nat

Henry David Thoreau wrote, "What is commonly called friendship is only a little more honor among rogues." If that be true, I have two honorable rogues to thank: Jon Orwant, who engineered my job at O'Reilly & Associates; and Linda Mui, who helped me keep it.

As with the first edition, the book in your hands wouldn't be there without Tom's drive, attention to detail, and willingness to tackle the hard stuff. Thanks for taking the Unicode bullet, Tom.

And finally, my family. Jenine nearly became a solo parent while I worked on this book. My heart broke when William sadly told a friend, "My daddy works and works—all day and all night," and again when one of Raley's first two-word sentences was "Daddy work." Thank you all.

Previous | Home | Next
0.7. Acknowledgments for the First Edition | Book Index | 1. Strings
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 1. Strings

Contents:

Introduction
Accessing Substrings
Establishing a Default Value
Exchanging Values Without Using Temporary Variables
Converting Between Characters and Values
Using Named Unicode Characters
Processing a String One Character at a Time
Reversing a String by Word or Character
Treating Unicode Combined Characters as Single Characters
Canonicalizing Strings with Unicode Combined Characters
Treating a Unicode String as Octets
Expanding and Compressing Tabs
Expanding Variables in User Input
Controlling Case
Properly Capitalizing a Title or Headline
Interpolating Functions and Expressions Within Strings
Indenting Here Documents
Reformatting Paragraphs
Escaping Characters
Trimming Blanks from the Ends of a String
Parsing Comma-Separated Data
Constant Variables
Soundex Matching
Program: fixstyle
Program: psgrep

Job 35:16

He multiplieth words without knowledge.

1.0. Introduction

Many programming languages force you to work at an uncomfortably low level. You think in lines, but your language wants you to deal with pointers. You think in strings, but it wants you to deal with bytes. Such a language can drive you to distraction. Don't despair; Perl isn't a low-level language, so lines and strings are easy to handle.

Perl was designed for easy but powerful text manipulation. In fact, Perl can manipulate text in so many ways that they can't all be described in one chapter. Check out other chapters for recipes on text processing. In particular, see Chapter 6 and Chapter 8, which discuss interesting techniques not covered here.

Perl's fundamental unit for working with data is the scalar, that is, single values stored in single (scalar) variables. Scalar variables hold strings, numbers, and references. Array and hash variables hold lists or associations of scalars, respectively. References are used for referring to values indirectly, not unlike pointers in low-level languages. Numbers are usually stored in your machine's double-precision floating-point notation. Strings in Perl may be of any length, within the limits of your machine's virtual memory, and can hold any arbitrary data you care to put there—even binary data containing null bytes.

A string in Perl is not an array of characters—nor of bytes, for that matter. You cannot use array subscripting on a string to address one of its characters; use substr for that. Like all data types in Perl, strings grow on demand. Space is reclaimed by Perl's garbage collection system when no longer used, typically when the variables have gone out of scope or when the expression in which they were used has been evaluated. In other words, memory management is already taken care of, so you don't have to worry about it.

A scalar value is either defined or undefined. If defined, it may hold a string, number, or reference. The only undefined value is undef. All other values are defined, even numeric and the empty string. Definedness is not the same as Boolean truth, though; to check whether a value is defined, use the defined function. Boolean truth has a specialized meaning, tested with operators such as && and || or in an if or while block's test condition.

Two defined strings are false: the empty string ("") and a string of length one containing the digit zero ("0"). All other defined values (e.g., "false", 15, and \$x) are true. You might be surprised to learn that "0" is false, but this is due to Perl's on-demand conversion between strings and numbers. The values 0., 0.00, and 0.0000000 are all numbers and are therefore false when unquoted, since the number zero in any of its guises is always false. However, those three values ("0.", "0.00", and "0.0000000") are true when used as literal quoted strings in your program code or when they're read from the command line, an environment variable, or an input file.

This is seldom an issue, since conversion is automatic when the value is used numerically. If it has never been used numerically, though, and you just test whether it's true or false, you might get an unexpected answer—Boolean tests never force any sort of conversion. Adding 0 to the variable makes Perl explicitly convert the string to a number:

print "Gimme a number: ";
0.00000
chomp($n = <STDIN>);  # $n now holds "0.00000";

print "The value $n is ", $n ? "TRUE" : "FALSE", "\n";
That value 0.00000 is TRUE

$n += 0;
print "The value $n is now ", $n ? "TRUE" : "FALSE", "\n";
That value 0 is now FALSE

The undef value behaves like the empty string ("") when used as a string, 0 when used as a number, and the null reference when used as a reference. But in all three possible cases, it's false. Using an undefined value where Perl expects a defined value will trigger a runtime warning message on STDERR if you've enabled warnings. Merely asking whether something is true or false demands no particular value, so this is exempt from warnings. Some operations do not trigger warnings when used on variables holding undefined values. These include the autoincrement and autodecrement operators, ++ and --, and the addition and concatenation assignment operators, += and .= ("plus-equals" and "dot-equals").

Specify strings in your program using single quotes, double quotes, the quoting operators q// and qq//, or here documents. No matter which notation you use, string literals are one of two possible flavors: interpolated or uninterpolated. Interpolation governs whether variable references and special sequences are expanded. Most are interpolated by default, such as in patterns (/regex/) and running commands ($x = `cmd`).

Where special characters are recognized, preceding any special character with a backslash renders that character mundane; that is, it becomes a literal. This is often referred to as "escaping" or "backslash escaping."

Using single quotes is the canonical way to get an uninterpolated string literal. Three special sequences are still recognized: ' to terminate the string, \' to represent a single quote, and \\ to represent a backslash in the string.

$string = '\n';                     # two characters, \ and an n
$string = 'Jon \'Maddog\' Orwant';  # literal single quotes

Double quotes interpolate variables (but not function calls—see Recipe 1.15 to find how to do this) and expand backslash escapes. These include "\n" (newline), "\033" (the character with octal value 33), "\cJ" (Ctrl-J), "\x1B" (the character with hex value 0x1B), and so on. The full list of these is given in the perlop(1) manpage and the section on "Specific Characters" in Chapter 5 of Programming Perl.

$string = "\n";                     # a "newline" character
$string = "Jon \"Maddog\" Orwant";  # literal double quotes

If there are no backslash escapes or variables to expand within the string, it makes no difference which flavor of quotes you use. When choosing between writing 'this' and writing "this", some Perl programmers prefer to use double quotes so that the strings stand out. This also avoids the slight risk of having single quotes mistaken for backquotes by readers of your code. It makes no difference to Perl, and it might help readers.

The q// and qq// quoting operators allow arbitrary delimiters on interpolated and uninterpolated literals, respectively, corresponding to single- and double-quoted strings. For an uninterpolated string literal that contains single quotes, it's easier to use q// than to escape all single quotes with backslashes:

$string = 'Jon \'Maddog\' Orwant';   # embedded single quotes
$string = q/Jon 'Maddog' Orwant/;    # same thing, but more legible

Choose the same character for both delimiters, as we just did with /, or pair any of the following four sets of bracketing characters:

$string = q[Jon 'Maddog' Orwant];   # literal single quotes
$string = q{Jon 'Maddog' Orwant};   # literal single quotes
$string = q(Jon 'Maddog' Orwant);   # literal single quotes
$string = q<Jon 'Maddog' Orwant>;   # literal single quotes

Here documents are a notation borrowed from the shell used to quote a large chunk of text. The text can be interpreted as single-quoted, double-quoted, or even as commands to be executed, depending on how you quote the terminating identifier. Uninterpolated here documents do not expand the three backslash sequences the way single-quoted literals normally do. Here we double-quote two lines with a here document:

$a = <<"EOF";
This is a multiline here document
terminated by EOF on a line by itself
EOF

Notice there's no semicolon after the terminating EOF. Here documents are covered in more detail in Recipe 1.16.

1.0.1. The Universal Character Code

As far as the computer is concerned, all data is just a series of individual numbers, each a string of bits. Even text strings are just sequences of numeric codes interpreted as characters by programs like web browsers, mailers, printing programs, and editors.

Back when memory sizes were far smaller and memory prices far more dear, programmers would go to great lengths to save memory. Strategies such as stuffing six characters into one 36-bit word or jamming three characters into one 16-bit word were common. Even today, the numeric codes used for characters usually aren't longer than 7 or 8 bits, which are the lengths you find in ASCII and Latin1, respectively.

That doesn't leave many bits per character—and thus, not many characters. Consider an image file with 8-bit color. You're limited to 256 different colors in your palette. Similarly, with characters stored as individual octets (an octet is an 8-bit byte), a document can usually have no more than 256 different letters, punctuation marks, and symbols in it.

ASCII, being the American Standard Code for Information Interchange, was of limited utility outside the United States, since it covered only the characters needed for a slightly stripped-down dialect of American English. Consequently, many countries invented their own incompatible 8-bit encodings built upon 7-bit ASCII. Conflicting schemes for assigning numeric codes to characters sprang up, all reusing the same limited range. That meant the same number could mean a different character in different systems and that the same character could have been assigned a different number in different systems.

Locales were an early attempt to address this and other language- and country-specific issues, but they didn't work out so well for character set selection. They're still reasonable for purposes unrelated to character sets, such as local preferences for monetary units, date and time formatting, and even collating sequences. But they are of far less utility for reusing the same 8-bit namespace for different character sets.

That's because if you wanted to produce a document that used Latin, Greek, and Cyrillic characters, you were in for big trouble, since the same numeric code would be a different character under each system. For example, character number 196 is a Latin capital A with a diaeresis above it in ISO 8859-1 (Latin1); under ISO 8859-7, that same numeric code represents a Greek capital delta. So a program interpreting numeric character codes in the ISO 8859-1 locale would see one character, but under the ISO 8859-7 locale, it would see something totally different.

This makes it hard to combine different character sets in the same document. Even if you did cobble something together, few programs could work with that document's text. To know what characters you had, you'd have to know what system they were in, and you couldn't easily mix systems. If you guessed wrong, you'd get a jumbled mess on your screen, or worse.

1.0.2. Unicode Support in Perl

Enter Unicode.

Unicode attempts to unify all character sets in the entire world, including many symbols and even fictional character sets. Under Unicode, different characters have different numeric codes, called code points.

Mixed-language documents are now easy, whereas before they weren't even possible. You no longer have just 128 or 256 possible characters per document. With Unicode you can have tens of thousands (and more) of different characters all jumbled together in the same document without confusion.

The problem of mixing, say, an Ä with a Δ evaporates. The first character, formally named "LATIN CAPITAL LETTER A WITH DIAERESIS" under Unicode, is assigned the code point U+00C4 (that's the Unicode preferred notation). The second, a "GREEK CAPITAL LETTER DELTA", is now at code point U+0394. With different characters always assigned different code points, there's no longer any conflict.

Perl has supported Unicode since v5.6 or so, but it wasn't until the v5.8 release that Unicode support was generally considered robust and usable. This by no coincidence corresponded to the introduction of I/O layers and their support for encodings into Perl. These are discussed in more detail in Chapter 8.

All Perl's string functions and operators, including those used for pattern matching, now operate on characters instead of octets. If you ask for a string's length, Perl reports how many characters are in that string, not how many bytes are in it. If you extract the first three characters of a string using substr, the result may or may not be three bytes. You don't know, and you shouldn't care, either. One reason not to care about the particular underlying bytewise representation is that if you have to pay attention to it, you're probably looking too closely. It shouldn't matter, really—but if it does, this might mean that Perl's implementation still has a few bumps in it. We're working on that.

Because characters with code points above 256 are supported, the chr function is no longer restricted to arguments under 256, nor is ord restricted to returning an integer smaller than that. Ask for chr(0x394), for example, and you'll get a Greek capital delta: Δ.

$char = chr(0x394);
$code = ord($char);
printf "char %s is code %d, %#04x\n", $char, $code, $code;

char Δ is code 916, 0x394

If you test the length of that string, it will say 1, because it's just one character. Notice how we said character; we didn't say anything about its length in bytes. Certainly the internal representation requires more than just 8 bits for a numeric code that big. But you the programmer are dealing with characters as abstractions, not as physical octets. Low-level details like that are best left up to Perl.

You shouldn't think of characters and bytes as the same. Programmers who interchange bytes and characters are guilty of the same class of sin as C programmers who blithely interchange integers and pointers. Even though the underlying representations may happen to coincide on some platforms, this is just a coincidence, and conflating abstract interfaces with physical implementations will always come back to haunt you, eventually.

You have several ways to put Unicode characters into Perl literals. If you're lucky enough to have a text editor that lets you enter Unicode directly into your Perl program, you can inform Perl you've done this via the use utf8 pragma. Another way is to use \x escapes in Perl interpolated strings to indicate a character by its code point in hex, as in \xC4. Characters with code points above 0xFF require more than two hex digits, so these must be enclosed in braces.

print "\xC4 and \x{0394} look different\n";

char Ä andΔ look different\n

Recipe 1.5 describes how to use charnames to put \N{NAME} escapes in string literals, such as \N{GREEK CAPITAL LETTER DELTA}, \N{greek:Delta}, or even just \N{Delta} to indicate a Δ character.

That's enough to get started using Unicode in Perl alone, but getting Perl to interact properly with other programs requires a bit more.

Using the old single-byte encodings like ASCII or ISO 8859-n, when you wrote out a character whose numeric code was NN, a single byte with numeric code NN would appear. What actually appeared depended on which fonts were available, your current locale setting, and quite a few other factors. But under Unicode, this exact duplication of logical character numbers (code points) into physical bytes emitted no longer applies. Instead, they must be encoded in any of several available output formats.

Internally, Perl uses a format called UTF-8, but many other encoding formats for Unicode exist, and Perl can work with those, too. The use encoding pragma tells Perl in which encoding your script itself has been written, or which encoding the standard filehandles should use. The use open pragma can set encoding defaults for all handles. Special arguments to open or to binmode specify the encoding format for that particular handle. The -C command-line flag is a shortcut to set the encoding on all (or just standard) handles, plus the program arguments themselves. The environment variables PERLIO, PERL_ENCODING, and PERL_UNICODE all give Perl various sorts of hints related to these matters.

Previous | Home | Next
0.8. Acknowledgments for the Second Edition | Book Index | 1.1. Accessing Substrings
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.1. Accessing Substrings

1.1.1. Problem

You want to access or modify just a portion of a string, not the whole thing. For instance, you've read a fixed-width record and want to extract individual fields.

1.1.2. Solution

The substr function lets you read from and write to specific portions of the string.

$value = substr($string, $offset, $count);
$value = substr($string, $offset);

substr($string, $offset, $count) = $newstring;
substr($string, $offset, $count, $newstring);  # same as previous
substr($string, $offset)         = $newtail;

The unpack function gives only read access, but is faster when you have many substrings to extract.

# get a 5-byte string, skip 3 bytes,
# then grab two 8-byte strings, then the rest;
# (NB: only works on ASCII data, not Unicode)
($leading, $s1, $s2, $trailing) =
    unpack("A5 x3 A8 A8 A*", $data);

# split at 5-byte boundaries
@fivers = unpack("A5" x (length($string)/5), $string);

# chop string into individual single-byte characters
@chars  = unpack("A1" x length($string), $string);

1.1.3. Discussion

Strings are a basic data type; they aren't arrays of a basic data type. Instead of using array subscripting to access individual characters as you sometimes do in other programming languages, in Perl you use functions like unpack or substr to access individual characters or a portion of the string.

The offset argument to substr indicates the start of the substring you're interested in, counting from the front if positive and from the end if negative. If the offset is 0, the substring starts at the beginning. The count argument is the length of the substring.

$string = "This is what you have";
#         +012345678901234567890  Indexing forwards  (left to right)
#          109876543210987654321- Indexing backwards (right to left)
#           note that 0 means 10 or 20, etc. above

$first  = substr($string, 0, 1);  # "T"
$start  = substr($string, 5, 2);  # "is"
$rest   = substr($string, 13);    # "you have"
$last   = substr($string, -1);    # "e"
$end    = substr($string, -4);    # "have"
$piece  = substr($string, -8, 3); # "you"

You can do more than just look at parts of the string with substr; you can actually change them. That's because substr is a particularly odd kind of function—an lvaluable one, that is, a function whose return value may be itself assigned a value. (For the record, the others are vec, pos, and keys. If you squint, local, my, and our can also be viewed as lvaluable functions.)

$string = "This is what you have";
print $string;
This is what you have
substr($string, 5, 2) = "wasn't"; # change "is" to "wasn't"
This wasn't what you have
substr($string, -12)  = "ondrous";# "This wasn't wondrous"
This wasn't wondrous
substr($string, 0, 1) = "";       # delete first character
his wasn't wondrous
substr($string, -10)  = "";       # delete last 10 characters
his wasn'

Use the =~ operator and the s///, m//, or tr/// operators in conjunction with substr to make them affect only that portion of the string.

# you can test substrings with =~
if (substr($string, -10) =~ /pattern/) {
            print "Pattern matches in last 10 characters\n";
}

# substitute "at" for "is", restricted to first five characters
substr($string, 0, 5) =~ s/is/at/g;

You can even swap values by using several substr s on each side of an assignment:

# exchange the first and last letters in a string
$a = "make a hat";
(substr($a,0,1), substr($a,-1)) =
(substr($a,-1),  substr($a,0,1));
print $a;
take a ham

Although unpack is not lvaluable, it is considerably faster than substr when you extract numerous values all at once. Specify a format describing the layout of the record to unpack. For positioning, use lowercase "x" with a count to skip forward some number of bytes, an uppercase "X" with a count to skip backward some number of bytes, and an "@" to skip to an absolute byte offset within the record. (If the data contains Unicode strings, be careful with those three: they're strictly byte-oriented, and moving around by bytes within multibyte data is perilous at best.)

# extract column with unpack
$a = "To be or not to be";
$b = unpack("x6 A6", $a);  # skip 6, grab 6
print $b;
or not

($b, $c) = unpack("x6 A2 X5 A2", $a); # forward 6, grab 2; backward 5, grab 2
print "$b\n$c\n";
or
be

Sometimes you prefer to think of your data as being cut up at specific columns. For example, you might want to place cuts right before positions 8, 14, 20, 26, and 30. Those are the column numbers where each field begins. Although you could calculate that the proper unpack format is "A7 A6 A6 A6 A4 A*", this is too much mental strain for the virtuously lazy Perl programmer. Let Perl figure it out for you. Use the cut2fmt function:

sub cut2fmt {
    my(@positions) = @_;
    my $template   = '';
    my $lastpos    = 1;
    foreach $place (@positions) {
        $template .= "A" . ($place - $lastpos) . " ";
        $lastpos   = $place;
    }
    $template .= "A*";
    return $template;
}

$fmt = cut2fmt(8, 14, 20, 26, 30);
print "$fmt\n";
A7 A6 A6 A6 A4 A*

The powerful unpack function goes far beyond mere text processing. It's the gateway between text and binary data.

In this recipe, we've assumed that all character data is 7- or 8-bit data so that pack's byte operations work as expected.

1.1.4. See Also

The pack, unpack, and substr functions in perlfunc(1) and in Chapter 29 of Programming Perl; use of the cut2fmt subroutine in Recipe 1.24; the binary use of unpack in Recipe 8.24

Previous | Home | Next
1. Strings | Book Index | 1.2. Establishing a Default Value
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.2. Establishing a Default Value

1.2.1. Problem

You would like to supply a default value to a scalar variable, but only if it doesn't already have one. It often happens that you want a hardcoded default value for a variable that can be overridden from the command line or through an environment variable.

1.2.2. Solution

Use the || or ||= operator, which work on both strings and numbers:

# use $b if $b is true, else $c
$a = $b || $c;

# set $x to $y unless $x is already true
$x ||= $y;

If 0, "0", and "" are valid values for your variables, use defined instead:

# use $b if $b is defined, else $c
$a = defined($b) ? $b : $c;

# the "new" defined-or operator from future perl
use v5.9;
$a = $b // $c;

1.2.3. Discussion

The big difference between the two techniques (defined and ||) is what they test: definedness versus truth. Three defined values are still false in the world of Perl: 0, "0", and "". If your variable already held one of those, and you wanted to keep that value, a || wouldn't work. You'd have to use the more elaborate three-way test with defined instead. It's often convenient to arrange for your program to care about only true or false values, not defined or undefined ones.

Rather than being restricted in its return values to a mere 1 or 0 as in most other languages, Perl's || operator has a much more interesting property: it returns its first operand (the lefthand side) if that operand is true; otherwise it returns its second operand. The && operator also returns the last evaluated expression, but is less often used for this property. These operators don't care whether their operands are strings, numbers, or references—any scalar will do. They just return the first one that makes the whole expression true or false. This doesn't affect the Boolean sense of the return value, but it does make the operators' return values more useful.

This property lets you provide a default value to a variable, function, or longer expression in case the first part doesn't pan out. Here's an example of ||, which would set $foo to be the contents of either $bar or, if $bar were false, "DEFAULT VALUE":

$foo = $bar || "DEFAULT VALUE";

Here's another example, which sets $dir to be either the first argument to the program or "/tmp" if no argument were given.

$dir = shift(@ARGV) || "/tmp";

We can do this without altering @ARGV:

$dir = $ARGV[0] || "/tmp";

If 0 is a valid value for $ARGV[0], we can't use ||, because it evaluates as false even though it's a value we want to accept. We must resort to Perl's only ternary operator, the ?: ("hook colon," or just "hook"):

$dir = defined($ARGV[0]) ? shift(@ARGV) : "/tmp";

We can also write this as follows, although with slightly different semantics:

$dir = @ARGV ? $ARGV[0] : "/tmp";

This checks the number of elements in @ARGV, because the first operand (here, @ARGV) is evaluated in scalar context. It's only false when there are 0 elements, in which case we use "/tmp". In all other cases (when the user gives an argument), we use the first argument.

The following line increments a value in %count, using as the key either $shell or, if $shell is false, "/bin/sh".

$count{ $shell || "/bin/sh" }++;

You may chain several alternatives together as we have in the following example. The first expression that returns a true value will be used.

# find the user name on Unix systems
$user = $ENV{USER}
     || $ENV{LOGNAME}
     || getlogin( )
     || (getpwuid($<))[0]
     || "Unknown uid number $<";

The && operator works analogously: it returns its first operand if that operand is false; otherwise, it returns the second one. Because there aren't as many interesting false values as there are true ones, this property isn't used much. One use is demonstrated in Recipe 13.12 and Recipe 14.19.

The ||= assignment operator looks odd, but it works exactly like the other binary assignment operators. For nearly all of Perl's binary operators, $VAR OP= VALUE means $VAR = $VAR OP VALUE; for example, $a += $b is the same as $a = $a + $b. So ||= is used to set a variable when that variable is itself still false. Since the || check is a simple Boolean one—testing for truth—it doesn't care about undefined values, even when warnings are enabled.

Here's an example of ||= that sets $starting_point to "Greenwich" unless it is already set. Again, we assume $starting_point won't have the value 0 or "0", or that if it does, it's okay to change it.

$starting_point ||= "Greenwich";

You can't use or in place of || in assignments, because or's precedence is too low. $a = $b or $c is equivalent to ($a = $b) or $c. This will always assign $b to $a, which is not the behavior you want.

Don't extend this curious use of || and ||= from scalars to arrays and hashes. It doesn't work, because the operators put their left operand into scalar context. Instead, you must do something like this:

@a = @b unless @a;          # copy only if empty
@a = @b ? @b : @c;          # assign @b if nonempty, else @c

Perl is someday expected to support new operators: //, //=, and err. It may already do so by the time you read this text. These defined-or operators will work just like the logical-or operators, ||, except that they will test definedness, not mere truth. That will make the following pairs equivalent:

$a = defined($b) ? $b : $c;
$a = $b // $c;

$x = defined($x) ? $x : $y;
$x //= $y;

defined(read(FH, $buf, $count)  or  die "read failed: $!";
read(FH, $buf, $count)          err die "read failed: $!";

These three operators are already present in Perl release v5.9, which being an odd-numbered release, is an experimental version and not what you want in a production environment. It is expected to be in v5.10, which will be a stable release, and will most certainly be in Perl v6, whose release date has not yet been determined.

1.2.4. See Also

The || operator in perlop(1) and Chapter 3 of Programming Perl; the defined and exists functions in perlfunc(1) and Chapter 29 of Programming Perl

Previous | Home | Next
1.1. Accessing Substrings | Book Index | 1.3. Exchanging Values Without Using Temporary Variables
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.3. Exchanging Values Without Using Temporary Variables

1.3.1. Problem

You want to exchange the values of two scalar variables, but don't want to use a temporary variable.

1.3.2. Solution

Use list assignment to reorder the variables.

($VAR1, $VAR2) = ($VAR2, $VAR1);

1.3.3. Discussion

Most programming languages require an intermediate step when swapping two variables' values:

$temp    = $a;
$a       = $b;
$b       = $temp;

Not so in Perl. It tracks both sides of the assignment, guaranteeing that you don't accidentally clobber any of your values. This eliminates the temporary variable:

$a       = "alpha";
$b       = "omega";
($a, $b) = ($b, $a);        # the first shall be last -- and versa vice

You can even exchange more than two variables at once:

($alpha, $beta, $production) = qw(January March August);
# move beta       to alpha,
# move production to beta,
# move alpha      to production
($alpha, $beta, $production) = ($beta, $production, $alpha);

When this code finishes, $alpha, $beta, and $production have the values "March", "August", and "January".

1.3.4. See Also

The section on "List value constructors" in perldata(1) and on "List Values and Arrays" in Chapter 2 of Programming Perl

Previous | Home | Next
1.2. Establishing a Default Value | Book Index | 1.4. Converting Between Characters and Values
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.4. Converting Between Characters and Values

1.4.1. Problem

You want to print the number represented by a given character, or you want to print a character given a number.

1.4.2. Solution

Use ord to convert a character to a number, or use chr to convert a number to its corresponding character:

$num  = ord($char);
$char = chr($num);

The %c format used in printf and sprintf also converts a number to a character:

$char = sprintf("%c", $num);                # slower than chr($num)
printf("Number %d is character %c\n", $num, $num);
Number 101 is character e

A C* template used with pack and unpack can quickly convert many 8-bit bytes; similarly, use U* for Unicode characters.

@bytes = unpack("C*", $string);
$string = pack("C*", @bytes);

$unistr = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
@unichars = unpack("U*", $unistr);

1.4.3. Discussion

Unlike low-level, typeless languages such as assembler, Perl doesn't treat characters and numbers interchangeably; it treats strings and numbers interchangeably. That means you can't just assign characters and numbers back and forth. Perl provides Pascal's chr and ord to convert between a character and its corresponding ordinal value:

$value     = ord("e");    # now 101
$character = chr(101);    # now "e"

If you already have a character, it's really represented as a string of length one, so just print it out directly using print or the %s format in printf and sprintf. The %c format forces printf or sprintf to convert a number into a character; it's not used for printing a character that's already in character format (that is, a string).

printf("Number %d is character %c\n", 101, 101);

The pack, unpack, chr, and ord functions are all faster than sprintf. Here are pack and unpack in action:

@ascii_character_numbers = unpack("C*", "sample");
print "@ascii_character_numbers\n";
115 97 109 112 108 101

$word = pack("C*", @ascii_character_numbers);
$word = pack("C*", 115, 97, 109, 112, 108, 101);   # same
print "$word\n";
sample

Here's how to convert from HAL to IBM:

$hal = "HAL";
@byte = unpack("C*", $hal);
foreach $val (@byte) {
    $val++;                 # add one to each byte value
}
$ibm = pack("C*", @byte);
print "$ibm\n";             # prints "IBM"

On single-byte character data, such as plain old ASCII or any of the various ISO 8859 charsets, the ord function returns numbers from 0 to 255. These correspond to C's unsigned char data type.

However, Perl understands more than that: it also has integrated support for Unicode, the universal character encoding. If you pass chr, sprintf "%c", or pack "U*" numeric values greater than 255, the return result will be a Unicode string.

Here are similar operations with Unicode:

@unicode_points = unpack("U*", "fac\x{0327}ade");
print "@unicode_points\n";
102 97 99 807 97 100 101

$word = pack("U*", @unicode_points);
print "$word\n";
façade

If all you're doing is printing out the characters' values, you probably don't even need to use unpack. Perl's printf and sprintf functions understand a v modifier that works like this:

printf "%vd\n", "fac\x{0327}ade";
102.97.99.807.97.100.101

printf "%vx\n", "fac\x{0327}ade";
66.61.63.327.61.64.65

The numeric value of each character (that is, its "code point" in Unicode parlance) in the string is emitted with a dot separator.

1.4.4. See Also

The chr, ord, printf, sprintf, pack, and unpack functions in perlfunc(1) and Chapter 29 of Programming Perl

Previous | Home | Next
1.3. Exchanging Values Without Using Temporary Variables | Book Index | 1.5. Using Named Unicode Characters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.5. Using Named Unicode Characters

1.5.1. Problem

You want to use Unicode names for fancy characters in your code without worrying about their code points.

1.5.2. Solution

Place a use charnames at the top of your file, then freely insert "\N{CHARSPEC}" escapes into your string literals.

1.5.3. Discussion

The use charnames pragma lets you use symbolic names for Unicode characters. These are compile-time constants that you access with the \N{CHARSPEC} double-quoted string sequence. Several subpragmas are supported. The :full subpragma grants access to the full range of character names, but you have to write them out in full, exactly as they occur in the Unicode character database, including the loud, all-capitals notation. The :short subpragma gives convenient shortcuts. Any import without a colon tag is taken to be a script name, giving case-sensitive shortcuts for those scripts.

use charnames ':full';
print "\N{GREEK CAPITAL LETTER DELTA} is called delta.\n";

Δ is called delta.

use charnames ':short';
print "\N{greek:Delta} is an upper-case delta.\n";

Δ is an upper-case delta.

use charnames qw(cyrillic greek);
print "\N{Sigma} and \N{sigma} are Greek sigmas.\n";
print "\N{Be} and \N{be} are Cyrillic bes.\n";

Σ and σ are Greek sigmas.
Б and б are Cyrillic bes.

Two functions, charnames::viacode and charnames::vianame, can translate between numeric code points and the long names. The Unicode documents use the notation U+XXXX to indicate the Unicode character whose code point is XXXX, so we'll use that here in our output.

use charnames qw(:full);
for $code (0xC4, 0x394) {
    printf "Character U+%04X (%s) is named %s\n",
        $code, chr($code), charnames::viacode($code);
}

Character U+00C4 (Ä) is named LATIN CAPITAL LETTER A WITH DIAERESIS
Character U+0394 (Δ) is named GREEK CAPITAL LETTER DELTA

use charnames qw(:full);
$name = "MUSIC SHARP SIGN";
$code = charnames::vianame($name);
printf "%s is character U+%04X (%s)\n",
    $name, $code, chr($code);

MUSIC SHARP SIGN is character U+266F (#)

Here's how to find the path to Perl's copy of the Unicode character database:

% perl -MConfig -le 'print "$Config{privlib}/unicore/NamesList.txt"'
/usr/local/lib/perl5/5.8.1/unicore/NamesList.txt

Read this file to learn the character names available to you.

1.5.4. See Also

The charnames(3) manpage and Chapter 31 of Programming Perl; the Unicode Character Database at http://www.unicode.org/

Previous | Home | Next
1.4. Converting Between Characters and Values | Book Index | 1.6. Processing a String One Character at a Time
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.6. Processing a String One Character at a Time

1.6.1. Problem

You want to process a string one character at a time.

1.6.2. Solution

Use split with a null pattern to break up the string into individual characters, or use unpack if you just want the characters' values:

@array = split(//, $string);      # each element a single character
@array = unpack("U*", $string);   # each element a code point (number)

Or extract each character in turn with a loop:

while (/(.)/g) {         # . is never a newline here
        # $1 has character, ord($1) its number
    }

1.6.3. Discussion

As we said before, Perl's fundamental unit is the string, not the character. Needing to process anything a character at a time is rare. Usually some kind of higher-level Perl operation, like pattern matching, solves the problem more handily. See, for example, Recipe 7.14, where a set of substitutions is used to find command-line arguments.

Splitting on a pattern that matches the empty string returns a list of individual characters in the string. This is a convenient feature when done intentionally, but it's easy to do unintentionally. For instance, /X*/ matches all possible strings, including the empty string. Odds are you will find others when you don't mean to.

Here's an example that prints the characters used in the string "an apple a day", sorted in ascending order:

%seen = ( );
$string = "an apple a day";
foreach $char (split //, $string) {
    $seen{$char}++;
}
print "unique chars are: ", sort(keys %seen), "\n";
unique chars are:  adelnpy

These split and unpack solutions give an array of characters to work with. If you don't want an array, use a pattern match with the /g flag in a while loop, extracting one character at a time:

%seen = ( );
$string = "an apple a day";
while ($string =~ /(.)/g) {
    $seen{$1}++;
}
print "unique chars are: ", sort(keys %seen), "\n";
unique chars are:  adelnpy

In general, whenever you find yourself doing character-by-character processing, there's probably a better way to go about it. Instead of using index and substr or split and unpack, it might be easier to use a pattern. Instead of computing a 32-bit checksum by hand, as in the next example, the unpack function can compute it far more efficiently.

The following example calculates the checksum of $string with a foreach loop. There are better checksums; this just happens to be the basis of a traditional and computationally easy checksum. You can use the standard[3] Digest::MD5 module if you want a more robust checksum.

[3]It's standard as of the v5.8 release of Perl; otherwise, grab it from CPAN.

$sum = 0;
foreach $byteval (unpack("C*", $string)) {
    $sum += $byteval;
}
print "sum is $sum\n";
# prints "1248" if $string was "an apple a day"

This does the same thing, but much faster:

$sum = unpack("%32C*", $string);

This emulates the SysV checksum program:

#!/usr/bin/perl
# sum - compute 16-bit checksum of all input files
$checksum = 0;
while (<>) { $checksum += unpack("%16C*", $_) }
$checksum %= (2 ** 16) - 1;
print "$checksum\n";

Here's an example of its use:

% perl sum /etc/termcap
1510

If you have the GNU version of sum, you'll need to call it with the —sysv option to get the same answer on the same file.

% sum --sysv /etc/termcap
1510 851 /etc/termcap

Another tiny program that processes its input one character at a time is slowcat, shown in Example 1-1. The idea here is to pause after each character is printed so you can scroll text before an audience slowly enough that they can read it.

Example 1-1. slowcat

  #!/usr/bin/perl
  # slowcat - emulate a   s l o w   line printer
  # usage: slowcat [-DELAY] [files ...]
  $DELAY = ($ARGV[0] =~ /^-([.\d]+)/) ? (shift, $1) : 1;
  $| = 1;
  while (<>) {
      for (split(//)) {
          print;
          select(undef,undef,undef, 0.005 * $DELAY);
      }
  }

1.6.4. See Also

The split and unpack functions in perlfunc(1) and Chapter 29 of Programming Perl; the use of expanding select for timing is explained in Recipe 3.10

Previous | Home | Next
1.5. Using Named Unicode Characters | Book Index | 1.7. Reversing a String by Word or Character
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.7. Reversing a String by Word or Character

1.7.1. Problem

You want to reverse the words or characters of a string.

1.7.2. Solution

Use the reverse function in scalar context for flipping characters:

$revchars = reverse($string);

To flip words, use reverse in list context with split and join:

$revwords = join(" ", reverse split(" ", $string));

1.7.3. Discussion

The reverse function is two different functions in one. Called in scalar context, it joins together its arguments and returns that string in reverse order. Called in list context, it returns its arguments in the opposite order. When using reverse for its character-flipping behavior, use scalar to force scalar context unless it's entirely obvious.

$gnirts   = reverse($string);       # reverse letters in $string

@sdrow    = reverse(@words);        # reverse elements in @words

$confused = reverse(@words);        # reverse letters in join("", @words)

Here's an example of reversing words in a string. Using a single space, " ", as the pattern to split is a special case. It causes split to use contiguous whitespace as the separator and also discard leading null fields, just like awk. Normally, split discards only trailing null fields.

# reverse word order
$string = 'Yoda said, "can you see this?"';
@allwords    = split(" ", $string);
$revwords    = join(" ", reverse @allwords);
print $revwords, "\n";
this?" see you "can said, Yoda

We could remove the temporary array @allwords and do it on one line:

$revwords = join(" ", reverse split(" ", $string));

Multiple whitespace in $string becomes a single space in $revwords. If you want to preserve whitespace, use this:

$revwords = join("", reverse split(/(\s+)/, $string));

One use of reverse is to test whether a word is a palindrome (a word that reads the same backward or forward):

$word = "reviver";
$is_palindrome = ($word eq reverse($word));

We can turn this into a one-liner that finds big palindromes in /usr/dict/words:

% perl -nle 'print if $_ eq reverse && length > 5' /usr/dict/words
deedeed
degged
deified
denned
hallah
kakkak
murdrum
redder
repaper
retter
reviver
rotator
sooloos
tebbet
terret
tut-tut

1.7.4. See Also

The split, reverse, and scalar functions in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 1.8

Previous | Home | Next
1.6. Processing a String One Character at a Time | Book Index | 1.8. Treating Unicode Combined Characters as Single Characters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.8. Treating Unicode Combined Characters as Single Characters

1.8.1. Problem

You have a Unicode string that contains combining characters, and you'd like to treat each of these sequences as a single logical character.

1.8.2. Solution

Process them using \X in a regular expression.

$string = "fac\x{0327}ade";         # "façade"
$string =~ /fa.ade/;                # fails
$string =~ /fa\Xade/;               # succeeds

@chars = split(//, $string);        # 7 letters in @chars
@chars = $string =~ /(.)/g;         # same thing
@chars = $string =~ /(\X)/g;        # 6 "letters" in @chars

1.8.3. Discussion

In Unicode, you can combine a base character with one or more non-spacing characters following it; these are usually diacritics, such as accent marks, cedillas, and tildas. Due to the presence of precombined characters, for the most part to accommodate legacy character systems, there can be two or more ways of writing the same thing.

For example, the word "façade" can be written with one character between the two a's, "\x{E7}", a character right out of Latin1 (ISO 8859-1). These characters might be encoded into a two-byte sequence under the UTF-8 encoding that Perl uses internally, but those two bytes still only count as one single character. That works just fine.

There's a thornier issue. Another way to write U+00E7 is with two different code points: a regular "c" followed by "\x{0327}". Code point U+0327 is a non-spacing combining character that means to go back and put a cedilla underneath the preceding base character.

There are times when you want Perl to treat each combined character sequence as one logical character. But because they're distinct code points, Perl's character-related operations treat non-spacing combining characters as separate characters, including substr, length, and regular expression metacharacters, such as in /./ or /[^abc]/.

In a regular expression, the \X metacharacter matches an extended Unicode combining character sequence, and is exactly equivalent to (?:\PM\pM*) or, in long-hand:

(?x:                # begin non-capturing group
        \PM         # one character without the M (mark) property,
                    #   such as a letter
        \pM         # one character that does have the M (mark) property,
                    #   such as an accent mark
        *           # and you can have as many marks as you want
)

Otherwise simple operations become tricky if these beasties are in your string. Consider the approaches for reversing a word by character from the previous recipe. Written with combining characters, "année" and "niño" can be expressed in Perl as "anne\x{301}e" and "nin\x{303}o".

for $word ("anne\x{301}e", "nin\x{303}o") {
    printf "%s simple reversed to %s\n", $word,
        scalar reverse $word;
    printf "%s better reversed to %s\n", $word,
        join("", reverse $word =~ /\X/g);
}

That produces:

année simple reversed to éenna
année better reversed to eénna
niño simple reversed to õnin
niño better reversed to oñin

In the reversals marked as simply reversed, the diacritical marking jumped from one base character to the other one. That's because a combining character always follows its base character, and you've reversed the whole string. By grabbing entire sequences of a base character plus any combining characters that follow, then reversing that list, this problem is avoided.

1.8.4. See Also

The perlre(1) and perluniintro(1) manpages; Chapter 15 of Programming Perl; Recipe 1.9

Previous | Home | Next
1.7. Reversing a String by Word or Character | Book Index | 1.9. Canonicalizing Strings with Unicode Combined Characters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.9. Canonicalizing Strings with Unicode Combined Characters

1.9.1. Problem

You have two strings that look the same when you print them out, but they don't test as string equal and sometimes even have different lengths. How can you get Perl to consider them the same strings?

1.9.2. Solution

When you have otherwise equivalent strings, at least some of which contain Unicode combining character sequences, instead of comparing them directly, compare the results of running them through the NFD( ) function from the Unicode::Normalize module.

use Unicode::Normalize;
$s1 = "fa\x{E7}ade";
$s2 = "fac\x{0327}ade";
if (NFD($s1) eq NFD($s2)) { print "Yup!\n" }

1.9.3. Discussion

The same character sequence can sometimes be specified in multiple ways. Sometimes this is because of legacy encodings, such as the letters from Latin1 that contain diacritical marks. These can be specified directly with a single character (like U+00E7, LATIN SMALL LETTER C WITH CEDILLA) or indirectly via the base character (like U+0063, LATIN SMALL LETTER C) followed by a combining character (U+0327, COMBINING CEDILLA).

Another possibility is that you have two or more marks following a base character, but the order of those marks varies in your data. Imagine you wanted the letter "c" to have both a cedilla and a caron on top of it in order to print a Figure . That could be specified in any of these ways:

$string = v231.780;
#   LATIN SMALL LETTER C WITH CEDILLA
#   COMBINING CARON

$string = v99.807.780;
#         LATIN SMALL LETTER C
#         COMBINING CARON
#         COMBINING CEDILLA

$string = v99.780.807
#         LATIN SMALL LETTER C
#         COMBINING CEDILLA
#         COMBINING CARON

The normalization functions rearrange those into a reliable ordering. Several are provided, including NFD( ) for canonical decomposition and NFC( ) for canonical decomposition followed by canonical composition. No matter which of these three ways you used to specify your Figure , the NFD version is v99.807.780, whereas the NFC version is v231.780.

Sometimes you may prefer NFKD( ) and NFKC( ), which are like the previous two functions except that they perform compatible decomposition, which for NFKC( ) is then followed by canonical composition. For example, \x{FB00} is the double-f ligature. Its NFD and NFC forms are the same thing, "\x{FB00}", but its NFKD and NFKC forms return a two-character string, "\x{66}\x{66}".

1.9.4. See Also

The Universal Character Code section at the beginning of this chapter; the documentation for the Unicode::Normalize module; Recipe 8.20

Previous | Home | Next
1.8. Treating Unicode Combined Characters as Single Characters | Book Index | 1.10. Treating a Unicode String as Octets
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.10. Treating a Unicode String as Octets

1.10.1. Problem

You have a Unicode string but want Perl to treat it as octets (e.g., to calculate its length or for purposes of I/O).

1.10.2. Solution

The use bytes pragma makes all Perl operations in its lexical scope treat the string as a group of octets. Use it when your code is calling Perl's character-aware functions directly:

$ff = "\x{FB00}";             # ff ligature
$chars = length($ff);         # length is one character
{
  use bytes;                  # force byte semantics
  $octets = length($ff);      # length is two octets
}
$chars = length($ff);         # back to character semantics

Alternatively, the Encode module lets you convert a Unicode string to a string of octets, and back again. Use it when the character-aware code isn't in your lexical scope:

use Encode qw(encode_utf8);

sub somefunc;                 # defined elsewhere

$ff = "\x{FB00}";             # ff ligature
$ff_oct = encode_utf8($ff);   # convert to octets

$chars = somefunc($ff);       # work with character string
$octets = somefunc($ff_oct);  # work with octet string

1.10.3. Discussion

As explained in this chapter's Introduction, Perl knows about two types of string: those made of simple uninterpreted octets, and those made of Unicode characters whose UTF-8 representation may require more than one octet. Each individual string has a flag associated with it, identifying the string as either UTF-8 or octets. Perl's I/O and string operations (such as length) check this flag and give character or octet semantics accordingly.

Sometimes you need to work with bytes and not characters. For example, many protocols have a Content-Length header that specifies the size of the body of a message in octets. You can't simply use Perl's length function to calculate the size, because if the string you're calling length on is marked as UTF-8, you'll get the size in characters.

The use bytes pragma makes all Perl functions in its lexical scope use octet semantics for strings instead of character semantics. Under this pragma, length always returns the number of octets, and read always reports the number of octets read. However, because the use bytes pragma is lexically scoped, you can't use it to change the behavior of code in another scope (e.g., someone else's function).

For this you need to create an octet-encoded copy of the UTF-8 string. In memory, of course, the same byte sequence is used for both strings. The difference is that the copy of your UTF-8 string has the UTF-8 flag cleared. Functions acting on the octet copy will give octet semantics, regardless of the scope they're in.

There is also a no bytes pragma, which forces character semantics, and a decode_utf8 function, which turns octet-encoded strings into UTF-8 encoded strings. However, these functions are less useful because not all octet strings are valid UTF-8 strings, whereas all UTF-8 strings are valid octet strings.

1.10.4. See Also

The documentation for the bytes pragma; the documentation for the standard Encode module

Previous | Home | Next
1.9. Canonicalizing Strings with Unicode Combined Characters | Book Index | 1.11. Expanding and Compressing Tabs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.11. Expanding and Compressing Tabs

1.11.1. Problem

You want to convert tabs in a string to the appropriate number of spaces, or vice versa. Converting spaces into tabs can be used to reduce file size when the file has many consecutive spaces. Converting tabs into spaces may be required when producing output for devices that don't understand tabs or think them at different positions than you do.

1.11.2. Solution

Either use a rather funny looking substitution:

while ($string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {
    # spin in empty loop until substitution finally fails
}

or use the standard Text::Tabs module:

use Text::Tabs;
@expanded_lines  = expand(@lines_with_tabs);
@tabulated_lines = unexpand(@lines_without_tabs);

1.11.3. Discussion

Assuming tab stops are set every N positions (where N is customarily eight), it's easy to convert them into spaces. The standard textbook method does not use the Text::Tabs module but suffers slightly from being difficult to understand. Also, it uses the $` variable, whose very mention currently slows down every pattern match in the program. This is explained in Special Variables in Chapter 6. You could use this algorithm to make a filter to expand its input's tabstops to eight spaces each:

while (<>) {
    1 while s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
    print;
}

To avoid $`, you could use a slightly more complicated alternative that uses the numbered variables for explicit capture; this one expands tabstops to four each instead of eight:

1 while s/^(.*?)(\t+)/$1 . ' ' x (length($2) * 4 - length($1) % 4)/e;

Another approach is to use the offsets directly from the @+ and @- arrays. This also expands to four-space positions:

1 while s/\t+/' ' x (($+[0] - $-[0]) * 4 - $-[0] % 4)/e;

If you're looking at all of these 1 while loops and wondering why they couldn't have been written as part of a simple s///g instead, it's because you need to recalculate the length from the start of the line again each time rather than merely from where the last match occurred.

The convention 1 while CONDITION is the same as while (CONDITION) { }, but shorter. Its origins date to when Perl ran the first incredibly faster than the second. While the second is now almost as fast, it remains convenient, and the habit has stuck.

The standard Text::Tabs module provides conversion functions to convert both directions, exports a $tabstop variable to control the number of spaces per tab, and does not incur the performance hit because it uses $1 and $2 rather than $& and $`.

use Text::Tabs;
$tabstop = 4;
while (<>) { print expand($_) }

We can also use Text::Tabs to "unexpand" the tabs. This example uses the default $tabstop value of 8:

use Text::Tabs;
while (<>) { print unexpand($_) }

1.11.4. See Also

The manpage for the Text::Tabs module; the s/// operator in perlre(1) and perlop(1); the @- and @+ variables (@LAST_MATCH_START and @LAST_MATCH_END) in Chapter 28 of Programming Perl; the section on "When a global substitution just isn't global enough" in Chapter 5 of Programming Perl

Previous | Home | Next
1.10. Treating a Unicode String as Octets | Book Index | 1.12. Expanding Variables in User Input
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.12. Expanding Variables in User Input

1.12.1. Problem

You've read a string with an embedded variable reference, such as:

You owe $debt to me.

Now you want to replace $debt in the string with its value.

1.12.2. Solution

Use a substitution with symbolic references if the variables are all globals:

$text =~ s/\$(\w+)/${$1}/g;

But use a double /ee if they might be lexical (my) variables:

$text =~ s/(\$\w+)/$1/gee;

1.12.3. Discussion

The first technique is basically to find what looks like a variable name, then use symbolic dereferencing to interpolate its contents. If $1 contains the string somevar, ${$1} will be whatever $somevar contains. This won't work if the use strict 'refs' pragma is in effect because that bans symbolic dereferencing.

Here's an example:

our ($rows, $cols);
no strict 'refs';                   # for ${$1}/g below
my $text;

($rows, $cols) = (24, 80);
$text = q(I am $rows high and $cols long);  # like single quotes!
$text =~ s/\$(\w+)/${$1}/g;
print $text;
I am 24 high and 80 long

You may have seen the /e substitution modifier used to evaluate the replacement as code rather than as a string. It's designed for situations where you don't know the exact replacement value, but you do know how to calculate it. For example, doubling every whole number in a string:

$text = "I am 17 years old";
$text =~ s/(\d+)/2 * $1/eg;

When Perl is compiling your program and sees a /e on a substitute, it compiles the code in the replacement block along with the rest of your program, long before the substitution actually happens. When a substitution is made, $1 is replaced with the string that matched. The code to evaluate would then be something like:

2 * 17

If we tried saying:

$text = 'I am $AGE years old';      # note single quotes
$text =~ s/(\$\w+)/$1/eg;           # WRONG

assuming $text held a mention of the variable $AGE, Perl would dutifully replace $1 with $AGE and then evaluate code that looked like:

'$AGE'

which just yields us our original string back again. We need to evaluate the result again to get the value of the variable. To do that, just add another /e:

$text =~ s/(\$\w+)/$1/eeg;          # finds my( ) variables

Yes, you can have as many /e modifiers as you'd like. Only the first one is compiled and syntax-checked with the rest of your program. This makes it work like the eval {BLOCK} construct, except that it doesn't trap exceptions. Think of it more as a do {BLOCK} instead.

Subsequent /e modifiers are quite different. They're more like the eval "STRING" construct. They don't get compiled until runtime. A small advantage of this scheme is that it doesn't require a no strict 'refs' pragma for the block. A tremendous advantage is that unlike symbolic dereferencing, this mechanism finds lexical variables created with my, something symbolic references can never do.

The following example uses the /x modifier to enable whitespace and comments in the pattern part of the substitute and /e to evaluate the righthand side as code. The /e modifier gives more control over what happens in case of error or other extenuating circumstances, as we have here:

# expand variables in $text, but put an error message in
# if the variable isn't defined
$text =~ s{
     \$                         # find a literal dollar sign
    (\w+)                       # find a "word" and store it in $1
}{
    no strict 'refs';           # for $$1 below
    if (defined ${$1}) {
        ${$1};                    # expand global variables only
    } else {
        "[NO VARIABLE: \$$1]";  # error msg
    }
}egx;

Once upon a time, long ago and far away, $$1 used to mean ${$}1 when it occurred within a string; that is, the $$ variable followed by a 1. This was grandfathered to work that way so you could more readily expand the $$ variable as your process ID to compose temporary filenames. It now always means ${$1}, i.e., dereference the contents of the $1 variable. We have written it the more explicit way for clarity, not correctness.

1.12.4. See Also

The s/// operator in perlre(1) and perlop(1) and Chapter 5 of Programming Perl; the eval function in perlfunc(1) and Chapter 29 of Programming Perl; the similar use of substitutions in Recipe 20.9

Previous | Home | Next
1.11. Expanding and Compressing Tabs | Book Index | 1.13. Controlling Case
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.13. Controlling Case

1.13.1. Problem

A string in uppercase needs converting to lowercase, or vice versa.

1.13.2. Solution

Use the lc and uc functions or the \L and \U string escapes.

$big = uc($little);             # "bo peep" -> "BO PEEP"
$little = lc($big);             # "JOHN"    -> "john"
$big = "\U$little";             # "bo peep" -> "BO PEEP"
$little = "\L$big";             # "JOHN"    -> "john"

To alter just one character, use the lcfirst and ucfirst functions or the \l and \u string escapes.

$big = "\u$little";             # "bo"      -> "Bo"
$little = "\l$big";             # "BoPeep"  -> "boPeep"

1.13.3. Discussion

The functions and string escapes look different, but both do the same thing. You can set the case of either just the first character or the whole string. You can even do both at once to force uppercase (actually, titlecase; see later explanation) on initial characters and lowercase on the rest.

$beast   = "dromedary";
# capitalize various parts of $beast
$capit   = ucfirst($beast);         # Dromedary
$capit   = "\u\L$beast";            # (same)
$capall  = uc($beast);              # DROMEDARY
$capall  = "\U$beast";              # (same)
$caprest = lcfirst(uc($beast));     # dROMEDARY
$caprest = "\l\U$beast";            # (same)

These capitalization-changing escapes are commonly used to make a string's case consistent:

# titlecase each word's first character, lowercase the rest
$text = "thIS is a loNG liNE";
$text =~ s/(\w+)/\u\L$1/g;
print $text;
This Is A Long Line

You can also use these for case-insensitive comparison:

if (uc($a) eq uc($b)) { # or "\U$a" eq "\U$b"
    print "a and b are the same\n";
}

The randcap program, shown in Example 1-2, randomly titlecases 20 percent of the letters of its input. This lets you converse with 14-year-old WaREz d00Dz.

Example 1-2. randcap

  #!/usr/bin/perl -p
  # randcap: filter to randomly capitalize 20% of the letters
  # call to srand( ) is unnecessary as of v5.4
  BEGIN { srand(time( ) ^ ($$ + ($$<<15))) }
  sub randcase { rand(100) < 20 ? "\u$_[0]" : "\l$_[0]" }
  s/(\w)/randcase($1)/ge;
  % randcap < genesis | head -9
  boOk 01 genesis
  001:001 in the BEginning goD created the heaven and tHe earTh.

  001:002 and the earth wAS without ForM, aND void; AnD darkneSS was
          upon The Face of the dEEp. and the spIrit of GOd movEd upOn
          tHe face of the Waters.
  001:003 and god Said, let there be ligHt: and therE wAs LigHt.

In languages whose writing systems distinguish between uppercase and titlecase, the ucfirst( ) function (and \u, its string escape alias) converts to titlecase. For example, in Hungarian the "dz" sequence occurs. In uppercase, it's written as "DZ", in titlecase as "Dz", and in lowercase as "dz". Unicode consequently has three different characters defined for these three situations:

Code point  Written   Meaning
01F1        DZ        LATIN CAPITAL LETTER DZ
01F2        Dz        LATIN CAPITAL LETTER D WITH SMALL LETTER Z
01F3        dz        LATIN SMALL LETTER DZ

It is tempting but ill-advised to just use tr[a-z][A-Z] or the like to convert case. This is a mistake because it omits all characters with diacritical markings—such as diaereses, cedillas, and accent marks—which are used in dozens of languages, including English. However, correctly handling case mappings on data with diacritical markings can be far trickier than it seems. There is no simple answer, although if everything is in Unicode, it's not all that bad, because Perl's case-mapping functions do work perfectly fine on Unicode data. See the section on The Universal Character Code in the Introduction to this chapter for more information.

1.13.4. See Also

The uc, lc, ucfirst, and lcfirst functions in perlfunc(1) and Chapter 29 of Programming Perl; \L, \U, \l, and \u string escapes in the "Quote and Quote-like Operators" section of perlop(1) and Chapter 5 of Programming Perl

Previous | Home | Next
1.12. Expanding Variables in User Input | Book Index | 1.14. Properly Capitalizing a Title or Headline
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.14. Properly Capitalizing a Title or Headline

1.14.1. Problem

You have a string representing a headline, the title of book, or some other work that needs proper capitalization.

1.14.2. Solution

Use a variant of this tc( ) titlecasing function:

INIT {
    our %nocap;
    for (qw(
            a an the
            and but or
            as at but by for from in into of off on onto per to with
        ))
    {
        $nocap{$_}++;
    }
}

sub tc {
    local $_ = shift;

    # put into lowercase if on stop list, else titlecase
    s/(\pL[\pL']*)/$nocap{$1} ? lc($1) : ucfirst(lc($1))/ge;

    s/^(\pL[\pL']*) /\u\L$1/x;  # last  word guaranteed to cap
    s/ (\pL[\pL']*)$/\u\L$1/x;  # first word guaranteed to cap

    # treat parenthesized portion as a complete title
    s/\( (\pL[\pL']*) /(\u\L$1/x;
    s/(\pL[\pL']*) \) /\u\L$1)/x;

    # capitalize first word following colon or semi-colon
    s/ ( [:;] \s+ ) (\pL[\pL']* ) /$1\u\L$2/x;

    return $_;
}

1.14.3. Discussion

The rules for correctly capitalizing a headline or title in English are more complex than simply capitalizing the first letter of each word. If that's all you need to do, something like this should suffice:

s/(\w+\S*\w*)/\u\L$1/g;

Most style guides tell you that the first and last words in the title should always be capitalized, along with every other word that's not an article, the particle "to" in an infinitive construct, a coordinating conjunction, or a preposition.

Here's a demo, this time demonstrating the distinguishing property of titlecase. Assume the tc function is as defined in the Solution.

# with apologies (or kudos) to Stephen Brust, PJF,
# and to JRRT, as always.
@data = (
            "the enchantress of \x{01F3}ur mountain",
    "meeting the enchantress of \x{01F3}ur mountain",
    "the lord of the rings: the fellowship of the ring",
);

$mask = "%-20s: %s\n";

sub tc_lame {
    local $_ = shift;
    s/(\w+\S*\w*)/\u\L$1/g;
    return $_;
}

for $datum (@data) {
    printf $mask, "ALL CAPITALS",       uc($datum);
    printf $mask, "no capitals",        lc($datum);
    printf $mask, "simple titlecase",   tc_lame($datum);
    printf $mask, "better titlecase",   tc($datum);
    print "\n";
}

ALL CAPITALS        : THE ENCHANTRESS OF DZUR MOUNTAIN
no capitals         : the enchantress of dzur mountain
simple titlecase    : The Enchantress Of Dzur Mountain
better titlecase    : The Enchantress of Dzur Mountain

ALL CAPITALS        : MEETING THE ENCHANTRESS OF DZUR MOUNTAIN
no capitals         : meeting the enchantress of dzur mountain
simple titlecase    : Meeting The Enchantress Of Dzur Mountain
better titlecase    : Meeting the Enchantress of Dzur Mountain

ALL CAPITALS        : THE LORD OF THE RINGS: THE FELLOWSHIP OF THE RING
no capitals         : the lord of the rings: the fellowship of the ring
simple titlecase    : The Lord Of The Rings: The Fellowship Of The Ring
better titlecase    : The Lord of the Rings: The Fellowship of the Ring

One thing to consider is that some style guides prefer capitalizing only prepositions that are longer than three, four, or sometimes five letters. O'Reilly & Associates, for example, keeps prepositions of four or fewer letters in lowercase. Here's a longer list of prepositions if you prefer, which you can modify to your needs:

@all_prepositions = qw{
    about above absent across after against along amid amidst
    among amongst around as at athwart before behind below
    beneath beside besides between betwixt beyond but by circa
    down during ere except for from in into near of off on onto
    out over past per since than through till to toward towards
    under until unto up upon versus via with within without
};

This kind of approach can take you only so far, though, because it doesn't distinguish between words that can be several parts of speech. Some prepositions on the list might also double as words that should always be capitalized, such as subordinating conjunctions, adverbs, or even adjectives. For example, it's "Down by the Riverside" but "Getting By on Just $30 a Day", or "A Ringing in My Ears" but "Bringing In the Sheaves".

Another consideration is that you might prefer to apply the \u or ucfirst conversion by itself without also putting the whole string into lowercase. That way a word that's already in all capital letters, such as an acronym, doesn't lose that trait. You probably wouldn't want to convert "FBI" and "LBJ" into "Fbi" and "Lbj".

1.14.4. See Also

The uc, lc, ucfirst, and lcfirst functions in perlfunc(1) and Chapter 29 of Programming Perl; the \L, \U, \l, and \u string escapes in the "Quote and Quote-like Operators" section of perlop(1) and Chapter 5 of Programming Perl

Previous | Home | Next
1.13. Controlling Case | Book Index | 1.15. Interpolating Functions and Expressions Within Strings
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.15. Interpolating Functions and Expressions Within Strings

1.15.1. Problem

You want a function call or expression to expand within a string. This lets you construct more complex templates than with simple scalar variable interpolation.

1.15.2. Solution

Break up your expression into distinct concatenated pieces:

$answer = $var1 . func( ) . $var2;   # scalar only

Or use the slightly sneaky @{[ LIST EXPR ]} or ${ \(SCALAR EXPR ) } expansions:

$answer = "STRING @{[ LIST EXPR ]} MORE STRING";
$answer = "STRING ${\( SCALAR EXPR )} MORE STRING";

1.15.3. Discussion

This code shows both techniques. The first line shows concatenation; the second shows the expansion trick:

$phrase = "I have " . ($n + 1) . " guanacos.";
$phrase = "I have ${\($n + 1)} guanacos.";

The first technique builds the final string by concatenating smaller strings, avoiding interpolation but achieving the same end. Because print effectively concatenates its entire argument list, if we were going to print $phrase, we could have just said:

print "I have ",  $n + 1, " guanacos.\n";

When you absolutely must have interpolation, you need the punctuation-riddled interpolation from the Solution. Only @, $, and \ are special within double quotes and most backquotes. (As with m// and s///, the qx( ) synonym is not subject to double-quote expansion if its delimiter is single quotes! $home = qx'echo home is $HOME'; would get the shell $HOME variable, not one in Perl.) So, the only way to force arbitrary expressions to expand is by expanding a ${ } or @{ } whose block contains a reference.

In the example:

$phrase = "I have ${\( count_em( ) )} guanacos.";

the function call within the parentheses is not in scalar context; it is still in list context. The following overrules that:

$phrase = "I have ${\( scalar count_em( ) )} guanacos.";

You can do more than simply assign to a variable after interpolation. It's a general mechanism that can be used in any double-quoted string. For instance, this example builds a string with an interpolated expression and passes the result to a function:

some_func("What you want is @{[ split /:/, $rec ]} items");

You can interpolate into a here document, as by:

die "Couldn't send mail" unless send_mail(<<"EOTEXT", $target);
To: $naughty
From: Your Bank
Cc: @{ get_manager_list($naughty) }
Date: @{[ do { my $now = `date`; chomp $now; $now } ]} (today)

Dear $naughty,

Today, you bounced check number @{[ 500 + int rand(100) ]} to us.
Your account is now closed.

Sincerely,
the management
EOTEXT

Expanding backquotes (``) is particularly challenging because you would normally end up with spurious newlines. By creating a braced block following the @ within the @{[ ]} anonymous array dereference, as in the last example, you can create private variables.

Although these techniques work, simply breaking your work up into several steps or storing everything in temporary variables is almost always clearer to the reader.

The Interpolation module from CPAN provides a more syntactically palatable covering. For example, to make elements of the hash %E evaluate and return its subscript:

use Interpolation E     => 'eval';
print "You bounced check number $E{500 + int rand(100)}\n";

Or to make a hash named %money call a suitably defined function of your choice:

use Interpolation money => \&currency_commify;

print "That will be $money{ 4 * $payment }, right now.\n";

expect to get something like:

That will be $3,232.421.04, right now.

1.15.4. See Also

perlref(1) and the "Other Tricks You Can Do with Hard References" section in Chapter 8 of Programming Perl; the Interpolation CPAN module

Previous | Home | Next
1.14. Properly Capitalizing a Title or Headline | Book Index | 1.16. Indenting Here Documents
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.16. Indenting Here Documents

1.16.1. Problem

When using the multiline quoting mechanism called a here document, the text must be flush against the margin, which looks out of place in the code. You would like to indent the here document text in the code, but not have the indentation appear in the final string value.

1.16.2. Solution

Use a s/// operator to strip out leading whitespace.

# all in one
($var = << HERE_TARGET) =~ s/^\s+//gm;
    your text
    goes here
HERE_TARGET

# or with two steps
$var = << HERE_TARGET;
    your text
    goes here
HERE_TARGET
$var =~ s/^\s+//gm;

1.16.3. Discussion

The substitution is straightforward. It removes leading whitespace from the text of the here document. The /m modifier lets the ^ character match at the start of each line in the string, and the /g modifier makes the pattern-matching engine repeat the substitution as often as it can (i.e., for every line in the here document).

($definition = << 'FINIS') =~ s/^\s+//gm;
    The five varieties of camelids
    are the familiar camel, his friends
    the llama and the alpaca, and the
    rather less well-known guanaco
    and vicuña.
FINIS

Be warned: all patterns in this recipe use \s, meaning one whitespace character, which will also match newlines. This means they will remove any blank lines in your here document. If you don't want this, replace \s with [^\S\n] in the patterns.

The substitution uses the property that the result of an assignment can be used as the lefthand side of =~. This lets us do it all in one line, but works only when assigning to a variable. When you're using the here document directly, it would be considered a constant value, and you wouldn't be able to modify it. In fact, you can't change a here document's value unless you first put it into a variable.

Not to worry, though, because there's an easy way around this, particularly if you're going to do this a lot in the program. Just write a subroutine:

sub fix {
    my $string = shift;
    $string =~ s/^\s+//gm;
    return $string;
}

print fix( << "END");
    My stuff goes here
END

# With function predeclaration, you can omit the parens:
print fix << "END";
    My stuff goes here
END

As with all here documents, you have to place this here document's target (the token that marks its end, END in this case) flush against the lefthand margin. To have the target indented also, you'll have to put the same amount of whitespace in the quoted string as you use to indent the token.

($quote = << '    FINIS') =~ s/^\s+//gm;
        ...we will have peace, when you and all your works have
        perished--and the works of your dark master to whom you would
        deliver us. You are a liar, Saruman, and a corrupter of men's
        hearts.  --Theoden in /usr/src/perl/taint.c
    FINIS
$quote =~ s/\s+--/\n--/;      #move attribution to line of its own

If you're doing this to strings that contain code you're building up for an eval, or just text to print out, you might not want to blindly strip all leading whitespace, because that would destroy your indentation. Although eval wouldn't care, your reader might.

Another embellishment is to use a special leading string for code that stands out. For example, here we'll prepend each line with @@@, properly indented:

if ($REMEMBER_THE_MAIN) {
    $perl_main_C = dequote << '    MAIN_INTERPRETER_LOOP';
        @@@ int
        @@@ runops( ) {
        @@@     SAVEI32(runlevel);
        @@@     runlevel++;
        @@@     while ( op = (*op->op_ppaddr)( ) ) ;
        @@@     TAINT_NOT;
        @@@     return 0;
        @@@ }
    MAIN_INTERPRETER_LOOP
    # add more code here if you want
}

Destroying indentation also gets you in trouble with poets.

sub dequote;
$poem = dequote << EVER_ON_AND_ON;
       Now far ahead the Road has gone,
          And I must follow, if I can,
       Pursuing it with eager feet,
          Until it joins some larger way
       Where many paths and errands meet.
          And whither then? I cannot say.
                --Bilbo in /usr/src/perl/pp_ctl.c
EVER_ON_AND_ON
print "Here's your poem:\n\n$poem\n";

Here is its sample output:

Here's your poem:

Now far ahead the Road has gone,
   And I must follow, if I can,
Pursuing it with eager feet,
   Until it joins some larger way
Where many paths and errands meet.
   And whither then? I cannot say.
         --Bilbo in /usr/src/perl/pp_ctl.c

The following dequote function handles all these cases. It expects to be called with a here document as its argument. It checks whether each line begins with a common substring, and if so, strips that off. Otherwise, it takes the amount of leading whitespace found on the first line and removes that much from each subsequent line.

sub dequote {
    local $_ = shift;
    my ($white, $leader);  # common whitespace and common leading string
    if (/^\s*(?:([^\w\s]+)(\s*).*\n)(?:\s*\1\2?.*\n)+$/) {
        ($white, $leader) = ($2, quotemeta($1));
    } else {
        ($white, $leader) = (/^(\s+)/, '');
    }
    s/^\s*?$leader(?:$white)?//gm;
    return $_;
}

If that pattern makes your eyes glaze over, you could always break it up and add comments by adding /x:

if (m{
            ^                       # start of line
            \s *                    # 0 or more whitespace chars
            (?:                     # begin first non-remembered grouping
                 (                  #   begin save buffer $1
                    [^\w\s]         #     one character neither space nor word
                    +               #     1 or more of such
                 )                  #   end save buffer $1
                 ( \s* )            #   put 0 or more white in buffer $2
                 .* \n              #   match through the end of first line
             )                      # end of first grouping
             (?:                    # begin second non-remembered grouping
                \s *                #   0 or more whitespace chars
                \1                  #   whatever string is destined for $1
                \2 ?                #   what'll be in $2, but optionally
                .* \n               #   match through the end of the line
             ) +                    # now repeat that group idea 1 or more
             $                      # until the end of the line
          }x
       )
    {
        ($white, $leader) = ($2, quotemeta($1));
    } else {
        ($white, $leader) = (/^(\s+)/, '');
    }
    s{
         ^                          # start of each line (due to /m)
         \s *                       # any amount of leading whitespace
            ?                       #   but minimally matched
         $leader                    # our quoted, saved per-line leader
         (?:                        # begin unremembered grouping
            $white                  #    the same amount
         ) ?                        # optionalize in case EOL after leader
    }{  }xgm;

There, isn't that much easier to read? Well, maybe not; sometimes it doesn't help to pepper your code with insipid comments that mirror the code. This may be one of those cases.

1.16.4. See Also

The "Scalar Value Constructors" section of perldata(1) and the section on "Here Documents" in Chapter 2 of Programming Perl; the s/// operator in perlre(1) and perlop(1), and the "Pattern Matching" section in Chapter 5 of Programming Perl

Previous | Home | Next
1.15. Interpolating Functions and Expressions Within Strings | Book Index | 1.17. Reformatting Paragraphs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.17. Reformatting Paragraphs

1.17.1. Problem

Your string is too big to fit the screen, and you want to break it up into lines of words, without splitting a word between lines. For instance, a style correction script might read a text file a paragraph at a time, replacing bad phrases with good ones. Replacing a phrase like utilizes the inherent functionality of with uses will change the length of lines, so it must somehow reformat the paragraphs when they're output.

1.17.2. Solution

Use the standard Text::Wrap module to put line breaks at the right place:

use Text::Wrap;
@output = wrap($leadtab, $nexttab, @para);

Or use the more discerning CPAN module, Text::Autoformat, instead:

use Text::Autoformat;
$formatted = autoformat $rawtext;

1.17.3. Discussion

The Text::Wrap module provides the wrap function, shown in Example 1-3, which takes a list of lines and reformats them into a paragraph with no line more than $Text::Wrap::columns characters long. We set $columns to 20, ensuring that no line will be longer than 20 characters. We pass wrap two arguments before the list of lines: the first is the indent for the first line of output, the second the indent for every subsequent line.

Example 1-3. wrapdemo

  #!/usr/bin/perl -w
  # wrapdemo - show how Text::Wrap works
  @input = ("Folding and splicing is the work of an editor,",
            "not a mere collection of silicon",
            "and",
            "mobile electrons!");
  use Text::Wrap qw($columns &wrap);
  $columns = 20;
  print "0123456789" x 2, "\n";
  print wrap("    ", "  ", @input), "\n";

The result of this program is:

01234567890123456789
    Folding and
  splicing is the
  work of an
  editor, not a
  mere collection
  of silicon and
  mobile electrons!

We get back a single string, with newlines ending each line but the last:

# merge multiple lines into one, then wrap one long line
use Text::Wrap;
undef $/;
print wrap('', '', split(/\s*\n\s*/, <>));

If you have the Term::ReadKey module (available from CPAN) on your system, you can determine your window size so you can wrap lines to fit the current screen size. If you don't have the module, sometimes the screen size can be found in $ENV{COLUMNS} or by parsing the output of the stty(1) command.

The following program tries to reformat both short and long lines within a paragraph, similar to the fmt(1) program, by setting the input record separator $/ to the empty string (causing <> to read paragraphs) and the output record separator $\ to two newlines. Then the paragraph is converted into one long line by changing all newlines and any surrounding whitespace to single spaces. Finally, we call the wrap function with leading and subsequent tab strings set to the empty string so we can have block paragraphs.

use Text::Wrap      qw(&wrap $columns);
use Term::ReadKey   qw(GetTerminalSize);
($columns) = GetTerminalSize( );
($/, $\)  = ('', "\n\n");   # read by paragraph, output 2 newlines
while (<>) {                # grab a full paragraph
    s/\s*\n\s*/ /g;         # convert intervening newlines to spaces
    print wrap('', '', $_); # and format
}

The CPAN module Text::Autoformat is much more clever. For one thing, it tries to avoid "widows," that is, very short lines at the end. More remarkably, it correctly copes with reformatting paragraphs that have multiple, deeply nested citations. An example from that module's manpage shows how the module can painlessly convert:

In comp.lang.perl.misc you wrote:
: > <CN = Clooless Noobie> writes:
: > CN> PERL sux because:
: > CN>    * It doesn't have a switch statement and you have to put $
: > CN>signs in front of everything
: > CN>    * There are too many OR operators: having |, || and 'or'
: > CN>operators is confusing
: > CN>    * VB rools, yeah!!!!!!!!!
: > CN> So anyway, how can I stop reloads on a web page?
: > CN> Email replies only, thanks - I don't read this newsgroup.
: >
: > Begone, sirrah! You are a pathetic, Bill-loving, microcephalic
: > script-infant.
: Sheesh, what's with this group - ask a question, get toasted! And how
: *dare* you accuse me of Ianuphilia!

into:

In comp.lang.perl.misc you wrote:
: > <CN = Clooless Noobie> writes:
: > CN> PERL sux because:
: > CN>    * It doesn't have a switch statement and you
: > CN>      have to put $ signs in front of everything
: > CN>    * There are too many OR operators: having |, ||
: > CN>      and 'or' operators is confusing
: > CN>    * VB rools, yeah!!!!!!!!! So anyway, how can I
: > CN>      stop reloads on a web page? Email replies
: > CN>      only, thanks - I don't read this newsgroup.
: >
: > Begone, sirrah! You are a pathetic, Bill-loving,
: > microcephalic script-infant.
: Sheesh, what's with this group - ask a question, get toasted!
: And how *dare* you accuse me of Ianuphilia!

simply via print autoformat($badparagraph). Pretty impressive, eh?

Here's a miniprogram that uses that module to reformat each paragraph of its input stream:

use Text::Autoformat;
$/ = '';
while (<>) {
    print autoformat($_, {squeeze => 0, all => 1}), "\n";
}

1.17.4. See Also

The split and join functions in perlfunc(1) and Chapter 29 of Programming Perl; the manpage for the standard Text::Wrap module; the CPAN module Term::ReadKey, and its use in Recipe 15.6 and the CPAN module Text::Autoformat

Previous | Home | Next
1.16. Indenting Here Documents | Book Index | 1.18. Escaping Characters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.18. Escaping Characters

1.18.1. Problem

You need to output a string with certain characters (quotes, commas, etc.) escaped. For instance, you're producing a format string for sprintf and want to convert literal % signs into %%.

1.18.2. Solution

Use a substitution to backslash or double each character to be escaped:

# backslash
$var =~ s/([CHARLIST])/\\$1/g;

# double
$var =~ s/([CHARLIST])/$1$1/g;

1.18.3. Discussion

$var is the variable to be altered. The CHARLIST is a list of characters to escape and can contain backslash escapes like \t and \n. If you just have one character to escape, omit the brackets:

$string =~ s/%/%%/g;

The following code lets you do escaping when preparing strings to submit to the shell. (In practice, you would need to escape more than just ' and " to make any arbitrary string safe for the shell. Getting the list of characters right is so hard, and the risks if you get it wrong are so great, that you're better off using the list form of system and exec to run programs, shown in Recipe 16.2. They avoid the shell altogether.)

$string = q(Mom said, "Don't do that.");
$string =~ s/(['"])/\\$1/g;

We had to use two backslashes in the replacement because the replacement section of a substitution is read as a double-quoted string, and to get one backslash, you need to write two. Here's a similar example for VMS DCL, where you need to double every quote to get one through:

$string = q(Mom said, "Don't do that.");
$string =~ s/(['"])/$1$1/g;

Microsoft command interpreters are harder to work with. In Windows, COMMAND.COM recognizes double quotes but not single ones, disregards backquotes for running commands, and requires a backslash to make a double quote into a literal. Any of the many free or commercial Unix-like shell environments available for Windows will work just fine, though.

Because we're using character classes in the regular expressions, we can use - to define a range and ^ at the start to negate. This escapes all characters that aren't in the range A through Z.

$string =~ s/([^A-Z])/\\$1/g;

In practice, you wouldn't want to do that, since it would pick up a lowercase "a" and turn it into "\a", for example, which is ASCII BEL character. (Usually when you mean non-alphabetic characters, \PL works better.)

If you want to escape all non-word characters, use the \Q and \E string metacharacters or the quotemeta function. For example, these are equivalent:

$string = "this \Qis a test!\E";
$string = "this is\\ a\\ test\\!";
$string = "this " . quotemeta("is a test!");

1.18.4. See Also

The s/// operator in perlre(1) and perlop(1) and Chapter 5 of Programming Perl; the quotemeta function in perlfunc(1) and Chapter 29 of Programming Perl; the discussion of HTML escaping in Recipe 19.1; Recipe 19.5 for how to avoid having to escape strings to give the shell

Previous | Home | Next
1.17. Reformatting Paragraphs | Book Index | 1.19. Trimming Blanks from the Ends of a String
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.19. Trimming Blanks from the Ends of a String

1.19.1. Problem

You have read a string that may have leading or trailing whitespace, and you want to remove it.

1.19.2. Solution

Use a pair of pattern substitutions to get rid of them:

$string =~ s/^\s+//;
$string =~ s/\s+$//;

Or write a function that returns the new value:

$string = trim($string);
@many   = trim(@many);

sub trim {
    my @out = @_;
    for (@out) {
        s/^\s+//;          # trim left
        s/\s+$//;          # trim right
    }
    return @out =  = 1
              ? $out[0]   # only one to return
              : @out;     # or many
}

1.19.3. Discussion

This problem has various solutions, but this one is the most efficient for the common case. This function returns new versions of the strings passed in to it with their leading and trailing whitespace removed. It works on both single strings and lists.

To remove the last character from the string, use the chop function. Be careful not to confuse this with the similar but different chomp function, which removes the last part of the string contained within that variable if and only if it is contained in the $/ variable, "\n" by default. These are often used to remove the trailing newline from input:

# print what's typed, but surrounded by > < symbols
while (<STDIN>) {
    chomp;
    print ">$_<\n";
}

This function can be embellished in any of several ways.

First, what should you do if several strings are passed in, but the return context demands a single scalar? As written, the function given in the Solution does a somewhat silly thing: it (inadvertently) returns a scalar representing the number of strings passed in. This isn't very useful. You could issue a warning or raise an exception. You could also squash the list of return values together.

For strings with spans of extra whitespace at points other than their ends, you could have your function collapse any remaining stretch of whitespace characters in the interior of the string down to a single space each by adding this line as the new last line of the loop:

s/\s+/ /g;                # finally, collapse middle

That way a string like " but\t\tnot here\n" would become "but not here". A more efficient alternative to the three substitution lines:

s/^\s+//;
s/\s+$//;
s/\s+/ /g;

would be:

$_ = join(' ', split(' '));

If the function isn't passed any arguments at all, it could act like chop and chomp by defaulting to $_. Incorporating all of these embellishments produces this function:

# 1. trim leading and trailing white space
# 2. collapse internal whitespace to single space each
# 3. take input from $_ if no arguments given
# 4. join return list into single scalar with intervening spaces
#     if return is scalar context

sub trim {
    my @out = @_ ? @_ : $_;
    $_ = join(' ', split(' ')) for @out;
    return wantarray ? @out : "@out";
}

1.19.4. See Also

The s/// operator in perlre(1) and perlop(1) and Chapter 5 of Programming Perl; the chomp and chop functions in perlfunc(1) and Chapter 29 of Programming Perl; we trim leading and trailing whitespace in the getnum function in Recipe 2.1

Previous | Home | Next
1.18. Escaping Characters | Book Index | 1.20. Parsing Comma-Separated Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.20. Parsing Comma-Separated Data

1.20.1. Problem

You have a data file containing comma-separated values that you need to read, but these data fields may have quoted commas or escaped quotes in them. Most spreadsheets and database programs use comma-separated values as a common interchange format.

1.20.2. Solution

If your data file follows normal Unix quoting and escaping conventions, where quotes within a field are backslash-escaped "like \"this\"", use the standard Text::ParseWords and this simple code:

use Text::ParseWords;
sub parse_csv0 {
    return quotewords("," => 0, $_[0]);
}

However, if quotes within a field are doubled "like ""this""", you could use the following procedure from Mastering Regular Expressions, Second Edition:

sub parse_csv1 {
    my $text = shift;      # record containing comma-separated values
    my @fields  = ( );

    while ($text =~ m{
        # Either some non-quote/non-comma text:
        ( [^"',] + )

         # ...or...
         |

        # ...a double-quoted field: (with "" allowed inside)

        " # field's opening quote; don't save this
         (   now a field is either
          (?:     [^"]    # non-quotes or
              |
                  ""      # adjacent quote pairs
           ) *  # any number
         )
        " # field's closing quote; unsaved

    }gx)
    {
      if (defined $1) {
          $field = $1;
      } else {
          ($field = $2) =~ s/""/"/g;
      }
      push @fields, $field;
    }
    return @fields;
}

Or use the CPAN Text:CSV module:

use Text::CSV;
sub parse_csv1 {
    my $line = shift;
    my $csv = Text::CSV->new( );
    return $csv->parse($line) && $csv->fields( );
}

Or use the CPAN Tie::CSV_File module:

tie @data, "Tie::CSV_File", "data.csv";

for ($i = 0; $i < @data; $i++) {
    printf "Row %d (Line %d) is %s\n", $i, $i+1, "@{$data[$i]}";
    for ($j = 0; $j < @{$data[$i]}; $j++) {
        print "Column $j is <$data[$i][$j]>\n";
    }
}

1.20.3. Discussion

Comma-separated input is a deceptive and complex format. It sounds simple, but involves a fairly complex escaping system because the fields themselves can contain commas. This makes the pattern-matching solution complex and rules out a simple split /,/. Still worse, quoting and escaping conventions vary between Unix-style files and legacy systems. This incompatibility renders impossible any single algorithm for all CSV data files.

The standard Text::ParseWords module is designed to handle data whose quoting and escaping conventions follow those found in most Unix data files. This makes it eminently suitable for parsing the numerous colon-separated data files found on Unix systems, including disktab(5), gettytab(5), printcap(5), and termcap(5). Pass that module's quotewords function two arguments and the CSV string. The first argument is the separator (here a comma, but often a colon), and the second is a true or false value controlling whether the strings are returned with quotes around them.

In this style of data file, you represent quotation marks inside a field delimited by quotation marks by escaping them with backslashes "like\"this\"". Quotation marks and backslashes are the only characters that have meaning when backslashed. Any other use of a backslash will be left in the output string. The standard Text::ParseWords module's quotewords( ) function can handle such data.

However, it's of no use on data files from legacy systems that represent quotation marks inside such a field by doubling them "like""this""". For those, you'll need one of the other solutions. The first of these is based on the regular expression from Mastering Regular Expressions, Second Edition, by Jeffrey E. F. Friedl (O'Reilly). It enjoys the advantage of working on any system without requiring installation of modules not found in the standard distribution. In fact, it doesn't use any modules at all. Its slight disadvantage is the risk of sending the unseasoned reader into punctuation shock, despite its copious commenting.

The object-oriented CPAN module Text::CSV demonstrated in the next solution hides that parsing complexity in more easily digestible wrappers. An even more elegant solution is offered by the Tie::CSV_File module from CPAN, in which you are given what appears to be a two-dimensional array. The first dimension represents each line of the file, and the second dimension each column on each row.

Here's how you'd use our two kinds of parse_csv subroutines. The q( ) is just a fancy quote so we didn't have to backslash everything.

$line = q(XYZZY,"","O'Reilly, Inc","Wall, Larry","a \"glug\" bit,",5,"Error, Core
Dumped");
@fields = parse_csv0($line);
for ($i = 0; $i < @fields; $i++) {
    print "$i : $fields[$i]\n";
}

0 : XYZZY
1 :
2 : O'Reilly, Inc
3 : Wall, Larry
4 : a "glug" bit,
5 : 5
6 : Error, Core Dumped

If the second argument to quotewords had been 1 instead of 0, the quotes would have been retained, producing this output instead:

0 : XYZZY
1 : ""
2 : "O'Reilly, Inc"
3 : "Wall, Larry"
4 : "a \"glug\" bit,"
5 : 5
6 : "Error, Core Dumped"

The other sort of data file is manipulated the same way, but using our parse_csv1 function instead of parse_csv0. Notice how the embedded quotes are doubled, not escaped.

$line = q(Ten Thousand,10000, 2710 ,,"10,000","It's ""10 Grand"", baby",10K);
@fields = parse_csv1($line);
for ($i = 0; $i < @fields; $i++) {
    print "$i : $fields[$i]\n";
}

0 : Ten Thousand
1 : 10000
2 :  2710
3 :
4 : 10,000
5 : It's "10 Grand", baby
6 : 10K

1.20.4. See Also

The explanation of regular expression syntax in perlre(1) and Chapter 5 of Programming Perl; the documentation for the standard Text::ParseWords module; the section on "Parsing CSV Files" in Chapter 5 of Mastering Regular Expressions, Second Edition

Previous | Home | Next
1.19. Trimming Blanks from the Ends of a String | Book Index | 1.21. Constant Variables
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.21. Constant Variables

1.21.1. Problem

You want a variable whose value cannot be modified once set.

1.21.2. Solution

If you don't need it to be a scalar variable that can interpolate, the use constant pragma will work:

use constant AVOGADRO => 6.02252e23;

printf "You need %g of those for guac\n", AVOGADRO;

If it does have to be a variable, assign to the typeglob a reference to a literal string or number, then use the scalar variable:

*AVOGADRO = \6.02252e23;
print "You need $AVOGADRO of those for guac\n";

But the most foolproof way is via a small tie class whose STORE method raises an exception:

package Tie::Constvar;
use Carp;
sub TIESCALAR {
    my ($class, $initval) = @_;
    my $var = $initval;
    return bless \$var => $class;
}
sub FETCH {
    my $selfref = shift;
    return $$selfref;
}
sub STORE {
    confess "Meddle not with the constants of the universe";
}

1.21.3. Discussion

The use constant pragma is the easiest to use, but has a few drawbacks. The biggest one is that it doesn't give you a variable that you can expand in double-quoted strings. Another is that it isn't scoped; it puts a subroutine of that name into the package namespace.

The way the pragma really works is to create a subroutine of that name that takes no arguments and always returns the same value (or values if a list is provided). That means it goes into the current package's namespace and isn't scoped. You could do the same thing yourself this way:

sub AVOGADRO( ) { 6.02252e23 }

If you wanted it scoped to the current block, you could make a temporary subroutine by assigning an anonymous subroutine to the typeglob of that name:

use subs qw(AVOGADRO);
local *AVOGADRO = sub ( ) { 6.02252e23 };

But that's pretty magical, so you should comment the code if you don't plan to use the pragma.

If instead of assigning to the typeglob a reference to a subroutine, you assign to it a reference to a constant scalar, then you'll be able to use the variable of that name. That's the second technique given in the Solution. Its disadvantage is that typeglobs are available only for package variables, not for lexicals created via my. Under the recommended use strict pragma, an undeclared package variable will get you into trouble, too, but you can declare the variable using our:

our $AVOGADRO;
local *AVOGADRO = \6.02252e23;

The third solution provided, that of creating your own little tie class, might appear the most complicated, but it provides the most flexibility. Plus you get to declare it as a lexical if you want.

tie my $AVOGADRO, Tie::Constvar, 6.02252e23;

After which this is okay:

print "You need $AVOGADRO of those for guac\n";

But this will get you in trouble:

$AVOGADRO = 6.6256e-34;   # sorry, Max

1.21.4. See Also

Recipe 1.15; Recipe 5.3; the discussion on folding constant subroutines toward the end of the section on "Compiling Your Code" in Chapter 18 of Programming Perl; the CPAN module Tie::Scalar::RestrictUpdates might give you some other ideas

Previous | Home | Next
1.20. Parsing Comma-Separated Data | Book Index | 1.22. Soundex Matching
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.22. Soundex Matching

1.22.1. Problem

You have two English surnames and want to know whether they sound somewhat similar, regardless of spelling. This would let you offer users a "fuzzy search" of names in a telephone book to catch "Smith" and "Smythe" and others within the set, such as "Smite" and "Smote".

1.22.2. Solution

Use the standard Text::Soundex module:

use Text::Soundex;
$CODE  = soundex($STRING);
@CODES = soundex(@LIST);

Or use the CPAN module Text::Metaphone:

use Text::Metaphone;
$phoned_words = Metaphone('Schwern');

1.22.3. Discussion

The soundex algorithm hashes words (particularly English surnames) into a small space using a simple model that approximates an English speaker's pronunciation of the words. Roughly speaking, each word is reduced to a four-character string. The first character is an uppercase letter; the remaining three are digits. By comparing the soundex values of two strings, we can guess whether they sound similar.

The following program prompts for a name and looks for similarly sounding names from the password file. This same approach works on any database with names, so you could key the database on the soundex values if you wanted to. Such a key wouldn't be unique, of course.

use Text::Soundex;
use User::pwent;

print "Lookup user: ";
chomp($user =<STDIN>);
exit unless defined $user;
$name_code = soundex($user);

while ($uent = getpwent( )) {
    ($firstname, $lastname) = $uent->gecos =~ /(\w+)[^,]*\b(\w+)/;

    if ($name_code eq soundex($uent->name) ||
        $name_code eq soundex($lastname)   ||
        $name_code eq soundex($firstname)  )
    {
        printf "%s: %s %s\n", $uent->name, $firstname, $lastname;
    }
}

The Text::Metaphone module from CPAN addresses the same problem in a different and better way. The soundex function returns a letter and a three-digit code that maps just the beginning of the input string, whereas Metaphone returns a code as letters of variable length. For example:

                            soundex  metaphone

    Christiansen            C623     KRSXNSN
    Kris Jenson             K625     KRSJNSN

    Kyrie Eleison           K642     KRLSN
    Curious Liaison         C624     KRSLSN

To get the most of Metaphone, you should also use the String::Approx module from CPAN, described more fully in Recipe 6.13. It allows for there to be errors in the match and still be successful. The edit distance is the number of changes needed to go from one string to the next. This matches a pair of strings with an edit distance of two:

if (amatch("string1", [2], "string2") {  }

There's also an adist function that reports the edit distance. The edit distance between "Kris Jenson" "Christiansen" is 6, but between their Metaphone encodings is only 1. Likewise, the distance between the other pair is 8 originally, but down to 1 again if you compare Metaphone encodings.

use Text::Metaphone qw(Metaphone);
use String::Approx  qw(amatch);

if (amatch(Metaphone($s1), [1], Metaphone($s1)) {
    print "Close enough!\n";
}

This would successfully match both of our example pairs.

1.22.4. See Also

The documentation for the standard Text::Soundex and User::pwent modules; the Text::Metaphone and String::Approx modules from CPAN; your system's passwd(5) manpage; Volume 3, Chapter 6 of The Art of Computer Programming, by Donald E. Knuth (Addison-Wesley)

Previous | Home | Next
1.21. Constant Variables | Book Index | 1.23. Program: fixstyle
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.23. Program: fixstyle

Imagine you have a table with both old and new strings, such as the following:

Old words | New words
bonnet | hood
rubber | eraser
lorry | truck
trousers | pants

The program in Example 1-4 is a filter that changes all occurrences of each element in the first set to the corresponding element in the second set.

When called without filename arguments, the program is a simple filter. If filenames are supplied on the command line, an in-place edit writes the changes to the files, with the original versions saved in a file with a ".orig" extension. See Recipe 7.16 for a description. A -v command-line option writes notification of each change to standard error.

The table of original strings and their replacements is stored below _ _END_ _ in the main program, as described in Recipe 7.12. Each pair of strings is converted into carefully escaped substitutions and accumulated into the $code variable like the popgrep2 program in Recipe 6.10.

A -t check to test for an interactive run check tells whether we're expecting to read from the keyboard if no arguments are supplied. That way if users forget to give an argument, they aren't wondering why the program appears to be hung.

Example 1-4. fixstyle

    #!/usr/bin/perl -w
    # fixstyle - switch first set of <DATA> strings to second set
    #   usage: $0 [-v] [files ...]
    use strict;
    my $verbose = (@ARGV && $ARGV[0] eq '-v' && shift);
    if (@ARGV) {
      $^I = ".orig";          # preserve old files
    } else {
      warn "$0: Reading from stdin\n" if -t STDIN;
    }
    my $code = "while (<>) {\n";
    # read in config, build up code to eval
    while (<DATA>) {
      chomp;
      my ($in, $out) = split /\s*=>\s*/;
      next unless $in && $out;
      $code .= "s{\\Q$in\\E}{$out}g";
      $code .= "&& printf STDERR qq($in => $out at \$ARGV line \$.\\n)"
                                                          if $verbose;
      $code .= ";\n";
    }
    $code .= "print;\n}\n";
    eval "{ $code } 1" || die;
    _ _END_ _
    analysed        => analyzed
    built-in        => builtin
    chastized       => chastised
    commandline     => command-line
    de-allocate     => deallocate
    dropin          => drop-in
    hardcode        => hard-code
    meta-data       => metadata
    multicharacter  => multi-character
    multiway        => multi-way
    non-empty       => nonempty
    non-profit      => nonprofit
    non-trappable   => nontrappable
    pre-define      => predefine
    preextend       => pre-extend
    re-compiling    => recompiling
    reenter         => re-enter
    turnkey         => turn-key

One caution: this program is fast, but it doesn't scale if you need to make hundreds of changes. The larger the DATA section, the longer it takes. A few dozen changes won't slow it down, and in fact, the version given in Example 1-4 is faster for that case. But if you run the program on hundreds of changes, it will bog down.

Example 1-5 is a version that's slower for few changes but faster when there are many changes.

Example 1-5. fixstyle2

    #!/usr/bin/perl -w
    # fixstyle2 - like fixstyle but faster for many many changes
    use strict;
    my $verbose = (@ARGV && $ARGV[0] eq '-v' && shift);
    my %change = ( );
    while (<DATA>) {
      chomp;
      my ($in, $out) = split /\s*=>\s*/;
      next unless $in && $out;
      $change{$in} = $out;
    }
    if (@ARGV) {
      $^I = ".orig";
    } else {
      warn "$0: Reading from stdin\n" if -t STDIN;
    }
    while (<>) {
      my $i = 0;
      s/^(\s+)// && print $1;         # emit leading whitespace
      for (split /(\s+)/, $_, -1) {   # preserve trailing whitespace
          print( ($i++ & 1) ? $_ : ($change{$_} || $_));
      }
    }
    _ _END_ _
    analysed        => analyzed
    built-in        => builtin
    chastized       => chastised
    commandline     => command-line
    de-allocate     => deallocate
    dropin          => drop-in
    hardcode        => hard-code
    meta-data       => metadata
    multicharacter  => multi-character
    multiway        => multi-way
    non-empty       => nonempty
    non-profit      => nonprofit
    non-trappable   => nontrappable
    pre-define      => predefine
    preextend       => pre-extend
    re-compiling    => recompiling
    reenter         => re-enter
    turnkey         => turn-key

This version breaks each line into chunks of whitespace and words, which isn't a fast operation. It then uses those words to look up their replacements in a hash, which is much faster than a substitution. So the first part is slower, the second faster. The difference in speed depends on the number of matches.

If you don't care about keeping the whitespace separating each word constant, the second version can run as fast as the first, even for a few changes. If you know a lot about your input, collapse whitespace into single blanks by plugging in this loop:

# very fast, but whitespace collapse
while (<>) {
  for (split) {
      print $change{$_} || $_, " ";
  }
  print "\n";
}

That leaves an extra blank at the end of each line. If that's a problem, you could use the technique from Recipe 16.5 to install an output filter. Place the following code in front of the while loop that's collapsing whitespace:

my $pid = open(STDOUT, "|-");
die "cannot fork: $!" unless defined $pid;
unless ($pid) {             # child
      while (<STDIN>) {
      s/ $//;
      print;
  }
  exit;
}
Previous | Home | Next
1.22. Soundex Matching | Book Index | 1.24. Program: psgrep
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.24. Program: psgrep

Many programs, including ps, netstat, lsof, ls -l, find -ls, and tcpdump, can produce more output than can be conveniently summarized. Logfiles also often grow too long to be easily viewed. You could send these through a filter like grep to pick out only certain lines, but regular expressions and complex logic don't mix well; just look at the hoops we jump through in Recipe 6.18.

What we'd really like is to make full queries on the program output or logfile. For example, to ask ps something like, "Show me all processes that exceed 10K in size but which aren't running as the superuser" or "Which commands are running on pseudo-ttys?"

The psgrep program does this—and infinitely more—because the specified selection criteria are not mere regular expressions; they're full Perl code. Each criterion is applied in turn to every line of output. Only lines matching all arguments are output. The following is a list of things to find and how to find them.

Lines containing "sh" at the end of a word:

% psgrep '/sh\b/'

Processes whose command names end in "sh":

% psgrep 'command =~ /sh$/'

Processes running with a user ID below 10:

% psgrep 'uid < 10'

Login shells with active ttys:

% psgrep 'command =~ /^-/' 'tty ne "?"'

Processes running on pseudo-ttys:

% psgrep 'tty =~ /^[p-t]/'

Non-superuser processes running detached:

% psgrep 'uid && tty eq "?"'

Huge processes that aren't owned by the superuser:

% psgrep 'size > 10 * 2**10' 'uid != 0'

The last call to psgrep produced the following output when run on our system. As one might expect, only netscape and its spawn qualified.

 FLAGS   UID   PID  PPID PRI  NI   SIZE   RSS WCHAN     STA TTY TIME COMMAND
     0   101  9751     1   0   0  14932  9652 do_select S   p1  0:25 netscape
100000   101  9752  9751   0   0  10636   812 do_select S   p1  0:00 (dns helper)

Example 1-6 shows the psgrep program.

Example 1-6. psgrep

    #!/usr/bin/perl -w
    # psgrep - print selected lines of ps output by
    #          compiling user queries into code
    use strict;
    # each field from the PS header
    my @fieldnames = qw(FLAGS UID PID PPID PRI NICE SIZE
                      RSS WCHAN STAT TTY TIME COMMAND);
    # determine the unpack format needed (hard-coded for Linux ps)
    my $fmt = cut2fmt(8, 14, 20, 26, 30, 34, 41, 47, 59, 63, 67, 72);
    my %fields;                         # where the data will store
    die << Thanatos unless @ARGV;
    usage: $0 criterion ...
      Each criterion is a Perl expression involving:
       @fieldnames
      All criteria must be met for a line to be printed.
    Thanatos
    # Create function aliases for uid, size, UID, SIZE, etc.
    # Empty parens on
    closure args needed for void prototyping.
    for my $name (@fieldnames) {
      no strict 'refs';
      *$name = *{lc $name} = sub ( ) { $fields{$name} };
    }
    my $code = "sub is_desirable { " . join(" and ", @ARGV) . " } ";
    unless (eval $code.1) {
      die "Error in code: $@\n\t$code\n";
    }
    open(PS, "ps wwaxl |")              || die "cannot fork: $!";
    print scalar <PS>;                  # emit header line
    while (<PS>) {
      @fields{@fieldnames} = trim(unpack($fmt, $_));
      print if is_desirable( );        # line matches their criteria
    }
    close(PS)                           || die "ps failed!";
    # convert cut positions to unpack format
    sub cut2fmt {
      my(@positions) = @_;
      my $template  = '';
      my $lastpos   = 1;
      for my $place (@positions) {
          $template .= "A" . ($place - $lastpos) . " ";
          $lastpos   = $place;
      }
      $template .= "A*";
      return $template;
    }
    sub trim {
      my @strings = @_;
      for (@strings) {
          s/^\s+//;
          s/\s+$//;
      }
      return wantarray ? @strings : $strings[0];
    }
    # the following was used to determine column cut points.
    # sample input data follows
    #123456789012345678901234567890123456789012345678901234567890123456789012345
    #         1         2         3         4         5         6         7
    # Positioning:
    #       8     14    20    26  30  34     41    47          59  63  67   72
    #       |     |     |     |   |   |      |     |           |   |   |    |
    _ _END_ _
   FLAGS   UID   PID  PPID PRI  NI   SIZE   RSS WCHAN       STA TTY TIME COMMAND
     100     0     1     0   0   0    760   432 do_select   S   ?   0:02 init
     140     0   187     1   0   0    784   452 do_select   S   ?   0:02 syslogd
  100100   101   428     1   0   0   1436   944 do_exit     S    1  0:00 /bin/login
  100140    99 30217   402   0   0   1552  1008 posix_lock_ S   ?   0:00 httpd
       0   101   593   428   0   0   1780  1260 copy_thread S    1  0:00 -tcsh
  100000   101 30639  9562  17   0    924   496             R   p1  0:00 ps axl
       0   101 25145  9563   0   0   2964  2360 idetape_rea S   p2  0:06 trn
  100100     0 10116  9564   0   0   1412   928 setup_frame T   p3  0:00 ssh -C www
  100100     0 26560 26554   0   0   1076   572 setup_frame T   p2  0:00 less
  100000   101 19058  9562   0   0   1396   900 setup_frame T   p1  0:02 nvi /tmp/a

The psgrep program integrates many techniques presented throughout this book. Stripping strings of leading and trailing whitespace is found in Recipe 1.19. Converting cut marks into an unpack format to extract fixed fields is in Recipe 1.1. Matching strings with regular expressions is the entire topic of Chapter 6.

The multiline string in the here document passed to die is discussed in Recipe 1.15 and Recipe 1.16. The assignment to @fields{@fieldnames} sets many values at once in the hash named %fields. Hash slices are discussed in Recipe 4.8 and Recipe 5.11.

The sample program input contained beneath _ _END_ _ is described in Recipe 7.12. During development, we used canned input from the DATA filehandle for testing purposes. Once the program worked properly, we changed it to read from a piped-in ps command but left a remnant of the original filter input to aid in future porting and maintenance. Launching other programs over a pipe is covered in Chapter 16, including Recipe 16.10 and Recipe 16.13.

The real power and expressiveness in psgrep derive from Perl's use of string arguments not as mere strings but directly as Perl code. This is similar to the technique in Recipe 9.9, except that in psgrep, the user's arguments are wrapped with a routine called is_desirable. That way, the cost of compiling strings into Perl code happens only once, before the program whose output we'll process is even begun. For example, asking for UIDs under 10 creates this string to eval:

eval "sub is_desirable { uid < 10 } " . 1;

The mysterious ".1" at the end is so that if the user code compiles, the whole eval returns true. That way we don't even have to check $@ for compilation errors as we do in Recipe 10.12.

Specifying arbitrary Perl code in a filter to select records is a breathtakingly powerful approach, but it's not entirely original. Perl owes much to the awk programming language, which is often used for such filtering. One problem with awk is that it can't easily treat input as fixed-size fields instead of fields separated by something. Another is that the fields are not mnemonically named: awk uses $1, $2, etc. Plus, Perl can do much that awk cannot.

The user criteria don't even have to be simple expressions. For example, this call initializes a variable $id to user nobody's number to use later in its expression:

% psgrep 'no strict "vars";
        BEGIN { $id = getpwnam("nobody") }
        uid =  = $id '

How can we use unquoted words without even a dollar sign, like uid, command, and size, to represent those respective fields in each input record? We directly manipulate the symbol table by assigning closures to indirect typeglobs, which creates functions with those names. The function names are created using both uppercase and lowercase names, allowing both "UID < 10" and "uid > 10". Closures are described in Recipe 11.4, and assigning them to typeglobs to create function aliases is shown in Recipe 10.14.

One twist here not seen in those recipes is empty parentheses on the closure. These allowed us to use the function in an expression anywhere we'd use a single term, like a string or a numeric constant. It creates a void prototype so the field-accessing function named uid accepts no arguments, just like the built-in function time. If these functions weren't prototyped void, expressions like "uid < 10" or "size/2 > rss" would confuse the parser because it would see the unterminated start of a wildcard glob and of a pattern match, respectively. Prototypes are discussed in Recipe 10.11.

The version of psgrep demonstrated here expects the output from Red Hat Linux's ps. To port to other systems, look at which columns the headers begin at. This approach isn't relevant only to ps or only to Unix systems; it's a generic technique for filtering input records using Perl expressions, easily adapted to other record layouts. The input format could be in columns, space separated, comma separated, or the result of a pattern match with capturing parentheses.

The program could even be modified to handle a user-defined database with a small change to the selection functions. If you had an array of records as described in Recipe 11.9, you could let users specify arbitrary selection criteria, such as:

sub id( )         { $_->{ID}   }
sub title( )      { $_->{TITLE} }
sub executive( )  { title =~ /(?:vice-)?president/i }

# user search criteria go in the grep clause
@slowburners = grep { id<10 && !executive } @employees;

For reasons of security and performance, this kind of power is seldom found in database engines like those described in Chapter 14. SQL doesn't support this, but given Perl and small bit of ingenuity, it's easy to roll it up on your own.

Previous | Home | Next
1.23. Program: fixstyle | Book Index | 2. Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 2. Numbers

Contents:

Introduction
Checking Whether a String Is a Valid Number
Rounding Floating-Point Numbers
Comparing Floating-Point Numbers
Operating on a Series of Integers
Working with Roman Numerals
Generating Random Numbers
Generating Repeatable Random Number Sequences
Making Numbers Even More Random
Generating Biased Random Numbers
Doing Trigonometry in Degrees, Not Radians
Calculating More Trigonometric Functions
Taking Logarithms
Multiplying Matrices
Using Complex Numbers
Converting Binary, Octal, and Hexadecimal Numbers
Putting Commas in Numbers
Printing Correct Plurals
Program: Calculating Prime Factors

John von Neumann (1951)

Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.

2.0. Introduction

Numbers, the most basic data type of almost any programming language, can be surprisingly tricky. Random numbers, numbers with decimal points, series of numbers, and conversion between strings and numbers all pose trouble.

Perl works hard to make life easy for you, and the facilities it provides for manipulating numbers are no exception to that rule. If you treat a scalar value as a number, Perl converts it to one. This means that when you read ages from a file, extract digits from a string, or acquire numbers from any of the other myriad textual sources that Real Life pushes your way, you don't need to jump through the hoops created by other languages' cumbersome requirements to turn an ASCII string into a number.

Perl tries its best to interpret a string as a number when you use it as one (such as in a mathematical expression), but it has no direct way of reporting that a string doesn't represent a valid number. Perl quietly converts non-numeric strings to zero, and it will stop converting the string once it reaches a non-numeric character—so "A7" is still 0, and "7A" is just 7. (Note, however, that the -w flag will warn of such improper conversions.) Sometimes, such as when validating input, you need to know whether a string represents a valid number. We show you how in Recipe 2.1.

Recipe 2.15 shows how to get a number from strings containing hexadecimal, octal, or binary representations of numbers such as "0xff", "0377", and "0b10110". Perl automatically converts numeric literals of these non-decimal bases that occur in your program code (so $a = 3 + 0xff will set $a to 258) but not data read by that program (you can't read "ff" or even "0xff" into $b and then say $a = 3 + $b to make $a become 258).

As if integers weren't giving us enough grief, floating-point numbers can cause even more headaches. Internally, a computer represents numbers with decimal points as floating-point numbers in binary format. Floating-point numbers are not the same as real numbers; they are an approximation of real numbers, with limited precision. Although infinitely many real numbers exist, you only have finite space to represent them, usually about 64 bits or so. You have to cut corners to fit them all in.

When numbers are read from a file or appear as literals in your program, they are converted from their textual representation—which is always in base 10 for numbers with decimal points in them—into an internal, base-2 representation. The only fractional numbers that can be exactly represented using a finite number of digits in a particular numeric base are those that can be written as the sum of a finite number of fractions whose denominators are integral powers of that base.

For example, 0.13 is one tenth plus three one-hundredths. But that's in base-10 notation. In binary, something like 0.75 is exactly representable because it's the sum of one half plus one quarter, and 2 and 4 are both powers of two. But even so simple a number as one tenth, written as 0.1 in base-10 notation, cannot be rewritten as the sum of some set of halves, quarters, eighths, sixteenths, etc. That means that, just as one third can't be exactly represented as a non-repeating decimal number, one tenth can't be exactly represented as a non-repeating binary number. Your computer's internal binary representation of 0.1 isn't exactly 0.1; it's just an approximation!

$ perl -e 'printf "%.60f\n", 0.1'
0.100000000000000005551115123125782702118158340454101562500000

Recipe 2.2 and Recipe 2.3 demonstrate how to make your computer's floating-point representations behave more like real numbers.

Recipe 2.4 gives three ways to perform one operation on each element of a set of consecutive integers. We show how to convert to and from Roman numerals in Recipe 2.5.

Random numbers are the topic of several recipes. Perl's rand function returns a floating-point value between 0 and 1, or between 0 and its argument. We show how to get random numbers in a given range, how to make random numbers more random, and how to make rand give a different sequence of random numbers each time you run your program.

We round out the chapter with recipes on trigonometry, logarithms, matrix multiplication, complex numbers, and the often-asked question: "How do you put commas in numbers?"

Previous | Home | Next
1.24. Program: psgrep | Book Index | 2.1. Checking Whether a String Is a Valid Number
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.1. Checking Whether a String Is a Valid Number

2.1.1. Problem

You want to check whether a string represents a valid number. This is a common problem when validating input, as in CGI scripts, configuration files, and command-line arguments.

2.1.2. Solution

Compare it against a regular expression that matches the kinds of numbers you're interested in:

if ($string =~ /PATTERN/) {
    # is a number
} else {
    # is not
}

Or use the patterns provided by the CPAN module Regexp::Common:

if ($string =~ m{^$RE{num}{real}$}) {
    # is a real number
} else {
    # is not
}

2.1.3. Discussion

This problem gets to the heart of what we mean by a number. Even things that sound simple, like integer, make you think hard about what you will accept; for example, "Is a leading + for positive numbers optional, mandatory, or forbidden?" The many ways that floating-point numbers can be represented could overheat your brain.

Decide what you will and will not accept. Then, construct a regular expression to match those things alone. Here are some precooked solutions (the Cookbook's equivalent of just-add-water meals) for most common cases:

warn "has nondigits"        if     /\D/;
warn "not a natural number" unless /^\d+$/;             # rejects -3
warn "not an integer"       unless /^-?\d+$/;           # rejects +3
warn "not an integer"       unless /^[+-]?\d+$/;
warn "not a decimal number" unless /^-?\d+\.?\d*$/;     # rejects .2
warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
warn "not a C float"
       unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;

These lines do not catch the IEEE notations of "Infinity" and "NaN", but unless you're worried that IEEE committee members will stop by your workplace and beat you over the head with copies of the relevant standards documents, you can probably forget about these strange forms.

If your number has leading or trailing whitespace, those patterns won't work. Either add the appropriate logic directly, or call the trim function from Recipe 1.19.

The CPAN module Regexp::Common provides a wealth of canned patterns that test whether a string looks like a number. Besides saving you from having to figure out the patterns on your own, it also makes your code more legible. By default, this module exports a hash called %RE that you index into, according to which kind of regular expression you're looking for. Be careful to use anchors as needed; otherwise, it will search for that pattern anywhere in the string. For example:

use Regexp::Common;
$string = "Gandalf departed from the Havens in 3021 TA.";
print "Is an integer\n"           if $string =~ / ^   $RE{num}{int}  $ /x;
print "Contains the integer $1\n" if $string =~ /   ( $RE{num}{int} )  /x;

The following examples are other patterns that the module can use to match numbers:

$RE{num}{int}{-sep=>',?'}              # match 1234567 or 1,234,567
$RE{num}{int}{-sep=>'.'}{-group=>4}    # match 1.2345.6789
$RE{num}{int}{-base => 8}              # match 014 but not 99
$RE{num}{int}{-sep=>','}{-group=3}     # match 1,234,594
$RE{num}{int}{-sep=>',?'}{-group=3}    # match 1,234 or 1234
$RE{num}{real}                         # match 123.456 or -0.123456
$RE{num}{roman}                        # match xvii or MCMXCVIII
$RE{num}{square}                       # match 9 or 256 or 12321

Some of these patterns, such as square, were not available in early module versions. General documentation for the module can be found in the Regexp::Common manpage, but more detailed documentation for just the numeric patterns is in the Regexp::Common::number manpage.

Some techniques for identifying numbers don't involve regular expressions. Instead, these techniques use functions from system libraries or Perl to determine whether a string contains an acceptable number. Of course, these functions limit you to the definition of "number" offered by your libraries and Perl.

If you're on a POSIX system, Perl supports the POSIX::strtod function. Its semantics are cumbersome, so the following is a getnum wrapper function for more convenient access. This function takes a string and returns either the number it found or undef for input that isn't a C float. The is_numeric function is a frontend to getnum for when you just want to ask, "Is this a float?"

sub getnum {
    use POSIX qw(strtod);
    my $str = shift;
    $str =~ s/^\s+//;           # remove leading whitespace
    $str =~ s/\s+$//;           # remove trailing whitespace
    $! = 0;
    my($num, $unparsed) = strtod($str);
    if (($str eq '') || ($unparsed != 0) || $!) {
        return;
    } else {
        return $num;
    }
}

sub is_numeric { defined scalar &getnum }

The Scalar::Util module, newly standard as of Perl v5.8.1, exports a function called looks_like_number( ) that uses the Perl compiler's own internal function of the same name (see perlapi(1)). It returns true for any base-10 number that is acceptable to Perl itself, such as 0, 0.8, 14.98, and 6.02e23—but not 0xb1010, 077, 0x392, or numbers with underscores in them. This means that you must check for alternate bases and decode them yourself if you want to permit users to enter such numbers, as in Example 2-1.

Example 2-1. Decode numbers

    #!/usr/bin/perl -w
    use Scalar::Util qw(looks_like_number);
    print "$0: hit ^D (your eof character) to exit\n";
    for (;;) {
        my ($on, $n);      # original string and its numeric value
        print "Pick a number, any number: ";
        $on = $n = <STDIN>;
        last if !defined $n;
        chomp($on,$n);
        $n =~ s/_//g;                      # allow 186_282.398_280_685
        $n = oct($n) if $n =~ /^0/;  # allow 0xFF, 037, 0b1010
        if (looks_like_number($n)) {
            printf "Decimal double of $on is %g\n", 2*$n;
        } else {
            print "That doesn't look like a number to Perl.\n";
        }
    }
    print "\nBye.\n";

2.1.4. See Also

The regular expression syntax in perlre(1) and Chapter 5 of Programming Perl; your system's strtod(3) manpage; the perlapi(1) manpage; the documentation for the CPAN module Regexp::Common, including the Regexp::Common::number manpage; the documentation for the standard POSIX and Scalar::Util modules (also in Chapter 32 of Programming Perl)

Previous | Home | Next
2. Numbers | Book Index | 2.2. Rounding Floating-Point Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.2. Rounding Floating-Point Numbers

2.2.1. Problem

You want to round a floating-point value to a certain number of decimal places. This problem arises from the same inaccuracies in representation that make testing for equality difficult (see Recipe 2.3), as well as in situations where you must reduce the precision of your answers for readability.

2.2.2. Solution

Use the Perl function sprintf, or printf if you're just trying to produce output:

# round off to two places
$rounded = sprintf("%.2f"", $unrounded);

Or you can use other rounding functions described in the Discussion.

2.2.3. Discussion

Whether visible or not, rounding of some sort is virtually unavoidable when working with floating-point numbers. Carefully defined standards (namely, IEEE 754, the standard for binary floating-point arithmetic) coupled with reasonable defaults within Perl often manage to eliminate or at least hide these round-off errors.

In fact, Perl's implicit rounding on output is usually good enough so that it rarely surprises. It's almost always best to leave the numbers unrounded until output, and then, if you don't like Perl's default rounding, use printf or sprintf yourself with a format that makes the rounding explicit. The %f, %e, and %g formats all let you specify how many decimal places to round their argument to. Here's an example showing how all three behave; in each case, we're asking for a field that's 12 spaces wide, but with a precision of no more than four digits to the right of the decimal place.

for $n ( 0.0000001, 10.1, 10.00001, 100000.1 ) {
    printf "%12.4e %12.4f %12.4g\n", $n, $n, $n;
}

This produces the following output:

1.0000e-07       0.0000        1e-07
1.0100e+01      10.1000         10.1
1.0000e+01      10.0000           10
1.0000e+05  100000.1000        1e+05

If that were all there were to the matter, rounding would be pretty easy. You'd just pick your favorite output format and be done with it.

However, it's not that easy: sometimes you need to think more about what you really want and what's really happening. As we explained in the Introduction, even a simple number like 10.1 or 0.1 can only be approximated in binary floating-point. The only decimal numbers that can be exactly represented as floating-point numbers are those that can be rewritten as a finite sum of one or more fractions whose denominators are all powers of two. For example:

$a = 0.625;                # 1/2 + 1/8
$b = 0.725;                # 725/1000, or 29/40
printf "$_ is %.30g\n", $_ for $a, $b;

prints out:

0.625 is 0.625
0.725 is 0.724999999999999977795539507497

The number in $a is exactly representable in binary, but the one in $b is not. When Perl is told to print a floating-point number but not told the precision, as occurs for the interpolated value of $_ in the string, it automatically rounds that number to however many decimal digits of precision that your machine supports. Typically, this is like using an output format of "%.15g", which, when printed, produces the same number as you assigned to $b.

Usually the round-off error is so small you never even notice it, and if you do, you can always specify how much precision you'd like in your output. But because the underlying approximation is still a little bit off from what a simple print might show, this can produce unexpected results. For example, while numbers such as 0.125 and 0.625 are exactly representable, numbers such as 0.325 and 0.725 are not. So let's suppose you'd like to round to two decimal places. Will 0.325 become 0.32 or 0.33? Will 0.725 become 0.72 or 0.73?

$a = 0.325;                # 1/2 + 1/8
$b = 0.725;                # 725/1000, or 29/40
printf "%s is %.2f or %.30g\n", ($_) x 3 for $a, $b;

This produces:

0.325 is 0.33 or 0.325000000000000011102230246252
0.725 is 0.72 or 0.724999999999999977795539507497

Since 0.325's approximation is a bit above that, it rounds up to 0.33. On the other hand, 0.725's approximation is really a little under that, so it rounds down, giving 0.72 instead.

But what about if the number is exactly representable, such 1.5 or 7.5, since those are just whole numbers plus one-half? The rounding rule used in that case is probably not the one you learned in grade school. Watch:

for $n (-4 .. +4) {
    $n += 0.5;
    printf "%4.1f %2.0f\n", $n, $n;
}

That produces this:

-3.5 -4
-2.5 -2
-1.5 -2
-0.5 -0
 0.5  0
 1.5  2
 2.5  2
 3.5  4
 4.5  4

What's happening is that the rounding rule preferred by numerical analysts isn't "round up on a five," but instead "round toward even." This way the bias in the round-off error tends to cancel itself out.

Three useful functions for rounding floating-point values to integral ones are int, ceil, and floor. Built into Perl, int returns the integral portion of the floating-point number passed to it. This is called "rounding toward zero." This is also known as integer truncation because it ignores the fractional part: it rounds down for positive numbers and up for negative ones. The POSIX module's floor and ceil functions also ignore the fractional part, but they always round down and up to the next integer, respectively, no matter the sign.

use POSIX qw(floor ceil);
printf "%8s %8s %8s %8s %8s\n",
    qw(number even zero down up);
for $n (-6 .. +6) {
    $n += 0.5;
    printf "%8g %8.0f %8s %8s %8s\n",
            $n, $n, int($n), floor($n), ceil($n);
}

This produces the following illustrative table; each column heading shows what happens when you round the number in the specified direction.

number     even     zero     down       up
  -5.5       -6       -5       -6       -5
  -4.5       -4       -4       -5       -4
  -3.5       -4       -3       -4       -3
  -2.5       -2       -2       -3       -2
  -1.5       -2       -1       -2       -1
  -0.5       -0        0       -1        0
   0.5        0        0        0        1
   1.5        2        1        1        2
   2.5        2        2        2        3
   3.5        4        3        3        4
   4.5        4        4        4        5
   5.5        6        5        5        6
   6.5        6        6        6        7

If you add up each column, you'll see that you arrive at rather different totals:

   6.5        6        6        0       13

What this tells you is that your choice of rounding style—in effect, your choice of round-off error—can have tremendous impact on the final outcome. That's one reason why you're strongly advised to wait until final output for any rounding. Even still, some algorithms are more sensitive than others to accumulation of round-off error. In particularly delicate applications, such as financial computations and thermonuclear missiles, prudent programmers will implement their own rounding functions instead of relying on their computers' built-in logic, or lack thereof. (A good textbook on numerical analysis is also recommended.)

2.2.4. See Also

The sprintf and int functions in perlfunc(1) and Chapter 29 of Programming Perl; the floor and ceil entries in the documentation for the standard POSIX module (also in Chapter 32 of Programming Perl); we introduce the sprintf technique in Recipe 2.3

Previous | Home | Next
2.1. Checking Whether a String Is a Valid Number | Book Index | 2.3. Comparing Floating-Point Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.3. Comparing Floating-Point Numbers

2.3.1. Problem

Floating-point arithmetic isn't exact. You want to compare two floating-point numbers and know whether they're equal when carried out to a certain number of decimal places. Most of the time, this is the way you should compare floating-point numbers for equality.

2.3.2. Solution

Use sprintf to format the numbers to a certain number of decimal places, then compare the resulting strings:

# equal(NUM1, NUM2, PRECISION) : returns true if NUM1 and NUM2 are
# equal to PRECISION number of decimal places
sub equal {
    my ($A, $B, $dp) = @_;
    return sprintf("%.${dp}g", $A) eq sprintf("%.${dp}g", $B);
  }

Alternatively, store the numbers as integers by assuming the decimal place.

2.3.3. Discussion

You need the equal routine because computers' floating-point representations are just approximations of most real numbers, as we discussed in the Introduction to this chapter. Perl's normal printing routines display numbers rounded to 15 decimal places or so, but its numeric tests don't round. So sometimes you can print out numbers that look the same (after rounding) but do not test the same (without rounding).

This problem is especially noticeable in a loop, where round-off error can silently accumulate. For example, you'd think that you could start a variable out at zero, add one-tenth to it ten times, and end up with one. Well, you can't, because a base-2 computer can't exactly represent one-tenth. For example:

for ($num = $i = 0; $i < 10; $i++) { $num += 0.1 }
if ($num != 1) {
    printf "Strange, $num is not 1; it's %.45f\n", $num;
}

prints out:

Strange, 1 is not 1; it's 0.999999999999999888977697537484345957636833191

The $num is interpolated into the double-quoted string using a default conversion format of "%.15g" (on most systems), so it looks like 1. But internally, it really isn't. If you had checked only to a few decimal places, for example, five:

!equal($num, 1, 5)

then you'd have been okay.

If you have a fixed number of decimal places, as with currency, you can often sidestep the problem by storing your values as integers. Storing $3.50 as 350 instead of 3.5 removes the need for floating-point values. Reintroduce the decimal point on output:

$wage = 536;                # $5.36/hour
$week = 40 * $wage;         # $214.40
printf("One week's wage is: \$%.2f\n", $week/100);

One week's wage is: $214.40

It rarely makes sense to compare more than 15 decimal places, because you probably only have that many digits of precision in your computer's hardware.

2.3.4. See Also

The sprintf function in perlfunc(1) and Chapter 29 of Programming Perl; the entry on $OFMT in the perlvar(1) manpage and Chapter 28 of Programming Perl; the documentation for the standard Math::BigFloat module (also in Chapter 32 of Programming Perl); we use sprintf in Recipe 2.2; Volume 2, Section 4.2.2 of The Art of Computer Programming

Previous | Home | Next
2.2. Rounding Floating-Point Numbers | Book Index | 2.4. Operating on a Series of Integers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.4. Operating on a Series of Integers

2.4.1. Problem

You want to perform an operation on all integers between X and Y, such as when you're working on a contiguous section of an array or wherever you want to process all numbers[4] within a range.

[4]Okay, integers. It's hard to find all the reals. Just ask Cantor.

2.4.2. Solution

Use a for loop, or .. in conjunction with a foreach loop:

foreach ($X .. $Y) {
    # $_ is set to every integer from X to Y, inclusive
}

foreach $i ($X .. $Y) {
    # $i is set to every integer from X to Y, inclusive
}

for ($i = $X; $i <= $Y; $i++) {
    # $i is set to every integer from X to Y, inclusive
}

for ($i = $X; $i <= $Y; $i += 7) {
    # $i is set to every integer from X to Y, stepsize = 7
}

2.4.3. Discussion

The first two approaches use a foreach loop in conjunction with the $X .. $Y construct, which creates a list of integers between $X and $Y. Now, if you were just assigning that range to an array, this would use up a lot of memory whenever $X and $Y were far apart. But in a foreach loop, Perl notices this and doesn't waste time or memory allocating a temporary list. When iterating over consecutive integers, the foreach loop will run faster than the equivalent for loop.

Another difference between the two constructs is that the foreach loop implicitly localizes the loop variable to the body of the loop, but the for loop does not. That means that after the for loop finishes, the loop variable will contain the value it held upon the final iteration. But in the case of the foreach loop, that value will be inaccessible, and the variable will hold whatever it held—if anything—prior to entering the loop. You can, however, use a lexically scoped variable as the loop variable:

foreach my $i ($X .. $Y)       { ... }
for (my $i=$X; $i <= $Y; $i++) { ... }

The following code shows each technique. Here we just print the numbers we generate:

print "Infancy is: ";
foreach (0 .. 2) {
    print "$_ ";
}
print "\n";

print "Toddling is: ";
foreach $i (3 .. 4) {
    print "$i ";
}
print "\n";

print "Childhood is: ";
for ($i = 5; $i <= 12; $i++) {
    print "$i ";
}
print "\n";

Infancy is: 0 1 2
Toddling is: 3 4
Childhood is: 5 6 7 8 9 10 11 12

2.4.4. See Also

The for and foreach operators in perlsyn(1) and the "For Loops" and "Foreach Loops" sections of Chapter 4 of Programming Perl

Previous | Home | Next
2.3. Comparing Floating-Point Numbers | Book Index | 2.5. Working with Roman Numerals
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.5. Working with Roman Numerals

2.5.1. Problem

You want to convert between regular numbers and Roman numerals. You need to do this with items in outlines, page numbers on a preface, and copyrights for movie credits.

2.5.2. Solution

Use the Roman module from CPAN:

use Roman;
$roman = roman($arabic);                        # convert to roman numerals
$arabic = arabic($roman) if isroman($roman);    # convert from roman numerals

2.5.3. Discussion

The Roman module provides both Roman and roman for converting Arabic ("normal") numbers to their Roman equivalents. Roman produces uppercase letters, whereas roman gives lowercase ones.

The module only deals with Roman numbers from 1 to 3999, inclusive. The Romans didn't represent negative numbers or zero, and 5000 (which 4000 is represented in terms of) uses a symbol outside the ASCII character set.

use Roman;
$roman_fifteen = roman(15);                         # "xv"
print "Roman for fifteen is $roman_fifteen\n";
$arabic_fifteen = arabic($roman_fifteen);
print "Converted back, $roman_fifteen is $arabic_fifteen\n";

Roman for fifteen is xv
Converted back, xv is 15

Or to print the current year:

use Time::localtime;
use Roman;
printf "The year is now %s\n", Roman(1900 + localtime->year);

The year is now MMIII

Now, if you happen to have Unicode fonts available, you'll find that code points U+2160 through U+2183 represent Roman numerals, including those beyond the typical ASCII values.

use charnames ":full";
print "2003 is \N{ROMAN NUMERAL ONE THOUSAND}" x 2, "\N{ROMAN NUMERAL THREE}\n";

2003 is Figure Figure Figure

However, the Roman module doesn't yet have an option to use those characters.

Believe it or not, there's even a CPAN module that lets you use Roman numerals in arithmetic.

use Math::Roman qw(roman);
print $a  = roman('I'); #  I
print $a += 2000;       #  MMI
print $a -= "III";      #  MCMXCVIII
print $a -= "MCM";      #  XCVIII

2.5.4. See Also

The Encyclopaedia Britannica article on "Mathematics, History Of"; the documentation with the CPAN modules Roman and Math::Roman; Recipe 6.23

Previous | Home | Next
2.4. Operating on a Series of Integers | Book Index | 2.6. Generating Random Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.6. Generating Random Numbers

2.6.1. Problem

You want to make random numbers in a given range, inclusive, such as when you randomly pick an array index, simulate rolling a die in a game of chance, or generate a random password.

2.6.2. Solution

Use Perl's rand function:

$random = int( rand( $Y-$X+1 ) ) + $X;

2.6.3. Discussion

This code generates and prints a random integer between 25 and 75, inclusive:

$random = int( rand(51)) + 25;
print "$random\n";

The rand function returns a fractional number, from (and including) 0 up to (but not including) its argument. We give it an argument of 51 to get a number that can be 0 or more, but never 51 or more. We take the integer portion of this to get a number from 0 to 50, inclusive (50.99999.... will be turned into 50 by int). We then add 25 to it to get a number from 25 to 75, inclusive.

A common application of this is the random selection of an element from an array:

$elt = $array[ rand @array ];

That's just like saying:

$elt = $array[ int( rand(0+@array) ) ];

Because rand is prototyped to take just one argument, it implicitly imposes scalar context on that argument, which, on a named array, is the number of elements in that array. The function then returns a floating-point number smaller than its argument and greater than or equal to zero. A floating-point number used as an array subscript implicitly undergoes integer truncation (rounding toward zero), producing in the end an evenly distributed, randomly selected array element to assign to $elt.

Generating a random password from a sequence of characters is similarly easy:

@chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
$password = join("", @chars[ map { rand @chars } ( 1 .. 8 ) ]);

We use map to generate eight random indices into @chars, extract the corresponding characters with a slice, and join them together to form the random password. This isn't a good random number, though, as its security relies on the choice of seed, which (in older versions of Perl) is based on the time the program started. See Recipe 2.7 for a way to better seed your random number generator.

2.6.4. See Also

The int, rand, map, and join functions in perlfunc(1) and Chapter 29 of Programming Perl; we explore random numbers further in Recipe 2.7, Recipe 2.8, and Recipe 2.9; we use random numbers in Recipe 1.13

Previous | Home | Next
2.5. Working with Roman Numerals | Book Index | 2.7. Generating Repeatable Random Number Sequences
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.7. Generating Repeatable Random Number Sequences

2.7.1. Problem

Every time you run your program, you get a different sequence of (pseudo-)random numbers. But you want a reproducible sequence, useful when running a simulation, so you need Perl to produce the same set of random numbers each time.

2.7.2. Solution

Use Perl's srand function:

srand EXPR;   # use a constant here for repeated sequences

2.7.3. Discussion

Making random numbers is hard. The best that computers can do, without special hardware, is generate "pseudo-random" numbers, which are evenly distributed in their range of values. These are generated using a mathematical formula, which means that given the same seed (starting point), two programs will produce identical pseudo-random numbers.

The srand function creates a new seed for the pseudo-random number generator. If given an argument, it uses that number as the seed. If no argument is given, srand uses a value that's reasonably difficult to guess as the seed.

If you call rand without first calling srand yourself, Perl calls srand for you, choosing a "good" seed. This way, every time you run your program you'll get a different set of random numbers. Ancient versions of Perl did not call srand, so the same program always produced the same sequence of pseudo-random numbers every time the program was run. Certain sorts of programs don't want a different set of random numbers each time; they want the same set. When you need that behavior, call srand yourself, supplying it with a particular seed:

srand( 42 );  # pick any fixed starting point

Don't call srand more than once in a program, because if you do, you'll start the sequence again from that point. Unless, of course, that's what you want.

Just because Perl tries to use a good default seed does not necessarily guarantee that the numbers generated are cryptographically secure against the most intrepid crackers. Textbooks on cryptography are usually good sources of cryptographically secure random number generators.

2.7.4. See Also

The srand function in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 2.6 and Recipe 2.8; Bruce Schneier's excellent Applied Cryptography (John Wiley & Sons)

Previous | Home | Next
2.6. Generating Random Numbers | Book Index | 2.8. Making Numbers Even More Random
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.8. Making Numbers Even More Random

2.8.1. Problem

You want to generate numbers that are more random than Perl's random numbers. Limitations of your C library's random number generator seeds can sometimes cause problems. The sequence of pseudo-random numbers may repeat too soon for some applications.

2.8.2. Solution

Use a different random number generator, such as those provided by the Math::Random and Math::TrulyRandom modules from CPAN:

use Math::TrulyRandom;
$random = truly_random_value( );

use Math::Random;
$random = random_uniform( );

2.8.3. Discussion

The Perl build process tries to find the best C-library routine to use for generating pseudo-random numbers, looking at rand(3), random(3), and drand48(3). (This can be changed manually at build time, however.) The standard library functions are getting pretty good, but some ancient implementations of the rand function return only 16-bit random numbers or have other algorithmic weaknesses, and may therefore not be sufficiently random for your purposes.

The Math::TrulyRandom module uses inadequacies of your system's timers to generate the random numbers. This takes a while, so it isn't useful for generating a lot of random numbers.

The Math::Random module uses the randlib library to generate random numbers. It also includes a wide range of related functions for generating random numbers according to specific distributions, such as binomial, poisson, and exponential.

2.8.4. See Also

The srand and rand functions in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 2.6 and Recipe 2.7; the documentation for the CPAN modules Math::Random and Math::TrulyRandom

Previous | Home | Next
2.7. Generating Repeatable Random Number Sequences | Book Index | 2.9. Generating Biased Random Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.9. Generating Biased Random Numbers

2.9.1. Problem

You want to pick a random value where the probabilities of the values are not equal (the distribution is not even). You might be trying to randomly select a banner to display on a web page, given a set of relative weights saying how often each banner is to be displayed. Alternatively, you might want to simulate behavior according to a normal distribution (the bell curve).

2.9.2. Solution

If you want a random value distributed according to a specific function—e.g., the Gaussian (Normal) distribution—consult a statistics textbook to find the appropriate function or algorithm. This subroutine generates random numbers that are normally distributed, with a standard deviation of 1 and a mean of 0:

sub gaussian_rand {
    my ($u1, $u2);  # uniformly distributed random numbers
    my $w;          # variance, then a weight
    my ($g1, $g2);  # gaussian-distributed numbers

    do {
        $u1 = 2 * rand( ) - 1;
        $u2 = 2 * rand( ) - 1;
        $w = $u1*$u1 + $u2*$u2;
    } while ($w >= 1 || $w =  = 0);

    $w = sqrt( (-2 * log($w))  / $w );
    $g2 = $u1 * $w;
    $g1 = $u2 * $w;
    # return both if wanted, else just one
    return wantarray ? ($g1, $g2) : $g1;
}

If you have a list of weights and values you want to randomly pick from, follow this two-step process: first, turn the weights into a probability distribution with weight_to_dist, and then use the distribution to randomly pick a value with weighted_rand:

# weight_to_dist: takes a hash mapping key to weight and returns
# a hash mapping key to probability
sub weight_to_dist {
    my %weights = @_;
    my %dist    = ( );
    my $total   = 0;
    my ($key, $weight);
    local $_;

    foreach (values %weights) {
        $total += $_;
    }

    while ( ($key, $weight) = each %weights ) {
        $dist{$key} = $weight/$total;
    }

    return %dist;
}

# weighted_rand: takes a hash mapping key to probability, and
# returns the corresponding element
sub weighted_rand {
    my %dist = @_;
    my ($key, $weight);

    while (1) {                     # to avoid floating point inaccuracies
        my $rand = rand;
        while ( ($key, $weight) = each %dist ) {
            return $key if ($rand -= $weight) < 0;
        }
    }
}

2.9.3. Discussion

The gaussian_rand function implements the polar Box Muller method for turning two independent, uniformly distributed random numbers between 0 and 1 (such as rand returns) into two numbers with a mean of 0 and a standard deviation of 1 (i.e., a Gaussian distribution). To generate numbers with a different mean and standard deviation, multiply the output of gaussian_rand by the new standard deviation, and then add the new mean:

# gaussian_rand as shown earlier
$mean = 25;
$sdev = 2;
$salary = gaussian_rand( ) * $sdev + $mean;
printf("You have been hired at \$%.2f\n", $salary);

The Math::Random module implements this and other distributions for you:

use Math::Random qw(random_normal);
$salary = random_normal(1, $mean, $sdev);

The weighted_rand function picks a random number between 0 and 1. It then uses the probabilities generated by weight_to_dist to see which element the random number corresponds to. Because of the vagaries of floating-point representation, accumulated errors in representation might mean we don't find an element to return. This is why we wrap the code in a while to pick a new random number and try again.

Also, the CPAN module Math::Random has functions to return random numbers from a variety of distributions.

2.9.4. See Also

The rand function in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 2.6; the documentation for the CPAN module Math::Random

Previous | Home | Next
2.8. Making Numbers Even More Random | Book Index | 2.10. Doing Trigonometry in Degrees, Not Radians
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.10. Doing Trigonometry in Degrees, Not Radians

2.10.1. Problem

You want your trigonometry routines to operate in degrees instead of Perl's native radians.

2.10.2. Solution

Convert between radians and degrees (2π radians equals 360 degrees):

use constant PI => (4 * atan2 (1, 1));

sub deg2rad {
    my $degrees = shift;
    return ($degrees / 180) * PI;
}

sub rad2deg {
    my $radians = shift;
    return ($radians / PI) * 180;
}

Alternatively, use the standard Math::Trig module:

use Math::Trig;

$radians = deg2rad($degrees);
$degrees = rad2deg($radians);

2.10.3. Discussion

If you're doing a lot of trigonometry, look into using either the standard Math::Trig or POSIX modules. They provide many more trigonometric functions than are defined in the Perl core. Otherwise, the first solution will define the rad2deg and deg2rad functions. The value of π isn't built directly into Perl, but you can calculate it to as much precision as your floating-point hardware provides. In the Solution, the PI function is a constant created with use constant. Instead of having to remember that π is 3.14159265358979 or so, we use the built-in function call, resolved at compile time, which, besides sparing us from memorizing a long string of digits, is also guaranteed to provide as much accuracy as the platform supports.

If you're looking for the sine in degrees, use this:

# deg2rad and rad2deg defined either as above or from Math::Trig
sub degree_sine {
    my $degrees = shift;
    my $radians = deg2rad($degrees);
    my $result = sin($radians);

    return $result;
}

2.10.4. See Also

The sin, cos, and atan2 functions in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the standard POSIX and Math::Trig modules (also in Chapter 32 of Programming Perl)

Previous | Home | Next
2.9. Generating Biased Random Numbers | Book Index | 2.11. Calculating More Trigonometric Functions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.11. Calculating More Trigonometric Functions

2.11.1. Problem

You want to calculate values for trigonometric functions like sine, tangent, or arc-cosine.

2.11.2. Solution

Perl provides only sin, cos, and atan2 as standard functions. From these, you can derive tan and all other trig functions (if you're intimately familiar with esoteric trig identities):

sub tan {
    my $theta = shift;

    return sin($theta)/cos($theta);
}

The POSIX module provides a wider range of trig functions:

use POSIX;

$y = acos(3.7);

The standard Math::Trig module provides a complete set of functions and supports operations on or resulting in complex numbers:

use Math::Trig;

$y = acos(3.7);

2.11.3. Discussion

The tan function will cause a division-by-zero exception when $theta is π/2, 3π/2, and so on, because the cosine is 0 for these values. Similarly, tan and many other functions from Math::Trig may generate the same error. To trap these, use eval:

eval {
    $y = tan($pi/2);
} or return undef;

2.11.4. See Also

The sin, cos, and atan2 functions in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the standard Math::Trig module; we talk about trigonometry in the context of imaginary numbers in Recipe 2.14; we talk about the use of eval to catch exceptions in Recipe 10.12

Previous | Home | Next
2.10. Doing Trigonometry in Degrees, Not Radians | Book Index | 2.12. Taking Logarithms
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.12. Taking Logarithms

2.12.1. Problem

You want to take a logarithm in various bases.

2.12.2. Solution

For logarithms to base e, use the built-in log :

$log_e = log(VALUE);

For logarithms to base 10, use the POSIX module's log10 function:

use POSIX qw(log10);
$log_10 = log10(VALUE);

For other bases, use the mathematical identity:

where x is the number whose logarithm you want, n is the desired base, and e is the natural logarithm base.

sub log_base {
    my ($base, $value) = @_;
    return log($value)/log($base);
}

2.12.3. Discussion

The log_base function lets you take logarithms to any base. If you know the base you'll want in advance, it's more efficient to cache the log of the base instead of recalculating it every time.

# log_base as defined earlier
$answer = log_base(10, 10_000);
print "log10(10,000) = $answer\n";
log10(10,000) = 4

The Math::Complex module does the caching for you via its logn( ) routine, so you can write:

use Math::Complex;
printf "log2(1024) = %lf\n", logn(1024, 2); # watch out for argument order!
log2(1024) = 10.000000

even though no complex number is involved here. This is not very efficient, but there are plans to rewrite Math::Complex in C for speed.

2.12.4. See Also

The log function in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the standard POSIX and Math::Complex modules (also in Chapter 32 of Programming Perl)

Previous | Home | Next
2.11. Calculating More Trigonometric Functions | Book Index | 2.13. Multiplying Matrices
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.13. Multiplying Matrices

2.13.1. Problem

You want to multiply a pair of two-dimensional arrays. Mathematicians and engineers often need this.

2.13.2. Solution

Use the PDL modules, available from CPAN. PDL is the Perl Data Language—modules that give fast access to compact matrix and mathematical functions:

use PDL;
# $a and $b are both pdl objects
$c = $a x $b;

Alternatively, apply the matrix multiplication algorithm to your two-dimensional array:

sub mmult {
    my ($m1,$m2) = @_;
    my ($m1rows,$m1cols) = matdim($m1);
    my ($m2rows,$m2cols) = matdim($m2);

    unless ($m1cols =  = $m2rows) {  # raise exception
        die "IndexError: matrices don't match: $m1cols != $m2rows";
    }

    my $result = [  ];
    my ($i, $j, $k);

    for $i (range($m1rows)) {
        for $j (range($m2cols)) {
            for $k (range($m1cols)) {
                $result->[$i][$j] += $m1->[$i][$k] * $m2->[$k][$j];
            }
        }
    }
    return $result;
}

sub range { 0 .. ($_[0] - 1) }

sub veclen {
    my $ary_ref = $_[0];
    my $type = ref $ary_ref;
    if ($type ne "ARRAY") { die "$type is bad array ref for $ary_ref" }
    return scalar(@$ary_ref);
}

sub matdim {
    my $matrix = $_[0];
    my $rows = veclen($matrix);
    my $cols = veclen($matrix->[0]);
    return ($rows, $cols);
}

2.13.3. Discussion

If you have the PDL library installed, you can use its lightning-fast manipulation of numbers. This requires far less memory and CPU than Perl's array manipulation. When using PDL objects, many numeric operators (such as + and *) are overloaded and work on an element-by-element basis (e.g., * is the so-called scalar multiplication operator). To get true matrix multiplication, use the overloaded x operator.

use PDL;

$a = pdl [
    [ 3, 2, 3 ],
    [ 5, 9, 8 ],
];

$b = pdl [
    [ 4, 7 ],
    [ 9, 3 ],
    [ 8, 1 ],
];

$c = $a x $b;  # x overload

If you don't have the PDL library, or don't feel like pulling it in for a small problem, you can always do the work yourself the good old-fashioned way.

# mmult( ) and other subroutines as shown earlier

$x = [
       [ 3, 2, 3 ],
       [ 5, 9, 8 ],
];

$y = [
       [ 4, 7 ],
       [ 9, 3 ],
       [ 8, 1 ],
];

$z = mmult($x, $y);

2.13.4. See Also

The documentation with the CPAN module PDL

Previous | Home | Next
2.12. Taking Logarithms | Book Index | 2.14. Using Complex Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.14. Using Complex Numbers

2.14.1. Problem

Your application must manipulate complex numbers, as are often needed in engineering, science, and mathematics.

2.14.2. Solution

Either keep track of the real and imaginary components yourself:

# $c = $a * $b manually
$c_real = ( $a_real * $b_real ) - ( $a_imaginary * $b_imaginary );
$c_imaginary = ( $a_real * $b_imaginary ) + ( $b_real * $a_imaginary );

or use the Math::Complex module (part of the standard Perl distribution):

# $c = $a * $b using Math::Complex
use Math::Complex;
$c = $a * $b;

2.14.3. Discussion

Here's how you'd manually multiply 3+5i and 2-2i:

$a_real = 3; $a_imaginary = 5;              # 3 + 5i;
$b_real = 2; $b_imaginary = -2;             # 2 - 2i;
$c_real = ( $a_real * $b_real ) - ( $a_imaginary * $b_imaginary );
$c_imaginary = ( $a_real * $b_imaginary ) + ( $b_real * $a_imaginary );
print "c = ${c_real}+${c_imaginary}i\n";

c = 16+4i

and with Math::Complex:

use Math::Complex;
$a = Math::Complex->new(3,5);               # or Math::Complex->new(3,5);
$b = Math::Complex->new(2,-2);
$c = $a * $b;
print "c = $c\n";

c = 16+4i

You may create complex numbers via the cplx constructor or via the exported constant i:

use Math::Complex;
$c = cplx(3,5) * cplx(2,-2);                # easier on the eye
$d = 3 + 4*i;                               # 3 + 4i
printf "sqrt($d) = %s\n", sqrt($d);

sqrt(3+4i) = 2+i

The Math::Trig module uses the Math::Complex module internally because some functions can break out from the real axis into the complex plane—for example, the inverse sine of 2.

2.14.4. See Also

The documentation for the standard Math::Complex module (also in Chapter 32 of Programming Perl)

Previous | Home | Next
2.13. Multiplying Matrices | Book Index | 2.15. Converting Binary, Octal, and Hexadecimal Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.15. Converting Binary, Octal, and Hexadecimal Numbers

2.15.1. Problem

You want to convert a string (e.g., "0b10110", "0x55", or "0755") containing a binary, octal, or hexadecimal number to the correct number.

Perl understands numbers specified in binary (base-2), octal (base-8), and hexadecimal (base-16) notation only when they occur as literals in your programs. If they come in as data—such as by reading from files or environment variables, or when supplied as command-line arguments—no automatic conversion takes place.

2.15.2. Solution

Use Perl's hex function if you have a hexadecimal string like "2e" or "0x2e":

$number = hex($hexadecimal);         # hexadecimal only ("2e" becomes 47)

Use the oct function if you have a hexadecimal string like "0x2e", an octal string like "047", or a binary string like "0b101110":

$number = oct($hexadecimal);         # "0x2e" becomes 47
$number = oct($octal);               # "057"  becomes 47
$number = oct($binary);              # "0b101110" becomes 47

2.15.3. Discussion

The oct function converts octal numbers with or without the leading "0"; for example, "0350" or "350". Despite its name, oct does more than convert octal numbers: it also converts hexadecimal ("0x350") numbers if they have a leading "0x" and binary ("0b101010") numbers if they have a leading "0b". The hex function converts only hexadecimal numbers, with or without a leading "0x": "0x255", "3A", "ff", or "deadbeef". (Letters may be in upper- or lowercase.)

Here's an example that accepts an integer in decimal, binary, octal, or hex, and prints that integer in all four bases. It uses the oct function to convert the data from binary, octal, and hexadecimal if the input begins with a 0. It then uses printf to convert into all four bases as needed.

print "Gimme an integer in decimal, binary, octal, or hex: ";
$num = <STDIN>;
chomp $num;
exit unless defined $num;
$num = oct($num) if $num =~ /^0/; # catches 077 0b10 0x20
printf "%d %#x %#o %#b\n", ($num) x 4;

The # symbol between the percent and the three non-decimal bases makes printf produce output that indicates which base the integer is in. For example, if you enter the number 255, the output would be:

255 0xff 0377 0b11111111

But without the # sign, you would only get:

255 ff 377 11111111

The following code converts Unix file permissions. They're always given in octal, so we use oct instead of hex.

print "Enter file permission in octal: ";
$permissions = <STDIN>;
die "Exiting ...\n" unless defined $permissions;
chomp $permissions;
$permissions = oct($permissions);   # permissions always octal
print "The decimal value is $permissions\n";

2.15.4. See Also

The "Scalar Value Constructors" section in perldata(1) and the "Numeric Literals" section of Chapter 2 of Programming Perl; the oct and hex functions in perlfunc(1) and Chapter 29 of Programming Perl

Previous | Home | Next
2.14. Using Complex Numbers | Book Index | 2.16. Putting Commas in Numbers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.16. Putting Commas in Numbers

2.16.1. Problem

You want to output a number with commas in the right places. People like to see long numbers broken up in this way, especially in reports.

2.16.2. Solution

Reverse the string so you can use backtracking to avoid substitution in the fractional part of the number. Then use a regular expression to find where you need commas, and substitute them in. Finally, reverse the string back.

sub commify {
    my $text = reverse $_[0];
    $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
    return scalar reverse $text;
}

2.16.3. Discussion

It's a lot easier in regular expressions to work from the front than from the back. With this in mind, we reverse the string and make a minor change to the algorithm that repeatedly inserts commas three digits from the end. When all insertions are done, we reverse the final string and return it. Because reverse is sensitive to its implicit return context, we force it to scalar context.

This function can easily be adjusted to accommodate the use of periods instead of commas, as are used in many countries.

Here's an example of commify in action:

# more reasonable web counter :-)
use Math::TrulyRandom;
$hits = truly_random_value( );       # negative hits!
$output = "Your web page received $hits accesses last month.\n";
print commify($output);
Your web page received -1,740,525,205 accesses last month.

2.16.4. See Also

perllocale(1); the reverse function in perlfunc(1) and Chapter 29 of Programming Perl; the section "Adding Commas to a Number with Lookaround" in Chapter 2 of Mastering Regular Expressions, Second Edition

Previous | Home | Next
2.15. Converting Binary, Octal, and Hexadecimal Numbers | Book Index | 2.17. Printing Correct Plurals
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.17. Printing Correct Plurals

2.17.1. Problem

You're printing something like "It took $time hours", but "It took 1 hours" is ungrammatical. You would like to get it right.

2.17.2. Solution

Use printf and the conditional operator (X ? Y : Z) to alter the noun or verb:

printf "It took %d hour%s\n", $time, $time =  = 1 ? "" : "s";

printf "%d hour%s %s enough.\n", $time,
        $time =  = 1 ? ""   : "s",
        $time =  = 1 ? "is" : "are";

Or use the Lingua::EN::Inflect module from CPAN, as described in the following Discussion.

2.17.3. Discussion

The only reason inane messages like "1 file(s) updated" appear is because their authors are too lazy to bother checking whether the count is 1 or not.

If your noun changes by more than an "-s", you'll need to change the printf accordingly:

printf "It took %d centur%s", $time, $time =  = 1 ? "y" : "ies";

This is good for simple cases, but you'll tire of writing it. This leads you to write funny functions like this:

sub noun_plural {
    local $_ = shift;
    # order really matters here!
    s/ss$/sses/                             ||
    s/([psc]h)$/${1}es/                     ||
    s/z$/zes/                               ||
    s/ff$/ffs/                              ||
    s/f$/ves/                               ||
    s/ey$/eys/                              ||
    s/y$/ies/                               ||
    s/ix$/ices/                             ||
    s/([sx])$/$1es/                         ||
    s/$/s/                                  ||
                die "can't get here";
    return $_;
}
*verb_singular = \&noun_plural;   # make function alias

As you find more exceptions, your function will become increasingly convoluted. When you need to handle such morphological changes, turn to the flexible solution provided by the Lingua::EN::Inflect module from CPAN.

use Lingua::EN::Inflect qw(PL classical);
classical(1);               # why isn't this the default?
while (<DATA>) {            # each line in the data
    for (split) {           # each word on the line
        print "One $_, two ", PL($_), ".\n";
    }
}
# plus one more
$_ = 'secretary general';
print "One $_, two ", PL($_), ".\n";

_ _END_ _
fish fly ox
species genus phylum
cherub radius jockey
index matrix mythos
phenomenon formula

That produces the following:

One fish, two fish.
One fly, two flies.
One ox, two oxen.
One species, two species.
One genus, two genera.
One phylum, two phyla.
One cherub, two cherubim.
One radius, two radii.
One jockey, two jockeys.
One index, two indices.
One matrix, two matrices.
One mythos, two mythoi.
One phenomenon, two phenomena.
One formula, two formulae.
One secretary general, two secretaries general.

Without calling classical, these lines would have come out different than in the previous output:

One phylum, two phylums.
One cherub, two cherubs.
One radius, two radiuses.
One index, two indexes.
One matrix, two matrixes.
One formula, two formulas.

This is just one of the many things the module can do. It also handles inflections or conjugations for other parts of speech, provides number-insensitive comparison functions, figures out whether to use a or an, and plenty more.

2.17.4. See Also

The "Conditional Operator" in perlop(1) and Chapter 3 of Programming Perl; the documentation with the CPAN module Lingua::EN::Inflect

Previous | Home | Next
2.16. Putting Commas in Numbers | Book Index | 2.18. Program: Calculating Prime Factors
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.18. Program: Calculating Prime Factors

The following program takes one or more integer arguments and determines the prime factors. It uses Perl's native numeric representation, unless those numbers use floating-point representation and thus lose accuracy. Otherwise (or if the program's -b switch is used), it uses the standard Math::BigInt library, thus allowing for huge numbers. However, it only loads this library if necessary. That's why we use require and import instead of use, which would unconditionally load the library at compile time instead of conditionally at runtime. This is not an efficient way to crack the huge integers used for cryptographic purposes.

Call the program with a list of numbers, and it will show you the prime factors of those numbers:

% bigfact 8 9 96 2178
8          2**3
9          3**2
96         2**5 3
2178       2 3**2 11**2

You can give it very large numbers:

% bigfact 239322000000000000000000
+239322000000000000000000 2**19 3 5**18 +39887

% bigfact 25000000000000000000000000
+25000000000000000000000000 2**24 5**26

The program is shown in Example 2-2.

Example 2-2. bigfact

  #!/usr/bin/perl
  # bigfact - calculate prime factors
  use strict;
  use integer;

  our ($opt_b, $opt_d);
  use Getopt::Std;

  @ARGV && getopts('bd')        or die "usage: $0 [-b] number ...";

  load_biglib( ) if $opt_b;

  ARG: foreach my $orig ( @ARGV ) {
      my ($n, %factors, $factor);
      $n = $opt_b ? Math::BigInt->new($orig) : $orig;
      if ($n + 0 ne $n) { # don't use -w for this
          printf STDERR "bigfact: %s would become %s\n", $n, $n+0 if $opt_d;
          load_biglib( );
          $n = Math::BigInt->new($orig);
      }
      printf "%-10s ", $n;

      # Here $sqi will be the square of $i. We will take advantage
      # of the fact that ($i + 1) ** 2 =  = $i ** 2 + 2 * $i + 1.
      for (my ($i, $sqi) = (2, 4); $sqi <= $n; $sqi += 2 * $i ++ + 1) {
          while ($n % $i =  = 0) {
              $n /= $i;
              print STDERR "<$i>" if $opt_d;
              $factors {$i} ++;
          }
      }

      if ($n != 1 && $n != $orig) { $factors{$n}++ }
      if (! %factors) {
          print "PRIME\n";
          next ARG;
      }
      for $factor ( sort { $a <=> $b } keys %factors ) {
          print "$factor";
          if ($factors{$factor} > 1) {
              print "**$factors{$factor}";
          }
          print " ";
      }
      print "\n";
  }

  # this simulates a use, but at runtime
  sub load_biglib {
      require Math::BigInt;
      Math::BigInt->import( );          #immaterial?
  }

Previous | Home | Next
2.17. Printing Correct Plurals | Book Index | 3. Dates and Times
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 3. Dates and Times

Contents:

Introduction
Finding Today's Date
Converting DMYHMS to Epoch Seconds
Converting Epoch Seconds to DMYHMS
Adding to or Subtracting from a Date
Difference of Two Dates
Day in a Week/Month/Year or Week Number
Parsing Dates and Times from Strings
Printing a Date
High-Resolution Timers
Short Sleeps
Program: hopdelta

IEEE Std 1003.1b-1993 (POSIX) Section B.2.2.2

It is inappropriate to require that a time represented as seconds since the Epoch precisely represent the number of seconds between the referenced time and the Epoch.

3.0. Introduction

Times and dates are important things to be able to manipulate. "How many users logged in last month?", "How many seconds should I sleep if I want to wake up at midday?", and "Has this user's password expired yet?" are common questions whose answers involve surprisingly non-obvious manipulations.

Perl represents points in time as intervals, measuring seconds past a point in time called the Epoch. On Unix and many other systems, the Epoch was 00:00 Jan 1, 1970, UTC (Universal Corrected Time).[5]

[5]UTC is the preferred way to specify what used to be called GMT, or Greenwich Mean Time.

When we talk about dates and times, we often interchange two different concepts: points in time (dates and times) and intervals between points in time (weeks, months, days, etc.). Epoch seconds represent intervals and points in the same units, so you can do basic arithmetic on them.

However, people are not used to working with Epoch seconds. We are more used to dealing with individual year, month, day, hour, minute, and second values. Furthermore, the month can be represented by its full name or its abbreviation. The day can precede or follow the month. Because of the difficulty of performing calculations with a variety of formats, we typically convert human-supplied strings or lists to Epoch seconds, calculate, and then convert back to strings or lists for output.

Epoch seconds are an absolute number of seconds, so they don't take into account time zones or daylight saving times. When converting to or from distinct values, always consider whether the time represented is UTC or local. Use different conversion functions depending on whether you need to convert from UTC to local time or vice versa.

Perl's time function returns the number of seconds that have passed since the Epoch—more or less.[6] POSIX requires that time not include leap seconds, a peculiar practice of adjusting the world's clock by a second here and there to account for the slowing down of the Earth's rotation due to tidal angular-momentum dissipation. (See the sci.astro FAQ, section 3, at http://sciastro.astronomy.net/sci.astro.3.FAQ.) To convert Epoch seconds into distinct values for days, months, years, hours, minutes, and seconds, use the localtime and gmtime functions. In list context, these functions return a nine-element list, as shown in Table 3-1.

[6]Well, less actually. To be precise, 22 seconds less as of this writing.

Table 3-1. Values (and their ranges) returned from localtime and gmtime

Variable | Values | Range
$sec | seconds | 0-60
$min | minutes | 0-59
$hours | hours | 0-23
$mday | day of month | 1-31
$mon | month of year | 0-11, 0 = = January
$year | years since 1900 | 1-138 (or more)
$wday | day of week | 0-6, 0 = = Sunday
$yday | day of year | 0-365
$isdst | 0 or 1 | true if daylight saving is in effect

The values for seconds range from 0-60 to account for leap seconds; you never know when a spare second will leap into existence at the urging of various standards bodies.

From now on, we'll refer to a list of day, month, year, hour, minute, and seconds as DMYHMS, for no better reason than that writing and reading "distinct day, month, year, hour, minute, and seconds values" is wearisome. The abbreviation is not meant to suggest an order of return values.

Perl does not return a two-digit year value. It returns the year minus 1900, which just happens to be a two-digit number through 1999. Perl doesn't intrinsically have a Year 2000 problem, unless you make one yourself. (Your computer, and Perl, may have a 2038 problem, though, if we're still using 32 bits by that time.) Add 1900 to get the full year value instead of using the construct "20$year", or your programs will refer to the year as something like "20103". We can't pin down the year value's range, because it depends on how big an integer your operating system uses for Epoch seconds. Small integers mean a small range; big (64-bit) integers mean a very big range.

In scalar context, localtime and gmtime return the date and time formatted as an ASCII string:

Fri Apr 11 09:27:08 1997

The standard Time::tm module provides a named interface to these values. The standard Time::localtime and Time::gmtime modules override the list-returning localtime and gmtime functions, replacing them with versions that return Time::tm objects. Compare these two pieces of code:

# using arrays
print "Today is day ", (localtime)[7], " of the current year.\n";
Today is day 117 of the current year.

# using Time::tm objects
use Time::localtime;
$tm = localtime;
print "Today is day ", $tm->yday, " of the current year.\n";
Today is day 117 of the current year.

To go from a list to Epoch seconds, use the standard Time::Local module. It provides the functions timelocal and timegm, both of which take a nine-element list and return an integer. The list's values have the same meaning and ranges as those returned by localtime and gmtime.

Epoch seconds values are limited by the size of an integer. If you have a 32-bit signed integer holding your Epoch seconds, you can only represent dates (in UTC) from Fri Dec 13 20:45:52 1901 to Tue Jan 19 03:14:07 2038 (inclusive). By 2038, it is assumed, computers will change to use larger integers for Epoch seconds. We hope. For operations on dates outside this range, you must use another representation or work from distinct year, month, and day values.

The Date::Calc and Date::Manip modules on CPAN both work from these distinct values, but be warned: years don't necessarily have 1900 subtracted from them the way the year value returned by localtime does, nor do months and weeks always start at 0. As always, consult the manpage of the appropriate module to make sure you're giving it what it expects and getting back from it what you expect. There's little more embarrassing than realizing you've calculated your company payroll based on a calendar that's 1,900 years in the past.

Previous | Home | Next
2.18. Program: Calculating Prime Factors | Book Index | 3.1. Finding Today's Date
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.1. Finding Today's Date

3.1.1. Problem

You need to find the year, month, and day values for today's date.

3.1.2. Solution

Use localtime, which returns values for the current date and time if given no arguments. You can either use localtime and extract the information you want from the list it returns:

($DAY, $MONTH, $YEAR) = (localtime)[3,4,5];

or use Time::localtime, which overrides localtime to return a Time::tm object:

use Time::localtime;
$tm = localtime;
($DAY, $MONTH, $YEAR) = ($tm->mday, $tm->mon, $tm->year);

3.1.3. Discussion

Here's how you'd print the current date as "YYYY MM DD", using the non-overridden localtime:

($day, $month, $year) = (localtime)[3,4,5];
printf("The current date is %04d %02d %02d\n", $year+1900, $month+1, $day);
The current date is 2003 03 06

To extract the fields we want from the list returned by localtime, we take a list slice. We could also have written it as:

($day, $month, $year) = (localtime)[3..5];

This is how we'd print the current date as "YYYY-MM-DD" (in approved ISO 8601 fashion), using Time::localtime:

use Time::localtime;
$tm = localtime;
printf("The current date is %04d-%02d-%02d\n", $tm->year+1900,
    ($tm->mon)+1, $tm->mday);
The current date is 2003-03-06

The object interface might look out of place in a short program. However, when you do a lot of work with the distinct values, accessing them by name makes code much easier to understand.

A more obfuscated way that does not involve temporary variables is:

printf("The current date is %04d-%02d-%02d\n",
       sub {($_[5]+1900, $_[4]+1, $_[3])}->(localtime));

There is also strftime from the POSIX module discussed in Recipe 3.8:

use POSIX qw(strftime);
print strftime "%Y-%m-%d\n", localtime;

The gmtime function works just as localtime does, but gives the answer in UTC instead of your local time zone.

3.1.4. See Also

The localtime and gmtime functions in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the standard Time::localtime module

Previous | Home | Next
3. Dates and Times | Book Index | 3.2. Converting DMYHMS to Epoch Seconds
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.2. Converting DMYHMS to Epoch Seconds

3.2.1. Problem

You want to convert a date, a time, or both with distinct values for day, month, year, etc. to Epoch seconds.

3.2.2. Solution

Use the timelocal or timegm functions in the standard Time::Local module, depending on whether the date and time is in the current time zone or in UTC.

use Time::Local;
$TIME = timelocal($sec, $min, $hours, $mday, $mon, $year);
$TIME = timegm($sec, $min, $hours, $mday, $mon, $year);

3.2.3. Discussion

The built-in function localtime converts an Epoch seconds value to distinct DMYHMS values; the timelocal subroutine from the standard Time::Local module converts distinct DMYHMS values to an Epoch seconds value. Here's an example that shows how to find Epoch seconds for a time in the current day. It gets the day, month, and year values from localtime:

# $hours, $minutes, and $seconds represent a time today,
# in the current time zone
use Time::Local;
$time = timelocal($seconds, $minutes, $hours, (localtime)[3,4,5]);

If you're passing month and year values to timelocal, it expects values with the same range as those which localtime returns. Namely, months start at 0, and years have 1900 subtracted from them.

The timelocal function assumes the DMYHMS values represent a time in the current time zone. Time::Local also exports a timegm subroutine that assumes the DMYHMS values represent a time in the UTC time zone. Unfortunately, there is no convenient way to convert from a time zone other than the current local time zone or UTC. The best you can do is convert to UTC and add or subtract the time zone offset in seconds.

This code illustrates both the use of timegm and how to adjust the ranges of months and years:

# $day is day in month (1-31)
# $month is month in year (1-12)
# $year is four-digit year e.g., 1967
# $hours, $minutes and $seconds represent UTC (GMT) time
use Time::Local;
$time = timegm($seconds, $minutes, $hours, $day, $month-1, $year-1900);

As explained in the introduction, Epoch seconds cannot hold values before Fri Dec 13 20:45:52 1901 or after Tue Jan 19 03:14:07 2038. Don't convert such dates to Epoch seconds—use a Date:: module from CPAN, and do your calculations with that instead.

3.2.4. See Also

The documentation for the standard Time::Local module (also in Chapter 32 of Programming Perl); convert in the other direction using Recipe 3.3

Previous | Home | Next
3.1. Finding Today's Date | Book Index | 3.3. Converting Epoch Seconds to DMYHMS
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.3. Converting Epoch Seconds to DMYHMS

3.3.1. Problem

You have a date and time in Epoch seconds, and you want to calculate individual DMYHMS values from it.

3.3.2. Solution

Use the localtime or gmtime functions, depending on whether you want the date and time in UTC or your local time zone.

($seconds, $minutes, $hours, $day_of_month, $month, $year,
    $wday, $yday, $isdst) = localtime($time);

The standard Time::timelocal and Time::gmtime modules override the localtime and gmtime functions to provide named access to the individual values.

use Time::localtime;        # or Time::gmtime
$tm = localtime($TIME);     # or gmtime($TIME)
$seconds = $tm->sec;
# ...

3.3.3. Discussion

The localtime and gmtime functions return strange year and month values; the year has 1900 subtracted from it, and 0 is the month value for January. Be sure to correct the base values for year and month, as this example does:

($seconds, $minutes, $hours, $day_of_month, $month, $year,
    $wday, $yday, $isdst) = localtime($time);
printf("Dateline: %02d:%02d:%02d-%04d/%02d/%02d\n",
    $hours, $minutes, $seconds, $year+1900, $month+1,
    $day_of_month);

We could have used the Time::localtime module to avoid the temporary variables:

use Time::localtime;
$tm = localtime($time);
printf("Dateline: %02d:%02d:%02d-%04d/%02d/%02d\n",
    $tm->hour, $tm->min, $tm->sec, $tm->year+1900,
    $tm->mon+1, $tm->mday);

3.3.4. See Also

The localtime function in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the standard Time::localtime and Time::gmtime modules; convert in the other direction using Recipe 3.2

Previous | Home | Next
3.2. Converting DMYHMS to Epoch Seconds | Book Index | 3.4. Adding to or Subtracting from a Date
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.4. Adding to or Subtracting from a Date

3.4.1. Problem

You have a date and time and want to find the date and time of some period in the future or past.

3.4.2. Solution

Simply add or subtract Epoch seconds:

$when = $now + $difference;
$then = $now - $difference;

If you have distinct DMYHMS values, use the CPAN Date::Calc module. If you're doing arithmetic with days only, use Add_Delta_Days ($offset is a positive or negative integral number of days):

use Date::Calc qw(Add_Delta_Days);
($y2, $m2, $d2) = Add_Delta_Days($y, $m, $d, $offset);

If you are concerned with hours, minutes, and seconds (in other words, times as well as dates), use Add_Delta_DHMS:

use Date::Calc qw(Add_Delta_DHMS);
($year2, $month2, $day2, $h2, $m2, $s2) =
    Add_Delta_DHMS( $year, $month, $day, $hour, $minute, $second,
                $days_offset, $hour_offset, $minute_offset, $second_offset );

3.4.3. Discussion

Calculating with Epoch seconds is easiest, disregarding the effort to get dates and times into and out of Epoch seconds. This code shows how to calculate an offset (55 days, 2 hours, 17 minutes, and 5 seconds, in this case) from a given base date and time:

$birthtime = 96176750;                  # 18/Jan/1973, 3:45:50 am
$interval = 5 +                         # 5 seconds
            17 * 60 +                   # 17 minutes
            2  * 60 * 60 +              # 2 hours
            55 * 60 * 60 * 24;          # and 55 days
$then = $birthtime + $interval;
print "Then is ", scalar(localtime($then)), "\n";
Then is Wed Mar 14 06:02:55 1973

We could have used Date::Calc's Add_Delta_DHMS function and avoided the conversion to and from Epoch seconds:

use Date::Calc qw(Add_Delta_DHMS);
($year, $month, $day, $hh, $mm, $ss) = Add_Delta_DHMS(
    1973, 1, 18, 3, 45, 50, # 18/Jan/1973, 3:45:50 am
             55, 2, 17, 5); # 55 days, 2 hrs, 17 min, 5 sec
print "To be precise: $hh:$mm:$ss, $month/$day/$year\n";
To be precise: 6:2:55, 3/14/1973

As usual, we need to know the range of values the function expects. Add_Delta_DHMS takes a full year value—that is, one that hasn't had 1900 subtracted from it. The month value for January is 1, not 0. Date::Calc's Add_Delta_Days function expects the same kind of values:

use Date::Calc qw(Add_Delta_Days);
($year, $month, $day) = Add_Delta_Days(1973, 1, 18, 55);
print "Nat was 55 days old on: $month/$day/$year\n";
Nat was 55 days old on: 3/14/1973

3.4.4. See Also

The documentation for the CPAN module Date::Calc

Previous | Home | Next
3.3. Converting Epoch Seconds to DMYHMS | Book Index | 3.5. Difference of Two Dates
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.5. Difference of Two Dates

3.5.1. Problem

You need to find the number of days between two dates or times.

3.5.2. Solution

If your dates are in Epoch seconds and fall in the range Fri Dec 13 20:45:52 1901 to Tue Jan 19 03:14:07 2038 (inclusive), subtract one from the other and convert the seconds to days:

$seconds = $recent - $earlier;

If you have distinct DMYMHS values or are worried about the range limitations of Epoch seconds, use the Date::Calc module from CPAN. It can calculate the difference between dates:

use Date::Calc qw(Delta_Days);
$days = Delta_Days( $year1, $month1, $day1, $year2, $month2, $day2);

It also calculates the difference between a pair of dates and times:

use Date::Calc qw(Delta_DHMS);
($days, $hours, $minutes, $seconds) =
  Delta_DHMS( $year1, $month1, $day1, $hour1, $minute1, $seconds1,  # earlier
              $year2, $month2, $day2, $hour2, $minute2, $seconds2); # later

3.5.3. Discussion

One problem with Epoch seconds is how to convert the large integers back to forms that people can read. The following example shows one way of converting an Epoch seconds value back to its component numbers of weeks, days, hours, minutes, and seconds:

$bree = 361535725;          # 16 Jun 1981, 4:35:25
$nat  =  96201950;          # 18 Jan 1973, 3:45:50

$difference = $bree - $nat;
print "There were $difference seconds between Nat and Bree\n";
There were 265333775 seconds between Nat and Bree

$seconds    =  $difference % 60;
$difference = ($difference - $seconds) / 60;
$minutes    =  $difference % 60;
$difference = ($difference - $minutes) / 60;
$hours      =  $difference % 24;
$difference = ($difference - $hours)   / 24;
$days       =  $difference % 7;
$weeks      = ($difference - $days)    /  7;

print "($weeks weeks, $days days, $hours:$minutes:$seconds)\n";
(438 weeks, 4 days, 23:49:35)

Date::Calc's functions can ease these calculations. The Delta_Days function returns the number of days between two dates. It takes the two dates as a list: year, month, day. The dates are given chronologically—earliest first.

use Date::Calc qw(Delta_Days);
@bree = (1981, 6, 16);      # 16 Jun 1981
@nat  = (1973, 1, 18);      # 18 Jan 1973
$difference = Delta_Days(@nat, @bree);
print "There were $difference days between Nat and Bree\n";
There were 3071 days between Nat and Bree

The Delta_DHMS function returns a four-element list corresponding to the number of days, hours, minutes, and seconds between the two dates you give it.

use Date::Calc qw(Delta_DHMS);
@bree = (1981, 6, 16, 4, 35, 25);   # 16 Jun 1981, 4:35:25
@nat  = (1973, 1, 18, 3, 45, 50);   # 18 Jan 1973, 3:45:50
@diff = Delta_DHMS(@nat, @bree);
print "Bree came $diff[0] days, $diff[1]:$diff[2]:$diff[3] after Nat\n";
Bree came 3071 days, 0:49:35 after Nat

3.5.4. See Also

The documentation for the CPAN module Date::Calc

Previous | Home | Next
3.4. Adding to or Subtracting from a Date | Book Index | 3.6. Day in a Week/Month/Year or Week Number
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.6. Day in a Week/Month/Year or Week Number

3.6.1. Problem

You have a date, either in Epoch seconds or as distinct year, month, etc. values. You want to find out what week of the year, day of the week, day of the month, or day of the year that the date falls on.

3.6.2. Solution

If you have Epoch seconds, the day of the year, day of the month, and day of the week are returned by localtime. The week of the year is easily calculated from the day of the year (but see the following discussion, as standards differ).

($MONTHDAY, $WEEKDAY, $YEARDAY) = (localtime $DATE)[3,6,7];
$WEEKNUM = int($YEARDAY / 7) + 1;

If you have distinct DMYHMS values, you can either convert them to Epoch seconds values as in Recipe 3.2 and then use the previous solution, or else use the Day_of_Week, Week_Number, and Day_of_Year functions from the CPAN module Date::Calc:

use Date::Calc qw(Day_of_Week Week_Number Day_of_Year);
# you have $year, $month, and $day
# $day is day of month, by definition.
$wday = Day_of_Week($year, $month, $day);
$wnum = Week_Number($year, $month, $day);
$dnum = Day_of_Year($year, $month, $day);

3.6.3. Discussion

The Day_of_Week, Week_Number, and Day_of_Year functions all expect years that haven't had 1900 subtracted from them and months where January is 1, not 0. The return value from Day_of_Week can be 1 through 7 (corresponding to Monday through Sunday) or 0 in case of an error (an invalid date, for example).

use Date::Calc qw(Day_of_Week Week_Number Day_of_Week_to_Text);

$year  = 1981;
$month = 6;         # (June)
$day   = 16;

$wday = Day_of_Week($year, $month, $day);
print "$month/$day/$year was a ", Day_of_Week_to_Text($wday), "\n";
## see comment above

$wnum = Week_Number($year, $month, $day);
print "in the $wnum week.\n";
6/16/1981 was a Tuesday
in week number 25.

The governing standard bodies of particular countries may have rules about when the first week of the year starts. For example, in Norway the first week must have at least 4 days in it (and weeks start on Mondays). If January 1 falls on a week with 3 or fewer days, it is counted as week 52 (or 53) of the previous year. In America, the first Monday of the year is usually the start of the first workweek. Given such rules, you may have to write your own algorithm, or at least look at the %G, %L, %W, and %U formats to the UnixDate function in Date::Manip.

3.6.4. See Also

The localtime function in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the CPAN module Date::Calc

Previous | Home | Next
3.5. Difference of Two Dates | Book Index | 3.7. Parsing Dates and Times from Strings
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.7. Parsing Dates and Times from Strings

3.7.1. Problem

You read in a date or time specification in an arbitrary format but need to parse that string into distinct year, month, etc. values.

3.7.2. Solution

If your date is already numeric, or in a rigid and easily parsed format, use a regular expression (and possibly a hash mapping month names to numbers) to extract individual day, month, and year values, and then use the standard Time::Local module's timelocal and timegm functions to turn that into an Epoch seconds value.

use Time::Local;
# $date is "2003-02-13" (YYYY-MM-DD form).
($yyyy, $mm, $dd) = ($date =~ /(\d+)-(\d+)-(\d+)/);
# calculate epoch seconds at midnight on that day in this timezone
$epoch_seconds = timelocal(0, 0, 0, $dd, $mm-1, $yyyy);

For a more flexible solution, use the ParseDate function provided by the CPAN module Date::Manip, and then use UnixDate to extract the individual values.

use Date::Manip qw(ParseDate UnixDate);
$date = ParseDate($STRING);
if (!$date) {
    # bad date
} else {
    @VALUES = UnixDate($date, @FORMATS);
}

3.7.3. Discussion

The flexible ParseDate function accepts many formats. It even converts strings such as "today", "2 weeks ago Friday", "2nd Sunday in 1996", and "last Sunday in December", plus it understands the date and time format used in mail and news headers. It returns the decoded date in its own format: a string of the form "YYYYMMDDHH:MM:SS". You could compare two such strings to compare the dates they represent, but arithmetic is difficult. We therefore use the UnixDate function to extract the year, month, and day values in a preferred format.

UnixDate takes a date (as returned by ParseDate) and a list of formats. It applies each format to the string and returns the result. A format is a string describing one or more elements of the date and time and the way that the elements are to be formatted. For example, %Y is the format for the year in four-digit form. Here's an example:

use Date::Manip qw(ParseDate UnixDate);

while (<>) {
    $date = ParseDate($_);
    if (!$date) {
        warn "Bad date string: $_\n";
        next;
    } else {
        ($year, $month, $day) = UnixDate($date, "%Y", "%m", "%d");
        print "Date was $month/$day/$year\n";
    }
}

3.7.4. See Also

The documentation for the CPAN module Date::Manip; we use this in Recipe 3.11

Previous | Home | Next
3.6. Day in a Week/Month/Year or Week Number | Book Index | 3.8. Printing a Date
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.8. Printing a Date

3.8.1. Problem

You need to print a date and time shown in Epoch seconds format in human-readable form.

3.8.2. Solution

Call localtime or gmtime in scalar context, which takes an Epoch seconds value and returns a string of the form Tue July 22 05:15:20 2003:

$STRING = localtime($EPOCH_SECONDS);

Alternatively, the strftime function in the standard POSIX module supports a more customizable output format and takes individual DMYHMS values:

use POSIX qw(strftime);
$STRING = strftime($FORMAT, $SECONDS, $MINUTES, $HOUR,
                   $DAY_OF_MONTH, $MONTH, $YEAR, $WEEKDAY,
                   $YEARDAY, $DST);

The CPAN module Date::Manip has a UnixDate routine that works like a specialized form sprintf designed to handle dates. Pass it a Date::Manip date value. Using Date::Manip in lieu of POSIX::strftime has the advantage of not requiring a POSIX-compliant system.

use Date::Manip qw(UnixDate);
$STRING = UnixDate($DATE, $FORMAT);

3.8.3. Discussion

The simplest solution is built into Perl already: the localtime function. In scalar context, it returns the string formatted in a particular way:

Wed July 16 23:58:36 2003

This makes for simple code, although it restricts the format of the string:

use Time::Local;
$time = timelocal(50, 45, 3, 18, 0, 73);
print "Scalar localtime gives: ", scalar(localtime($time)), "\n";
Scalar localtime gives: Thu Jan 18 03:45:50 1973

Of course, localtime requires the date and time in Epoch seconds. The POSIX::strftime function takes individual DMYMHS values plus a format and returns a string. The format is similar to a printf format: % directives specify fields in the output string. A full list of these directives is available in your system's documentation for strftime. The strftime function expects the individual values representing the date and time to be in the same range as those returned by localtime:

use POSIX qw(strftime);
use Time::Local;
$time = timelocal(50, 45, 3, 18, 0, 73);
print "strftime gives: ", strftime("%A %D", localtime($time)), "\n";
strftime gives: Thursday 01/18/73

All values are shown in their national representation when using POSIX::strftime. So, if you run it in France, your program would print "Sunday" as "Dimanche". Be warned: Perl's interface to the POSIX function strftime assumes the date falls in the current time zone.

If you don't have access to POSIX's strftime function, there's always the trusty Date::Manip CPAN module, described in Recipe 3.6.

use Date::Manip qw(ParseDate UnixDate);
$date = ParseDate("18 Jan 1973, 3:45:50");
$datestr = UnixDate($date, "%a %b %e %H:%M:%S %z %Y");    # as scalar
print "Date::Manip gives: $datestr\n";
Date::Manip gives: Thu Jan 18 03:45:50 GMT 1973

3.8.4. See Also

The gmtime and localtime functions in perlfunc(1) and Chapter 29 of Programming Perl; perllocale(1); your system's strftime(3) manpage; the documentation for the POSIX module (also in Chapter 32 of Programming Perl); the documentation for the CPAN module Date::Manip

Previous | Home | Next
3.7. Parsing Dates and Times from Strings | Book Index | 3.9. High-Resolution Timers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.9. High-Resolution Timers

3.9.1. Problem

You need to measure time with a finer granularity than the full seconds that time returns.

3.9.2. Solution

The Time::HiRes module, which is included standard starting with the v5.8 release of Perl, encapsulates this functionality for most systems:

use Time::HiRes qw(gettimeofday);
$t0 = gettimeofday( );
## do your operation here
$t1 = gettimeofday( );
$elapsed = $t1 - $t0;
# $elapsed is a floating point value, representing number
# of seconds between $t0 and $t1

3.9.3. Discussion

Here's some code that uses Time::HiRes to time how long the user takes to press the Return key:

use Time::HiRes qw(gettimeofday);
print "Press return when ready: ";
$before = gettimeofday( );
$line = <STDIN>;
$elapsed = gettimeofday( ) - $before;
print "You took $elapsed seconds.\n";

Press return when ready:
You took 0.228149 seconds.

The module's gettimeofday function returns a two-element list representing seconds and microseconds when called in list context, or a single floating-point number combining the two when called in scalar context. You can also import its time function to replace the standard core version by that name; this always acts like scalar gettimeofday.

The module also provides usleep and ualarm functions, which are alternate versions of the standard Perl sleep and alarm functions that understand granularities of microseconds instead of just seconds. They take arguments in microseconds; alternatively, you can import the module's sleep and alarm functions, which take floating-point arguments in seconds, to replace the standard versions, which take integer arguments in seconds. For access to your system's low-level itimer routines (if you have them), setitimer and getitimer are also provided.

If your system doesn't support that module, you might try to poke around by hand using syscall. Compare Time::HiRes to the equivalent syscall code. (This example is included principally so that you can see an example of Perl's abstruse and archaic syscall function.)

require 'sys/syscall.ph';

# initialize the structures returned by gettimeofday
$TIMEVAL_T = "LL";
$done = $start = pack($TIMEVAL_T, (0,0));

# prompt
print "Press return when ready: ";

# read the time into $start
syscall(&SYS_gettimeofday, $start, 0) != -1
           || die "gettimeofday: $!";

# read a line
$line = <>;

# read the time into $done
syscall(&SYS_gettimeofday, $done, 0) != -1
       || die "gettimeofday: $!";

# expand the structure
@start = unpack($TIMEVAL_T, $start);
@done  = unpack($TIMEVAL_T, $done);

# fix microseconds
for ($done[1], $start[1]) { $_ /= 1_000_000 }

# calculate time difference
$delta_time = sprintf "%.4f", ($done[0]  + $done[1]  )
                                         -
                              ($start[0] + $start[1] );

print "That took $delta_time seconds\n";
Press return when ready:
That took 0.3037 seconds

It's longer because it's doing system calls in Perl, whereas Time::HiRes does them in C providing a single function. It's complex because directly accessing system calls peculiar to your operating system requires understanding the underlying C structures that the system call takes and returns. Some programs that come with the Perl distribution try to automatically calculate the formats to pack and unpack for you, if fed the appropriate C header file. In the example, sys/syscall.ph is a Perl library file generated with h2ph, which converts the sys/syscall.h header file into sys/syscall.ph, defining (among other things) &SYS_gettimeofday as a subroutine that returns the system call number of gettimeofday.

Here's another example of Time::HiRes, showing how you could use it to benchmark a sort (if you didn't care to use the standard Benchmark module):

use Time::HiRes qw(gettimeofday);
# take mean sorting time
$size = 2000;
$number_of_times = 100;
$total_time = 0;

for ($i = 0; $i < $number_of_times; $i++) {
    my (@array, $j, $begin, $time);
    # populate array
    @array = ( );
    for ($j=0; $j < $size; $j++) { push(@array, rand) }

    # sort it
    $begin = gettimeofday;
    @array = sort { $a <=> $b } @array;
    $time = gettimeofday-$begin;
    $total_time += $time;
}

printf "On average, sorting %d random numbers takes %.5f seconds\n",
    $size, ($total_time/$number_of_times);
On average, sorting 2000 random numbers takes 0.01033 seconds

3.9.4. See Also

The documentation for the Time::HiRes and Benchmark modules; the syscall function in perlfunc(1) and Chapter 29 of Programming Perl; your system's syscall(2) manpage

Previous | Home | Next
3.8. Printing a Date | Book Index | 3.10. Short Sleeps
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.10. Short Sleeps

3.10.1. Problem

You need to sleep for less than a second.

3.10.2. Solution

Use the select( ) function, if your system supports it:

select(undef, undef, undef, $time_to_sleep);

Some systems don't support a four-argument select. The Time::HiRes module provides a sleep function that takes a floating-point number of seconds:

use Time::HiRes qw(sleep);
sleep($time_to_sleep);

3.10.3. Discussion

Here's an example of select. It's a simpler version of the program in Recipe 1.6. Think of it as your very own 300-baud terminal.

while (<>) {
    select(undef, undef, undef, 0.25);
    print;
}

Using Time::HiRes, we'd write it as:

use Time::HiRes qw(sleep);
while (<>) {
    sleep(0.25);
    print;
}

3.10.4. See Also

The documentation for the CPAN modules Time::HiRes and Benchmark; the sleep and select functions in perlfunc(1) and Chapter 29 of Programming Perl; we use the select function for short sleeps in the slowcat program in Recipe 1.6

Previous | Home | Next
3.9. High-Resolution Timers | Book Index | 3.11. Program: hopdelta
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.11. Program: hopdelta

Have you ever wondered why it took so long for someone's mail to get to you? With postal mail, you can't trace how long each intervening post office let your letter gather dust in their back office. But with electronic mail, you can. The message carries in its header Received: lines showing when each intervening mail transport agent along the way got the message.

The dates in the headers are hard to read. You have to read them backwards, bottom to top. They are written in many varied formats, depending on the whim of each transport agent. Worst of all, each date is written in its own local time zone. It's hard to eyeball "Tue, 26 May 1998 23:57:38 -0400" and "Wed, 27 May 1998 05:04:03 +0100" and realize these two dates are only 6 minutes and 25 seconds apart.

The ParseDate and DateCalc functions in the Date::Manip module from CPAN can help this:

use Date::Manip qw(ParseDate DateCalc);
$d1 = ParseDate("Sun, 09 Mar 2003 23:57:38 -0400");
$d2 = ParseDate("Mon, 10 Mar 2003 05:04:03 +0100");
print DateCalc($d1, $d2);
+0:0:0:0:0:6:25

That's a nice format for a program to read, but it's still not what the casual reader wants to see. The hopdelta program, shown in Example 3-1, takes a mailer header and tries to analyze the deltas (difference) between each hop (mail stop). Its output is shown in the local time zone.

Example 3-1. hopdelta

  #!/usr/bin/perl
  # hopdelta - feed mail header, produce lines
  #            showing delay at each hop.
  use strict;
  use Date::Manip qw (ParseDate UnixDate);

  # print header; this should really use format/write due to
  # printf complexities
  printf "%-20.20s %-20.20s %-20.20s   %s\n",
          "Sender", "Recipient", "Time", "Delta";

  $/ = '';                # paragraph mode
  $_ = <>;                # read header
  s/\n\s+/ /g;            # join continuation lines

  # calculate when and where this started
  my($start_from) = /^From.*\@([^\s>]*)/m;
  my($start_date) = /^Date:\s+(.*)/m;
  my $then = getdate($start_date);
  printf "%-20.20s %-20.20s %s\n", 'Start', $start_from, fmtdate($then);

  my $prevfrom = $start_from;

  # now process the headers lines from the bottom up
  for (reverse split(/\n/)) {
      my ($delta, $now, $from, $by, $when);
      next unless /^Received:/;
      s/\bon (.*?) (id.*)/; $1/s;         # qmail header, I think
      unless (($when) = /;\s+(.*)$/) {    # where the date falls
          warn "bad received line: $_";
          next;
      }
      ($from) = /from\s+(\S+)/;
      ($from) = /\((.*?)\)/ unless $from; # some put it here
      $from =~ s/\)$//;                   # someone was too greedy
      ($by)   = /by\s+(\S+\.\S+)/;        # who sent it on this hop

      # now random mungings to get their string parsable
      for ($when) {
          s/ (for|via) .*$//;
          s/([+-]\d\d\d\d) \(\S+\)/$1/;
          s/id \S+;\s*//;
      }
      next unless $now = getdate($when);          # convert to Epoch
      $delta = $now - $then;

      printf "%-20.20s %-20.20s %s  ", $from, $by, fmtdate($now);
      $prevfrom = $by;
      puttime($delta);
      $then = $now;
  }

  exit;

  # convert random date strings into Epoch seconds
  sub getdate {
      my $string     =  shift;
      $string        =~ s/\s+\(.*\)\s*$//;        # remove nonstd tz
      my $date       =  ParseDate($string);
      my $epoch_secs =  UnixDate($date,"%s");
      return $epoch_secs;
  }

  # convert Epoch seconds into a particular date string
  sub fmtdate {
      my $epoch = shift;
      my($sec,$min,$hour,$mday,$mon,$year) = localtime($epoch);
      return sprintf "%02d:%02d:%02d %04d/%02d/%02d",
                      $hour, $min, $sec,
                      $year + 1900, $mon + 1, $mday,
  }

  # take seconds and print in pleasant-to-read format
  sub puttime {
      my($seconds) = shift;
      my($days, $hours, $minutes);

      $days    = pull_count($seconds, 24 * 60 * 60);
      $hours   = pull_count($seconds, 60 * 60);
      $minutes = pull_count($seconds, 60);

      put_field('s', $seconds);
      put_field('m', $minutes);
      put_field('h', $hours);
      put_field('d', $days);

      print "\n";
  }

  # usage: $count = pull_count(seconds, amount)
  # remove from seconds the amount quantity, altering caller's version.
  # return the integral number of those amounts so removed.
  sub pull_count {
      my($answer) = int($_[0] / $_[1]);
      $_[0] -= $answer * $_[1];
      return $answer;
  }

  # usage: put_field(char, number)
  # output number field in 3-place decimal format, with trailing char
  # suppress output unless char is 's' for seconds
  sub put_field {
      my ($char, $number) = @_;
      printf " %3d%s", $number, $char if $number || $char eq 's';
  }

  =end

  Sender               Recipient            Time                   Delta
  Start                wall.org             09:17:12 1998/05/23
  wall.org             mail.brainstorm.net  09:20:56 1998/05/23    44s   3m
  mail.brainstorm.net  jhereg.perl.com      09:20:58 1998/05/23     2s

Previous | Home | Next
3.10. Short Sleeps | Book Index | 4. Arrays
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 4. Arrays

Contents:

Introduction
Specifying a List in Your Program
Printing a List with Commas
Changing Array Size
Implementing a Sparse Array
Iterating Over an Array
Iterating Over an Array by Reference
Extracting Unique Elements from a List
Finding Elements in One Array but Not Another
Computing Union, Intersection, or Difference of Unique Lists
Appending One Array to Another
Reversing an Array
Processing Multiple Elements of an Array
Finding the First List Element That Passes a Test
Finding All Elements in an Array Matching Certain Criteria
Sorting an Array Numerically
Sorting a List by Computable Field
Implementing a Circular List
Randomizing an Array
Program: words
Program: permute

E.M. Forster

Works of art, in my opinion, are the only objects in the material universe to possess internal order, and that is why, though I don't believe that only art matters, I do believe in Art for Art's sake.

4.0. Introduction

If you are asked about the contents of your pockets, or the names of the first three Greek letters, or how to get to the highway, you recite a list: you name one thing after another in a particular order. Lists are part of your conception of the world. With Perl's powerful list- and array-handling primitives, you can translate this world view directly into code.

In this chapter, we'll use the terms list and array as the Perl language thinks of them. Take ("alpha", "beta", "gamma"); that's a list of the names of the first three Greek letters, in order. To store that list into a variable, use an array, as in @greeks = ("alpha", "beta", "gamma"). Both are ordered groups of scalar values; the difference is that an array is a named variable, one whose array length can be directly changed, whereas a list is a more ephemeral notion. You might think of an array as a variable and a list as the values it contains.

This distinction may seem arbitrary, but operations that modify the length of these groupings (like push and pop) require a proper array and not merely a list. Think of the difference between $a and 4. You can say $a++ but not 4++. Likewise, you can say pop(@a) but not pop (1,2,3).

The most important thing to glean from this is that Perl's lists and arrays are both ordered groupings of scalars. Operators and functions that work on lists or arrays are designed to provide faster or more convenient access to the elements than manual access would provide. Since few actually deal with modifying the array's length, you can usually use arrays and lists interchangeably.

You can't use nested parentheses to create a list of lists. If you try that in Perl, your lists get flattened, meaning that both these lines are equivalent:

@nested = ("this", "that", "the", "other");
@nested = ("this", "that", ("the", "other"));

Why doesn't Perl (usefully) just support nested lists directly? Although partially for historical reasons, this easily allows for operations (like print or sort) that work on arbitrarily long lists of arbitrary contents.

What happens if you want a more complex data structure, such as an array of arrays or an array of hashes? Remember that scalars aren't restricted to containing just numbers or strings; they can also hold references. Complex (multilevel) data structures in Perl are always put together using references. Therefore, what appear to be "two-dimensional arrays" or "arrays of arrays" are always implemented as arrays of array references, in the same way that two-dimensional arrays in C can be arrays of pointers to arrays.

Most recipes in this chapter don't care what you keep in your arrays; for example, the problem of merging two arrays is the same whether the arrays contains strings, numbers, or references. Some problems are intrinsically tied to the contents of your arrays; recipes for those are in Chapter 11. This chapter's recipes deal with generic arrays.

Let's have some more terminology. The scalar items in an array or list are called elements, which you access by specifying their position, or index. Indices in Perl start at 0. So, given this list:

@greeks = ( "alpha", "beta", "gamma" );

"alpha" is in the first position, but you'd access it as $greeks[0]. "beta" is in the second position, but you'd access it as $greeks[1]. This structure is doubly justified: the contrariness of computers, whose first representable number is 0, and the contrariness of language designers, who chose 0 because it is an offset into the array, not the ordinal number of the element.

Previous | Home | Next
3.11. Program: hopdelta | Book Index | 4.1. Specifying a List in Your Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.1. Specifying a List in Your Program

4.1.1. Problem

You want to include a list in your program. This is how you initialize arrays.

4.1.2. Solution

You can write out a comma-separated list of elements:

@a = ("quick", "brown", "fox");

If you have a lot of single-word elements, use the qw( ) operator:

@a = qw(Meddle not in the affairs of wizards.);

If you have a lot of multiword elements, use a here document and extract lines:

@lines = (<< "END_OF_HERE_DOC" =~ /^\s*(.+)/gm);
    I sit beside the fire and think
    of all that I have seen,
    of meadow-flowers and butterflies
    and summers that have been;
END_OF_HERE_DOC

4.1.3. Discussion

The first technique is the one most commonly used, often because only small arrays are normally initialized as program literals. Initializing a large array would fill your program with values and make it hard to read, so such arrays either tend to be initialized in a separate library file (see Chapter 12), or else have their values read in from a file:

@bigarray = ( );
open(FH, "<", "myinfo")   or die "Couldn't open myinfo: $!";
while (<FH>) {
    chomp;
    push(@bigarray, $_);
}
close(FH);

The second technique uses qw( ), one of several pseudo-functions in Perl used for quoting without having to resort to actual quotation marks. This one splits its string argument on whitespace to produce a list of words, where "words" in this instance means strings that don't contain any whitespace. The initial argument is not subject to interpolation of variables or (most) backslash escape sequences.

@banner = ('Costs', 'only', '$4.95');
@banner = qw(Costs only $4.95);
@banner = split(' ', 'Costs only $4.95');

You can use qw( ) only when each whitespace-separated argument is to be a distinct element in the return list. Be careful not to give Columbus four ships instead of three:

@ships  = qw(Niña Pinta Santa María);               # WRONG
@ships  = ('Niña', 'Pinta', 'Santa María');         # right

The third solution takes a here document, which is a single, multiline string, and applies a global pattern match to that string. The pattern /^\s*(.+)/ says to skip any whitespace at the start of the line, then capture everything through the end of each line. The /g modifier means to apply that match globally, and the /m modifier says to permit ^ to match not just at the beginning of the string, but also immediately after a newline, which, in a multiline string, is just what you need. Applying that technique to the ships example yields:

@ships = ( << "END_OF_FLOTILLA" =~ /^\s*(.+)/gm);
              Niña
              Pinta
              Santa María
END_OF_FLOTILLA

4.1.4. See Also

The "List Value Constructors" section of perldata(1); the "List Values and Arrays" section of Chapter 2 of Programming Perl; the "Quote and Quote-Like Operators" section of perlop(1); the s/// operator in perlop(1) and Chapter 5 of Programming Perl

Previous | Home | Next
4. Arrays | Book Index | 4.2. Printing a List with Commas
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.2. Printing a List with Commas

4.2.1. Problem

You'd like to print out a list containing an unknown number of elements, placing an "and" before the last element and commas between each element if there are more than two.

4.2.2. Solution

Use this function, which returns the formatted string:

sub commify_series {
    (@_ =  = 0) ? ''                                      :
    (@_ =  = 1) ? $_[0]                                   :
    (@_ =  = 2) ? join(" and ", @_)                       :
                join(", ", @_[0 .. ($#_-1)], "and $_[-1]");
}

4.2.3. Discussion

It often looks odd to print out arrays:

@array = ("red", "yellow", "green");
print "I have ", @array, " marbles.\n";
print "I have @array marbles.\n";
I have redyellowgreen marbles.
I have red yellow green marbles.

What you really want it to say is, "I have red, yellow, and green marbles". The function given in the solution generates strings in that format. The word "and" is placed between the last two list elements. If there are more than two elements in the list, a comma is placed between every element.

Example 4-1 gives a complete demonstration of the function, with one addition: if any element in the list already contains a comma, a semicolon is used for the separator character instead.

Example 4-1. commify_series

  #!/usr/bin/perl -w
  # commify_series - show proper comma insertion in list output

  # @lists is an array of (references to anonymous) arrays
  @lists = (
      [ 'just one thing' ],
      [ qw(Mutt Jeff) ],
      [ qw(Peter Paul Mary) ],
      [ 'To our parents', 'Mother Theresa', 'God' ],
      [ 'pastrami', 'ham and cheese', 'peanut butter and jelly', 'tuna' ],
      [ 'recycle tired, old phrases', 'ponder big, happy thoughts' ],
      [ 'recycle tired, old phrases',
        'ponder big, happy thoughts',
        'sleep and dream peacefully' ],
      );

  foreach $aref (@lists) {
      print "The list is: " . commify_series(@$aref) . ".\n";
  }
  # demo for single list
  @list = qw(one two three);
  print "The last list is: " . commify_series(@list) . ".\n";

  sub commify_series {
      my $sepchar = grep(/,/ => @_) ? ";" : ",";
      (@_ =  = 0) ? ''                                      :
      (@_ =  = 1) ? $_[0]                                   :
      (@_ =  = 2) ? join(" and ", @_)                       :
                  join("$sepchar ", @_[0 .. ($#_-1)], "and $_[-1]");
  }

Here's the output from the program:

The list is: just one thing.
The list is: Mutt and Jeff.
The list is: Peter, Paul, and Mary.
The list is: To our parents, Mother Theresa, and God.
The list is: pastrami, ham and cheese, peanut butter and jelly, and tuna.
The list is: recycle tired, old phrases and ponder big, happy thoughts.
The list is: recycle tired, old phrases; ponder
   big, happy thoughts; and sleep and dream peacefully.
The last list is: one, two, and three.

As you see, we don't follow the ill-advised practice of omitting the final comma from a series under any circumstances. To do so introduces unfortunate ambiguities and unjustifiable exceptions. The examples shown would have claimed that we were the offspring of Mother Teresa and God, and would have had us eating sandwiches made of jelly and tuna fish mixed together atop the peanut butter.

4.2.4. See Also

Fowler's Modern English Usage; we explain the nested list syntax in Recipe 11.1; the grep function in perlfunc(1) and Chapter 29 of Programming Perl; the conditional operator ("?:") is discussed in perlop(1) and in the "Conditional Operator" section of Chapter 3 of Programming Perl

Previous | Home | Next
4.1. Specifying a List in Your Program | Book Index | 4.3. Changing Array Size
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.3. Changing Array Size

4.3.1. Problem

You want to enlarge or truncate an array. For example, you might truncate an array of employees that's already sorted by salary to list the five highest-paid employees. Or, if you know how big your array will get and that it will grow piecemeal, it's more efficient to grab memory for it in one step by enlarging just once than to keep push ing values onto the end.

4.3.2. Solution

Assign to $#ARRAY :

# grow or shrink @ARRAY
$#ARRAY = $NEW_LAST_ELEMENT_INDEX_NUMBER;

Assigning to an element past the end automatically extends the array:

$ARRAY[$NEW_LAST_ELEMENT_INDEX_NUMBER] = $VALUE;

4.3.3. Discussion

$#ARRAY is the number of the last valid index in @ARRAY. If we assign it a number smaller than its current value, we truncate the array. Truncated elements are lost forever. If we assign $#ARRAY a number larger than its current value, the array grows. New elements have the undefined value.

$#ARRAY is not @ARRAY, though. Although $#ARRAY is the last valid index in the array, @ARRAY (in scalar context, as when treated as a number) is the number of elements. $#ARRAY is one less than @ARRAY because array indices start at 0.

Here's some code that uses both. We have to say scalar @array in the print because Perl gives list context to (most) functions' arguments, but we want @array in scalar context.

sub what_about_that_array {
    print "The array now has ", scalar(@people), " elements.\n";
    print "The index of the last element is $#people.\n";
    print "Element #3 is `$people[3]'.\n";
}

@people = qw(Crosby Stills Nash Young);
what_about_that_array( );

prints:

The array now has 4 elements.
The index of the last element is 3.
Element #3 is `Young'.

whereas:

$#people--;
what_about_that_array( );

prints:

The array now has 3 elements.
The index of the last element is 2.
Element #3 is ''.

Element #3 disappeared when we shortened the array. If we'd turned on warnings (either with the -w command-line option to Perl or with use warnings inside the program), Perl would also have warned "use of uninitialized value" because $people[3] is undefined.

$#people = 10_000;
what_about_that_array( );

prints:

The array now has 10001 elements.
The index of the last element is 10000.
Element #3 is ''.

The "Young" element is now gone forever. Instead of assigning to $#people, we could have said:

$people[10_000] = undef;

although this isn't exactly the same. If you have a three-element array, as in:

@colors = qw(red blue green);

and you undef its last element:

undef $colors[2];        # green is gone

you still have a three-element array; its last element is just undefined. If you pop the array, either via the function or manually by changing $#colors:

$last_color = $colors[ $#colors-- ];

then the array grows shorter by one element.

Perl arrays are not sparse. In other words, if you have a 10,000th element, you must have the 9,999 other elements, too. They may be undefined, but they still take up memory. For this reason, $array[time( )], or any other construct that uses a very large integer as an array index, is a really bad idea. Use a hash instead.

4.3.4. See Also

The discussion of the $#ARRAY notation in perldata(1), also explained in the "List Values and Arrays" section of Chapter 2 of Programming Perl

Previous | Home | Next
4.2. Printing a List with Commas | Book Index | 4.4. Implementing a Sparse Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.4. Implementing a Sparse Array

4.4.1. Problem

An array with large, unoccupied expanses between occupied elements wastes memory. How do you reduce that overhead?

4.4.2. Solution

Use a hash instead of an array.

4.4.3. Discussion

If you assign to the millionth element of an array, Perl allocates a million and one slots to store scalars. Only the last element contains interesting data, leaving earlier ones each set to undef at a cost of four (or more) bytes per unoccupied slot.

In recent versions of Perl, if you grow an array by assigning either past the end or directly to $#ARRAY, you can distinguish these implicit undef s from those that would result from assigning undef there by using exists instead of defined, just as you would with a hash.

$#foo = 5;
@bar = ( (undef) x 5 ) ;

printf "foo element 3 is%s defined\n",
        defined $foo[3] ? "" : "n't";
printf "foo element 3 does%s exist\n",
        exists $foo[3] ? "" : "n't";
printf "bar element 3 is%s defined\n",
        defined $bar[3] ? "" : "n't";
printf "bar element 3 does%s exist\n",
        exists $bar[3] ? "" : "n't";

foo element 3 isn't defined
foo element 3 doesn't exist
bar element 3 isn't defined
bar element 3 does exist

However, you still waste a lot of space. That's because Perl's array implementation reserves a contiguous vector, one for each element up to the highest occupied position.

$real_array[ 1_000_000 ] = 1;       # costs 4+ megabytes

A hash works differently: you pay only for what you really use, not for unoccupied positions. Although a hash element costs somewhat more than an array element because you need to store both the value and its key, with sparse arrays, the savings can be astonishing.

$fake_array{ 1_000_000 } = 1;       # costs 28 bytes

What's the trade-off? Because a hash's keys aren't ordered, a little more work is needed to sort the numeric keys so you can handle their values in the same order as you would if they were stored as a real array. With an array, you'd just do this to process elements in index order:

foreach $element ( @real_array ) {
    # do something with $element
}

or this to process indices in ascending order:

foreach $idx ( 0 .. $#real_array ) {
    # do something with $real_array[$idx]
}

Using a hash representation, you should instead do either this to process elements in index order:

foreach $element ( @fake_array{ sort {$a <=> $b} keys %fake_array } ) {
    # do something with $element
}

or this to process indices in ascending order:

foreach $idx ( sort {$a <=> $b} keys %fake_array ) {
    # do something with $fake_array{$idx}
}

If you don't care about handling elements in a particular order, however, you don't need to go through all that. Just process the values according to their internal order, either like this:

foreach $element ( values %fake_array ) {
    # do something with $element
}

or like this:

# process indices in internal hash order
foreach $idx ( keys %fake_array ) {
    # do something with $fake_array{$idx}
}

If you're determined to use an array, two fairly specialized cases occasionally arise in which you can save substantial amounts of memory by using an alternate storage scheme. Both cases also apply to arrays that are densely populated, not just those that are mostly empty.

The first case shows up when you grow an array by repeatedly appending new elements until its subscripts become large. Because of how Perl reallocates memory for growing arrays, this can use up to four times the memory you really need. If you happen to know how big the array will (or might) eventually become, you can avoid this reallocation overhead either by storing the large subscripts first instead of the small ones:

for ($i = 10_000; $i >= 0; $i--) { $real_array[$i] = 1 }

or by presizing the array by assigning to the special $#ARRAY notation:

$#real_array = 10_000;

The second special case comes up when each array element holds nothing but a single one-bit value—essentially either a true or a false. For example, suppose you are keeping track of numbered USENET news articles, and you only need to know whether a given article number has been read. For situations like this, use a bit vector instead of a real array:

my $have_read = '';
for ($i = 10_000; $i >= 0; $i--) { vec($have_read, $i, 1) = 1 }

Then you can check to see whether a given article has been read this way:

if (vec($have_read, $artno, 1)) { .... }

4.4.4. See Also

The vec function in perlfunc(1) and in Chapter 29 of Programming Perl

Previous | Home | Next
4.3. Changing Array Size | Book Index | 4.5. Iterating Over an Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.5. Iterating Over an Array

4.5.1. Problem

You want to repeat a procedure for every element in a list.

Often you use an array to collect information you're interested in; for instance, login names of users who have exceeded their disk quota. When you finish collecting the information, you want to process it by doing something with every element in the array. In the disk quota example, you might send each user a stern mail message.

4.5.2. Solution

Use a foreach loop:

foreach $item (LIST) {
    # do something with $item
}

4.5.3. Discussion

Let's say we've used @bad_users to compile a list of users who are over their allotted disk quotas. To call some complain subroutine for each user, we'd use:

foreach $user (@bad_users) {
        complain($user);
}

Rarely is this recipe so simply applied. Instead, we often use functions to generate the list:

foreach $var (sort keys %ENV) {
    print "$var=$ENV{$var}\n";
}

Here we're using sort and keys to build a sorted list of environment variable names. If you use the list more than once, you'll obviously keep it around by saving in an array. But for one-shot processing, it's often tidier to process the list directly.

Not only can we add complexity to this formula by building up the list in the foreach, we can also add complexity by doing more work inside the code block. A common application of foreach is to gather information on every element of a list and then, based on that information, decide whether to do something. For instance, returning to the disk quota example:

foreach $user (@all_users) {
    $disk_space = get_usage($user);     # find out how much disk space in use
    if ($disk_space > $MAX_QUOTA) {     # if it's more than we want ...
        complain($user);                # ... then object vociferously
    }
}

More complicated program flow is possible. The code can call last to jump out of the loop, next to move on to the next element, or redo to jump back to the first statement inside the block. Use these to say "no point continuing with this one, I know it's not what I'm looking for" (next), "I've found what I'm looking for, there's no point in my checking the rest" (last), or "I've changed some things, I'd better run this loop's calculations again" (redo).

The variable set to each value in the list is called a loop variable or iterator variable. If no iterator variable is supplied, the global variable $_ is used. $_ is the default variable for many of Perl's string, list, and file functions. In brief code blocks, omitting $_ improves readability. (In long ones, though, too much implicit use hampers readability.) For example:

foreach (`who`) {
    if (/tchrist/) {
        print;
    }
}

or combining with a while loop:

while (<FH>) {              # $_ is set to the line just read
    chomp;                  # $_ has a trailing \n removed, if it had one
    foreach (split) {       # $_ is split on whitespace, into @_
                            # then $_ is set to each chunk in turn
        $_ = reverse;       # the characters in $_ are reversed
        print;              # $_ is printed
    }
}

Perhaps all these uses of $_ are starting to make you nervous. In particular, the foreach and the while both give values to $_. You might fear that at the end of the foreach, the full line as read into $_ with <FH> would be forever gone.

Fortunately, your fears would be unfounded, at least in this case. Perl won't permanently clobber $_'s old value, because the foreach's iterator variable (here, $_) is automatically preserved during the loop. It saves away any old value on entry and restores it upon exit.

However, there is some cause for concern. If the while had been the inner loop and the foreach the outer one, your fears would have been realized. Unlike a foreach loop, the while (<FH>) construct clobbers the value of the global $_ without first localizing it! So any routine—or block for that matter—that uses this construct with $_ should declare local $_.

If a lexical variable (one declared with my) is in scope, the temporary variable will be lexically scoped, private to that loop. Otherwise, it will be a dynamically scoped global variable. To avoid strange magic at a distance, write this more obviously and more clearly as:

foreach my $item (@array) {
    print "i = $item\n";
}

The foreach looping construct has another feature: each time through the loop, the iterator variable becomes not a copy of but rather an alias for the current element. This means that when you change that iterator variable, you really change each element in the list:

@array = (1,2,3);
foreach $item (@array) {
    $item--;
}
print "@array\n";
0 1 2

# multiply everything in @a and @b by seven
@a = ( .5, 3 ); @b = ( 0, 1 );
foreach $item (@a, @b) {
    $item *= 7;
}
print "@a @b\n";
3.5 21 0 7

You can't change a constant, though, so this is illegal:

foreach $n (1, 2, 3) {
    $n **= 2;
}

This aliasing means that using a foreach loop to modify list values is both more readable and faster than the equivalent code using a three-part for loop and explicit indexing would be. This behavior is a feature, not a bug, that was introduced by design. If you didn't know about it, you might accidentally change something. Now you know about it.

For example, to trim leading and trailing whitespace in a hash, we take advantage of how the values function works: the elements of its return list really are the values of the hash, and changing these changes the original hash. Because we use s/// directly on the list returned by the values function without copying these into a variable, we change the real hash itself.

# trim whitespace in the scalar, the array, and in all
# the values in the hash
foreach ($scalar, @array, values %hash) {
    s/^\s+//;
    s/\s+$//;
}

For reasons hearkening back to the equivalent construct in the Unix Bourne shell, the for and foreach keywords are interchangeable:

for $item (@array) {  # same as foreach $item (@array)
    # do something
}

for (@array)      {   # same as foreach $_ (@array)
    # do something
}

This style often indicates that its author writes or maintains shell scripts, perhaps for Unix system administration. As such, their life is probably hard enough, so don't speak too harshly of them. Remember, TMTOWTDI. This is just one of those ways.

If you aren't fluent in Bourne shell, you might find it clearer to express "for each $thing in this @list" by saying foreach, to make your code look less like the shell and more like English. (But don't try to make your English look like your code!)

4.5.4. See Also

The "For Loops," "Foreach Loops," and "Loop Control" sections of perlsyn(1) and Chapter 4 of Programming Perl; the "Temporary Values via local" section of perlsub(1); the "Scoped Declarations" section of Chapter 4 of Programming Perl; we talk about local in Recipe 10.13; we talk about my in Recipe 10.2

Previous | Home | Next
4.4. Implementing a Sparse Array | Book Index | 4.6. Iterating Over an Array by Reference
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.6. Iterating Over an Array by Reference

4.6.1. Problem

You have a reference to an array, and you want to use a loop to work with the array's elements.

4.6.2. Solution

Use foreach or for to loop over the dereferenced array:

# iterate over elements of array in $ARRAYREF
foreach $item (@$ARRAYREF) {
    # do something with $item
}

for ($i = 0; $i <= $#$ARRAYREF; $i++) {
    # do something with $ARRAYREF->[$i]
}

4.6.3. Discussion

The solutions assume you have a scalar variable containing the array reference. This lets you do things like this:

@fruits = ( "Apple", "Blackberry" );
$fruit_ref = \@fruits;
foreach $fruit (@$fruit_ref) {
    print "$fruit tastes good in a pie.\n";
}
Apple tastes good in a pie.
Blackberry tastes good in a pie.

We could have rewritten the foreach loop as a for loop like this:

for ($i=0; $i <= $#$fruit_ref; $i++) {
    print "$fruit_ref->[$i] tastes good in a pie.\n";
}

Frequently, though, the array reference is the result of a more complex expression. Use the @{ EXPR } notation to turn the result of the expression back into an array:

$namelist{felines} = \@rogue_cats;
foreach $cat ( @{ $namelist{felines} } ) {
    print "$cat purrs hypnotically..\n";
}
print "--More--\nYou are controlled.\n";

Again, we can replace the foreach with a for loop:

for ($i=0; $i <= $#{ $namelist{felines} }; $i++) {
    print "$namelist{felines}[$i] purrs hypnotically.\n";
}

4.6.4. See Also

perlref(1) and perllol(1); Chapter 8 of Programming Perl; Recipe 11.1; Recipe 4.5

Previous | Home | Next
4.5. Iterating Over an Array | Book Index | 4.7. Extracting Unique Elements from a List
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.7. Extracting Unique Elements from a List

4.7.1. Problem

You want to eliminate duplicate values from a list, such as when you build the list from a file or from the output of another command. This recipe is equally applicable to removing duplicates as they occur in input and to removing duplicates from an array you've already populated.

4.7.2. Solution

Use a hash to record which items have been seen, then keys to extract them. You can use Perl's idea of truth to shorten and speed up your code.

4.7.2.1. Straightforward

%seen = ( );
@uniq = ( );
foreach $item (@list) {
    unless ($seen{$item}) {
        # if we get here, we have not seen it before
        $seen{$item} = 1;
        push(@uniq, $item);
    }
}

4.7.2.2. Faster

%seen = ( );
foreach $item (@list) {
    push(@uniq, $item) unless $seen{$item}++;
}

4.7.2.3. Similar but with user function

%seen = ( );
foreach $item (@list) {
    some_func($item) unless $seen{$item}++;
}

4.7.2.4. Faster but different

%seen = ( );
foreach $item (@list) {
    $seen{$item}++;
}
@uniq = keys %seen;

4.7.2.5. Faster and even more different

%seen = ( );
@uniq = grep { ! $seen{$_} ++ } @list;

4.7.3. Discussion

The question at the heart of the matter is "Have I seen this element before?" Hashes are ideally suited to such lookups. The first technique (Recipe 4.7.2.1) builds up the array of unique values as we go along, using a hash to record whether something is already in the array.

The second technique (Recipe 4.7.2.2) is the most natural way to write this sort of thing in Perl. It creates a new entry in the hash every time it sees an element that hasn't been seen before, using the ++ operator. This has the side effect of making the hash record the number of times the element was seen. This time we only use the hash for its property of working like a set.

The third example (Recipe 4.7.2.3) is similar to the second but rather than storing the item away, we call some user-defined function with that item as its argument. If that's all we're doing, keeping a spare array of those unique values is unnecessary.

The next mechanism (Recipe 4.7.2.4) waits until it's done processing the list to extract the unique keys from the %seen hash. This may be convenient, but the original order has been lost.

The final approach (Recipe 4.7.2.5) merges the construction of the %seen hash with the extraction of unique elements. This preserves the original order of elements.

Using a hash to record the values has two side effects: processing long lists can take a lot of memory, and the list returned by keys is unordered.

Here's an example of processing input as it is read. We use `who` to gather information on the current user list, then extract the username from each line before updating the hash:

# generate a list of users logged in, removing duplicates
%ucnt = ( );
for (`who`) {
    s/\s.*\n//;   # kill from first space till end-of-line, yielding username
    $ucnt{$_}++;  # record the presence of this user
}
# extract and print unique keys
@users = sort keys %ucnt;
print "users logged in: @users\n";

4.7.4. See Also

The "Foreach Loops" section of perlsyn(1) and Chapter 4 of Programming Perl; the keys function in perlfunc(1) and Chapter 29 of Programming Perl; the "Hashes" section of Chapter 2 of Programming Perl; Chapter 5; we use hashes in a similar fashion in Recipe 4.8 and Recipe 4.9

Previous | Home | Next
4.6. Iterating Over an Array by Reference | Book Index | 4.8. Finding Elements in One Array but Not Another
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.8. Finding Elements in One Array but Not Another

4.8.1. Problem

You want to find elements that are in one array but not another.

4.8.2. Solution

You want to find elements in @A that aren't in @B. Build a hash of the keys of @B to use as a lookup table. Then check each element in @A to see whether it is in @B.

4.8.2.1. Straightforward implementation

# assume @A and @B are already loaded
%seen = ( );                    # lookup table to test membership of B
@aonly = ( );                   # answer

# build lookup table
foreach $item (@B) { $seen{$item} = 1 }

# find only elements in @A and not in @B
foreach $item (@A) {
    unless ($seen{$item}) {
        # it's not in %seen, so add to @aonly
        push(@aonly, $item);
    }
}

4.8.2.2. More idiomatic version

my %seen;     # lookup table
my @aonly;    # answer

# build lookup table
@seen{@B} = ( );

foreach $item (@A) {
    push(@aonly, $item) unless exists $seen{$item};
}

4.8.2.3. Loopless version

my @A = ...;
my @B = ...;

my %seen;
@seen {@A} = ( );
delete @seen {@B};

my @aonly = keys %seen;

4.8.3. Discussion

As with nearly any problem in Perl that asks whether a scalar is in one list or another, this one uses a hash. First, process @B so that the %seen hash records each element from @B by setting its value to 1. Then process @A one element at a time, checking whether that particular element had been in @B by consulting the %seen hash.

The given code retains duplicate elements in @A. This can be fixed easily by adding the elements of @A to %seen as they are processed:

foreach $item (@A) {
    push(@aonly, $item) unless $seen{$item};
    $seen{$item} = 1;                       # mark as seen
}

The first two solutions differ mainly in how they build the hash. The first iterates through @B. The second uses a hash slice to initialize the hash. A hash slice is easiest illustrated by this example:

$hash{"key1"} = 1;
$hash{"key2"} = 2;

which is equivalent to:

@hash{"key1", "key2"} = (1,2);

The list in the curly braces holds the keys; the list on the right holds the values. We initialize %seen in the first solution by looping over each element in @B and setting the appropriate value of %seen to 1. In the second, we simply say:

@seen{@B} = ( );

This uses items in @B as keys for %seen, setting each corresponding value to undef, because there are fewer values on the right than places to put them. This works out here because we check for existence of the key, not logical truth or defined ness of the value. If we needed true values, a slice could still shorten our code:

@seen{@B} = (1) x @B;

In the third solution, we make use of this property even further and avoid explicit loops altogether. (Not that avoiding loops should be construed as being particularly virtuous; we're just showing you that there's more than one way to do it.) The slice assignment makes any element that was in @A a key, and the slice deletion removes from the hash any keys that were elements of @B, leaving those that were only in @A.

A fairly common situation where this might arise is when you have two files and would like to know which lines from the second file either were or weren't in the first. Here's a simple solution based on this recipe:

open(OLD, $path1)        || die "can't open $path1: $!";
@seen{ <OLD> } = ( );
open(NEW, $path2)        || die "can't open $path2: $!";
while (<NEW>) {
    print if exists $seen{$_};
}

This shows the lines in the second file that were already seen in the first one. Use unless instead of if to show the lines in the second file that were not in the first.

Imagine two files, the first containing the lines:

red
yellow
green
blue

and the second containing:

green
orange
purple
black
yellow

The output using if would be:

green
yellow

and the output using unless would be:

orange
purple
black

You could even do this from the command line; given a suitable cat(1) program, it's easy:

% perl -e '@s{`cat OLD`}=( ); exists $s{$_} && print for `cat NEW''
% perl -e '@s{`cat OLD`}=( ); exists $s{$_} || print for `cat NEW''

You'd find that you just emulated these calls to the Unix fgrep(1) program:

% fgrep -Ff  OLD NEW
% fgrep -vFf OLD NEW

4.8.4. See Also

Hash slices are explained in perldata(1) and the "Variables" section of Chapter 2 of Programming Perl; Chapter 5; we use hashes in a similar fashion in Recipe 4.7 and Recipe 4.9

Previous | Home | Next
4.7. Extracting Unique Elements from a List | Book Index | 4.9. Computing Union, Intersection, or Difference of Unique Lists
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.9. Computing Union, Intersection, or Difference of Unique Lists

4.9.1. Problem

You have a pair of lists, each holding unduplicated items. You'd like to find out which items are in both lists (intersection), one but not the other (difference), or either (union).

4.9.2. Solution

The following solutions need the listed initializations:

@a = (1, 3, 5, 6, 7, 8);
@b = (2, 3, 5, 7, 9);

@union = @isect = @diff = ( );
%union = %isect = ( );
%count = ( );

4.9.2.1. Simple solution for union and intersection

foreach $e (@a) { $union{$e} = 1 }

foreach $e (@b) {
    if ( $union{$e} ) { $isect{$e} = 1 }
    $union{$e} = 1;
}
@union = keys %union;
@isect = keys %isect;

4.9.2.2. More idiomatic version

foreach $e (@a, @b) { $union{$e}++ && $isect{$e}++ }

@union = keys %union;
@isect = keys %isect;

4.9.2.3. Union, intersection, and symmetric difference

foreach $e (@a, @b) { $count{$e}++ }

@union = keys %count;
foreach $e (keys %count) {
    if ($count{$e} =  = 2) {
        push @isect, $e;
    } else {
        push @diff, $e;
    }
}

4.9.2.4. Indirect solution

@isect = @diff = @union = ( );

foreach $e (@a, @b) { $count{$e}++ }

@union = keys %count;
foreach $e (keys %count) {
    push @{ $count{$e} =  = 2 ? \@isect : \@diff }, $e;
}

4.9.3. Discussion

The first solution most directly computes the union and intersection of two lists, neither containing duplicates. Two hashes are used to record whether a particular item goes in the union or the intersection. We put every element of the first array in the union hash, giving it a true value. Then, processing each element of the second array, we check whether that element is already present in the union. If it is, we put it in the intersection as well. In any event, it goes into the union. When we're done, we extract the keys of both the union and intersection hashes. The values aren't needed.

The second solution (Recipe 4.8.2.2) is essentially the same but relies on familiarity with the Perl (and awk, C, C++, and Java) ++ and && operators. By placing the ++ after the variable, we first look at its old value before incrementing it. The first time through it won't be in the union, which makes the first part of the && false, so the second part is consequently ignored. The second time that we encounter the same element, it's already present in the union, so we put it in the intersection.

The third solution uses just one hash to track how many times each element is seen. Once both arrays have their elements recorded in the hash, we grab those keys and put them in the union. Then we process those hash keys one at a time. Keys whose values are 2 were in both arrays, so they go in the intersection array. Keys whose values are 1 were in just one of the two arrays, so they go in the difference array. Elements of the output arrays are not in the same order as those in the input arrays.

The last solution, like the previous one, uses just one hash to count how many times each element is encountered. Here, though, we dynamically select one of two possible arrays by placing within the @{...} array-dereferencing block an expression whose evaluation yields a reference to whichever array is demanded by the situation.

In this recipe we compute the symmetric difference, not the simple difference. These are terms from set theory. A symmetric difference is the set of all elements that are members of either @A or @B, but not both. A simple difference is the set of members of @A but not @B, which we calculated in Recipe 4.8.

4.9.4. See Also

The "Hashes" section of Chapter 2 of Programming Perl; Chapter 5; we use hashes in a similar fashion in Recipe 4.7 and Recipe 4.8

Previous | Home | Next
4.8. Finding Elements in One Array but Not Another | Book Index | 4.10. Appending One Array to Another
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.10. Appending One Array to Another

4.10.1. Problem

You want to join two arrays by appending all elements of one to the other.

4.10.2. Solution

Use push:

# push
push(@ARRAY1, @ARRAY2);

4.10.3. Discussion

The push function is optimized for appending a list to the end of an array. You can take advantage of Perl's list flattening to join two arrays, but this results in significantly more copying than push:

@ARRAY1 = (@ARRAY1, @ARRAY2);

Here's an example of push in action:

@members = ("Time", "Flies");
@initiates = ("An", "Arrow");
push(@members, @initiates);
# @members is now ("Time", "Flies", "An", "Arrow")

To insert the elements of one array into the middle of another, use the splice function:

splice(@members, 2, 0, "Like", @initiates);
print "@members\n";
splice(@members, 0, 1, "Fruit");
splice(@members, -2, 2, "A", "Banana");
print "@members\n";

This is the output:

Time Flies Like An Arrow
Fruit Flies Like A Banana

4.10.4. See Also

The splice and push functions in perlfunc(1) and Chapter 29 of Programming Perl; the "List Values and Arrays" section of Chapter 2 of Programming Perl; the "List Value Constructors" section of perldata(1)

Previous | Home | Next
4.9. Computing Union, Intersection, or Difference of Unique Lists | Book Index | 4.11. Reversing an Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.11. Reversing an Array

4.11.1. Problem

You want to reverse an array.

4.11.2. Solution

Use the reverse function:

# reverse @ARRAY into @REVERSED
@REVERSED = reverse @ARRAY;

Or process with a foreach loop on a reversed list:

foreach $element (reverse @ARRAY) {
    # do something with $element
}

Or use a for loop, starting with the index of the last element and working your way down:

for ($i = $#ARRAY; $i >= 0; $i--) {
    # do something with $ARRAY[$i]
}

4.11.3. Discussion

Called in list context, the reverse function reverses elements of its argument list. You can save a copy of that reversed list into an array, or just use foreach to walk through it directly if that's all you need. The for loop processes the array elements in reverse order by using explicit indices. If you don't need a reversed copy of the array, the for loop can save memory and time on very large arrays.

If you're using reverse to reverse a list that you just sorted, you should have sorted it in the correct order to begin with. For example:

# two-step: sort then reverse
@ascending = sort { $a cmp $b } @users;
@descending = reverse @ascending;

# one-step: sort with reverse comparison
@descending = sort { $b cmp $a } @users;

4.11.4. See Also

The reverse function in perlfunc(1) and Chapter 29 of Programming Perl; we use reverse in Recipe 1.7

Previous | Home | Next
4.10. Appending One Array to Another | Book Index | 4.12. Processing Multiple Elements of an Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.12. Processing Multiple Elements of an Array

4.12.1. Problem

You want to pop or shift multiple elements at a time.

4.12.2. Solution

Use splice:

# remove $N elements from front of @ARRAY (shift $N)
@FRONT = splice(@ARRAY, 0, $N);

# remove $N elements from the end of the array (pop $N)
@END = splice(@ARRAY, -$N);

4.12.3. Discussion

The splice function allows you to add elements, delete elements, or both, at any point in an array, not just at the ends. All other operations that modify an array's length can also be written as a splice:

Direct method

Splice equivalent

push(@a, $x, $y)

splice(@a, @a, 0, $x, $y)

pop(@a)

splice(@a, -1)

shift(@a)

splice(@a, 0, 1)

unshift(@a, $x, $y)

splice(@a, 0, 0, $x, $y)

$a[$x] = $y

splice(@a, $x, 1, $y)

(@a, @a = ( ))

splice(@a)

Unlike pop and unshift, though, which always delete and return just one element at a time—and from the ends only—splice lets you specify the number of elements. This leads to code like the examples in the Solution.

It's often convenient to wrap these splice s as functions:

sub shift2 (\@) {
    return splice(@{$_[0]}, 0, 2);
}

sub pop2 (\@) {
    return splice(@{$_[0]}, -2);
}

This makes their behavior more apparent when you use them:

@friends = qw(Peter Paul Mary Jim Tim);
($this, $that) = shift2(@friends);
# $this contains Peter, $that has Paul, and
# @friends has Mary, Jim, and Tim

@beverages = qw(Dew Jolt Cola Sprite Fresca);
@pair = pop2(@beverages);
# $pair[0] contains Sprite, $pair[1] has Fresca,
# and @beverages has (Dew, Jolt, Cola)

The splice function returns the elements it removed from the array, so shift2 replaces the first two elements in @ARRAY with nothing (i.e., deletes them) and returns the two elements deleted. In pop2, the two elements at end of the array are removed and returned.

These two functions are prototyped to take an array reference as their argument to better mimic the built-in shift and pop functions. The caller doesn't pass in an explicit reference using a backslash. Instead, the compiler, having seen the array reference prototype, arranges to pass the array by reference anyway. Advantages to this approach include efficiency, transparency, and compile-time parameter checking. One disadvantage is that the thing passed in must look like a real array with a leading @ sign, not just a scalar containing an array reference. If it did, you'd have to prepend an @, making it less transparent:

$line[5] = \@list;
@got = pop2( @{ $line[5] } );

This is another example of where a proper array and not a mere list is called for. The \@ prototype requires that whatever goes in that argument slot be an array. $line[5] isn't an array, but an array reference. That's why we need the "extra" @ sign.

4.12.4. See Also

The splice function in perlfunc(1) and Chapter 29 of Programming Perl; the "Prototypes" sections of perlsub(1) and Chapter 6 of Programming Perl; we use splice in Recipe 4.10

Previous | Home | Next
4.11. Reversing an Array | Book Index | 4.13. Finding the First List Element That Passes a Test
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.13. Finding the First List Element That Passes a Test

4.13.1. Problem

You want the first element in the list (or its index) that passes a test. Alternatively, you want to know whether any element passes the test. The test can be simple identity ("Is this element in the list?")[7] or more complex ("I have a list of Employee objects, sorted from highest salary to lowest. Which manager has the highest salary?"). Simple cases normally require only the value of the element, but when the array itself will be altered, you probably need to know the index number of the first matching element.

[7]But why didn't you use a hash then?

4.13.2. Solution

To find a matching value, use foreach to loop over every element, and call last as soon as you find a match:

my ($match, $found, $item);
foreach $item (@array) {
    if (CRITERION) {
        $match = $item;  # must save
        $found = 1;
        last;
    }
}
if ($found) {
    ## do something with $match
} else {
    ## unfound
}

To find a matching index, use for to loop a variable over every array index, and call last as soon as you find a match:

my ($i, $match_idx);
for ($i = 0; $i < @array; $i++) {
    if (CRITERION) {
        $match_idx = $i;    # save the index
        last;
    }
}

if (defined $match_idx) {
    ## found in $array[$match_idx]
} else {
    ## unfound
}

The List::Util module, shipped standard with Perl as of v5.8 but available on CPAN for earlier versions, provides an even easier approach:

use List::Util qw(first);
$match = first { CRITERION } @list

4.13.3. Discussion

Lacking (until recently) a built-in mechanism to do this, we must write our own code to go through the list and test each element. We use foreach and for, and call last to ensure that we stop as soon as we find a match. Before we use last to stop looking, though, we save the value or index.

A common approach is to try to use grep here. But grep always tests all elements and finds all matches, so it's inefficient if you want only the first match. However, grep might still be faster. That's because there will be less source code if you use grep rather than writing your own loop. That means fewer internal Perl operations, and it is these that in practice often dominate runtimes.

Beyond a certain size of your data set, a loop that terminates early will still be faster—assuming it has the chance to do so. Empirical evidence suggests that for will be faster as long as you can exit before the first two-thirds of the list has been examined. It's worthwhile to know how to do that.

We have to set $match when we want the value of the first matching element. We can't just test $item at the end of the loop, because foreach automatically local izes the iterator variable and thereby prevents us from accessing the final loop value after the loop ends. See Recipe 4.5.

Here's an example. Assume that @all_emps holds a list of Employee objects, sorted in descending order by salary. We wish to find the highest paid engineer, who will be the first engineer in the array. We only want to print the engineer's name, so we want the value, not the index.

foreach $employee (@all_emps) {
    if ( $employee->category( ) eq 'engineer' ) {
        $top_engr = $employee;
        last;
    }
}
print "Highest paid engineer is: ", $highest_engineer->name( ), "\n";

When we're searching and want only the index, we can save some code by remembering that $i will not be an acceptable array index if we don't find a match. This mainly saves us code space, as not doing an assignment doesn't really win much compared to the time spent testing list elements. It's more obscure, because it tests if ($i < @ARRAY) to check whether we found a match, instead of the more obvious defined test in the previous solution.

for ($i = 0; $i < @ARRAY; $i++) {
    last if CRITERION;
}
if ($i < @ARRAY) {
    ## found and $i is the index
} else {
    ## not found
}

The first function from List::Util encapsulates the logic from an entire loop into a convenient, easy-to-use function. It acts just like a short-circuiting form of the built-in grep function that stops as soon as a match is found. While running, each list element is in a localized $_ variable. For example:

$first_odd = first { $_ % 2 =  = 1 } @ARRAY;

Or rewriting the previous employee loop:

$top_engr = first { $_->category( ) eq 'engineer' } @all_emps;

4.13.4. See Also

The "For Loops," "Foreach Loops," and "Loop Control" sections of perlsyn(1) and Chapter 4 of Programming Perl; the grep function in perlfunc(1) and Chapter 29 of Programming Perl

Previous | Home | Next
4.12. Processing Multiple Elements of an Array | Book Index | 4.14. Finding All Elements in an Array Matching Certain Criteria
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.14. Finding All Elements in an Array Matching Certain Criteria

4.14.1. Problem

From a list, you want only the elements that match certain criteria.

This notion of extracting a subset of a larger list is common. It's how you find all engineers in a list of employees, all users in the "staff" group, or all the filenames you're interested in.

4.14.2. Solution

Use grep to apply a condition to all elements in the list and return only those for which the condition was true:

@MATCHING = grep { TEST ($_) } @LIST;

4.14.3. Discussion

This could also be accomplished with a foreach loop:

@matching = ( );
foreach (@list) {
    push(@matching, $_) if TEST ($_);
}

The Perl grep function is shorthand for all that looping and mucking about. It's not really like the Unix grep command; it doesn't have options to return line numbers or to negate the test, and it isn't limited to regular-expression tests. For example, to filter out just the large numbers from an array or to find out which keys in a hash have very large values:

@bigs = grep { $_ > 1_000_000 } @nums;
@pigs = grep { $users{$_} > 1e7 } keys %users;

Here's something that sets @matching to lines from the who command that start with "gnat ":

@matching = grep { /^gnat / } `who`;

Here's another example:

@engineers = grep { $_->position( ) eq "Engineer" } @employees;

It extracts only those objects from the array @employees whose position method returns the string Engineer.

You could have even more complex tests in a grep:

@secondary_assistance = grep { $_->income >= 26_000 &&
                               $_->income <  30_000 }
                        @applicants;

But at that point you may decide it would be more legible to write a proper loop instead.

4.14.4. See Also

The "For Loops," "Foreach Loops," and "Loop Control" sections of perlsyn(1) and Chapter 4 of Programming Perl; the grep function in perlfunc(1) and Chapter 29 of Programming Perl; your system's who(1) manpage, if it exists; Recipe 4.13

Previous | Home | Next
4.13. Finding the First List Element That Passes a Test | Book Index | 4.15. Sorting an Array Numerically
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.15. Sorting an Array Numerically

4.15.1. Problem

You want to sort a list of numbers, but Perl's sort (by default) sorts in ASCII order.

4.15.2. Solution

Use Perl's sort function and the <=> numerical comparison operator:

@sorted = sort { $a <=> $b } @unsorted;

4.15.3. Discussion

The sort function takes an optional code block, which lets you replace the default alphabetic comparison with your own subroutine. This comparison function is called each time sort has to compare two values. The values to compare are loaded into the special package variables $a and $b, which are automatically local ized.

The comparison function should return a negative number if $a ought to appear before $b in the output list, 0 if they're the same and their order doesn't matter, or a positive number if $a ought to appear after $b. Perl has two operators that behave this way: <=> for sorting numbers in ascending numeric order, and cmp for sorting strings in ascending alphabetic order. By default, sort uses cmp-style comparisons.

Here's code that sorts the list of PIDs in @pids, lets the user select one, then sends it a TERM signal followed by a KILL signal. We use a code block that compares $a to $b with <=> to sort numerically:

# @pids is an unsorted array of process IDs
foreach my $pid (sort { $a <=> $b } @pids) {
    print "$pid\n";
}
print "Select a process ID to kill:\n";
chomp ($pid = <>);
die "Exiting ... \n" unless $pid && $pid =~ /^\d+$/;
kill('TERM',$pid);
sleep 2;
kill('KILL',$pid);

If you use $a <=> $b or $a cmp $b, the list will be sorted in ascending order. For a descending sort, all we have to do is swap $a and $b in the sort subroutine:

@descending = sort { $b <=> $a } @unsorted;

Comparison routines must be consistent; that is, they should always return the same answer when called with the same values. Inconsistent comparison routines lead to infinite loops or core dumps, especially in older releases of Perl.

You can also say sort SUBNAME LIST where SUBNAME is the name of a comparison subroutine returning -1, 0, or +1. In the interests of speed, the normal calling conventions are bypassed, and the values to be compared magically appear for the duration of the subroutine in the global package variables $a and $b. Because of the odd way Perl calls this subroutine, it may not be recursive.

A word of warning: $a and $b are set in the package active in the call to sort, which may not be the same as the one that the SUBNAME function passed to sort was compiled in! For example:

package Sort_Subs;
sub revnum { $b <=> $a }

package Other_Pack;
@all = sort Sort_Subs::revnum 4, 19, 8, 3;

This will silently fail (unless you have -w in effect, in which case it will vocally fail) because the sort call sets the package variables $a and $b in its own package, Other_Pack, but the revnum function uses its own package's versions. This is another reason why in-lining sort functions is easier, as in:

@all = sort { $b <=> $a } 4, 19, 8, 3;

For more on packages, see Chapter 10.

4.15.4. See Also

The cmp and <=> operators in perlop(1) and Chapter 3 of Programming Perl; the kill, sort, and sleep functions in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 4.16

Previous | Home | Next
4.14. Finding All Elements in an Array Matching Certain Criteria | Book Index | 4.16. Sorting a List by Computable Field
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.16. Sorting a List by Computable Field

4.16.1. Problem

You want to sort a list by something more complex than a simple string or numeric comparison.

This is common when working with objects ("sort by the employee's salary") or complex data structures ("sort by the third element in the array that this is a reference to"). It's also applicable when you want to sort by more than one key; for instance, sorting by birthday and then by name when multiple people share the same birthday.

4.16.2. Solution

Use the customizable comparison routine in sort:

@ordered = sort { compare( ) } @unordered;

You can speed this up by precomputing the field.

@precomputed = map { [compute( ),$_] } @unordered;
@ordered_precomputed = sort { $a->[0] <=> $b->[0] } @precomputed;
@ordered = map { $_->[1] } @ordered_precomputed;

And, finally, you can combine the three steps:

@ordered = map { $_->[1] }
           sort { $a->[0] <=> $b->[0] }
           map { [compute( ), $_] }
           @unordered;

4.16.3. Discussion

The use of a comparison routine was explained in Recipe 4.15. As well as using built-in operators like <=>, you can construct more complex tests:

@ordered = sort { $a->name cmp $b->name } @employees;

You often see sort used like this in part of a foreach loop:

foreach $employee (sort { $a->name cmp $b->name } @employees) {
    print $employee->name, " earns \$", $employee->salary, "\n";
}

If you're going to do a lot of work with elements in a particular order, it's more efficient to sort once and work from that:

@sorted_employees = sort { $a->name cmp $b->name } @employees;
foreach $employee (@sorted_employees) {
    print $employee->name, " earns \$", $employee->salary, "\n";
}
# load %bonus
foreach $employee (@sorted_employees) {
    if ( $bonus{ $employee->ssn } ) {
      print $employee->name, " got a bonus!\n";
    }
}

We can put multiple comparisons in the routine and separate them with ||. || is a short-circuit operator: it returns the first true value it finds. This means we can sort by one kind of comparison, but if the elements are equal (the comparison returns 0), we can sort by another. This has the effect of a sort within a sort:

@sorted = sort { $a->name cmp $b->name
                           ||
                  $b->age <=> $a->age } @employees;

This first considers the names of the two employees to be compared. If they're not equal, || stops and returns the result of the cmp (effectively sorting them in ascending order by name). If the names are equal, though, || keeps testing and returns the result of the <=> (sorting them in descending order by age). The result is a list that is sorted by name and by age within groups of the same name.

Let's look at a real-life example of sorting. First we fetch all system users, represented as User::pwent objects. Then we sort them by name and print the sorted list:

use User::pwent qw(getpwent);
@users = ( );
# fetch all users
while (defined($user = getpwent)) {
    push(@users, $user);
}
@users = sort { $a->name cmp $b->name } @users;
foreach $user (@users) {
    print $user->name, "\n";
}

We can have more than simple comparisons, or combinations of simple comparisons. This code sorts a list of names by comparing the second letters of the names. It gets the second letters by using substr:

@sorted = sort { substr($a,1,1) cmp substr($b,1,1) } @names;

and here we sort by string length:

@sorted = sort { length $a <=> length $b } @strings;

The sort function calls the code block each time it needs to compare two elements, so the number of comparisons grows dramatically with the number of elements we're sorting. Sorting 10 elements requires (on average) 46 comparisons, but sorting 1,000 elements requires 14,000 comparisons. A time-consuming operation like a split or a subroutine call for each comparison can easily make your program crawl.

Fortunately, we can remove this bottleneck by running the operation once per element prior to the sort. Use map to store the results of the operation in an array whose elements are anonymous arrays containing both the computed field and the original field. Then we sort this array of arrays on the precomputed field and use map to get the sorted original data. This map-sort-map concept is useful and common, so let's look at it in depth.

Let's apply map-sort-map to the sorting by string length example:

@temp   = map  {  [ length $_, $_ ]  } @strings;
@temp   = sort { $a->[0] <=> $b->[0] } @temp;
@sorted = map  {        $_->[1]      } @temp;

The first line creates a temporary array of strings and their lengths, using map. The second line sorts the temporary array by comparing the precomputed lengths. The third line turns the sorted temporary array of strings and lengths back into a sorted array of strings. This way, we calculate the length of each string only once.

Because the input to each line is the output of the previous line (the @temp array we make in line 1 is fed to sort in line 2, and that output is fed to map in line 3), we can combine it into one statement and eliminate the temporary array:

@sorted = map  { $_->[1] }
          sort { $a->[0] <=> $b->[0] }
          map  { [ length $_, $_ ] }
          @strings;

The operations now appear in reverse order. When you meet a map-sort-map, you should read it from the bottom up to determine the function:

@strings
The last part is the data to be sorted. Here it's just an array, but later we'll see that this can be a subroutine or even backticks. Anything that returns a list is fair game.

map
The map closer to the bottom builds the temporary list of anonymous arrays. This list contains the precomputed fields (length $_) and also records the original element ($_) by storing both in an anonymous array. Look at this map line to find out how the fields are computed.

sort
The sort line sorts the list of anonymous arrays by comparing the precomputed fields. It won't tell you much, other than whether the list is sorted in ascending or descending order.

map
The map at the top of the statement turns the sorted list of anonymous arrays back into a list of the sorted original elements. It will generally be the same for every map-sort-map.

Here's a more complicated example, which sorts by the first number that appears on each line in @fields:

@temp          = map  {    [ /(\d+)/, $_ ]  } @fields;
@sorted_temp   = sort { $a->[0] <=> $b->[0] } @temp;
@sorted_fields = map  {       $_->[1]       } @sorted_temp;

The regular expression mumbo jumbo in the first line extracts the first number from the line being processed by map. We use the regular expression /(\d+)/ in a list context to extract the number.

We can remove the temporary arrays in that code, giving us:

@sorted_fields = map  { $_->[1] }
                 sort { $a->[0] <=> $b->[0] }
                 map  { [ /(\d+)/, $_ ] }
                 @fields;

This final example compactly sorts colon-separated data, as from Unix's passwd file. It sorts the file numerically by the fourth field (group id), then numerically by the third field (user id), and then alphabetically by the first field (username).

print map  { $_->[0] }             # whole line
      sort {
              $a->[1] <=> $b->[1]  # gid
                      ||
              $a->[2] <=> $b->[2]  # uid
                      ||
              $a->[3] cmp $b->[3]  # login
      }
      map  { [ $_, (split /:/)[3,2,0] ] }
      `cat /etc/passwd`;

4.16.4. See Also

The sort function in perlfunc(1) and Chapter 29 of Programming Perl; the cmp and <=> operators in perlop(1) and Chapter 3 of Programming Perl; Recipe 4.15

Previous | Home | Next
4.15. Sorting an Array Numerically | Book Index | 4.17. Implementing a Circular List
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.17. Implementing a Circular List

4.17.1. Problem

You want to create and manipulate a circular list.

4.17.2. Solution

Use unshift and pop (or push and shift) on a normal array.

4.17.3. Procedure

unshift(@circular, pop(@circular));  # the last shall be first
push(@circular, shift(@circular));   # and vice versa

4.17.4. Discussion

Circular lists are commonly used to repeatedly process things in order; for example, connections to a server. The code shown previously isn't a true computer science circular list, with pointers and true circularity. Instead, the operations provide for moving the last element to the first position, and vice versa.

sub grab_and_rotate ( \@ ) {
    my $listref = shift;
    my $element = $listref->[0];
    push(@$listref, shift @$listref);
    return $element;
}

@processes = ( 1, 2, 3, 4, 5 );
while (1) {
    $process = grab_and_rotate(@processes);
    print "Handling process $process\n";
    sleep 1;
}

4.17.5. See Also

The unshift and push functions in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 13.13

Previous | Home | Next
4.16. Sorting a List by Computable Field | Book Index | 4.18. Randomizing an Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.18. Randomizing an Array

4.18.1. Problem

You want to randomly shuffle the elements of an array. The obvious application is writing a card game, where you must shuffle a deck of cards, but it is equally applicable to any situation where you want to treat elements of an array in a random order.

4.18.2. Solution

Use the shuffle function from the standard List::Util module, which returns the elements of its input list in a random order.

use List::Util qw(shuffle);
@array = shuffle(@array);

4.18.3. Discussion

Shuffling is a surprisingly tricky process. It's easy to write a bad shuffle:

sub naive_shuffle {                             # DON'T DO THIS
    for (my $i = 0; $i < @_; $i++) {
        my $j = int rand @_;                    # pick random element
        ($_[$i], $_[$j]) = ($_[$j], $_[$i]);    # swap 'em
    }
}

This algorithm is biased; the list's possible permutations don't all have the same probability of being generated. The proof of this is simple: take the case where we're passed a three-element list. We generate three random numbers, each of which can have three possible values, yielding 27 possible outcomes. There are only six permutations of the three-element list, though. Because 27 isn't evenly divisible by 6, some outcomes are more likely than others.

The List::Util module's shuffle function avoids this bias to produce a more randomly shuffled result.

If all you want to do is pick one random element from the array, use:

$value = $array[ int(rand(@array)) ];

4.18.4. See Also

The rand function in perlfunc(1) and Chapter 29 of Programming Perl; for more on random numbers, see Recipe 2.6, Recipe 2.7, and Recipe 2.8; Recipe 4.20 provides another way to select a random permutation

Previous | Home | Next
4.17. Implementing a Circular List | Book Index | 4.19. Program: words
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.19. Program: words

Have you ever wondered how programs like ls generate columns of sorted output that you read down the columns instead of across the rows? For example:

awk      cp       ed       login    mount    rmdir    sum
basename csh      egrep    ls       mt       sed      sync
cat      date     fgrep    mail     mv       sh       tar
chgrp    dd       grep     mkdir    ps       sort     touch
chmod    df       kill     mknod    pwd      stty     vi
chown    echo     ln       more     rm       su

Example 4-2 does this.

Example 4-2. words

  #!/usr/bin/perl -w
  # words - gather lines, present in columns

  use strict;

  my ($item, $cols, $rows, $maxlen);
  my ($xpixel, $ypixel, $mask, @data);

  getwinsize( );

  # first gather up every line of input,
  # remembering the longest line length seen
  $maxlen = 1;
  while (<>) {
      my $mylen;
      s/\s+$//;
      $maxlen = $mylen if (($mylen = length) > $maxlen);
      push(@data, $_);
  }

  $maxlen += 1;               # to make extra space

  # determine boundaries of screen
  $cols = int($cols / $maxlen) || 1;
  $rows = int(($#data+$cols) / $cols);

  # pre-create mask for faster computation
  $mask = sprintf("%%-%ds ", $maxlen-1);

  # subroutine to check whether at last item on line
  sub EOL { ($item+1) % $cols =  = 0 }

  # now process each item, picking out proper piece for this position
  for ($item = 0; $item < $rows * $cols; $item++) {
      my $target =  ($item % $cols) * $rows + int($item/$cols);
      my $piece = sprintf($mask, $target < @data ? $data[$target] : "");
      $piece =~ s/\s+$// if EOL( );  # don't blank-pad to EOL
      print $piece;
      print "\n" if EOL( );
  }

  # finish up if needed
  print "\n" if EOL( );

  # not portable -- linux only
  sub getwinsize {
      my $winsize = "\0" x 8;
      my $TIOCGWINSZ = 0x40087468;
      if (ioctl(STDOUT, $TIOCGWINSZ, $winsize)) {
          ($rows, $cols, $xpixel, $ypixel) = unpack('S4', $winsize);
      } else {
          $cols = 80;
      }
  }

The most obvious way to print out a sorted list in columns is to print each element of the list, one at a time, padded out to a particular width. Then when you're about to hit the end of the line, generate a newline. But that only works if you're planning on reading each row from left to right. If you instead expect to read it down each column, this approach won't do.

The words program is a filter that generates output going down the columns. It reads all input, keeping track of the length of the longest line seen. Once everything has been read in, it divides the screen width by the length of the longest input record seen, yielding the expected number of columns.

Then the program goes into a loop that executes once per input record, but the output order isn't in the obvious order. Imagine you had a list of nine items:

Wrong       Right
-----       -----
1 2 3       1 4 7
4 5 6       2 5 8
7 8 9       3 6 9

The words program does the necessary calculations to print out elements (1,4,7) on one line, (2,5,8) on the next, and (3,6,9) on the last.

To figure out the current window size, this program does an ioctl call. This works fine—on the system it was written for. On any other system, it won't work. If that's good enough for you, then good for you. Recipe 12.17 shows how to find this on your system using the ioctl.ph file, or with a C program. Recipe 15.4 shows a more portable solution, but that requires installing a CPAN module.

4.19.1. See Also

Recipe 15.4

Previous | Home | Next
4.18. Randomizing an Array | Book Index | 4.20. Program: permute
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.20. Program: permute

Have you ever wanted to generate all possible permutations of an array or to execute some code for every possible permutation? For example:

% echo man bites dog | permute
dog bites man
bites dog man
dog man bites
man dog bites
bites man dog
man bites dog

The number of permutations of a set is the factorial of the size of the set. This number grows extremely fast, so you don't want to run it on many permutations:

Set Size            Permutations
1                   1
2                   2
3                   6
4                   24
5                   120
6                   720
7                   5040
8                   40320
9                   362880
10                  3628800
11                  39916800
12                  479001600
13                  6227020800
14                  87178291200
15                  1307674368000

Doing something for each alternative takes a correspondingly large amount of time. In fact, factorial algorithms exceed the number of particles in the universe with very small inputs. The factorial of 500 is greater than ten raised to the thousandth power!

use Math::BigInt;
sub factorial {
    my $n = shift;
    my $s = 1;
    $s *= $n-- while $n > 0;
    return $s;
}
print factorial(Math::BigInt->new("500"));
+1220136... (1035 digits total)

The two solutions that follow differ in the order of the permutations they return.

The solution in Example 4-3 uses a classic list permutation algorithm used by Lisp hackers. It's relatively straightforward but makes unnecessary copies. It's also hardwired to do nothing but print out its permutations.

Example 4-3. tsc-permute

  #!/usr/bin/perl -n
  # tsc_permute: permute each word of input
  permute([split], [  ]);
  sub permute {
      my @items = @{ $_[0] };
      my @perms = @{ $_[1] };
      unless (@items) {
          print "@perms\n";
      } else {
          my (@newitems,@newperms,$i);
          foreach $i (0 .. $#items) {
              @newitems = @items;
              @newperms = @perms;
              unshift(@newperms, splice(@newitems, $i, 1));
              permute( \@newitems, \@newperms);
          }
      }
  }

The solution in Example 4-4, provided by Mark-Jason Dominus, is faster (by around 25%) and more elegant. Rather than precalculate all permutations, his code generates the nth particular permutation. It is elegant in two ways. First, it avoids recursion except to calculate the factorial, which the permutation algorithm proper does not use. Second, it generates a permutation of integers rather than permute the actual data set.

He also uses a time-saving technique called memoizing. The idea is that a function that always returns a particular answer when called with a particular argument memorizes that answer. That way, the next time it's called with the same argument, no further calculations are required. The factorial function uses a private array @fact to remember previously calculated factorial values as described in Recipe 10.3. This technique is so useful that there's a standard module that will handle the value caching for you. If you just had a regular factorial function that didn't have its own caching, you could add caching to the existing function this way:

use Memoize;
memoize("factorial");

You call n2perm with two arguments: the permutation number to generate (from 0 to factorial(N), where N is the size of your array) and the subscript of the array's last element. The n2perm function calculates directions for the permutation in the n2pat subroutine. Then it converts those directions into a permutation of integers in the pat2perm subroutine. The directions are a list like (0 2 0 1 0), which means: "Splice out the 0th element, then the second element from the remaining list, then the 0th element, then the first, then the 0th."

Example 4-4. mjd-permute

  #!/usr/bin/perl -w
  # mjd_permute: permute each word of input
  use strict;
  sub factorial($);  # forward reference to declare prototype

  while (<>) {
      my @data = split;
      my $num_permutations = factorial(scalar @data);
      for (my $i=0; $i < $num_permutations; $i++) {
          my @permutation = @data[n2perm($i, $#data)];
          print "@permutation\n";
      }
  }

  # Utility function: factorial with memoizing
  BEGIN {
    my @fact = (1);
    sub factorial($) {
        my $n = shift;
        return $fact[$n] if defined $fact[$n];
        $fact[$n] = $n * factorial($n - 1);
    }
  }

  # n2pat($N, $len) : produce the $N-th pattern of length $len
  sub n2pat {
      my $i   = 1;
      my $N   = shift;
      my $len = shift;
      my @pat;
      while ($i <= $len + 1) {   # Should really be just while ($N) { ...
          push @pat, $N % $i;
          $N = int($N/$i);
          $i++;
      }
      return @pat;
  }

  # pat2perm(@pat) : turn pattern returned by n2pat( ) into
  # permutation of integers.  XXX: splice is already O(N)
  sub pat2perm {
      my @pat    = @_;
      my @source = (0 .. $#pat);
      my @perm;
      push @perm, splice(@source, (pop @pat), 1) while @pat;
      return @perm;
  }

  # n2perm($N, $len) : generate the Nth permutation of $len objects
  sub n2perm {
      pat2perm(n2pat(@_));
  }

4.20.1. See Also

unshift and splice in perlfunc(1) or Chapter 29 of Programming Perl; the sections discussing closures in perlsub(1) and perlref(1) and Chapter 8 of Programming Perl; Recipe 2.6; Recipe 10.3

Previous | Home | Next
4.19. Program: words | Book Index | 5. Hashes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 5. Hashes

Contents:

Introduction
Adding an Element to a Hash
Testing for the Presence of a Key in a Hash
Creating a Hash with Immutable Keys or Values
Deleting from a Hash
Traversing a Hash
Printing a Hash
Retrieving from a Hash in Insertion Order
Hashes with Multiple Values per Key
Inverting a Hash
Sorting a Hash
Merging Hashes
Finding Common or Different Keys in Two Hashes
Hashing References
Presizing a Hash
Finding the Most Common Anything
Representing Relationships Between Data
Program: dutree

Larry Wall

Doing linear scans over an associative array is like trying to club someone to death with a loaded Uzi.

5.0. Introduction

People and parts of computer programs interact in all sorts of ways. Single scalar variables are like hermits, living a solitary existence whose only meaning comes from within the individual. Arrays are like cults, where multitudes marshal themselves under the name of a charismatic leader. In the middle lies the comfortable, intimate ground of the one-to-one relationship that is the hash. (Older documentation for Perl often called hashes associative arrays, but that's a mouthful. Other languages that support similar constructs sometimes use different terms for them; you may hear about hash tables, tables, dictionaries, mappings, or even alists, depending on the language.)

Unfortunately, this isn't a relationship of equals. The relationship encoded in a hash is that of the genitive case or the possessive, like the word "of " in English, or like "'s". We could encode that the boss of Nat is Tim. Hashes only give convenient ways to access values for Nat's boss; you can't ask whose boss Tim is. Finding the answer to that question is a recipe in this chapter.

Fortunately, hashes have their own special benefits, just like relationships. Hashes are a built-in data type in Perl. Their use reduces many complex algorithms to simple variable accesses. They are also fast and convenient to build indices and quick lookup tables.

Only use the % when referring to the hash as a whole, such as %boss. When referring to the value associated with a particular key, that's a single scalar value, so a $ is called for—just as when referring to one element of an array, you also use a $. This means that "the boss of Nat" would be written as $boss{"Nat"}. We can assign "Tim" to that:

$boss{"Nat"} = "Tim";

It's time to put a name to these notions. The relationship embodied in a hash is a good thing to use for its name. In the previous example you see a dollar sign, which might surprise you since this is a hash, not a scalar. But we're setting a single scalar value in that hash, so use a dollar sign. Where a lone scalar has $ as its type identifier and an entire array has @, an entire hash has %.

A regular array uses integers for indices, but the indices of a hash are always strings. Its values may be any arbitrary scalar values, including references. With references as values, you can create hashes that hold not merely strings or numbers, but also arrays, other hashes, or objects. (Or rather, references to arrays, hashes, or objects.)

An entire hash can be initialized with a list, where elements of the list are key and value pairs:

%age = ( "Nat",   30,
         "Jules", 31,
         "Josh",  23 );

This is equivalent to:

$age{"Nat"}   = 30;
$age{"Jules"} = 31;
$age{"Josh"}  = 23;

To make it easier to read and write hash initializations, the => operator, sometimes known as a comma arrow, was created. Mostly it behaves like a better-looking comma. For example, you can write a hash initialization this way:

%food_color = (
               "Apple"  => "red",
               "Banana" => "yellow",
               "Lemon"  => "yellow",
               "Carrot" => "orange"
              );

(This particular hash is used in many examples in this chapter.) This initialization is also an example of hash-list equivalence—hashes behave in some ways as though they were lists of key-value pairs. We'll use this in a number of recipes, including the merging and inverting recipes.

Unlike a regular comma, the comma arrow has a special property: it quotes any word preceding it, which means you can safely omit the quotes and improve legibility. Single-word hash keys are also automatically quoted when they occur inside braces, which means you can write $hash{somekey} instead of $hash{"somekey"}. You could rewrite the preceding initialization of %food_color as:

%food_color = (
                Apple  => "red",
                Banana => "yellow",
                Lemon  => "yellow",
                Carrot => "orange"
               );

One important issue to be aware of regarding hashes is that their elements are stored in an internal order convenient for efficient retrieval. This means that no matter what order you insert your data, it will come out in an unpredictable disorder.

5.0.1. See Also

The perldata(1) manpage; the two sections on "Hashes" in the first and second chapters of Programming Perl

Previous | Home | Next
4.20. Program: permute | Book Index | 5.1. Adding an Element to a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.1. Adding an Element to a Hash

5.1.1. Problem

You need to add an entry to a hash.

5.1.2. Solution

Simply assign to the hash key:

$HASH{$KEY} = $VALUE;

5.1.3. Discussion

Putting something into a hash is straightforward. In languages that don't provide the hash as an intrinsic data type, you have to worry about overflows, resizing, and collisions in your hash table. In Perl, all that is taken care of for you with a simple assignment. If that entry was already occupied (had a previous value), memory for that value is automatically freed, just as when assigning to a simple scalar.

# %food_color defined per the introduction
$food_color{Raspberry} = "pink";
print "Known foods:\n";
foreach $food (keys %food_color) {
    print "$food\n";
}

Known foods:
Banana
Apple
Raspberry
Carrot
Lemon

If you don't want to overwrite an existing value, but somehow have one key reference multiple values, see Recipe 5.8 and Recipe 11.2.

5.1.4. See Also

The "List Value Constructors" section of perldata(1); the "List Values and Arrays" section of Chapter 2 of Programming Perl; Recipe 5.2

Previous | Home | Next
5. Hashes | Book Index | 5.2. Testing for the Presence of a Key in a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.2. Testing for the Presence of a Key in a Hash

5.2.1. Problem

You need to know whether a hash has a particular key, regardless of whatever value may be associated with that key.

5.2.2. Solution

Use the exists function.

# does %HASH have a value for $KEY ?
if (exists($HASH{$KEY})) {
    # it exists
} else {
    # it doesn't
}

5.2.3. Discussion

This code uses exists to check whether a key is in the %food_color hash:

# %food_color per the introduction
foreach $name ("Banana", "Martini") {
    if (exists $food_color{$name}) {
        print "$name is a food.\n";
    } else {
        print "$name is a drink.\n";
    }
}

Banana is a food.
Martini is a drink.

The exists function tests whether a key is in the hash. It doesn't test whether the value corresponding to that key is defined, nor whether the value is true or false. We may be splitting hairs, but problems caused by confusing existence, definedness, and truth can multiply like rabbits. Take this code:

%age = ( );
$age{"Toddler"}  = 3;
$age{"Unborn"}   = 0;
$age{"Phantasm"} = undef;

foreach $thing ("Toddler", "Unborn", "Phantasm", "Relic") {
    print "$thing: ";
    print "Exists "  if exists  $age{$thing};
    print "Defined " if defined $age{$thing};
    print "True "    if         $age{$thing};
    print "\n";
}

Toddler: Exists Defined True
Unborn: Exists Defined
Phantasm: Exists
Relic:

$age{"Toddler"} passes the existence, definedness, and truth tests. It exists because we gave "Toddler" a value in the hash; it's defined because that value isn't undef; and it's true because the value isn't one of Perl's false values.

$age{"Unborn"} passes only the existence and definedness tests. It exists because we gave "Unborn" a value in the hash, and it's defined because that value isn't undef. It isn't true, however, because 0 is one of Perl's false values.

$age{"Phantasm"} passes only the existence test. It exists because we gave "Phantasm" a value in the hash. But because that value was undef, it doesn't pass the definedness test. Because undef is also one of Perl's false values, it doesn't pass the truth test either.

$age{"Relic"} passes none of the tests. We didn't put a value for "Relic" into the hash, so the existence test fails. Because we didn't put a value in, $age{"Relic"} is undef whenever we try to access it. We know from "Phantasm" that undef fails the definedness and truth tests.

Sometimes it's useful to store undef in a hash. This indicates "I've seen this key, but it didn't have a meaningful value associated with it." Take, for instance, a program to look up file sizes given a list of files as input. This version tries to skip files we've seen before, but it doesn't skip zero-length files, and it doesn't skip files that we've seen before but don't exist.

%size = ( );
while (<>) {
    chomp;
    next if $size{$_};              # WRONG attempt to skip
    $size{$_} = -s $_;
}

If we change the incorrect line to call exists, we also skip files that couldn't be stat ted, instead of repeatedly trying (and failing) to look them up:

next if exists $size{$_};

5.2.4. See Also

The exists and defined functions in perlfunc(1) and Chapter 29 of Programming Perl; the discussion of truth in the "Scalar Values" section of perldata(1), and the "Boolean Context" section of Chapter 2 of Programming Perl

Previous | Home | Next
5.1. Adding an Element to a Hash | Book Index | 5.3. Creating a Hash with Immutable Keys or Values
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.3. Creating a Hash with Immutable Keys or Values

5.3.1. Problem

You'd like to have a hash whose keys or values can't be altered once set.

5.3.2. Solution

Use the appropriate functions from the standard Hash::Util module.

use Hash::Util qw{ lock_keys  unlock_keys
                   lock_value unlock_value
                   lock_hash  unlock_hash  };

To restrict access to keys already in the hash, so no new keys can be introduced:

lock_keys(%hash);                # restrict to current keys
lock_keys(%hash, @klist);        # restrict to keys from @klist

To forbid deletion of the key or modification of its value:

lock_value(%hash, $key);

To make all keys and their values read-only:

lock_hash(%hash);

5.3.3. Discussion

Suppose you're using a hash to implement a record (or an object) with some pre-determined set of keys, such as "NAME", "RANK", and "SERNO". You'd like to consider it an error to access any keys besides the ones initially in the hash, such as "ANME", a typo. Because Perl always creates hash elements on demand, this wouldn't be caught the way it would if you misspelled a variable name while under the use strict pragma.

The Hash::Util module's lock_keys function takes care of this for you. Once a hash is marked as having locked keys, you can't use any other keys than those. The keys need not yet be in the hash, and they may still be deleted if they are. But no new keys may be used.

Access to the values in those locked keys is not restricted by lock_keys. However, you may use the lock_value function to render a value in a hash read-only. That hash can also have its keys locked, but doesn't need to if the goal is just to have one or more values marked read-only.

If you want to lock down the entire hash, thereby restricting both its keys and its values, the lock_hash function will do.

5.3.4. See Also

The documentation for the Hash::Util module

Previous | Home | Next
5.2. Testing for the Presence of a Key in a Hash | Book Index | 5.4. Deleting from a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.4. Deleting from a Hash

5.4.1. Problem

You want to remove an entry from a hash so that it doesn't show up with keys, values, or each. If you were using a hash to associate salaries with employees, and an employee resigned, you'd want to remove their entry from the hash.

5.4.2. Solution

Use the delete function:

# remove $KEY and its value from %HASH
delete($HASH{$KEY});

5.4.3. Discussion

Sometimes people mistakenly try to use undef to remove an entry from a hash. undef $hash{$key} and $hash{$key} = undef both make %hash have an entry with key $key and value undef.

The delete function is the only way to remove a specific entry from a hash. Once you've deleted a key, it no longer shows up in a keys list or an each iteration, and exists will return false for that key.

This demonstrates the difference between undef and delete:

# %food_color as per Introduction
sub print_foods {
    my @foods = keys %food_color;
    my $food;

    print "Keys: @foods\n";
    print "Values: ";

    foreach $food (@foods) {
        my $color = $food_color{$food};

        if (defined $color) {
            print "$color ";
        } else {
            print "(undef) ";
        }
    }
    print "\n";
}

print "Initially:\n";
print_foods( );

print "\nWith Banana undef\n";
undef $food_color{"Banana"};
print_foods( );

print "\nWith Banana deleted\n";
delete $food_color{"Banana"};
print_foods( );

Initially:
Keys: Banana Apple Carrot Lemon
Values: yellow red orange yellow

With Banana undef
Keys: Banana Apple Carrot Lemon
Values: (undef) red orange yellow

With Banana deleted
Keys: Apple Carrot Lemon
Values: red orange yellow

As you see, if we set $food_color{"Banana"} to undef, "Banana" still shows up as a key in the hash. The entry is still there; we only succeeded in making the value undef. On the other hand, delete actually removed it from the hash—"Banana" is no longer in the list returned by keys.

delete can also take a hash slice, deleting all listed keys at once:

delete @food_color{"Banana", "Apple", "Cabbage"};

5.4.4. See Also

The delete and keys functions in perlfunc(1) and in Chapter 29 of Programming Perl; we use keys in Recipe 5.5

Previous | Home | Next
5.3. Creating a Hash with Immutable Keys or Values | Book Index | 5.5. Traversing a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.5. Traversing a Hash

5.5.1. Problem

You want to perform an action on each entry (i.e., each key-value pair) in a hash.

5.5.2. Solution

Use each with a while loop:

while(($key, $value) = each(%HASH)) {
    # do something with $key and $value
}

Or use keys with a foreach loop, unless the hash is potentially very large:

foreach $key (keys %HASH) {
    $value = $HASH{$key};
    # do something with $key and $value
}

5.5.3. Discussion

Here's a simple example, iterating through the %food_color hash from the introduction:

# %food_color per the introduction
while(($food, $color) = each(%food_color)) {
    print "$food is $color.\n";
}
Banana is yellow.
Apple is red.
Carrot is orange.
Lemon is yellow.

foreach $food (keys %food_color) {
    my $color = $food_color{$food};
    print "$food is $color.\n";
}
Banana is yellow.
Apple is red.
Carrot is orange.
Lemon is yellow.

We didn't really need the $color variable in the foreach example, because we use it only once. Instead, we could have written:

print "$food is $food_color{$food}.\n"

Every time each is called on the same hash, it returns the "next" key-value pair. We say "next" because the pairs are returned in the order the underlying lookup structure imposes on them, which appears to be no order at all. When each runs out of hash elements, it returns the empty list ( ), whose assignment tests false and terminates the while loop.

The foreach example uses keys, which constructs an entire list containing every key from the hash before the loop even begins executing. The advantage to using each is that it gets the keys and values one pair at a time. If the hash contains many keys, not having to preconstruct a complete list of them can save substantial memory. The each function, however, doesn't let you control the order in which pairs are processed.

Using foreach and keys to loop over the list lets you impose an order. For instance, if we wanted to print the food names in alphabetical order:

foreach $food (sort keys %food_color) {
    print "$food is $food_color{$food}.\n";
}
Apple is red.
Banana is yellow.
Carrot is orange.
Lemon is yellow.

This is a common use of foreach. We use keys to obtain a list of keys in the hash, and then we use foreach to iterate over them. The danger is that if the hash contains a large number of elements, the list returned by keys will use a lot of memory. The trade-off lies between memory use and the ability to process the entries in a particular order. We cover sorting in more detail in Recipe 5.10.

Because keys, values, and each all share the same internal data structures, be careful about mixing calls to these functions or prematurely exiting an each loop. Each time you call keys or values, the current location for each is reset. This code loops forever, printing the first key returned by each:

while ( ($k,$v) = each %food_color ) {
    print "Processing $k\n";
    keys %food_color;               # goes back to the start of %food_color
}

Modifying a hash while looping over it with each or foreach is, in general, fraught with danger. The each function can behave differently with tie d and untied hashes when you add or delete keys from a hash. A foreach loops over a pregenerated list of keys, so once the loop starts, foreach can't know whether you've added or deleted keys. Keys added in the body of the loop aren't automatically appended to the list of keys to loop over, nor are keys deleted by the body of the loop deleted from this list.

Example 5-1 reads a mailbox file and reports the number of messages from each person. It uses the From: line to determine the sender. (It isn't clever in this respect, but we're showing hash manipulation, not mail-file processing.) Supply the mailbox filename as a command-line argument, or use a "-" to indicate you're piping the mailbox to the program. (When Perl opens a file named "-" for reading using fewer than three arguments to open, this means to use the current standard input.)

Example 5-1. countfrom

  #!/usr/bin/perl
  # countfrom - count number of messages from each sender
  $filename = $ARGV[0] || "-";          # "-" means standard input
  open(FILE, "< $filename")                    or die "Can't open $filename : $!";
  while(<FILE>) {
      if (/^From: (.*)/) { $from{$1}++ }
  }
  foreach $person (sort keys %from) {
      print "$person: $from{$person}\n";
  }

5.5.4. See Also

The each and keys functions in perlfunc(1) and in Chapter 29 of Programming Perl; we talk about for and foreach in Recipe 4.6

Previous | Home | Next
5.4. Deleting from a Hash | Book Index | 5.6. Printing a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.6. Printing a Hash

5.6.1. Problem

You want to print a hash, but neither print "%hash" nor print %hash does what you want; the first is a literal, while the second just has the keys and values all scrunched together.

5.6.2. Solution

One of several approaches is to iterate over every key-value pair in the hash using Recipe 5.5 and print them:

while ( ($k,$v) = each %hash ) {
    print "$k => $v\n";
}

Or use map to generate a list of strings:

print map { "$_ => $hash{$_}\n" } keys %hash;

Or use the interpolation trick from Recipe 1.15 to interpolate the hash as a list:

print "@{[ %hash ]}\n";

Or use a temporary array variable to hold the hash, and then print that:

{
    my @temp = %hash;
    print "@temp";
}

5.6.3. Discussion

The methods differ in the degree that their output is customizable (in order and formatting) and in their efficiency.

The first method, iterating over the hash, is flexible and space-efficient. You can format the output as you like it, and it requires only two scalar variables: the current key and value. You can print the hash in key order (at the cost of building a list of sorted keys) if you use a foreach loop:

foreach $k (sort keys %hash) {
    print "$k => $hash{$k}\n";
}

The map function is just as flexible. You can still process the list in any order by sorting the keys. You can customize the output to your heart's content. But it builds up a list of strings like "KEY =>VALUE\n" to pass to print.

The last two methods are interpolation tricks. By treating the hash as a list, you can't predict or control the output order of key-value pairs. Furthermore, the output will consist of a list of keys and values, each separated by whatever string that $" happens to hold. You can't put newlines between pairs or "=>" within them, as we could with the other methods.

Another solution is to print the hash in a list context after temporarily localizing the $, variable to a space.

{
    local $, = " ";
    print %hash;
}

This is like the solution of copying to an array and then doing double-quote interpolation on that array, except it doesn't duplicate the contents of the hash twice more than you need (i.e., once for the array, then again for the string).

The Dumpvalue module, described in Recipe 11.11, can provide for pretty printed output displays, plus much more. For example:

use Dumpvalue;
$dumper = Dumpvalue->new;
$dumper->dumpValue(\%food_color);
'Apple' => 'red'
'Banana' => 'yellow'
'Carrot' => 'orange'
'Lemon' => 'yellow'

5.6.4. See Also

The $" and $, variables in perlvar(1) and in the "Per-Filehandle Variables" section of Chapter 28 of Programming Perl; the foreach, map, keys, sort, and each functions in perlfunc(1) and Chapter 29 of Programming Perl; we give a technique for interpolating into strings in Recipe 1.15; we discuss the techniques for hash traversal in Recipe 5.5

Previous | Home | Next
5.5. Traversing a Hash | Book Index | 5.7. Retrieving from a Hash in Insertion Order
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.7. Retrieving from a Hash in Insertion Order

5.7.1. Problem

The keys and each functions traverse the hash elements in a strange order, and you want them in the order in which you inserted them.

5.7.2. Solution

Use the Tie::IxHash module.

use Tie::IxHash;
tie %HASH, "Tie::IxHash";
# manipulate %HASH
@keys = keys %HASH;         # @keys is in insertion order

5.7.3. Discussion

Tie::IxHash makes keys, each, and values return the hash elements in the order they were added. This often removes the need to preprocess the hash keys with a complex sort comparison or maintain a distinct array containing the keys in the order they were inserted into the hash.

Tie::IxHash also provides an object-oriented interface to splice, push, pop, shift, unshift, keys, values, and delete, among others.

Here's an example, showing both keys and each:

# initialize
use Tie::IxHash;

tie %food_color, "Tie::IxHash";
$food_color{"Banana"} = "Yellow";
$food_color{"Apple"}  = "Green";
$food_color{"Lemon"}  = "Yellow";

print "In insertion order, the foods are:\n";
foreach $food (keys %food_color) {
    print "  $food\n";
}

print "Still in insertion order, the foods' colors are:\n";
while (( $food, $color ) = each %food_color ) {
    print "$food is colored $color.\n";
}

In insertion order, the foods are:
  Banana
  Apple
  Lemon
Still in insertion order, the foods' colors are:
Banana is colored Yellow.
Apple is colored Green.
Lemon is colored Yellow.

5.7.4. See Also

The documentation for the CPAN module Tie::IxHash; Recipe 13.5

Previous | Home | Next
5.6. Printing a Hash | Book Index | 5.8. Hashes with Multiple Values per Key
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.8. Hashes with Multiple Values per Key

5.8.1. Problem

You want to store more than one value for each key.

5.8.2. Solution

Store an array reference in $hash{$key}, then put the values into the referenced array.

5.8.3. Discussion

You can store only scalar values in a hash. References, however, are scalars. This solves the problem of storing multiple values for one key by making $hash{$key} a reference to an array containing values for $key. The normal hash operations—insertion, deletion, iteration, and testing for existence—can now be written in terms of array operations like push, splice, and foreach.

This code shows simple insertion into the hash. It processes the output of who(1) on Unix machines and outputs a terse listing of users and the ttys they're logged in on:

%ttys = ( );

open(WHO, "who|")                   or die "can't open who: $!";
while (<WHO>) {
    ($user, $tty) = split;
    push( @{$ttys{$user}}, $tty );
}

foreach $user (sort keys %ttys) {
    print "$user: @{$ttys{$user}}\n";
}

The heart of the code is the push line, the multivalued version of $ttys{$user} = $tty. The first time through, that hash value is undefined, so Perl automatically allocates a new anonymous hash and stores its reference in that value so that the push can succeed. This is called autovivification, and is explained more in Chapter 11.

We interpolate all the tty names in the print line with @{$ttys{$user}}. We'd loop over the anonymous array if, for instance, we wanted to print the owner of each tty:

foreach $user (sort keys %ttys) {
    print "$user: ", scalar( @{$ttys{$user}} ), " ttys.\n";
    foreach $tty (sort @{$ttys{$user}}) {
        @stat = stat("/dev/$tty");
        $user = @stat ? ( getpwuid($stat[4]) )[0] : "(not available)";
        print "\t$tty (owned by $user)\n";
    }
}

The exists function can have two meanings: "Is there at least one value for this key?" and "Does this value exist for this key?" Implementing the second approach requires searching the array for the value. The delete function and the first sense of exists are interrelated: if we can guarantee that no anonymous array is ever empty, we can use the built-in exists. We ensure that no anonymous array is ever empty by checking for that after deleting an element.

sub multihash_delete {
    my ($hash, $key, $value) = @_;
    my $i;

    return unless ref( $hash->{$key} );
    for ($i = 0; $i < @{ $hash->{$key} }; $i++) {
        if ($hash->{$key}->[$i] eq $value) {
            splice( @{$hash->{$key}}, $i, 1);
            last;
        }
    }

    delete $hash->{$key} unless @{$hash->{$key}};
}

An alternative approach to multivalued hashes is given in Chapter 13, implemented as tied normal hashes.

5.8.4. See Also

The splice, delete, push, foreach, and exists functions in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 11.1; we cover ties in Recipe 13.15

Previous | Home | Next
5.7. Retrieving from a Hash in Insertion Order | Book Index | 5.9. Inverting a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.9. Inverting a Hash

5.9.1. Problem

Hashes map keys to values. You have a hash and a value whose corresponding key you want to find.

5.9.2. Solution

Use reverse to create an inverted hash whose values are the original hash's keys and vice versa.

# %LOOKUP maps keys to values
%REVERSE = reverse %LOOKUP;

5.9.3. Discussion

This technique uses the list equivalence of hashes mentioned in the introduction. In list context, reverse treats %LOOKUP as a list and reverses the order of its elements. The significant property of a hash treated as a list is that the list elements come in associated pairs: the first element is the key; the second, the value. When you reverse such a list, the first element is now the value, and the second the key. Treating this list as a hash results in a hash whose values are the keys of the original hash and vice versa.

Here's an example:

%surname = ( "Mickey" => "Mantle", "Babe" => "Ruth" );
%first_name = reverse %surname;
print $first_name{"Mantle"}, "\n";
Mickey

When we treat %surname as a list, it becomes:

("Mickey", "Mantle", "Babe", "Ruth")

(or maybe ("Babe", "Ruth", "Mickey", "Mantle") because we can't predict the order). Reversing this list gives us:

("Ruth", "Babe", "Mantle", "Mickey")

When we treat this list as a hash, it becomes:

("Ruth" => "Babe", "Mantle" => "Mickey")

Now instead of turning first names into surnames, it turns surnames into first names.

Example 5-2 is a program called foodfind. If you give it a food name, it'll tell you the color of that food. If you give it a color, it'll tell you a food of that color.

Example 5-2. foodfind

  #!/usr/bin/perl -w
  # foodfind - find match for food or color
  $given = shift @ARGV or die "usage: foodfind food_or_color\n";
  %color = (
             "Apple"  => "red",
             "Banana" => "yellow",
             "Lemon"  => "yellow",
             "Carrot" => "orange"
           );
  %food = reverse %color;
  if (exists $color{$given}) {
      print "$given is a food with color $color{$given}.\n";
  }
  if (exists $food{$given}) {
      print "$food{$given} is a food with color $given.\n";
  }

If two keys in the original hash have the same value (as "Lemon" and "Banana" do in the color example), then the inverted hash will only have one (which is dependent on the hashing order, and you shouldn't try to predict it). This is because hashes have, by Perl definition, unique keys.

If you want to invert a hash with non-unique values, you must use the techniques shown in Recipe 5.8. That is, build up a hash whose values are a list of keys in the original hash:

# %food_color as per the introduction
while (($food,$color) = each(%food_color)) {
    push(@{$foods_with_color{$color}}, $food);
}

print "@{$foods_with_color{yellow}} were yellow foods.\n";
Banana Lemon were yellow foods.

This also lets us change the foodfind program to handle colors represented by more than one food. For instance, foodfind yellow reports bananas and lemons.

If any values in the original hash were references instead of strings or numbers, the inverted hash poses a problem because references don't work well as hash keys—unless you use the Tie::RefHash module described in Recipe 5.13.

5.9.4. See Also

The reverse function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 13.15

Previous | Home | Next
5.8. Hashes with Multiple Values per Key | Book Index | 5.10. Sorting a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.10. Sorting a Hash

5.10.1. Problem

You need to work with the elements of a hash in a particular order.

5.10.2. Solution

Use keys to get a list of keys, then sort them based on the ordering you want:

# %hash is the hash to sort
@keys = sort { criterion( ) } (keys %hash);
foreach $key (@keys) {
    $value = $hash{$key};
    # do something with $key, $value
}

5.10.3. Discussion

Even though you can't directly maintain a hash in a specific order (unless you use the Tie::IxHash module mentioned in Recipe 5.7), you can access its entries in any order.

This technique offers many variations on the same basic mechanism: you extract the keys, reorder them using the sort function, and then process the entries in the new order. All the sorting tricks shown in Chapter 4 can be used here. Let's look at some applications.

The following code simply uses sort to order the keys alphabetically:

foreach $food (sort keys %food_color) {
    print "$food is $food_color{$food}.\n";
}

This sorts the keys by their associated values:

foreach $food (sort { $food_color{$a} cmp $food_color{$b} }
                keys %food_color)
{
    print "$food is $food_color{$food}.\n";
}

This sorts by length of the values:

@foods = sort {
          length($food_color{$a}) <=> length($food_color{$b})
         } keys %food_color;
foreach $food (@foods) {
    print "$food is $food_color{$food}.\n";
}

5.10.4. See Also

The sort and keys functions in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 5.7; we discuss sorting lists in Recipe 4.16

Previous | Home | Next
5.9. Inverting a Hash | Book Index | 5.11. Merging Hashes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.11. Merging Hashes

5.11.1. Problem

You need to make a new hash with the entries of two existing hashes.

5.11.2. Solution

Treat them as lists, and join them as you would lists.

%merged = (%A, %B);

To save memory, loop over the hashes' elements and build a new hash that way:

%merged = ( );
while ( ($k,$v) = each(%A) ) {
    $merged{$k} = $v;
}
while ( ($k,$v) = each(%B) ) {
    $merged{$k} = $v;
}

5.11.3. Discussion

The first method, like the earlier recipe on inverting a hash, uses the hash-list equivalence explained in the introduction. (%A, %B) evaluates to a list of paired keys and values. When we assign it to %merged, Perl turns that list of pairs back into a hash.

Here's an example of that technique:

# %food_color as per the introduction
%drink_color = ( Galliano  => "yellow",
                 "Mai Tai" => "blue" );

%ingested_color = (%drink_color, %food_color);

Keys in both input hashes appear just once in the output hash. If a food and a drink shared the same name, for instance, then the last one seen by the first merging technique would be the one that showed up in the resultant hash.

This style of direct assignment, as in the first example, is easier to read and write, but requires a lot of memory if the hashes are large. That's because Perl has to unroll both hashes into a temporary list before the assignment to the merged hash is done. Step-by-step merging using each, as in the second technique, spares you that cost and lets you decide what to do with duplicate keys.

The first example could be rewritten to use the each technique:

# %food_color per the introduction, then
%drink_color = ( Galliano  => "yellow",
                 "Mai Tai" => "blue" );

%substance_color = ( );
while (($k, $v) = each %food_color) {
    $substance_color{$k} = $v;
}
while (($k, $v) = each %drink_color) {
    $substance_color{$k} = $v;
}

That technique duplicated the while and assignment code. Here's a sneaky way to get around that:

foreach $substanceref ( \%food_color, \%drink_color ) {
    while (($k, $v) = each %$substanceref) {
        $substance_color{$k} = $v;
    }
}

If we're merging hashes with duplicates, we can insert our own code to decide what to do with those duplicates:

foreach $substanceref ( \%food_color, \%drink_color ) {
    while (($k, $v) = each %$substanceref) {
        if (exists $substance_color{$k}) {
            print "Warning: $k seen twice.  Using the first definition.\n";
            next;
        }
        $substance_color{$k} = $v;
    }
}

In the special case of appending one hash to another, we can use the hash slice notation to give an elegant shorthand:

@all_colors{keys %new_colors} = values %new_colors;

This requires enough memory for lists of the keys and values of %new_colors. As with the first technique, the memory requirement might make this technique infeasible when such lists would be large.

5.11.4. See Also

This is a variation on Recipe 4.10; the each function in perlfunc(1) and in Chapter 29 of Programming Perl

Previous | Home | Next
5.10. Sorting a Hash | Book Index | 5.12. Finding Common or Different Keys in Two Hashes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.12. Finding Common or Different Keys in Two Hashes

5.12.1. Problem

You need to find keys in one hash that are or are not present in another hash.

5.12.2. Solution

Use keys to loop through the keys of one hash, checking whether each key is also in the other hash.

5.12.2.1. Find common keys

my @common = ( );
foreach (keys %hash1) {
        push(@common, $_) if exists $hash2{$_};
}
# @common now contains common keys

5.12.2.2. Find keys from one hash that aren't in both

my @this_not_that = ( );
foreach (keys %hash1) {
        push(@this_not_that, $_) unless exists $hash2{$_};
}

5.12.3. Discussion

Because we're finding common or different keys of the hashes, we can apply our earlier array recipes for finding common or different elements to arrays of the hashes' keys. For an explanation, see Recipe 4.9.

This code uses the difference technique to find non-citrus foods:

# %food_color per the introduction

# %citrus_color is a hash mapping citrus food name to its color.
%citrus_color = ( Lemon  => "yellow",
                  Orange => "orange",
                  Lime   => "green" );

# build up a list of non-citrus foods
@non_citrus = ( );

foreach (keys %food_color) {
    push (@non_citrus, $_) unless $citrus_color{$_};
}

5.12.4. See Also

The "Hashes" section of Chapter 2 of Programming Perl; the each function in perlfunc(1) and in Chapter 29 of Programming Perl

Previous | Home | Next
5.11. Merging Hashes | Book Index | 5.13. Hashing References
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.13. Hashing References

5.13.1. Problem

When you use keys on a hash whose keys are references, the references that keys returns no longer work. This situation often arises when you want to cross-reference two different hashes.

5.13.2. Solution

Use Tie::RefHash:

use Tie::RefHash;
tie %hash, "Tie::RefHash";
# you may now use references as the keys to %hash

5.13.3. Discussion

Hash keys are automatically "stringified," that is, treated as though they appeared between double quotes. With numbers or strings, nothing is lost. This isn't so with references, though.

Stringified references look like these:

Class::Somewhere=HASH(0x72048)
ARRAY(0x72048)

A stringified reference can't be dereferenced, because it is just a string and no longer a reference. This means you can't use references as the keys to a hash without losing their "magic."

Hand-rolled solutions to this problem involve maintaining a distinct hash whose keys are stringified references and whose values are the actual references. This is what Tie::RefHash does. We'll use IO objects for filehandles here to show you that even such strange references can index a hash tied with Tie::RefHash.

Here's an example:

use Tie::RefHash;
use IO::File;

tie %name, "Tie::RefHash";
foreach $filename ("/etc/termcap", "/vmunix", "/bin/cat") {
    $fh = IO::File->new("< $filename") or next;
    $name{$fh} = $filename;
}
print "open files: ", join(", ", values %name), "\n";
foreach $file (keys %name) {
    seek($file, 0, 2);      # seek to the end
    printf("%s is %d bytes long.\n", $name{$file}, tell($file));
}

If you're storing objects as the keys to a hash, though, you almost always should be storing a unique attribute of the object (e.g., name or ID number) instead.

5.13.4. See Also

The documentation for the standard Tie::RefHash module; the "Warning" section of perlref(1)

Previous | Home | Next
5.12. Finding Common or Different Keys in Two Hashes | Book Index | 5.14. Presizing a Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.14. Presizing a Hash

5.14.1. Problem

You want to preallocate memory for a hash to speed up your program so Perl won't have to incrementally allocate memory each time a new entry is added to the hash. Often you know the final size of a hash before you start building it up, and it's possible to use this information to speed up your program.

5.14.2. Solution

Assign the number of key-value pairs your hash will have to keys %HASH.

# presize %hash to $num
keys(%hash) = $num;

5.14.3. Discussion

This feature may or may not improve your performance. Perl already shares keys between hashes, so if you already have a hash with "Apple" as a key, Perl won't need to allocate memory for another copy of "Apple" when you add an entry whose key is "Apple" to another hash.

# will have 512 users in %users
keys(%users) = 512;

Perl's internal data structures require the number of keys to be a power of 2. If we had said:

keys(%users) = 1000;

Perl would have internally allocated 1024 "buckets" for the hash. Keys and buckets aren't always one to one. You get the best performance when they are, but the distribution of keys to buckets is dependent on your keys and Perl's (immutable) hash algorithm.

5.14.4. See Also

The keys function in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 4.3

Previous | Home | Next
5.13. Hashing References | Book Index | 5.15. Finding the Most Common Anything
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.15. Finding the Most Common Anything

5.15.1. Problem

You have an aggregate data structure, such as an array or a hash. You want to know how often each element in the array (or value in the hash) occurs. For instance, if your array contains web server transactions, you might want to find the most commonly requested file. If your hash maps usernames to number of logins, you want to find the most common number of logins.

5.15.2. Solution

Use a hash to count how many times each element, key, or value appears:

%count = ( );
foreach $element (@ARRAY) {
    $count{$element}++;
}

5.15.3. Discussion

Any time you want to count how often different things appear, you should probably be using a hash. The foreach adds one to $count{$element} for every occurrence of $element.

5.15.4. See Also

Recipe 4.7 and Recipe 4.8

Previous | Home | Next
5.14. Presizing a Hash | Book Index | 5.16. Representing Relationships Between Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.16. Representing Relationships Between Data

5.16.1. Problem

You want to represent relationships between elements of data—for instance, the mother of relationship in a family tree or parent process for a process table. This is closely related to representing tables in relational databases (tables represent relationships between information) and to representing computer science graph structures (edges represent relationships between nodes).

5.16.2. Solution

Use a hash to represent the relationship.

5.16.3. Discussion

Here's part of the family tree from the Bible:

%father = ( 'Cain'      => 'Adam',
            'Abel'      => 'Adam',
            'Seth'      => 'Adam',
            'Enoch'     => 'Cain',
            'Irad'      => 'Enoch',
            'Mehujael'  => 'Irad',
            'Methusael' => 'Mehujael',
            'Lamech'    => 'Methusael',
            'Jabal'     => 'Lamech',
            'Jubal'     => 'Lamech',
            'Tubalcain' => 'Lamech',
            'Enos'      => 'Seth' );

This lets us, for instance, easily trace a person's lineage:

while (<>) {
    chomp;
    do {
        print "$_ ";        # print the current name
        $_ = $father{$_};   # set $_ to $_'s father
    } while defined;        # until we run out of fathers
    print "\n";
}

We can already ask questions like "Who begat Seth?" by checking the %father hash. By inverting this hash, we invert the relationship. This lets us use Recipe 5.9 to answer questions like "Whom did Lamech beget?"

while ( ($k,$v) = each %father ) {
    push( @{ $children{$v} }, $k );
}

$" = ', ';                  # separate output with commas
while (<>) {
    chomp;
    if ($children{$_}) {
        @children = @{$children{$_}};
    } else {
        @children = "nobody";
    }
    print "$_ begat @children.\n";
}

Hashes can also represent relationships such as the C language #include s. A includes B if A contains #include B. This code builds the hash (it doesn't look for files in /usr/include as it should, but that's a minor change):

foreach $file (@files) {
    local *FH;
    unless (open(FH, " < $file")) {
        warn "Couldn't read $file: $!; skipping.\n";
        next;
    }

    while (<FH>) {
        next unless /^\s*#\s*include\s*<([^>]+)>/;
        push(@{$includes{$1}}, $file);
    }
    close FH;
}

This shows which files with include statements are not included in other files:

@include_free = ( );                 # list of files that don't include others
@uniq{map { @$_ } values %includes} = undef;
foreach $file (sort keys %uniq) {
        push( @include_free , $file ) unless $includes{$file};
}

The values of %includes are anonymous arrays because a single file can (and often does) include more than one other file. We use map to build up a big list of the included files and remove duplicates using a hash.

5.16.4. See Also

Recipe 4.7; the more complex data structures in Recipe 11.9 through Recipe 11.14

Previous | Home | Next
5.15. Finding the Most Common Anything | Book Index | 5.17. Program: dutree
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.17. Program: dutree

The dutree program, shown in Example 5-3, turns the output of du:

% du pcb
19      pcb/fix
20      pcb/rev/maybe/yes
10      pcb/rev/maybe/not
705     pcb/rev/maybe
54      pcb/rev/web
1371    pcb/rev
3       pcb/pending/mine
1016    pcb/pending
2412    pcb

into sorted, indented output:

2412 pcb
   |    1371 rev
   |       |    705 maybe
   |       |      |      675 .
   |       |      |       20 yes
   |       |      |       10 not
   |       |    612 .
   |       |     54 web
   |    1016 pending
   |       |        1013 .
   |       |           3 mine
   |      19 fix
   |       6 .

The arguments you give dutree are passed through to du. That way you could call dutree in any of these ways, or maybe more if your du supports other options:

% dutree
% dutree /usr
% dutree -a
% dutree -a /bin

The %Dirsize hash maintains the mapping of names to sizes. For example, $Dirsize{"pcb"} contains 2412 in this sample run. We'll use that hash both for output and for sorting each directory's subdirectories by size.

%Kids is more interesting. For any given path PATH, $Kids{PATH} contains a (reference to an) array of names of subdirectories of this one. The "pcb" entry contains a reference to an anonymous array containing "fix", "rev", and "pending". The "rev" entry contains "maybe" and "web". The "maybe" entry contains "yes" and "not", which do not have their own entries because they are end nodes in the tree.

The output function is passed the start of the tree—the last line read in from the output of du. First it prints that directory and its size. Then the function sorts the directory's children (if any) so that those with the most disk usage float to the top. Finally, output calls itself, recursing on each child in order. The extra arguments are used in formatting.

This program is inherently recursive because the filesystem is recursive. However, its data structure is not recursive; at least, not the way a circular linked list is. Each value is an array of further keys to process. The recursion resides in the processing, not in the storage.

Example 5-3. dutree

  #!/usr/bin/perl -w
  # dutree - print sorted indented rendition of du output
  use strict;
  my %Dirsize;
  my %Kids;
  getdots(my $topdir = input( ));
  output($topdir);
  # run du, read in input, save sizes and kids
  # return last directory (file?) read
  sub input {
      my($size, $name, $parent);
      @ARGV = ("du @ARGV |");         # prep the arguments
      while (<>) {              # magic open is our friend
          ($size, $name) = split;
          $Dirsize{$name} = $size;
          ($parent = $name) =~ s#/[^/]+$##;   # dirname
          push @{ $Kids{$parent} }, $name unless eof;
      }
      return $name;
  }
  # figure out how much is taken up in each directory
  # that isn't stored in subdirectories.  add a new
  # fake kid called "." containing that much.
  sub getdots {
      my $root = $_[0];
      my($size, $cursize);
      $size = $cursize = $Dirsize{$root};
      if ($Kids{$root}) {
          for my $kid (@{ $Kids{$root} }) {
              $cursize -= $Dirsize{$kid};
              getdots($kid);
          }
      }
      if ($size != $cursize) {
          my $dot = "$root/.";
          $Dirsize{$dot} = $cursize;
          push @{ $Kids{$root} }, $dot;
      }
  }
  # recursively output everything,
  # passing padding and number width in as well
  # on recursive calls
  sub output {
      my($root, $prefix, $width) = (shift, shift || '', shift || 0);
      my $path;
      ($path = $root) =~ s#.*/##;     # basename
      my $size = $Dirsize{$root};
      my $line = sprintf("%${width}d %s", $size, $path);
      print $prefix, $line, "\n";
      for ($prefix .= $line) {        # build up more output
          s/\d /| /;
          s/[^|]/ /g;
      }
      if ($Kids{$root}) {             # not a bachelor node
          my @Kids = @{ $Kids{$root} };
          @Kids = sort { $Dirsize{$b} <=> $Dirsize{$a} } @Kids;
          $Dirsize{$Kids[0]} =~ /(\d+)/;
          my $width = length $1;
          for my $kid (@Kids) { output($kid, $prefix, $width) }
      }
  }

Before Perl supported hashes of arrays directly, Herculean efforts were required to emulate these higher order constructs. Some folks used repeated calls to split and join, but these were exceedingly slow.

Example 5-4 is a version of dutree from those days of Perl antiquity. Because we didn't have proper array references, we had to usurp the Perl symbol table itself. This program created variables on the fly with bizarre names. Can you find which hash this program is using?

The @{"pcb"} array contains "pcb/fix", "pcb/rev", and "pcb/pending". The @{"pcb/rev"} array contains "pcb/rev/maybe" and "pcb/rev/web". The @{"pcb/rev/maybe"} array contains "pcb/rev/yes" and "pcb/rev/not".

When you assign something like "pcb/fix" to *kid, it promotes the string on the righthand side to a typeglob. This makes @kid an alias for @{"pcb/fix"}—among other things. It would also alias &kid to &{"pcb/fix"}, and so on.

If that isn't interesting enough, consider how the local is using dynamic scoping of global variables to avoid passing in extra arguments. Check out what's happening with the $width variable in the output routine.

Example 5-4. dutree-orig

  #!/usr/bin/perl
  # dutree_orig: the old version pre-perl5 (early 90s)
  @lines = `du @ARGV`;
  chop(@lines);
  &input($top = pop @lines);
  &output($top);
  exit;
  sub input {
      local($root, *kid, $him) = @_[0,0];
      while (@lines && &childof($root, $lines[$#lines])) {
          &input($him = pop(@lines));
          push(@kid, $him);
      }
      if (@kid) {
          local($mysize) = ($root =~ /^(\d+)/);
          for (@kid) { $mysize -= (/^(\d+)/)[0]; }
          push(@kid, "$mysize .") if $size != $mysize;
      }
      @kid = &sizesort(*kid);
  }
  sub output {
      local($root, *kid, $prefix) = @_[0,0,1];
      local($size, $path) = split(' ', $root);
      $path =~ s!.*/!!;
      $line = sprintf("%${width}d %s", $size, $path);
      print $prefix, $line, "\n";
      $prefix .= $line;
      $prefix =~ s/\d /| /;
      $prefix =~ s/[^|]/ /g;
      local($width) = $kid[0] =~ /(\d+)/ && length("$1");
      for (@kid) { &output($_, $prefix); };
  }
  sub sizesort {
      local(*list, @index) = shift;
      sub bynum { $index[$b] <=> $index[$a]; }
      for (@list) { push(@index, /(\d+)/); }
      @list[sort bynum 0..$#list];
  }
  sub childof {
      local(@pair) = @_;
      for (@pair) { s/^\d+\s+//g; s/$/\//; }
      index($pair[1], $pair[0]) >= 0;
  }

The answer to the question posed earlier — "Which hash is the old dutree using?" — is %main::, that is, the Perl symbol table itself. Needless to say, this program will never run under use strict. We're happy to report that the updated version runs three times as fast as the old one. That's because the old one keeps looking up variables in the symbol table, and the new one doesn't have to. It's also because we avoid all that slow splitting of the space used and the directory name. But we thought we'd show you the old version because it is instructive, too.

Previous | Home | Next
5.16. Representing Relationships Between Data | Book Index | 6. Pattern Matching
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 6. Pattern Matching

Contents:

Introduction
Copying and Substituting Simultaneously
Matching Letters
Matching Words
Commenting Regular Expressions
Finding the Nth Occurrence of a Match
Matching Within Multiple Lines
Reading Records with a Separator
Extracting a Range of Lines
Matching Shell Globs as Regular Expressions
Speeding Up Interpolated Matches
Testing for a Valid Pattern
Honoring Locale Settings in Regular Expressions
Approximate Matching
Matching from Where the Last Pattern Left Off
Greedy and Non-Greedy Matches
Detecting Doubled Words
Matching Nested Patterns
Expressing AND, OR, and NOT in a Single Pattern
Matching a Valid Mail Address
Matching Abbreviations
Program: urlify
Program: tcgrep
Regular Expression Grab Bag

Sir Herbert Read, The Meaning of Art

[Art is] pattern informed by sensibility.

6.0. Introduction

Most modern programming languages offer primitive pattern-matching tools, usually through an extra library. In contrast, Perl's patterns are integrated directly into the language core. Perl's pattern matching boasts features not found elsewhere, features that encourage a whole different way of looking at data. Just as chess players see patterns in the board positions that their pieces control, Perl adepts look at data in terms of patterns. These patterns, expressed in the intensely symbolic notation of regular expressions,[8] provide access to powerful algorithms normally available only to scholars of computer science.

[8]Technically, Perl's patterns far exceed the capabilities of mere regular expressions as that term is formally used in computing theory.

"If this pattern matching thing is so powerful and so fantastic," you may be asking, "why don't you have a hundred different recipes on regular expressions in this chapter?" Regular expressions are the natural solution to many problems involving numbers, strings, dates, web documents, mail addresses, and almost everything else in this book; we use pattern matching over 100 times in other chapters. This chapter mostly presents recipes in which pattern matching forms part of the questions, not just part of the answers.

Perl's extensive and integrated support for regular expressions means that you not only have features available that you won't find in any other language, but you have new ways of using them, too. Programmers new to Perl often look for functions like these:

match( $string, $pattern );
subst( $string, $pattern, $replacement );

but matching and substituting are such common tasks that they merit their own notation:

$meadow =~ m/sheep/;   # True if $meadow contains "sheep"
$meadow !~ m/sheep/;   # True if $meadow doesn't contain "sheep"
$meadow =~ s/old/new/; # Replace "old" with "new" in $meadow

Pattern matching isn't like direct string comparison, even at its simplest level; it's more like string searching with mutant wildcards on steroids. Without anchors, the position where the match occurs can float freely throughout the string. Any of the following lines would also be matched by the expression $meadow =~ /ovine/, giving false positives when looking for lost sheep:

Fine bovines demand fine toreadors.
Muskoxen are a polar ovibovine species.
Grooviness went out of fashion decades ago.

Sometimes they're right in front of you but they still don't match:

Ovines are found typically in oviaries.

The problem is that while you are probably thinking in some human language, the pattern-matching engine most assuredly is not. When the engine is presented with the pattern /ovine/ and a string to match against, it searches the string for an "o" that is immediately followed by a "v", then by an "i", then by an "n", and then finally by an "e". What comes before or after that sequence doesn't matter. Additionally, those letters are matched case-sensitively. That's why it didn't find "Ovines", since that string starts with a capital letter.

As you find your patterns matching some strings you don't want them to match and not matching other strings that you do want them to match, you start embellishing. When looking for nothing but sheep, you probably want to match a pattern more like this:

if ($meadow =~ /\bovines?\b/i) { print "Here be sheep!" }

Don't be tricked by the phantom cow lurking in that string—that's not a bovine. It's an ovine with a \b in front, which matches at a word boundary only.[9] The s? indicates an optional "s" so we can find one or more ovines. The trailing /i makes the whole pattern match case-insensitive.

[9]For Perl's idea of what defines a "word."

As you see, certain character sequences have special meaning to the pattern-matching engine, often standing in for several possible literal characters. These so-called metacharacters let you do such things as restrict the pattern to the start or end of the string, give alternatives for parts of a pattern, allow repetition and wildcarding, and remember part of the matching substring for use later in the pattern or in code.

Learning the syntax of pattern matching isn't as daunting as it might appear. Sure, there are a lot of symbols, but each has a reason for existing. Regular expressions aren't random jumbles of punctuation—they're carefully thought-out jumbles of punctuation! If you forget one, you can always look it up. Summary tables are included in Programming Perl, Learning Perl, Mastering Regular Expressions, and the perlre(1) and perlop(1) manpages included with every Perl installation.

6.0.2. The Tricky Bits

Much trickier than the syntax of regular expressions is their sneaky semantics. The three aspects of pattern-matching behavior that seem to cause folks the most trouble are greed, eagerness, and backtracking—and also how these three interact with each other.

Greed is the principle that if a standard quantifier (such as *) can match a varying number of times, it matches as long a substring as it can. This is explained in Recipe 6.15.

Eagerness is the notion that the leftmost match wins. The engine is eager to return you a match as quickly as possible, sometimes even before you are expecting it. Consider the match "Fred" =~ /x*/. If asked to explain this in plain language, you might say "Does the string "Fred" contain any x's?" If so, you might be surprised to learn that it seems to. That's because /x*/ doesn't truly mean "any x's," unless your idea of "any" includes nothing at all. Formally, it means zero or more of them, and here zero sufficed for the eager matcher.

A more illustrative example of eagerness would be the following:

$string = "good food";
$string =~ s/o*/e/;

Can you guess which of the following is in $string after that substitution?

good food
geod food
geed food
geed feed
ged food
ged fed
egood food

The correct answer is the last one, because the earliest point at which zero or more occurrences of "o" could be found was right at the beginning of the string. Surprised? Regular expressions can do that to you if you're unfamiliar with their semantics.

Here's another example of where greed takes a back seat to eagerness:

$ echo longest | perl -ne 'print "$&\n" if /long|longer|longest/'
long

That's because Perl uses what's called a traditional NFA,[10] a non-deterministic finite automaton. This kind of matching engine is not guaranteed to return the longest overall match, just the first match. You might think of Perl's greed as being left-to-right directed, not globally greedy.

[10]As opposed to a POSIX-style NFA. See Mastering Regular Expressions for the differences.

NFAs can be slow, but significant performance gains can be made by rewriting the patterns to exploit how the particular NFA implementation runs. This is a major part of Jeffrey Friedl's book, Mastering Regular Expressions.

The last and most powerful of the three tricky bits in pattern matching is backtracking. For a pattern to match, the entire regular expression must match, not just part of it. So if the beginning of a pattern containing a quantifier succeeds in a way that causes later parts in the pattern to fail, the matching engine backs up and tries to find another match for the beginning part—that's why it's called backtracking. It means that the engine is going to try different possibilities, systematically investigating alternate matches until it finds one that works. In some pattern-matching implementations, the engine keeps backtracking in case other submatches make the overall match longer. Perl's matcher doesn't do that; as soon as one possibility works, it uses that—until and unless something later in the pattern fails, forcing a backtrack to retry another possible way of matching. This is discussed in Recipe 6.16.

6.0.3. Pattern-Matching Modifiers

Pattern-matching modifiers are a lot easier to list and learn than the different metacharacters. Table 6-1 contains a brief summary of them.

Table 6-1. Pattern-matching modifiers and their meanings

Modifier | Meaning
/i | Ignore alphabetic case
/x | Ignore most whitespace in pattern and permit comments
/g | Global—match/substitute as often as possible
/gc | Don't reset search position on failed match
/s | Let . match newline
/m | Let ^ and $ match next to embedded \n
/o | Compile pattern once only
/e | Righthand side of an s/// is code whose result is used as the replacement value
/ee | Righthand side of an s/// is a string that's eval'd twice; the final result then used as the replacement value

/i and /g are the most commonly used modifiers. The pattern /ram/i matches "ram", "RAM", "Ram", and so forth. Backreferences are checked case-insensitively if this modifier is on; see Recipe 6.16 for an example. This case-insensitivity can be made aware of the user's current locale settings if the use locale pragma has been invoked.

The /g modifier is used with s/// to replace every non-overlapping match, not just the first one. /g is also used with m// in loops to find (but not replace) every matching occurrence:

while (m/(\d+)/g) {
    print "Found number $1\n";
}

Used on m// in list context, /g pulls out all matches:

@numbers = m/(\d+)/g;

That finds only non-overlapping matches. You have to be much sneakier to get overlapping ones by making a zero-width look-ahead with the (?=...) construct. Because it's zero-width, the match engine hasn't advanced at all. Within the look-ahead, capturing parentheses are used to grab the thing anyway. Although we've saved something, Perl notices we haven't made any forward progress on the /g, so it bumps us forward one character position.

This shows the difference:

$digits = "123456789";
@nonlap = $digits =~ /(\d\d\d)/g;
@yeslap = $digits =~ /(?=(\d\d\d))/g;
print "Non-overlapping:  @nonlap\n";
print "Overlapping:      @yeslap\n";
Non-overlapping:  123 456 789
Overlapping:      123 234 345 456 567 678 789

The /s and /m modifiers are useful when matching strings with embedded newlines. /s makes dot match "\n", something it doesn't normally do; it also makes the match ignore the value of the old, deprecated $* variable. /m makes ^ and $ match after and before "\n", respectively. They are useful with paragraph slurping mode as explained in the Introduction to Chapter 8, and in Recipe 6.6.

The /e modifier is used on replacements so that the righthand part is run as code and its return value is used as the replacement string. s/(\d+)/sprintf("%#x", $1)/ge converts all numbers into hex, changing, for example, 2581 into 0xb23.

Because different countries have different ideas of what constitutes an alphabet, the POSIX standard provides systems (and thus programs) with a standard way of representing alphabets, character set ordering, and so on. Perl gives you access to some of these through the use locale pragma; see the perllocale manpage for more information. When use locale is in effect, the \w character class includes accented and other exotic characters. The case-changing \u, \U, \l, and \L (and the corresponding uc, ucfirst, etc. functions) escapes also respect use locale, so σ will be turned into Σ with \u if the locale says it should. (This only matters in 8-bit encodings, such as ISO 8859-7 for the Greek character set. If those characters had been in Unicode, case translation would always apply, irrespective of current locale setting.)

6.0.4. Special Variables

Perl sets special variables as the result of certain matches: $1, $2, $3, and so on ad infinitum are set when a pattern contains capturing parentheses within parts of the pattern. Each open parenthesis as you read left to right in the pattern begins filling a new, numbered variable. The variable $+ contains the contents of the last backreference of the last successful match. This helps distinguish which of several alternate matches was found (for example, if /(x.*y)|(y.*z)/ matches, $+ contains whichever of $1 or $2 were filled). $& contains the complete text matched in the last successful pattern match. $` and $´ are the strings before and after the successful match, respectively:

$string = "And little lambs eat ivy";
$string =~ /l[^s]*s/;
print "($`) ($&) ($´)\n";
(And ) (little lambs) ( eat ivy)

$`, $&, and $´ are tempting, but dangerous. Their very presence anywhere in a program slows down every pattern match because the engine must populate these variables for every match. This is true even if you use one of these variables only once, or, for that matter, if you never use them at all, only mention them. Using $& is no longer so expensive as the other two.

A cheaper approach is to use the substr function in conjunction with the built-in array variables @- and @+, first introduced in Perl v5.6. These represent the starting and ending positions of the last submatches, respectively. The Nth elements of these two arrays hold the beginning and ending offset of the Nth submatch. So $-[1] is the offset where $1 begins, and $+[1] is the offset where it ends; $-[2] is the offset where $2 begins, and $+[2] is the offset where it ends; and so on. $-[0] is the offset of the beginning of the entire match, and $+[0] the offset of the end of the entire match. (When we say "offset of the end," we mean the offset to the first character following the end of whatever matched, so that we can subtract beginning offsets from end offsets and arrive at the length.)

After a match against some variable $string, the following equivalencies hold true:

Variable    Equivalent

$`          substr($string, 0,     $-[0])
$&          substr($string, $-[0], $+[0] - $-[0])
$´          substr($string, $+[0])
$1          substr($string, $-[1], $+[1] - $-[1])
$2          substr($string, $-[2], $+[2] - $-[2])
$3          substr($string, $-[3], $+[3] - $-[3])

And so on and so forth.

To learn far more about regular expressions than you ever thought existed, check out Mastering Regular Expressions, written by Jeffrey Friedl (O'Reilly). This book is dedicated to explaining regular expressions from a practical perspective. Not only does it cover general regular expressions and Perl specials, it also compares and contrasts these with patterns in other programming languages.

Previous | Home | Next
5.17. Program: dutree | Book Index | 6.1. Copying and Substituting Simultaneously
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.1. Copying and Substituting Simultaneously

6.1.1. Problem

You're tired of using two separate statements with redundant information, one to copy and another to substitute.

6.1.2. Solution

Instead of:

$dst = $src;
$dst =~ s/this/that/;

use:

($dst = $src) =~ s/this/that/;

6.1.3. Discussion

Sometimes you wish you could run a search and replace on a copy of a string, but you don't care to write this in two separate steps. You don't have to, because you can apply the regex operation to the result of the copy operation.

For example:

# strip to basename
($progname = $0)        =~ s!^.*/!!;

# Make All Words Title-Cased
($capword  = $word)     =~ s/(\w+)/\u\L$1/g;

# /usr/man/man3/foo.1 changes to /usr/man/cat3/foo.1
($catpage  = $manpage)  =~ s/man(?=\d)/cat/;

You can even use this technique on an entire array:

@bindirs = qw( /usr/bin /bin /usr/local/bin );
for (@libdirs = @bindirs) { s/bin/lib/ }
print "@libdirs\n";
/usr/lib /lib /usr/local/lib

Because of precedence, parentheses are required when combining an assignment if you wish to change the result in the leftmost variable. The result of a substitution is its success: either "" for failure, or an integer number of times the substitution was done. Contrast this with the preceding examples where the parentheses surround the assignment itself. For example:

($a =  $b) =~ s/x/y/g;      # 1: copy $b and then change $a
 $a = ($b  =~ s/x/y/g);     # 2: change $b, count goes in $a
 $a =  $b  =~ s/x/y/g;      # 3: same as 2

6.1.4. See Also

The "Variables" section of Chapter 2 of Programming Perl, and the "Assignment Operators" section of perlop(1) and Chapter 3 of Programming Perl

Previous | Home | Next
6. Pattern Matching | Book Index | 6.2. Matching Letters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.2. Matching Letters

6.2.1. Problem

You want to see whether a string contains only alphabetic characters.

6.2.2. Solution

The obvious character class for matching regular letters isn't good enough in the general case:

if ($var =~ /^[A-Za-z]+$/) {
    # it is purely alphabetic
}

because it doesn't pay attention to letters with diacritics or characters from other writing systems. The best solution is to use Unicode properties:

if ($var =~ /^\p{Alphabetic}+$/) {   # or just /^\pL+$/
    print "var is purely alphabetic\n";
}

On older releases of Perl that don't support Unicode, your only real option was to use either a negated character class:

if ($var =~ /^[^\W\d_]+$/) {
    print "var is purely alphabetic\n";
}

or, if supported, POSIX character classes:

if ($var =~ /^[[:alpha:]]+$/) {
    print "var is purely alphabetic\n";
}

But these don't work for non-ASCII letters unless you use locale and the system you're running on actually supports POSIX locales.

6.2.3. Discussion

Apart from Unicode properties or POSIX character classes, Perl can't directly express "something alphabetic" independent of locale, so we have to be more clever. The \w regular expression notation matches one alphabetic, numeric, or underscore character—hereafter known as an "alphanumunder" for short. Therefore, \W is one character that is not one of those. The negated character class [^\W\d_] specifies a character that must be neither a non-alphanumunder, a digit, nor an underscore. That leaves nothing but alphabetics, which is what we were looking for.

Here's how you'd use this in a program:

use locale;
use POSIX 'locale_h';

# the following locale string might be different on your system
unless (setlocale(LC_ALL, "fr_CA.ISO8859-1")) {
    die "couldn't set locale to French Canadian\n";
}

while (<DATA>) {
    chomp;
    if (/^[^\W\d_]+$/) {
        print "$_: alphabetic\n";
    } else {
        print "$_: line noise\n";
    }
}

_ _END_ _
silly
façade
coöperate
niño
Renée
Molière
hæmoglobin
naïve
tschüß
random!stuff#here

POSIX character classes help a little here; available ones are alpha, alnum, ascii, blank, cntrl, digit, graph, lower, print, punct, space, upper, word, and xdigit. These are valid only within a square-bracketed character class specification:

$phone =~ /\b[:digit:]{3}[[:space:][:punct:]]?[:digit:]{4}\b/;     # WRONG
$phone =~ /\b[[:digit:]]{3}[[:space:][:punct:]]?[[:digit:]]{4}\b/; # RIGHT

It would be easier to use properties instead, because they don't have to occur only within other square brackets:

$phone =~ /\b\p{Number}{3}[\p{Space}\p{Punctuation]?\p{Number}{4}\b/;
$phone =~ /\b\pN{3}[\pS\pP]?\pN{4}\b/;   # abbreviated form

Match any one character with Unicode property prop using \p{prop}; to match any character lacking that property, use \P{prop} or [^\p{prop}]. The relevant property when looking for alphabetics is Alphabetic, which can be abbreviated as simply Letter or even just L. Other relevant properties include UppercaseLetter, LowercaseLetter, and TitlecaseLetter; their short forms are Lu, Ll, and Lt, respectively.

6.2.4. See Also

The treatment of locales in Perl in perllocale(1); your system's locale(3) manpage; we discuss locales in greater depth in Recipe 6.12; the "Perl and the POSIX Locale" section of Chapter 7 of Mastering Regular Expressions; also much of that book's Chapter 3

Previous | Home | Next
6.1. Copying and Substituting Simultaneously | Book Index | 6.3. Matching Words
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.3. Matching Words

6.3.1. Problem

You want to pick out words from a string.

6.3.2. Solution

Think hard about what you want a word to be and what separates one word from the next, and then write a regular expression that encodes your decisions. For example:

/\S+/               # as many non-whitespace characters as possible
/[A-Za-z'-]+/       # as many letters, apostrophes, and hyphens

6.3.3. Discussion

Because words vary between applications, languages, and input streams, Perl does not have built-in definitions of words. You must make them from character classes and quantifiers yourself, as we did previously. The second pattern is an attempt to recognize "shepherd's" and "sheep-shearing" each as single words.

Most approaches have limitations because of the vagaries of written language. For instance, although the second pattern successfully identifies "spank'd" and "counter-clockwise" as words, it also pulls the "rd" out of "23rd Psalm". To be more precise when pulling words out from a string, specify the characters surrounding the word. Normally, this should be a word boundary, not whitespace:

/\b([A-Za-z]+)\b/            # usually best
/\s([A-Za-z]+)\s/            # fails at ends or w/ punctuation

Although Perl provides \w, which matches a character that is part of a valid Perl identifier, Perl identifiers are rarely what you think of as words, since we mean a string of alphanumerics and underscores, but not colons or quotes. Because it's defined in terms of \w, \b may surprise you if you expect to match an English word boundary (or, even worse, a Mongolian word boundary).

\b and \B can still be useful. For example, /\Bis\B/ matches the string "is" within a word only, not at the edges. And while "thistle" would be found, "vis-à-vis" wouldn't.

6.3.4. See Also

The treatment of \b, \w, and \s in perlre(1) and Chapter 5 of Programming Perl; the words-related patterns in Recipe 6.23

Previous | Home | Next
6.2. Matching Letters | Book Index | 6.4. Commenting Regular Expressions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.4. Commenting Regular Expressions

6.4.1. Problem

You want to make your complex regular expressions understandable and maintainable.

6.4.2. Solution

You have several techniques at your disposal: electing alternate delimiters to avoid so many backslashes, placing comments outside the pattern or inside it using the /x modifier, and building up patterns piecemeal in named variables.

6.4.3. Discussion

The piece of sample code in Example 6-1 uses the first couple techniques, and its initial comment describes the overall intent of the regular expression. For simple patterns, this may be all that is needed. More complex patterns, as in the example, require more documentation.

Example 6-1. resname

  #!/usr/bin/perl -p
  # resname - change all "foo.bar.com" style names in the input stream
  # into "foo.bar.com [204.148.40.9]" (or whatever) instead
  use Socket;                 # load inet_addr
  s{
      (                       # capture the hostname in $1
          (?:                 # these parens for grouping only
              (?! [-_]  )     # lookahead for neither underscore nor dash
              [\w-] +         # hostname component
              \.              # and the domain dot
          ) +                 # now repeat that whole thing a bunch of times
          [A-Za-z]            # next must be a letter
          [\w-] +             # now trailing domain part
      )                       # end of $1 capture
  }{                          # replace with this:
      "$1 " .                 # the original bit, plus a space
             ( ($addr = gethostbyname($1))   # if we get an addr
              ? "[" . inet_ntoa($addr) . "]" #        format it
              : "[???]"                      # else mark dubious
             )
  }gex;               # /g for global
                      # /e for execute
                      # /x for nice formatting

For aesthetics, the example uses alternate delimiters. When you split your match or substitution over multiple lines, using matching braces aids readability. A more common use of alternate delimiters is for patterns and replacements that themselves contain slashes, such as in s/\/\//\/..\//g. Alternate delimiters, as in s!//!/../!g or s{//}{/../}g, avoid escaping the non-delimiting slashes with backslashes, again improving legibility.

The /x pattern modifier makes Perl ignore whitespace in the pattern (outside a character class) and treat # characters and their following text as comments. The /e modifier changes the replacement portion from a string into code to run. Since it's code, you can put regular comments there, too.

To include literal whitespace or # characters in a pattern to which you've applied /x, escape them with a backslash:

s/                  # replace
  \#                #   a pound sign
  (\w+)             #   the variable name
  \#                #   another pound sign
/${$1}/xg;          # with the value of the global variable

Remember that comments should explain what you're doing and why, not merely restate the code. Using "$i++ # add one to i" is apt to lose points in your programming course or at least get you talked about in substellar terms by your coworkers.

The last technique for rendering patterns more legible (and thus, more maintainable) is to place each semantic unit into a variable given an appropriate name. We use single quotes instead of doubles so backslashes don't get lost.

$optional_sign      = '[-+]?';
$mandatory_digits   = '\d+';
$decimal_point      = '\.?';
$optional_digits    = '\d*';

$number = $optional_sign
        . $mandatory_digits
        . $decimal_point
        . $optional_digits;

Then use $number in further patterns:

if (/($number)/) {      # parse out one
    $found = $1;
}

@allnums = /$number/g;  # parse all out

unless (/^$number$/) {  # any extra?
    print "need a number, just a number\n";
}

We can even combine all of these techniques:

# check for line of whitespace-separated numbers
m{
    ^ \s *              # optional leading whitespace
    $number             # at least one number
    (?:                 # begin optional cluster
        \s +            # must have some separator
        $number         # more the next one
    ) *                 # repeat at will
    \s * $              # optional trailing whitespace
}x

which is certainly a lot better than writing:

/^\s*[-+]?\d+\.?\d*(?:\s+[-+]?\d+\.?\d*)*\s*/

Patterns that you put in variables should probably not contain capturing parentheses or backreferences, since a capture in one variable could change the numbering of those in others.

Clustering parentheses—that is, /(?:...)/ instead of /(...)/—though, are fine. Not only are they fine, they're necessary if you want to apply a quantifier to the whole variable. For example:

$number = "(?:"
        .   $optional_sign
        .   $mandatory_digits
        .   $decimal_point
        .   $optional_digits
        . ")";

Now you can say /$number+/ and have the plus apply to the whole number group. Without the grouping, the plus would have shown up right after the last star, which would have been illegal.

One more trick with clustering parentheses is that you can embed a modifier switch that applies only to that cluster. For example:

$hex_digit = '(?i:[0-9a-z])';
$hdr_line  = '(?m:[^:]*:.*)';

The qr// construct does this automatically using cluster parentheses, enabling any modifiers you specified and disabling any you didn't for that cluster:

$hex_digit = qr/[0-9a-z]/i;
$hdr_line  = qr/^[^:]*:.*/m;

print "hex digit is: $hex_digit\n";
print "hdr line is: $hdr_line\n";

hex digit is: (?i-xsm:[0-9a-z])
hdr line is: (?m-xis:^[^:]*:.*)

It's probably a good idea to use qr// in the first place:

$optional_sign      = qr/[-+]?/;
$mandatory_digits   = qr/\d+/;
$decimal_point      = qr/\.?/;
$optional_digits    = qr/\d*/;

$number = qr{
                 $optional_sign
                 $mandatory_digits
                 $decimal_point
                 $optional_digits
          }x;

Although the output can be a bit odd to read:

print "Number is $number\n";

Number is (?x-ism:
                     (?-xism:[-+]?)
                     (?-xism:\d+)
                     (?-xism:\.?)
                     (?-xism:\d*)
              )

6.4.4. See Also

The /x modifier in perlre(1) and Chapter 5 of Programming Perl; the "Comments Within a Regular Expression" section of Chapter 7 of Mastering Regular Expressions

Previous | Home | Next
6.3. Matching Words | Book Index | 6.5. Finding the Nth Occurrence of a Match
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.5. Finding the Nth Occurrence of a Match

6.5.1. Problem

You want to find the Nth match in a string, not just the first one. For example, you'd like to find the word preceding the third occurrence of "fish":

One fish two fish red fish blue fish

6.5.2. Solution

Use the /g modifier in a while loop, keeping count of matches:

$WANT = 3;
$count = 0;
while (/(\w+)\s+fish\b/gi) {
    if (++$count =  = $WANT) {
        print "The third fish is a $1 one.\n";
        # Warning: don't 'last' out of this loop
    }
}
The third fish is a red one.

Or use a repetition count and repeated pattern like this:

/(?:\w+\s+fish\s+){2}(\w+)\s+fish/i;

6.5.3. Discussion

As explained in this chapter's Introduction, using the /g modifier in scalar context creates something of a progressive match, useful in while loops. This is commonly used to count the number of times a pattern matches in a string:

# simple way with while loop
$count = 0;
while ($string =~ /PAT/g) {
    $count++;               # or whatever you'd like to do here
}

# same thing with trailing while
$count = 0;
$count++ while $string =~ /PAT/g;

# or with for loop
for ($count = 0; $string =~ /PAT/g; $count++) { }

# Similar, but this time count overlapping matches
$count++ while $string =~ /(?=PAT)/g;

To find the Nth match, it's easiest to keep your own counter. When you reach the appropriate N, do whatever you care to. A similar technique could be used to find every Nth match by checking for multiples of N using the modulus operator. For example, (++$count % 3) = = 0 would be used to find every third match.

If this is too much bother, you can always extract all matches and then hunt for the ones you'd like.

$pond  = 'One fish two fish red fish blue fish';

# using a temporary
@colors = ($pond =~ /(\w+)\s+fish\b/gi);      # get all matches
$color  = $colors[2];                         # then the one we want

# or without a temporary array
$color = ( $pond =~ /(\w+)\s+fish\b/gi )[2];  # just grab element 3

print "The third fish in the pond is $color.\n";
The third fish in the pond is red.

To find all even-numbered fish:

$count = 0;
$_ = 'One fish two fish red fish blue fish';
@evens = grep { $count++ % 2 =  = 0 } /(\w+)\s+fish\b/gi;
print "Even numbered fish are @evens.\n";
Even numbered fish are two blue.

For substitution, the replacement value should be a code expression that returns the proper string. Make sure to return the original as a replacement string for cases you aren't interested in changing. Here we fish out the fourth specimen and turn it into a snack:

$count = 0;
s{
   \b               # makes next \w more efficient
   ( \w+ )          # this is what we'll be changing
   (
     \s+ fish \b
   )
}{
    if (++$count =  = 4) {
        "sushi" . $2;
    } else {
         $1   . $2;
    }
}gex;
One fish two fish red fish sushi fish

Picking out the last match instead of the first one is a fairly common task. The easiest way is to skip the beginning part greedily. After /.*\b(\w+)\s+fish\b/s, for example, the $1 variable has the last fish.

Another way to get arbitrary counts is to make a global match in list context to produce all hits, then extract the desired element of that list:

$pond = 'One fish two fish red fish blue fish swim here.';
$color = ( $pond =~ /\b(\w+)\s+fish\b/gi )[-1];
print "Last fish is $color.\n";
Last fish is blue.

To express this same notion of finding the last match in a single pattern without /g, use the negative lookahead assertion (?!THING). When you want the last match of arbitrary pattern P, you find P followed by any amount of not P through the end of the string. The general construct is P(?!.*P)*, which can be broken up for legibility:

m{
    P               # find some pattern P
    (?!             # mustn't be able to find
        .*          # something
        P           # and P
    )
}xs

That leaves us with this approach for selecting the last fish:

$pond = 'One fish two fish red fish blue fish swim here.';
if ($pond =~ m{
                \b  (  \w+) \s+ fish \b
                (?! .* \b fish \b )
            }six )
{
    print "Last fish is $1.\n";
} else {
    print "Failed!\n";
}
Last fish is blue.

This approach has the advantage that it can fit in just one pattern, which makes it suitable for similar situations as shown in Recipe 6.18. It has its disadvantages, though. It's obviously much harder to read and understand, although once you learn the formula, it's not too bad. However, it also runs more slowly—around half as fast on the data set tested here.

6.5.4. See Also

The behavior of m//g in scalar context is given in the "Regexp Quote-like Operators" section of perlop(1), and in the "Pattern Matching Operators" section of Chapter 5 of Programming Perl; zero-width positive lookahead assertions are shown in the "Regular Expressions" section of perlre(1), and in the "Fancy Patterns" section of Chapter 5 of Programming Perl

Previous | Home | Next
6.4. Commenting Regular Expressions | Book Index | 6.6. Matching Within Multiple Lines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.6. Matching Within Multiple Lines

6.6.1. Problem

You want to use regular expressions on a string containing more than one logical line, but the special characters . (any character but newline), ^ (start of string), and $ (end of string) don't seem to work for you. This might happen if you're reading in multiline records or the whole file at once.

6.6.2. Solution

Use /m, /s, or both as pattern modifiers. /s allows . to match a newline (normally it doesn't). If the target string has more than one line in it, /foo.*bar/s could match a "foo" on one line and a "bar" on a following line. This doesn't affect dots in character classes like [#%.], since they are literal periods anyway.

The /m modifier allows ^ and $ to match immediately before and after an embedded newline, respectively. /^=head[1-7]/m would match that pattern not just at the beginning of the record, but anywhere right after a newline as well.

6.6.3. Discussion

A common, brute-force approach to parsing documents where newlines are not significant is to read the file one paragraph at a time (or sometimes even the entire file as one string) and then extract tokens one by one. If the pattern involves dot, such as .+ or .*?, and must match across newlines, you need to do something special to make dot match a newline; ordinarily, it does not. When you've read more than one line into a string, you'll probably prefer to have ^ and $ match beginning- and end-of-line, not just beginning- and end-of-string.

The difference between /m and /s is important: /m allows ^ and $ to match next to an embedded newline, whereas /s allows . to match newlines. You can even use them together—they're not mutually exclusive.

Example 6-2 creates a simplistic filter to strip HTML tags out of each file in @ARGV and then send those results to STDOUT. First we undefine the record separator so each read operation fetches one entire file. (There could be more than one file, because @ARGV could have several arguments in it. If so, each readline would fetch the entire contents of one file.) Then we strip out instances of beginning and ending angle brackets, plus anything in between them. We can't use just .* for two reasons: first, it would match closing angle brackets, and second, the dot wouldn't cross newline boundaries. Using .*? in conjunction with /s solves these problems.

Example 6-2. killtags

  #!/usr/bin/perl
  # killtags - very bad html tag killer
  undef $/;           # each read is whole file
  while (<>) {        # get one whole file at a time
      s/<.*?>//gs;    # strip tags (terribly)
      print;          # print file to STDOUT
  }

Because this is just a single character, it would be much faster to use s/<[^>]*>//gs, but that's still a naïve approach: it doesn't correctly handle tags inside HTML comments or angle brackets in quotes (<IMG SRC="here.gif" ALT="<<Ooh la la!>>">). Recipe 20.6 explains how to avoid these problems.

Example 6-3 takes a plain text document and looks for lines at the start of paragraphs that look like "Chapter 20: Better Living Through Chemisery". It wraps these with an appropriate HTML level-one header. Because the pattern is relatively complex, we use the /x modifier so we can embed whitespace and comments.

Example 6-3. headerfy

  #!/usr/bin/perl
  # headerfy: change certain chapter headers to html
  $/ = '';
  while (<> ) {              # fetch a paragraph
      s{
          \A                  # start of record
          (                   # capture in $1
              Chapter         # text string
              \s+             # mandatory whitespace
              \d+             # decimal number
              \s*             # optional whitespace
              :               # a real colon
              . *             # anything not a newline till end of line
          )
      }{<H1>$1</H1>}gx;
      print;
  }

Here it is as a one-liner from the command line for those of you for whom the extended comments just get in the way of understanding:

% perl -00pe 's{\A(Chapter\s+\d+\s*:.*)}{<H1>$1</H1>}gx' datafile

This problem is interesting because we need to be able to specify start-of-record and end-of-line in the same pattern. We could normally use ^ for start-of-record, but we need $ to indicate not only end-of-record, but end-of-line as well. We add the /m modifier, which changes ^ and $. Instead of using ^ to match beginning-of-record, we use \A instead. We're not using it here, but in case you're interested, the version of $ that always matches end-of-record with an optional newline, even in the presence of /m, is \Z. To match the real end without the optional newline, use \z.

The following example demonstrates using /s and /m together. That's because we want ^ to match the beginning of any line in the paragraph; we also want dot to match a newline. The predefined variable $. represents the record number of the filehandle most recently read from using readline(FH) or <FH>. The predefined variable $ARGV is the name of the file that's automatically opened by implicit <ARGV> processing.

$/ = '';            # paragraph read mode
while (<ARGV>) {
    while (/^START(.*?)^END/sm) {   # /s makes . span line boundaries
                                    # /m makes ^ match near newlines
        print "chunk $. in $ARGV has <<$1>>\n";
    }
}

If you're already committed to the /m modifier, use \A and \Z for the old meanings of ^ and $, respectively. But what if you've used the /s modifier and want the original meaning of dot? You use [^\n].

Finally, although $ and \Z can match one before the end of a string if that last character is a newline, \z matches only at the very end of the string. We can use lookaheads to define the other two as shortcuts involving \z:

$ without /m
(?=\n)?\z
$ with /m
(?=\n)|\z
\Z always
(?=\n)?\z

6.6.4. See Also

The $/ variable in perlvar(1) and in the "Per-Filehandle Variables" section of Chapter 28 of Programming Perl; the /s and /m modifiers in perlre(1) and "The Fine Print" section of Chapter 2 of Programming Perl; the "Anchors and Other Zero-Width Assertions" section in Chapter 3 of Mastering Regular Expressions; we talk more about the special variable $/ in Chapter 8

Previous | Home | Next
6.5. Finding the Nth Occurrence of a Match | Book Index | 6.7. Reading Records with a Separator
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.7. Reading Records with a Separator

6.7.1. Problem

You want to read records separated by a pattern, but Perl doesn't allow its input record separator variable to be a regular expression.

Many problems, most obviously those involving parsing complex file formats, become simpler when you can extract records separated by different strings.

6.7.2. Solution

Read the whole file and use split:

undef $/;
@chunks = split(/pattern/, <FILEHANDLE>);

6.7.3. Discussion

Perl's official record separator, the $/ variable, must be a fixed string, not a pattern. To sidestep this limitation, undefine the input record separator entirely so that the next readline operation reads the rest of the file. This is sometimes called slurp mode, because it slurps in the whole file as one big string. Then split that huge string using the record separating pattern as the first argument.

Here's an example where the input stream is a text file that includes lines consisting of ".Se", ".Ch", and ".Ss", which are special codes in the troff macro set that this book was developed under. These strings are the separators, and we want to find text that falls between them.

# .Ch, .Se and .Ss divide chunks of STDIN
{
    local $/ = undef;
    @chunks = split(/^\.(Ch|Se|Ss)$/m, <>);
}
print "I read ", scalar(@chunks), " chunks.\n";

We create a localized version of $/ so its previous value is restored once the block finishes. By using split with parentheses in the pattern, captured separators are also returned. This way data elements in the return list alternate with elements containing "Se", "Ch", or "Ss".

If you don't want separators returned, but still need parentheses, use non-capturing parentheses in the pattern: /^\.(?:Ch|Se|Ss)$/m.

To split before a pattern but include the pattern in the return, use a lookahead assertion: /^(?=\.(?:Ch|Se|Ss))/m. That way each chunk except the first starts with the pattern.

Be aware that this uses a lot of memory when the file is large. However, with today's machines and typical text files, this is less often an issue now than it once was. Just don't try it on a 200 MB logfile unless you have plenty of virtual memory for swapping out to disk! Even if you do have enough swap space, you'll likely end up thrashing.

6.7.4. See Also

The $/ variable in perlvar(1) and in the "Per-Filehandle Variables" section of Chapter 28 of Programming Perl; the split function in perlfunc(1) and Chapter 29 of Programming Perl; we talk more about the special variable $/ in Chapter 8.

Previous | Home | Next
6.6. Matching Within Multiple Lines | Book Index | 6.8. Extracting a Range of Lines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.8. Extracting a Range of Lines

6.8.1. Problem

You want to extract all lines from a starting pattern through an ending pattern or from a starting line number up to an ending line number.

A common example of this is extracting the first 10 lines of a file (line numbers 1 to 10) or just the body of a mail message (everything past the blank line).

6.8.2. Solution

Use the operators .. or ... with patterns or line numbers.

The .. operator will test the right operand on the same iteration that the left operand flips the operator into the true state.

while (<>) {
    if (/BEGIN PATTERN/ .. /END PATTERN/) {
        # line falls between BEGIN and END in the
        # text, inclusive.
    }
}

while (<>) {
    if (FIRST_LINE_NUM .. LAST_LINE_NUM) {
        # operate only between first and last line, inclusive.
    }
}

But the ... operator waits until the next iteration to check the right operand.

while (<>) {
    if (/BEGIN PATTERN/ ... /END PATTERN/) {
        # line is between BEGIN and END on different lines
    }
}

while (<>) {
    if (FIRST_LINE_NUM ... LAST_LINE_NUM) {
        # operate only between first and last line, not inclusive
    }
}

6.8.3. Discussion

The range operators, .. and ..., are probably the least understood of Perl's myriad operators. They were designed to allow easy extraction of ranges of lines without forcing the programmer to retain explicit state information. Used in scalar context, such as in the test of if and while statements, these operators return a true or false value that's partially dependent on what they last returned. The expression left_operand .. right_operand returns false until left_operand is true, but once that test has been met, it stops evaluating left_operand and keeps returning true until right_operand becomes true, after which it restarts the cycle. Put another way, the first operand turns on the construct as soon as it returns a true value, whereas the second one turns it off as soon as it returns true.

The two operands are completely arbitrary. You could write mytestfunc1( ) .. mytestfunc2( ), although this is rarely seen. Instead, the range operators are usually used with either line numbers as operands (the first example), patterns as operands (the second example), or both.

# command-line to print lines 15 through 17 inclusive (see below)
perl -ne 'print if 15 .. 17' datafile

# print all <XMP> .. </XMP> displays from HTML doc
while (<>) {
    print if m#<XMP>#i .. m#</XMP>#i;
}

# same, but as shell command
% perl -ne 'print if m#<XMP>#i .. m#</XMP>#i' document.html

If either operand is a numeric literal, the range operators implicitly compare against the $. variable ($NR or $INPUT_LINE_NUMBER if you use English). Be careful with implicit line number comparisons here. You must specify literal numbers in your code, not variables containing line numbers. That means you simply say 3 .. 5 in a conditional, but not $n .. $m where $n and $m are 3 and 5 respectively. For that, be more explicit by testing the $. variable directly.

perl -ne 'BEGIN { $top=3; $bottom=5 }  print if $top .. $bottom' /etc/passwd
       # WRONG
perl -ne 'BEGIN { $top=3; $bottom=5 }
    print if $. =  = $top .. $. =  =     $bottom' /etc/passwd    # RIGHT
perl -ne 'print if 3 .. 5' /etc/passwd   # also RIGHT

The difference between .. and ... is their behavior when both operands become true on the same iteration. Consider these two cases:

print if /begin/ ..  /end/;
print if /begin/ ... /end/;

Given the line "You may not end ere you begin", both versions of the previous range operator return true. But the code using .. won't print any further lines. That's because .. tests both conditions on the same line once the first test matches, and the second test tells it that it's reached the end of its region. On the other hand, ... continues until the next line that matches /end/ because it never tries to test both operands on the same line.

You may mix and match conditions of different sorts, as in:

while (<>) {
    $in_header =   1  .. /^$/;
    $in_body   = /^$/ .. eof( );
}

The first assignment sets $in_header to be true from the first input line until after the blank line separating the header, such as from a mail message, a USENET news posting, or even an HTTP header. (Technically, an HTTP header should have linefeeds and carriage returns as network line terminators, but in practice, servers are liberal in what they accept.) The second assignment sets $in_body to true as soon as the first blank line is encountered, up through end-of-file. Because range operators do not retest their initial condition, any further blank lines, like those between paragraphs, won't be noticed.

Here's an example. It reads files containing mail messages and prints addresses it finds in headers. Each address is printed only once. The extent of the header is from a line beginning with a "From:" up through the first blank line. If we're not within that range, go on to the next line. This isn't an RFC-822 notion of an address, but it is easy to write.

%seen = ( );
while (<>) {
    next unless /^From:?\s/i .. /^$/;
    while (/([^<>( ),;\s]+\@[^<>( ),;\s]+)/g) {
        print "$1\n" unless $seen{$1}++;
    }
}

6.8.4. See Also

The .. and ... operators in the "Range Operator" sections of perlop(1) and Chapter 3 of Programming Perl; the entry for $NR in perlvar(1) and the "Per-Filehandle Variables" section of Chapter 28 of Programming Perl

Previous | Home | Next
6.7. Reading Records with a Separator | Book Index | 6.9. Matching Shell Globs as Regular Expressions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.9. Matching Shell Globs as Regular Expressions

6.9.1. Problem

You want to allow users to specify matches using traditional shell wildcards, not full Perl regular expressions. Wildcards are easier to type than full regular expressions for simple cases.

6.9.2. Solution

Use the following subroutine to convert four shell wildcard characters into their equivalent regular expression; all other characters are quoted to render them literals.

sub glob2pat {
    my $globstr = shift;
    my %patmap = (
        '*' => '.*',
        '?' => '.',
        '[' => '[',
        ']' => ']',
    );
    $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
    return '^' . $globstr . '$';
}

6.9.3. Discussion

A Perl regex pattern is not the same as a shell wildcard pattern. The shell's *.* is not a valid regular expression. Its meaning as a pattern would be /^.*\..*$/s, which is admittedly much less fun to type.

The function given in the Solution makes these conversions for you, following the standard wildcard rules used by the glob built-in. Table 6-2 shows equivalent wildcard patterns in the shell and in Perl.

Table 6-2. Shell globs and equivalent Perl wildcard patterns

Shell | Perl
list.? | ^list\..$
project.* | ^project\..*$
*old | ^.*old$
type*.[ch] | ^type.*\.[ch]$
*.* | ^.*\..*$
* | ^.*$

The function returns a string, not a regex object, because the latter would lock in (and out) any modifier flags, such as /i, but we'd rather delay that decision until later.

Shell wildcard rules are different from those of a regular expression. The entire pattern is implicitly anchored at the ends; a question mark maps into any character; an asterisk is any amount of anything; and brackets are character ranges. Everything else is a literal.

Most shells do more than simple one-directory globbing. For instance, */* means "all files (including directory files) in all subdirectories of the current directory." Also, shells usually don't expand wildcards to include files with names beginning with a period; you usually have to put that leading period into your glob pattern explicitly. Our glob2pat function doesn't do these things—if you need them, use the File::KGlob module from CPAN.

6.9.4. See Also

Your system manpages for the various shells, such as csh(1), tcsh(1), sh(1), ksh(1), and bash(1); the glob function in perlfunc(1) and Chapter 29 of Programming Perl; the documentation for the CPAN module Glob::DosGlob; the "I/O Operators" section of perlop(1); we talk more about globbing in Recipe 9.6

Previous | Home | Next
6.8. Extracting a Range of Lines | Book Index | 6.10. Speeding Up Interpolated Matches
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.10. Speeding Up Interpolated Matches

6.10.1. Problem

You want your function or program to take one or more regular expressions as arguments, but doing so seems to run slower than using literals.

6.10.2. Solution

To overcome this bottleneck, if you have only one pattern whose value won't change during the entire run of a program, store it in a string and use /$pattern/o:

while ($line = <>) {
    if ($line =~ /$pattern/o) {
        # do something
    }
}

However, that won't work for more than one pattern. Precompile the pattern strings using the qr// operator, then match each result against each of the targets:

@pats = map { qr/$_/ } @strings;
while ($line = <>) {
    for $pat (@pats) {
        if ($line =~ /$pat/) {
            # do something;
        }
    }
}

6.10.3. Discussion

When Perl compiles a program, it converts patterns into an internal form. This conversion occurs at compile time for patterns without variables, but at runtime for those that do. Interpolating variables into patterns, as in /$pattern/, can slow your program down—sometimes substantially. This is particularly noticeable when $pattern changes often.

The /o modifier locks in the values from variables interpolated into the pattern. That is, variables are interpolated only once: the first time the match is run. Because Perl ignores any later changes to those variables, make sure to use it only on unchanging variables.

Using /o on patterns without interpolated variables doesn't hurt, but it also doesn't help. The /o modifier is also of no help when you have an unknown number of regular expressions and need to check one or more strings against all of these patterns, since you need to vary the patterns' contents. Nor is it of any use when the interpolated variable is a function argument, since each call to the function gives the variable a new value.

Example 6-4 is an example of the slow but straightforward technique for matching many patterns against many lines. The array @popstates contains the standard two-letter abbreviations for some of the places in the heartland of North America where we normally refer to soft drinks as pop (soda to us means either plain soda water or else handmade delicacies from the soda fountain at the corner drugstore, preferably with ice cream). The goal is to print any line of input that contains any of those places, matching them at word boundaries only. It doesn't use /o, because the variable that holds the pattern keeps changing.

Example 6-4. popgrep1

  #!/usr/bin/perl
  # popgrep1 - grep for abbreviations of places that say "pop"
  # version 1: slow but obvious way
  @popstates = qw(CO ON MI WI MN);
  LINE: while (defined($line = <>)) {
      for $state (@popstates) {
          if ($line =~ /\b$state\b/) {  # this is  s l o o o w
              print; next LINE;
         }
      }
  }

Such a direct, obvious, brute-force approach is also distressingly slow, because Perl has to recompile all patterns with each line of input. A better solution is the qr// operator (used in Example 6-5), which first appeared in v5.6 and offers a way to step around this bottleneck. The qr// operator quotes and possibly compiles its string argument, returning a scalar to use in later pattern matches. If that scalar is used by itself in the interpolated match, Perl uses the cached compiled form and so avoids recompiling the pattern.

Example 6-5. popgrep2

  #!/usr/bin/perl
  # popgrep2 - grep for abbreviations of places that say "pop"
  # version 2: fast way using qr//
  @popstates = qw(CO ON MI WI MN);
  @poppats = map { qr/\b$_\b/ } @popstates;
  LINE: while (defined($line = <>)) {
      for $pat (@poppats) {
          if ($line =~ /$pat/) {        # this is fast
              print; next LINE;
         }
      }
  }

Print the array @poppats and you'll see strings like this:

(?-xism:\bCO\b)
(?-xism:\bON\b)
(?-xism:\bMI\b)
(?-xism:\bWI\b)
(?-xism:\bMN\b)

Those are used for the stringified print value of the qr// operator, or to build up a larger pattern if the result is interpolated into a larger string. But also associated with each is a cached, compiled version of that string as a pattern, and this is what Perl uses when the interpolation into a match or substitution operator contains nothing else.

6.10.4. See Also

The qr// operator in perlop(1) and in the section on "The qr// quote regex operator" in Chapter 5 of Programming Perl

Previous | Home | Next
6.9. Matching Shell Globs as Regular Expressions | Book Index | 6.11. Testing for a Valid Pattern
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.11. Testing for a Valid Pattern

6.11.1. Problem

You want to let users enter their own patterns, but an invalid one would abort your program the first time you tried to use it.

6.11.2. Solution

Test the pattern in an eval { } construct first, matching against some dummy string. If $@ is not set, no exception occurred, so you know the pattern successfully compiled as a valid regular expression. Here is a loop that continues prompting until the user supplies a valid pattern:

do {
    print "Pattern? ";
    chomp($pat = <>);
    eval { "" =~ /$pat/ };
    warn "INVALID PATTERN $@" if $@;
} while $@;

Here's a standalone subroutine that verifies whether a pattern is valid:

sub is_valid_pattern {
    my $pat = shift;
    eval { "" =~ /$pat/ };
    return $@ ? 0 : 1;
}

Another way to write that is like this:

sub is_valid_pattern {
    my $pat = shift;
    return eval { "" =~ /$pat/; 1 } || 0;
}

This version doesn't need to use $@, because if the pattern match executes without exception, the next statement with just a 1 is reached and returned. Otherwise it's skipped, so just a 0 is returned.

6.11.3. Discussion

There's no limit to the number of invalid, uncompilable patterns. The user could mistakenly enter "<I\s*[^">, "*** GET RICH ***", or "+5-i". If you blindly use the proffered pattern in your program, it raises an exception, normally a fatal event.

The tiny program in Example 6-6 demonstrates this.

Example 6-6. paragrep

  #!/usr/bin/perl
  # paragrep - trivial paragraph grepper
  die "usage: $0 pat [files]\n" unless @ARGV;
  $/ = '';
  $pat = shift;
  eval { "" =~ /$pat/; 1 }      or die "$0: Bad pattern $pat: $@\n";
  while (<>) {
      print "$ARGV $.: $_" if /$pat/o;
  }

That /o means to interpolate variables once only, even if their contents later change.

You could encapsulate this in a function call that returns 1 if the block completes and 0 if not, as shown in the Solution. The simpler eval "/$pat/" would also work to trap the exception, but has two other problems. One is that any slashes (or whatever your chosen pattern delimiter is) in the string the user entered would raise an exception. More importantly, it would open a drastic security hole that you almost certainly want to avoid. Strings like this could ruin your day:

$pat = "You lose @{[ system('rm -rf *')]} big here";

If you don't want to let the user provide a real pattern, you can always metaquote the string first:

$safe_pat = quotemeta($pat);
something( ) if /$safe_pat/;

Or, even easier, use:

something( ) if /\Q$pat/;

But if you're going to do that, why are you using pattern matching at all? In that case, a simple use of index would be enough. But sometimes you want a literal part and a regex part, such as:

something( ) if /^\s*\Q$pat\E\s*$/;

Letting the user supply a real pattern gives them power enough for many interesting and useful operations. This is a good thing. You just have to be slightly careful. Suppose they wanted to enter a case-insensitive pattern, but you didn't provide the program with an option like grep's -i option. By permitting full patterns, the user can enter an embedded /i modifier as (?i), as in /(?i)stuff/.

What happens if the interpolated pattern expands to nothing? If $pat is the empty string, what does /$pat/ match—that is, what does a blank // match? It doesn't match the start of all possible strings. Surprisingly, matching the null pattern exhibits the dubiously useful semantics of reusing the previous successfully matched pattern. In practice, this is hard to make good use of in Perl.

6.11.4. See Also

The eval function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 10.12

Previous | Home | Next
6.10. Speeding Up Interpolated Matches | Book Index | 6.12. Honoring Locale Settings in Regular Expressions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.12. Honoring Locale Settings in Regular Expressions

6.12.1. Problem

You want to translate case when in a different locale, or you want to make \w match letters with diacritics, such as José or déjà vu.

For example, let's say you're given half a gigabyte of text written in German and told to index it. You want to extract words (with \w+) and convert them to lowercase (with lc or \L), but the normal versions of \w and lc neither match the German words nor change the case of accented letters.

6.12.2. Solution

Perl's regular-expression and text-manipulation routines have hooks to the POSIX locale setting. Under the use locale pragma, accented characters are taken care of—assuming a reasonable LC_CTYPE specification and system support for the same.

use locale;

6.12.3. Discussion

By default, \w+ and case-mapping functions operate on upper- and lowercase letters, digits, and underscores. This works only for the simplest of English words, failing even on many common imports. The use locale directive redefines what a "word character" means.

In Example 6-7 you see the difference in output between having selected the English ("en") locale and the German ("de") one.

Example 6-7. localeg

  #!/usr/bin/perl -w
  # localeg - demonstrate locale effects
  use locale;
  use POSIX 'locale_h';
  $name = "andreas k\xF6nig";
  @locale{qw(German English)} = qw(de_DE.ISO_8859-1 us-ascii);
  setlocale(LC_CTYPE, $locale{English})
    or die "Invalid locale $locale{English}";
  @english_names = ( );
  while ($name =~ /\b(\w+)\b/g) {
          push(@english_names, ucfirst($1));
  }
  setlocale(LC_CTYPE, $locale{German})
    or die "Invalid locale $locale{German}";
  @german_names = ( );
  while ($name =~ /\b(\w+)\b/g) {
          push(@german_names, ucfirst($1));
  }
  print "English names: @english_names\n";
  print "German names:  @german_names\n";
  English names: Andreas K Nig
  German names:  Andreas König

This approach relies on POSIX locale support for 8-bit character encodings, which your system may or may not provide. Even if your system does claim to provide POSIX locale support, the standard does not specify the locale names. As you might guess, portability of this approach is not assured. If your data is already in Unicode, you don't need POSIX locales for this to work.

6.12.4. See Also

The treatment of \b, \w, and \s in perlre(1) and in the "Classic Perl Character Class Shortcuts" section of Chapter 5 of Programming Perl; the treatment of locales in Perl in perllocale(1); your system's locale(3) manpage; we discuss locales in greater depth in Recipe 6.2; the "POSIX—An Attempt at Standardization" section of Chapter 3 of Mastering Regular Expressions

Previous | Home | Next
6.11. Testing for a Valid Pattern | Book Index | 6.13. Approximate Matching
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.13. Approximate Matching

6.13.1. Problem

You want to match fuzzily, that is, allowing for a margin of error, where the string doesn't quite match the pattern. Whenever you want to be forgiving of misspellings in user input, you want fuzzy matching.

6.13.2. Solution

Use the String::Approx module, available from CPAN:

use String::Approx qw(amatch);

if (amatch("PATTERN", @list)) {
    # matched
}

@matches = amatch("PATTERN", @list);

6.13.3. Discussion

String::Approx calculates the difference between the pattern and each string in the list. If less than a certain number—by default, 10 percent of the pattern length—of one-character insertions, deletions, or substitutions are required to make the string fit the pattern, it still matches. In scalar context, amatch returns the number of successful matches. In list context, it returns the strings matched.

use String::Approx qw(amatch);
open(DICT, "/usr/dict/words")               or die "Can't open dict: $!";
while(<DICT>) {
    print if amatch("balast");
}

ballast
balustrade
blast
blastula
sandblast

Options passed to amatch control case-sensitivity and the permitted number of insertions, deletions, or substitutions. These are fully described in the String::Approx documentation.

The module's matching function seems to run between 10 and 40 times slower than Perl's built-in pattern matching. So use String::Approx only if you're after a fuzziness in your matching that Perl's patterns can't provide.

6.13.4. See Also

The documentation for the CPAN module String::Approx; Recipe 1.22

Previous | Home | Next
6.12. Honoring Locale Settings in Regular Expressions | Book Index | 6.14. Matching from Where the Last Pattern Left Off
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.14. Matching from Where the Last Pattern Left Off

6.14.1. Problem

You want to match again in the same string, starting from where the last match left off. This is a useful approach to take when repeatedly extracting data in chunks from a string.

6.14.2. Solution

Use a combination of the /g and /c match modifiers, the \G pattern anchor, and the pos function.

6.14.3. Discussion

The /g modifier on a pattern match makes the matching engine keep track of the position in the string where it finished matching. If the next match also uses /g on that string, the engine starts looking for a match from this remembered position. This lets you, for example, use a while loop to progressively extract repeated occurrences of a match. Here we find all non-negative integers:

while (/(\d+)/g) {
    print "Found number $1\n";
}

Within a pattern, \G means the end of the previous match. For example, if you had a number stored in a string with leading blanks, you could change each leading blank into the digit zero this way:

$n = "   49 here";
$n =~ s/\G /0/g;
print $n;
00049 here

You can also make good use of \G in a while loop. Here we use \G to parse a comma-separated list of numbers (e.g., "3,4,5,9,120"):

while (/\G,?(\d+)/g) {
    print "Found number $1\n";
}

By default, when your match fails (when we run out of numbers in the examples, for instance) the remembered position is reset to the start. If you don't want this to happen, perhaps because you want to continue matching from that position but with a different pattern, use the modifier /c with /g:

$_ = "The year 1752 lost 10 days on the 3rd of September";

while (/(\d+)/gc) {
    print "Found number $1\n";
}
# the /c above left pos at end of final match

if (/\G(\S+)/g) {
    print "Found $1 right after the last number.\n";
}

Found number 1752
Found number 10
Found number 3
Found rd after the last number.

Successive patterns can use /g on a string, which remembers the ending position of the last successful match. That position is associated with the scalar matched against, not with the pattern. It's reset if the string is modified.

The position of the last successful match can be directly inspected or altered with the pos function, whose argument is the string whose position you want to get or set. Assign to the function to set the position.

$a = "Didst thou think that the eyes of the White Tower were blind?";
$a =~ /(\w{5,})/g;
print "Got $1, position in \$a is ", pos($a), "\n";
Got Didst, position in $a is 5

pos($a) = 30;
$a =~ /(\w{5,})/g;
print "Got $1, position in \$a now ", pos($a), "\n";
Got White, position in $a now 43

Without an argument, pos operates on $_:

$_ = "Nay, I have seen more than thou knowest, Grey Fool.";
/(\w{5,})/g;
print "Got $1, position in \$_ is ", pos, "\n";
pos = 42;
/\b(\w+)/g;
print "Next full word after position 42 is $1\n";

Got knowest, position in $_ is 39
Next full word after position 42 is Fool

6.14.4. See Also

The /g and /c modifiers are discussed in perlre(1) and the "The m// Operator (Matching)" section of Chapter 5 of Programming Perl

Previous | Home | Next
6.13. Approximate Matching | Book Index | 6.15. Greedy and Non-Greedy Matches
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.15. Greedy and Non-Greedy Matches

6.15.1. Problem

You have a pattern with a greedy quantifier like *, +, ?, or { }, and you want to stop it from being greedy.

A classic example is the naïve substitution to remove tags from HTML. Although it looks appealing, s#<TT>.*</TT>##gsi deletes everything from the first open TT tag through the last closing one. This would turn "Even <TT>vi</TT> can edit <TT>troff</TT> effectively." into "Even effectively", completely changing the meaning of the sentence!

6.15.2. Solution

Replace the offending greedy quantifier with the corresponding non-greedy version. That is, change *, +, ?, and { } into *?, +?, ??, and { }?, respectively.

6.15.3. Discussion

Perl has two sets of quantifiers: the maximal ones—*, +, ?, and { }—and the minimal ones—*?, +?, ??, and { }?. Less formally, these two sorts of quantifiers are often referred to as greedy and non-greedy (or sometimes lazy), respectively. For instance, given the string "Perl is a Swiss Army Chainsaw!", the pattern /(r.*s)/ matches "rl is a Swiss Army Chains", whereas /(r.*?s)/ matches "rl is".

With maximal quantifiers, when you ask to match a variable number of times, such as zero or more times for * or one or more times for +, the matching engine prefers the "or more" portion of that description. Thus /foo.*bar/ matches the first "foo" through the last "bar" in the string, rather than only through the next "bar" as some might expect. That's because the greedy .* first expands to the rest of the string, but since that wouldn't leave any characters for "bar" to match, the engine backs up one character at a time until it finds "bar".

To make any repetition operator match minimally instead of maximally, add an extra ?. So *? still matches zero or more times, but rather than match as much as it can, the way * would, it matches as little as it can.

# greedy pattern
s/<.*>//gs;              # try to remove tags, very badly

# nongreedy pattern
s/<.*?>//gs;             # try to remove tags, better (but still rather badly)

This approach doesn't remove tags from all possible HTML correctly, because a single regular expression is seldom an acceptable replacement for a real parser. See Recipe 20.6 for the right way.

Minimal matching isn't all it's cracked up to be. Don't fall into the trap of thinking that including the partial pattern BEGIN.*?END in a pattern amidst other elements will always match the shortest amount of text between occurrences of BEGIN and END. Consider the pattern /BEGIN(.*?)END/. If matched against the string "BEGIN and BEGIN and END", $1 would contain "and BEGIN and". This is probably not what you want.

Imagine trying to pull out everything between bold-italic pairs:

<b><i>this</i> and <i>that</i> are important</b> Oh, <b><i>me too!</i></b>

A pattern to find only text between bold-italic HTML pairs, that is, text that doesn't include them, might appear to be:

m{ <b><i>(.*?)</i></b> }sx

You might be surprised to learn that the pattern doesn't find such pairs. Many people incorrectly understand this as matching a "<b><i>" sequence, then anything up to a "</i></b>" sequence, leaving the intervening text in $1. While it often works out that way due to the input data, that's not what it says. There's nothing in that pattern that says .*? can't match "<b><i>" again (and again and again) before it comes to "</i></b>". If the intention were to extract only stuff between "<b><i>" and its corresponding "</i></b>", with no other bold-italic tags in between, that pattern would be incorrect.

If the string in question is just one character, and if what follows the minimal match is not a literal character, a negated class is remarkably more efficient than a minimal match, as in /X([^X]*)X/. But the general way to say "match BEGIN, then not BEGIN, then END" for any arbitrary values of BEGIN and END would be as follows (this also stores the intervening part in $1):

/BEGIN((?:(?!BEGIN).)*)END/s

or, more legibly:

{
  BEGIN               # locate initial portion
  (                   # save this group into $1
      (?:             # non-capturing group
          (?! BEGIN)  # assert: can't be at another BEGIN
          .           # now match any one character
      ) *             # entire group 0 or more
  )                   # end $1 group
  END                 # locate final portion
}sx

However, this might not be what you're after, either. The greedy star quantifier means that the non-BEGIN portion in $1 will be maximized, giving fence posts of the last BEGIN through not the first END, but the last one. So if your string were:

$_ = "BEGIN1 BEGIN2 BEGIN3 3END 2END 1END";

$1 would contain "3 3END 2END 1". Making the quantifier a minimal matching one:

/BEGIN((?:(?!BEGIN).)*?)END/s

puts "3 3" in $1 for you. Now add another lookahead negation, (?!END), next to the existing one. Written out with plenty of whitespace, we now have:

m{
    BEGIN           # locate initial portion
    (               # save this group into $1
        (?:         # non-capturing group
            (?! BEGIN   )   # can't be at a BEGIN
            (?! END     )   # also can't be at an END
            .               # finally, match any one char
        ) *         # repeat entire group ad libitum
    )               # end $1 capture
    END
}sx

Instead of adding another lookahead, another possibility is to use alternation within the existing one: (?!BEGIN|END). Applying this approach to the HTML-matching code, we end up with something like:

m{ <b><i>(  (?: (?!</b>|</i>). )*  ) </i></b> }sx

or perhaps:

m{ <b><i>(  (?: (?!</[ib]>). )*  ) </i></b> }sx

Jeffrey Friedl points out that this quick-and-dirty method isn't particularly efficient. He suggests crafting a more elaborate pattern when speed matters, such as:

m{
    <b><i>
    [^<]*  # stuff not possibly bad, and not possibly the end.
    (?:
 # at this point, we can have '<' if not part of something bad
     (?! </?[ib]>  )    # what we can't have
     <                  # okay, so match the '<'
     [^<]*              # and continue with more safe stuff
   ) *
   </i> </b>
 }sx

This is a variation on Jeffrey's unrolling-the-loop technique, described in Chapter 6 of Mastering Regular Expressions, Second Edition.

6.15.4. See Also

The non-greedy quantifiers in the "Regular Expressions" section of perlre(1) and in Chapter 5 of Programming Perl

Previous | Home | Next
6.14. Matching from Where the Last Pattern Left Off | Book Index | 6.16. Detecting Doubled Words
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.16. Detecting Doubled Words

6.16.1. Problem

You want to check for doubled words in a document.

6.16.2. Solution

Use backreferences in your pattern.

6.16.3. Discussion

Parentheses in a pattern make the matching engine remember what text that portion of the pattern matched. Later in the pattern, refer to the actual string that matched with \1 (indicating the string matched by the first set of parentheses), \2 (for the string matched by the second set of parentheses), and so on. Don't use $1 within a regex, because it would be a variable interpolated before the match began. The pattern /([A-Z])\1/ matches a capital letter followed not just by any capital letter, but by whichever one was just matched (i.e., captured by the first set of parentheses in that pattern).

The next sample code reads its input files by paragraph, with the definition of paragraph following Perl's notion of a paragraph—a chunk of text terminated by two or more contiguous newlines. Within each paragraph, the code finds all doubled words. It ignores case and can match across newlines.

Here we use /x to embed whitespace and comments to improve readability. The /i permits both instances of "is" in the sentence "Is is this ok?" to match, even though they differ in case. We use /g in a while loop to keep finding doubled words until we run out of text.

$/ = '';                      # paragrep mode
while (<>) {
    while ( m{
                \b            # start at a word boundary (begin letters)
                (\S+)         # find chunk of non-whitespace
                \b            # until another word boundary (end letters)
                (
                    \s+       # separated by some whitespace
                    \1        # and that very same chunk again
                    \b        # until another word boundary
                ) +           # one or more sets of those
             }xig
         )
    {
        print "dup word '$1' at paragraph $.\n";
    }
}

That code finds the duplicated test in the following paragraph:

This is a test
test of the doubled word finder.

Word boundary anchors surrounding \S+ are often a bad idea because they do something you might not be expecting. That's because word boundaries in Perl are defined as transitions between alphanumunders (that's a \w) and either the edge of the string or a non-alphanumunder. Surrounding \S+ with \b subtly changes \S+ from its normal meaning of one or more non-whitespace characters to a stretch of non-whitespace whose first and last character must be an alphanumunder.

Sometimes, though, this might be just what you're looking for. Consider the string:

$string = q("I can't see this," she remarked.);

@a = $string =~ /\b\S+\b/g;
@b = $string =~ /\S+/g;

The elements of @a are now:

0  I
1  can't
2  see
3  this
4  she
5  remarked

but those of @b are:

0  "I
1  can't
2  see
3  this,"
4  she
5  remarked.

Here's another interesting demonstration of backreferences. Imagine two words in which the end of the first word is the same as the start of the next one, such as "nobody" and "bodysnatcher". You'd like to find that overlapping part and come up with "nobodysnatcher". This is a variant on the doubled word problem.

Conventional character-by-character processing the way a C programmer would write it would take a great deal of tricky code. But with a backtracking pattern matcher, it just takes one simple pattern match.

$a = 'nobody';
$b = 'bodysnatcher';
if ("$a $b" =~ /^(\w+)(\w+) \2(\w+)$/) {
    print "$2 overlaps in $1-$2-$3\n";
}
body overlaps in no-body-snatcher

You might think that $1 would first grab up all of "nobody" due to greediness. It does—for a while. But once it's done so, there aren't any more characters to put in $2. So the engine backs up, and $1 begrudgingly gives up one character to $2. The space character matches successfully, but then sees \2, which currently holds a lone "y". The next character in the string is not a "y", but a "b". This makes the engine back up, eventually forcing $1 to surrender enough to $2 that the pattern can match some string, a space, and then that same string again.

That won't quite work out if the overlap is itself the product of a doubling, as in "rococo" and "cocoon". The preceding algorithm would have decided that the overlapping string, $2, must be just "co" rather than "coco". But we don't want a "rocococoon"; we want a "rococoon". Adding a minimal matching quantifier to the $1 part gives the much better pattern:

/^(\w+?)(\w+) \2(\w+)$/,

which solves this problem.

Backtracking is more powerful than you might imagine. Example 6-8 offers another take on the prime factorization problem from Chapter 1.

Example 6-8. prime-pattern

  #!/usr/bin/perl
  # prime_pattern -- find prime factors of argument using pattern matching
  for ($N = ('o' x shift); $N =~ /^(oo+?)\1+$/; $N =~ s/$1/o/g) {
      print length($1), " ";
  }
  print length ($N), "\n";

Although not practical, this approach marvelously demonstrates the power of backtracking.

Here's another example. Using a brilliant insight first illustrated by Doug McIlroy (or so says Andrew Hume), you can find solutions to Diophantine equations of order one with regular expressions. Consider the equation 12x + 15y + 16z = 281. Can you think of possible values for x, y, and z? Perl can!

# solve for 12x + 15y + 16z = 281, maximizing x
if (($X, $Y, $Z)  =
   (('o' x 281)  =~ /^(o*)\1{11}(o*)\2{14}(o*)\3{15}$/))
{
    ($x, $y, $z) = (length($X), length($Y), length($Z));
    print "One solution is: x=$x; y=$y; z=$z.\n";
} else {
    print "No solution.\n";
}
One solution is: x=17; y=3; z=2.

Because the first o* was greedy, x was allowed to grow as large as it could. Changing one or more * quantifiers to *?, +, or +? can produce different solutions.

('o' x 281)  =~ /^(o+)\1{11}(o+)\2{14}(o+)\3{15}$/
One solution is: x=17; y=3; z=2
('o' x 281)  =~ /^(o*?)\1{11}(o*)\2{14}(o*)\3{15}$/
One solution is: x=0; y=7; z=11.
('o' x 281)  =~ /^(o+?)\1{11}(o*)\2{14}(o*)\3{15}$/
One solution is: x=1; y=3; z=14.

An important lesson to be learned from these amazing feats of mathematical prowess by a lowly pattern matcher is that a pattern-matching engine, particularly a backtracking one, very much wants to give you an answer, and it will work phenomenally hard to do so. But solving a regular expression with backreferences can take time exponentially proportional to the length of the input to complete. For all but trivial inputs, such algorithms make continental drift seem brisk.

6.16.4. See Also

The explanation of backreferences in the "Regular Expressions" section of perlre(1), and in "The Little Engine That /Could(n't)?/" section of Chapter 5 of Programming Perl; the "The Doubled-Word Thing" section in Chapter 2 of Mastering Regular Expressions

Previous | Home | Next
6.15. Greedy and Non-Greedy Matches | Book Index | 6.17. Matching Nested Patterns
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.17. Matching Nested Patterns

6.17.1. Problem

You want to match a nested set of enclosing delimiters, such as the arguments to a function call.

6.17.2. Solution

Use match-time pattern interpolation, recursively:

my $np;
$np = qr{
           \(
           (?:
              (?> [^( )]+ )    # Non-capture group w/o backtracking
            |
              (??{ $np })     # Group with matching parens
           )*
           \)
        }x;

Or use the Text::Balanced module's extract_bracketed function.

6.17.3. Discussion

The $(??{ CODE }) construct runs the code and interpolates the string that the code returns right back into the pattern. A simple, non-recursive example that matches palindromes demonstrates this:

if ($word =~ /^(\w+)\w?(??{reverse $1})$/ ) {
    print "$word is a palindrome.\n";
}

Consider a word like "reviver", which this pattern correctly reports as a palindrome. The $1 variable contains "rev" partway through the match. The optional word character following catches the "i". Then the code reverse $1 runs and produces "ver", and that result is interpolated into the pattern.

For matching something balanced, you need to recurse, which is a bit tricker. A compiled pattern that uses (??{ CODE }) can refer to itself. The pattern given in the Solution matches a set of nested parentheses, however deep they may go. Given the value of $np in that pattern, you could use it like this to match a function call:

$text = "myfunfun(1,(2*(3+4)),5)";
$funpat = qr/\w+$np/;   # $np as above
$text =~ /^$funpat$/;   # Matches!

You'll find many CPAN modules that help with matching (parsing) nested strings. The Regexp::Common module supplies canned patterns that match many of the tricker strings. For example:

use Regexp::Common;
$text = "myfunfun(1,(2*(3+4)),5)";
if ($text =~ /(\w+\s*$RE{balanced}{-parens=>'( )'})/o) {
  print "Got function call: $1\n";
}

Other patterns provided by that module match numbers in various notations and quote-delimited strings:

$RE{num}{int}
$RE{num}{real}
$RE{num}{real}{'-base=2'}{'-sep=,'}{'-group=3'}
$RE{quoted}
$RE{delimited}{-delim=>'/'}

The standard (as of v5.8) Text::Balanced module provides a general solution to this problem.

use Text::Balanced qw/extract_bracketed/;
$text = "myfunfun(1,(2*(3+4)),5)";
if (($before, $found, $after)  = extract_bracketed($text, "(")) {
    print "answer is $found\n";
} else {
    print "FAILED\n";
}

6.17.4. See Also

The section on "Match-time pattern interpolation" in Chapter 5 of Programming Perl; the documentation for the Regexp::Common CPAN module and the standard Text::Balanced module

Previous | Home | Next
6.16. Detecting Doubled Words | Book Index | 6.18. Expressing AND, OR, and NOT in a Single Pattern
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.18. Expressing AND, OR, and NOT in a Single Pattern

6.18.1. Problem

You have an existing program that accepts a pattern as an argument or as input. It doesn't allow you to add extra logic, like case-insensitive options, ANDs, or NOTs. So you need to write a single pattern that matches either of two different patterns (the "or" case) or both of two patterns (the "and" case), or that reverses the sense of the match ("not").

This situation arises often in configuration files, web forms, or command-line arguments. Imagine there's a program that does this:

chomp($pattern = <CONFIG_FH>);
if ( $data =~ /$pattern/ ) { ..... }

As the maintainer of CONFIG_FH, you need to convey Booleans through to the program using one configuration parameter.

6.18.2. Solution

True if either /ALPHA/ or /BETA/ matches, like /ALPHA/ || /BETA/:

/ALPHA|BETA/
/(?:ALPHA)|(?:BETA)/  # works no matter what in both

True if both /ALPHA/ and /BETA/ match, but may overlap, meaning "BETALPHA" should be okay, like /ALPHA/ && /BETA/:

/^(?=.*ALPHA)BETA/s

True if both /ALPHA/ and /BETA/ match, but may not overlap, meaning that "BETALPHA" should fail:

/ALPHA.*BETA|BETA.*ALPHA/s

True if pattern /PAT/ does not match, like $var !~ /PAT/:

/^(?:(?!PAT).)*$/s

True if pattern BAD does not match, but pattern GOOD does:

/(?=^(?:(?!BAD).)*$)GOOD/s

(You can't actually count on being able to place the /s modifier there after the trailing slash, but we'll show how to include it in the pattern itself at the end of the Discussion.)

6.18.3. Discussion

When in a normal program you want to know whether something doesn't match, use one of:

    if (!($string =~ /pattern/)) { something( ) }   # ugly
    if (  $string !~ /pattern/)  { something( ) }   # preferred
unless (  $string =~ /pattern/)  { something( ) }   # sometimes clearer

To see whether both patterns match, use:

if ($string =~ /pat1/ && $string =~ /pat2/ ) { something( ) }

To see whether either of two patterns matches:

if ($string =~ /pat1/ || $string =~ /pat2/ ) { something( ) }

Instead of trying to do it all within a single pattern, it's often more efficient and clearer to use Perl's normal Boolean connectives to combine regular expressions. However, imagine a trivially short minigrep program that reads its single pattern as an argument, as shown in Example 6-9.

Example 6-9. minigrep

  #!/usr/bin/perl
  # minigrep - trivial grep
  $pat = shift;
  while (<>) {
      print if /$pat/o;
  }

To tell minigrep that some pattern must not match, or that it has to match both subpatterns in any order, you're at an impasse. The program isn't built to accept multiple patterns. How can you do it using one pattern? This need comes up in programs reading patterns from configuration files.

The OR case is pretty easy, since the | metacharacter provides for alternation. The AND and NOT cases, however, are more complex.

For AND, you have to distinguish between overlapping and non-overlapping needs. If, for example, you want to see whether a string matches both "bell" and "lab" and allow overlapping, the word "labelled" should be matched. But if you don't want to count overlaps, it shouldn't be matched. The overlapping case uses a lookahead assertion:

"labelled" =~ /^(?=.*bell)lab/s

Remember: in a normal program, you don't have to go through these contortions. Simply say:

$string =~ /bell/ && $string =~ /lab/

To unravel this, we'll spell it out using /x and comments. Here's the long version:

if ($murray_hill =~ m{
             ^              # start of string
            (?=             # zero-width lookahead
                .*          # any amount of intervening stuff
                bell        # the desired bell string
            )               # rewind, since we were only looking
            lab             # and the lab part
         }sx )              # /s means . can match newline
{
    print "Looks like Bell Labs might be in Murray Hill!\n";
}

We didn't use .*? to end early, because minimal matching is more expensive than maximal matching. It's more efficient to use .* over .*?, given random input where the occurrence of matches at the front or the end of the string is completely unpredictable. Of course, sometimes choosing between .* and .*? may depend on correctness rather than efficiency, but not here.

To handle the non-overlapping case, you need two parts separated by an OR. The first branch is THIS followed by THAT; the second is the other way around:

"labelled" =~ /(?:^.*bell.*lab)|(?:^.*lab.*bell)/

or in long form:

$brand = "labelled";
if ($brand =~ m{
        (?:                 # non-capturing grouper
              bell          # look for a bell
              .*?           # followed by any amount of anything
              lab           # look for a lab
          )                 # end grouper
    |                       # otherwise, try the other direction
        (?:                 # non-capturing grouper
              lab           # look for a lab
              .*?           # followed by any amount of anything
              bell          # followed by a bell
          )                 # end grouper
    }sx )                   # /s means . can match newline
{
    print "Our brand has bell and lab separate.\n";
}

Neither of those patterns matches the test data of "labelled", since there "bell" and "lab" do overlap.

These patterns aren't necessarily efficient. $murray_hill =~ /bell/ && $murray_hill =~ /lab/ scans the string at most twice, but the pattern-matching engine's only option is to try to find a "lab" for each occurrence of "bell" with (?=^.*?bell)(?=^.*?lab), leading to quadratic worst-case running times.

If you followed those examples, the NOT case should be a breeze. The general form looks like this:

$map =~ /^(?:(?!waldo).)*$/s

Spelled out in long form, this yields:

if ($map =~ m{
        ^                   # start of string
        (?:                 # clustering grouper
            (?!             # look ahead negation
                waldo       # is he ahead of us now?
            )               # is so, the negation failed
            .               # any character (cuzza /s)
        ) *                 # repeat that grouping 0 or more
        $                   # through the end of the string
    }sx )                   # /s means . can match newline
{
    print "There's no waldo here!\n";
}

How would you combine AND, OR, and NOT? It's not a pretty picture, and in a regular program, you'd almost never do this. But you have little choice when you're reading from a config file or pulling in arguments from the command line, because you specify only one pattern. You just have to combine what we've learned so far. Carefully.

Let's say you wanted to run the Unix w program and find out whether user tchrist were logged on anywhere but a terminal whose name began with ttyp; that is, tchrist must match, but ttyp must not.

Here's sample input from w:

 7:15am  up 206 days, 13:30,  4 users,  load average: 1.04, 1.07, 1.04
USER     TTY      FROM              LOGIN@  IDLE   JCPU   PCPU  WHAT
tchrist  tty1                       5:16pm 36days 24:43   0.03s  xinit
tchrist  tty2                       5:19pm  6days  0.43s  0.43s  -tcsh
tchrist  ttyp0    chthon            7:58am  3days 23.44s  0.44s  -tcsh
gnat     ttyS4    coprolith         2:01pm 13:36m  0.30s  0.30s  -tcsh

Here's how to do that using the minigrep program previously outlined or with the tcgrep program from the end of this chapter:

% w | minigrep '(?!.*ttyp)tchrist'

Decoding that pattern:

m{
    (?!                     # zero-width look-ahead assertion
        .*                  # any amount of anything (faster than .*?)
        ttyp                # the string you don't want to find
    )                       # end look-ahead negation; rewind to start
    tchrist                 # now try to find Tom
}x

Of course, this example is contrived: any sane person would call the standard grep program twice, once with a -v option to select only non-matches.

% w | grep tchrist | grep -v ttyp

The point is that Boolean conjunctions and negations can be coded up in one single pattern. You should comment this kind of thing, though, having pity on those who come after you—before they do.

One last thing: how would you embed that /s in a pattern passed to a program from the command line? The same way as you would a /i modifier: by using (?i) in the pattern. The /s and /m modifiers can be painlessly included in a pattern as well, using (?s) or (?m). These can even cluster, as in (?smi). That would make these two reasonably interchangeable:

% grep -i 'pattern' files
% minigrep '(?i)pattern' files

When you turn on a modifier that way, it remains on for the entire pattern. An alternative notation restricts the scope of the modifier. Use a clustering parenthesis set, (?:...), and place the modifiers between the question mark and the colon. Printing out a qr// quoted regex demonstrates how to do this:

% perl -le 'print qr/pattern/i'
(?i-xsm:pattern)

Modifiers placed before a minus are enabled for just that pattern; those placed after the minus are disabled for that pattern.

6.18.4. See Also

Lookahead assertions are shown in the "Regular Expressions" section of perlre (1), and in the "Lookaround Assertions" section of Chapter 5 of Programming Perl; your system's grep(1) and w(1) manpages; we talk about configuration files in Recipe 8.16

Previous | Home | Next
6.17. Matching Nested Patterns | Book Index | 6.19. Matching a Valid Mail Address
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.19. Matching a Valid Mail Address

6.19.1. Problem

You want to find a pattern to verify the validity of a supplied mail address.

6.19.2. Solution

Because you cannot do real-time validation of deliverable mail addresses, no single, succinct pattern will solve this problem. You must pick from several available compromise approaches.

6.19.3. Discussion

Our best advice for verifying a person's mail address is to have them enter their address twice, just as you would when changing a password. This usually weeds out typos. If both entries match, send mail to that address with a personal message such as:

Dear someuser@host.com,

Please confirm the mail address you gave us on Sun Jun 29
10:29:01 MDT 2003 by replying to this message.  Include the
string "Rumpelstiltskin" in that reply, but spelled in reverse;
that is, start with "Nik...".  Once this is done, your confirmed
address will be entered into our records.

If you get back a message where they've followed your directions, you can be reasonably assured that it's real.

A related strategy that's less open to forgery is to give them a personal identification number (PIN). Record the address and PIN (preferably a random one) for later processing. In the mail you send, ask them to include the PIN in their reply. In case your email bounces, or the message is included via a vacation script, ask them to mail back the PIN slightly altered, such as with the characters reversed, one added or subtracted to each digit, etc.

Most common patterns used for address verification or validation fail in various and sometimes subtle ways. For example, the address this&that@somewhere.com is valid and quite possibly deliverable, but most patterns that allegedly match valid mail addresses fail to let that one pass.

1 while $addr =~ s/\([^( )]*\)//g;

You could use the 6598-byte pattern given on the last page of the first edition of Mastering Regular Expressions to test for RFC conformance, but even that monster isn't perfect, for three reasons.

First, not all RFC-valid addresses are deliverable. For example, foo@foo.foo.foo.foo is valid in form, but in practice is not deliverable. Some people try to do DNS lookups for MX records, even trying to connect to the host handling that address's mail to check if it's valid at that site. This is a poor approach because most sites can't do a direct connect to any other site, and even if they could, mail-receiving sites increasingly either ignore the SMTP VRFY command or fib about its answer.

Second, some RFC-invalid addresses, in practice, are perfectly deliverable. For example, a lone postmaster is almost certainly deliverable, but doesn't pass RFC 822 muster: it doesn't have an @ in it.

Finally and most importantly, just because the address happens to be valid and deliverable doesn't mean that it's the right one. president@whitehouse.gov, for example, is valid by the RFC and deliverable. But it's unlikely in the extreme that that would be the mail address of the person submitting information to your CGI script.

The Email::Valid CPAN module makes a valiant (albeit provably imperfect) attempt at doing this correctly. It jumps through many hoops, including the RFC 822 regular expression from Mastering Regular Expressions, DNS MX record lookup, and stop lists for naughty words and famous people. But this is still a weak approach. The approach suggested at the beginning of the Discussion is easier to implement and less prone to error.

6.19.4. See Also

The "Matching an Email Address" section of Chapter 7 of the first edition Mastering Regular Expressions; Recipe 18.16

Previous | Home | Next
6.18. Expressing AND, OR, and NOT in a Single Pattern | Book Index | 6.20. Matching Abbreviations
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.20. Matching Abbreviations

6.20.1. Problem

Suppose you had a list of commands, such as "send", "abort", "list", and "edit". The user types one in, but you don't want to make them type out the whole thing.

6.20.2. Solution

Use the following technique if all strings start with different characters, or to arrange matches so one takes precedence over another, as "SEND" has precedence over "STOP" here:

chomp($answer = <>);
if    ("SEND"  =~ /^\Q$answer/i) { print "Action is send\n"  }
elsif ("STOP"  =~ /^\Q$answer/i) { print "Action is stop\n"  }
elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" }
elsif ("LIST"  =~ /^\Q$answer/i) { print "Action is list\n"  }
elsif ("EDIT"  =~ /^\Q$answer/i) { print "Action is edit\n"  }

Or use the Text::Abbrev module:

use Text::Abbrev;
$href = abbrev qw(send abort list edit);
for (print "Action: "; <>; print "Action: ") {
    chomp;
    my $action = $href->{ lc($_) };
    print "Action is $action\n";
}

6.20.3. Discussion

The first technique exchanges the typical operand order of a match. Normally you have a variable on the left side of the match and a known pattern on the right side. We might try to decide which action the user wanted us to take by saying $answer =~ /^ABORT/i, which is true if $answer begins with the string "ABORT". It matches regardless of whether $answer has anything after "ABORT", so "ABORT LATER" would still match. Handling abbreviations generally requires quite a bit of ugliness: $answer =~ /^A(B(O(R(T)?)?)?)?$/i.

Compare the classic variable =~ /pattern/ with "ABORT" =~ /^\Q$answer/i. The \Q escapes characters that would otherwise be treated specially: that way your program won't blow up if the user enters an invalid pattern. When the user enters something like "ab", the expanded match becomes "ABORT" =~ /^ab/i after variable substitution and metaquoting. This matches.

The standard Text::Abbrev module takes a different approach. You supply a list of words, and the abbrev( ) function returns a reference to a hash whose keys are all unambiguous abbreviations and whose values are the fully expanded strings. So if $href were created as in the Solution example, $href->{"a"} would return the string "abort".

This technique is commonly used to call a function based on the name of the string the user types in. Although it's possible to implement this using symbolic references, as in:

$name = 'send';
&$name($message);
$name->($message);    # alternate, simpler syntax

that's scary because it lets the user run any function whose name they know (or can guess), not just those we want to make available to them. It also runs afoul of that pesky use strict 'refs' pragma.

Here's a partial program that creates a hash in which the key is the command name and the value is a reference to the function to call for that command:

# assumes that &invoke_editor, &deliver_message,
# $file and $PAGER are defined somewhere else.
use Text::Abbrev;
my($href, %actions, $errors);
%actions = (
    "edit"  => \&invoke_editor,
    "send"  => \&deliver_message,
    "list"  => sub { system($PAGER, $file) },
    "abort" => sub {
                    print "See ya!\n";
                    exit;
               },
    ""      => sub {
                    print "Unknown command: $cmd\n";
                    $errors++;
               },
);

$href = abbrev(keys %actions);
for (print "Action: "; my $choice = <>; print "Action: ") {
    $choice =~ s/^\s+//;       # trim leading  white space
    $choice =~ s/\s+$//;       # trim trailing white space
    next unless $choice;
    $actions->{ $href->{ lc($choice) } }->( );
}

If you're not into long expressions or need practice typing, that last statement could have been written:

$abbreviation = lc($_);
$expansion    = $href->{$abbreviation};
$coderef      = $actions->{$expansion};
$coderef->( );

6.20.4. See Also

The documentation for the standard Text::Abbrev module; interpolation is explained in the "Scalar Value Constructors" section of perldata(1), and in the "String Literals" section of Chapter 2 of Programming Perl

Previous | Home | Next
6.19. Matching a Valid Mail Address | Book Index | 6.21. Program: urlify
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.21. Program: urlify

This program puts HTML links around URLs in files. It doesn't work on all possible URLs, but does hit the most common ones. It tries to avoid including end-of-sentence punctuation in the marked-up URL.

It is a typical Perl filter, so it can be fed input from a pipe:

% gunzip -c ~/mail/archive.gz | urlify > archive.urlified

or by supplying files on the command line:

% urlify ~/mail/*.inbox > ~/allmail.urlified

The program is shown in Example 6-10.

Example 6-10. urlify

  #!/usr/bin/perl
  # urlify - wrap HTML links around URL-like constructs
  $protos = '(http|telnet|gopher|file|wais|ftp)';
  $ltrs   = '\w';
  $gunk   = ';/#~:.?+=&%@!\-';
  $punc   = '.:?\-';
  $any    = "${ltrs}${gunk}${punc}";
  while (<>) {
      s{
        \b                    # start at word boundary
        (                     # begin $1  {
         $protos   :          # need resource and a colon
         [$any] +?            # followed by on or more
                              #  of any valid character, but
                              #  be conservative and take only
                              #  what you need to....
        )                     # end   $1  }
        (?=                   # look-ahead non-consumptive assertion
         [$punc]*             # either 0 or more punctuation
         [^$any]              #   followed by a non-url char
         |                    # or else
         $                    #   then end of the string
      )
     }{<A HREF="$1">$1</A>}igox;
    print;
  }
Previous | Home | Next
6.20. Matching Abbreviations | Book Index | 6.22. Program: tcgrep
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.22. Program: tcgrep

This program is a Perl rewrite of the Unix grep program. Although it runs slower than C versions (especially the GNU greps), it offers many more features.

The first and perhaps most important feature is that it runs anywhere Perl does. Other enhancements are that it can ignore anything that's not a plain text file, automatically expand compressed or gzipped files, recurse down directories, search complete paragraphs or user-defined records, look in younger files before older ones, and add underlining or highlighting of matches. It also supports the -c option to indicate a count of matching records, as well as -C for a count of matching patterns when there could be more than one per record.

This program uses gzcat or zcat to decompress compressed files, so this feature is unavailable on systems without these programs and systems that can't run external programs (such as old Macs).

Run the program with no arguments for a usage message (see the usage subroutine in the following code). The following example recursively and case-insensitively greps every file in ~/mail for mail messages from someone called "kate", reporting filenames that contained matches:

% tcgrep -ril '^From: .*kate' ~/mail

The program is shown in Example 6-11.

Example 6-11. tcgrep

  #!/usr/bin/perl -w
  # tcgrep: tom christiansen's rewrite of grep
  # v1.0: Thu Sep 30 16:24:43 MDT 1993
  # v1.1: Fri Oct  1 08:33:43 MDT 1993
  # v1.2: Fri Jul 26 13:37:02 CDT 1996
  # v1.3: Sat Aug 30 14:21:47 CDT 1997
  # v1.4: Mon May 18 16:17:48 EDT 1998
  use strict;
                                    # globals
  our ($Me, $Errors, $Grand_Total, $Mult, %Compress, $Matches);
  my ($matcher, $opt);              # matcher - anon. sub to check for matches
                                    # opt - ref to hash w/ command-line options
  init( );                           # initialize globals
  ($opt, $matcher) = parse_args( );  # get command line options and patterns
  matchfile($opt, $matcher, @ARGV); # process files
  exit(2) if $Errors;
  exit(0) if $Grand_Total;
  exit(1);
  ###################################
  sub init {
      ($Me = $0) =~ s!.*/!!;        # get basename of program, "tcgrep"
      $Errors = $Grand_Total = 0;   # initialize global counters
      $Mult = "";                   # flag for multiple files in @ARGV
      $| = 1;                       # autoflush output
      %Compress = (                 # file extensions and program names
          z  => 'gzcat',            # for uncompressing
          gz => 'gzcat',
          Z  => 'zcat',
      );
  }
  ###################################
  sub usage {
          die << EOF
  usage: $Me [flags] [files]
  Standard grep options:
          i   case insensitive
          n   number lines
          c   give count of lines matching
          C   ditto, but >1 match per line possible
          w   word boundaries only
          s   silent mode
          x   exact matches only
          v   invert search sense (lines that DON'T match)
          h   hide filenames
          e   expression (for exprs beginning with -)
          f   file with expressions
          l   list filenames matching
  Specials:
          1   1 match per file
          H   highlight matches
          u   underline matches
          r   recursive on directories or dot if none
          t   process directories in 'ls -t' order
          p   paragraph mode (default: line mode)
          P   ditto, but specify separator, e.g. -P '%%\\n'
          a   all files, not just plain text files
          q   quiet about failed file and dir opens
          T   trace files as opened
  May use a TCGREP environment variable to set default options.
  EOF
  }
  ###################################
  sub parse_args {
      use Getopt::Std;
      my ($optstring, $zeros, $nulls, %opt, $pattern, @patterns, $match_code);
      my ($SO, $SE);
      if (my $opts = $ENV{TCGREP}) {   # get envariable TCGREP
          $opts =~ s/^([^\-])/-$1/;    # add leading - if missing
          unshift(@ARGV, $opts);       # add TCGREP opt string to @ARGV
      }
      $optstring = "incCwsxvhe:f:l1HurtpP:aqT";
      $zeros = 'inCwxvhelut';       # options to init to 0
      $nulls = 'pP';                # options to init to ""
      @opt{ split //, $zeros } = ( 0 )  x length($zeros);
      @opt{ split //, $nulls } = ( '' ) x length($nulls);
      getopts($optstring, \%opt)              or usage( );
      # handle option "-f patfile", for list of patterns
      if ($opt{f}) {
          open(PATFILE, $opt{f})          or die "$Me: Can't open '$opt{f}': $!";
          # make sure each pattern in file is valid
          while ($pattern = <PATFILE>) {
              chomp $pattern;
              eval { 'foo' =~ /$pattern/, 1 } or
                  die "$Me: $opt{f}:$.: bad pattern: $@";
              push @patterns, $pattern;
          }
          close PATFILE;
      }
      else {                        # make sure pattern is valid
          $pattern = $opt{e} || shift(@ARGV) || usage( );
          eval { 'foo' =~ /$pattern/; 1 } or
              die "$Me: bad pattern: $@";
          @patterns = ($pattern);
      }
      # option -H is for highlight, option -u is for underline
      if ($opt{H} || $opt{u}) {
          my $term = $ENV{TERM} || 'vt100';
          my $terminal;
          # eval{  } only to trap potential exceptions in function calls
          eval {                    # try to look up escapes for stand-out
              require POSIX;        # or underline via Term::Cap
              use Term::Cap;
              my $termios = POSIX::Termios->new( );
              $termios->getattr;
              my $ospeed = $termios->getospeed;
              $terminal = Tgetent Term::Cap { TERM=>undef, OSPEED=>$ospeed }
          };
          unless ($@) {             # if successful, get escapes for either
              local $^W = 0;        # stand-out (-H) or underlined (-u)
              ($SO, $SE) = $opt{H}
                  ? ($terminal->Tputs('so'), $terminal->Tputs('se'))
                  : ($terminal->Tputs('us'), $terminal->Tputs('ue'));
          }
          else {                    # if use of Term::Cap fails,
              ($SO, $SE) = $opt{H}  # use tput command to get escapes
                  ? (`tput -T $term smso`, `tput -T $term rmso`)
                  : (`tput -T $term smul`, `tput -T $term rmul`)
          }
      }
      # option -i makes all pattern case insensitive
      if ($opt{i}) {
          @patterns = map {"(?i)$_"} @patterns;
      }
      # option -p or -P is paragraph mode, so add /m
      if ($opt{p} || $opt{P}) {
          @patterns = map {"(?m)$_"} @patterns;
      }
      # option -p is standard paragraph mode
      $opt{p}   && ($/ = '');
      # option -p is user-defined paragraph mode
      $opt{P}   && ($/ = eval(qq("$opt{P}")));     # for -P '%%\n'
      # option -w is at word boundary only (XXX: is this always optimal?)
      $opt{w}   && (@patterns = map {'\b' . $_ . '\b'} @patterns);
      # option -x is for whole lines only
      $opt{'x'} && (@patterns = map {"^$_\$"} @patterns);
      # determine whether to emit file name in front of each match
      if (@ARGV) {
          $Mult = 1 if ($opt{r} || (@ARGV > 1) || -d $ARGV[0]) && !$opt{h};
      }
      # if just listing filenames, stop after first match
      $opt{1}   += $opt{l};                   # that's a one and an ell
      # this way only need look for -H
      $opt{H}   += $opt{u};
      # if we're doing a complete count, where doing some counting
      $opt{c}   += $opt{C};
      # if we're counting, keep track of status
      $opt{'s'} += $opt{c};
      # stop at first match if checking status but not counting
      $opt{1}   += $opt{'s'} && !$opt{c};     # that's a one
      # default args are cwd if recursive, stdin otherwise
      @ARGV = ($opt{r} ? '.' : '-') unless @ARGV;
      # we're recursive even w/o -r if all args are directories
      $opt{r} = 1 if !$opt{r} && grep(-d, @ARGV) =  = @ARGV;
      ######
      # now the hard part: build of the matching function as text to eval
      #
      $match_code  = '';
      $match_code .= 'study;' if @patterns > 5; # might speed things up a bit
      foreach (@patterns) { s(/)(\\/)g }
      # add the stand-out and end-stand-out sequences for highlight mode
      if ($opt{H}) {
          foreach $pattern (@patterns) {
              $match_code .= "\$Matches += s/($pattern)/${SO}\$1${SE}/g;";
          }
      }
      # option -v means to count a line if it *doesn't* match
      elsif ($opt{v}) {
          foreach $pattern (@patterns) {
              $match_code .= "\$Matches += !/$pattern/;";
          }
      }
      # do full count, multiple hits per line
      elsif ($opt{C}) {
          foreach $pattern (@patterns) {
              $match_code .= "\$Matches++ while /$pattern/g;";
          }
      }
      else {
          foreach $pattern (@patterns) {
              $match_code .= "\$Matches++ if /$pattern/;";
          }
      }
      # now compile as a closure, and grab function pointer
      $matcher = eval "sub { $match_code }";
      die if $@;
      return (\%opt, $matcher);
  }
  ###################################
  sub matchfile {
      $opt = shift;                 # reference to option hash
      $matcher = shift;             # reference to matching sub
      my ($file, @list, $total, $name);
      local($_);
      $total = 0;
  FILE: while (defined ($file = shift(@_))) {
          if (-d $file) {
              if (-l $file && @ARGV != 1) {
                  warn "$Me: \"$file\" is a symlink to a directory\n"
                      if $opt->{T};
                  next FILE;
              }
              if (!$opt->{r}) {
                  warn "$Me: \"$file\" is a directory, but no -r given\n"
                      if $opt->{T};
                  next FILE;
              }
              unless (opendir(DIR, $file)) {
                  unless ($opt->{'q'}) {
                      warn "$Me: can't opendir $file: $!\n";
                      $Errors++;
                  }
                  next FILE;
              }
              @list = ( );
              for (readdir(DIR)) {                # skip cwd and parent dir
                  push(@list, "$file/$_") unless /^\.{1,2}$/;
              }
              closedir(DIR);
              # option -t is sort by age, youngest first
              # use algorithm from Recipe 4.XXX, Sorting a List by Computable Field
              if ($opt->{t}) {
                  @list = map  { $_->[0] }
                          sort { $a->[1] <=> $b->[1] }
                          map  { [ $_, -M $_ ] } @list;
              }
              else {
                  @list = sort @list;
              }
              matchfile($opt, $matcher, @list);    # process files
              next FILE;
          }
          # avoid annoying situation of grep wanting to read from keyboard
          # but user not realizing this
          if ($file eq '-') {
              warn "$Me: reading from stdin\n" if -t STDIN && !$opt->{'q'};
              $name = '<STDIN>';
          }
          else {
              $name = $file;
              unless (-e $file) {
                  warn qq($Me: file "$file" does not exist\n) unless $opt->{'q'};
                  $Errors++;
                  next FILE;
              }
              unless (-f $file || $opt->{a}) {
                  warn qq($Me: skipping non-plain file "$file"\n) if $opt->{T};
                  next FILE;
              }
              # could use File::Spec instead
              my ($ext) = $file =~ /\.([^.]+)$/;
              # check whether it's an extension whose contents we know
              # how to convert to plain text via a filter program
              if (defined($ext) && exists($Compress{$ext})) {
                  $file = "$Compress{$ext} < $file |";
              }
              elsif (! (-T $file  || $opt->{a})) {
                  warn qq($Me: skipping binary file "$file"\n) if $opt->{T};
                  next FILE;
              }
          }
          warn "$Me: checking $file\n" if $opt->{T};
          unless (open(FILE, $file)) {
              unless ($opt->{'q'}) {
                  warn "$Me: $file: $!\n";
                  $Errors++;
              }
              next FILE;
          }
          $total = 0;
          $Matches = 0;
  LINE:  while (<FILE>) {
              $Matches = 0;
              ##############
              &{$matcher}( );        # do it! (check for matches)
              ##############
              next LINE unless $Matches;
              $total += $Matches;
              if ($opt->{p} || $opt->{P}) {
                s/\n{2,}$/\n/ if $opt->{p};
                chomp         if $opt->{P};
              }
              print("$name\n"), next FILE if $opt->{l};
              # The following commented out block is the
              # expanded/legible version of the statement
              # that immediately follows it.  This is one
              # of the few times we sacrifice readability
              # for execution speed: we carefully arrange
              # that print( ) be called just once, not four times,
              # and we don't resort to a braced block either.
              # (note that $Mult must be "" not 0 for this to work)
              ########
              ## unless ($opt->{'s'}) {
              ##    print "$name:"                 if $Mult;
              ##    print "$.:"                    if $opt{n};
              ##    print;
              ##    print (('-' x 20) . "\n")         if $opt->{p} || $opt->{P};
              ## }
              ########
              $opt->{'s'} || print $Mult && "$name:",
                  $opt->{n} ? "$.:" : "",
                  $_,
                  ($opt->{p} || $opt->{P}) && ('-' x 20) . "\n";
              next FILE if $opt->{1};                 # that's a one
          }
      }
      continue {
          # again, next block equivalent to line following
          #######
          ## if ($opt->{c}) {
          ##         print $name if $Mult;
          ##         print "$total\n";
          ## }
          #######
          print $Mult && "$name:", "$total\n" if $opt->{c};
      }
      $Grand_Total += $total;
  }
Previous | Home | Next
6.21. Program: urlify | Book Index | 6.23. Regular Expression Grab Bag
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.23. Regular Expression Grab Bag

We have found these regular expressions useful or interesting:

Swap first two words
s/(\S+)(\s+)(\S+)/$3$2$1/
Keyword = Value
m/^(\w+)\s*=\s*(.*?)\s*$/             # keyword is $1, value is $2
Line of at least 80 characters
m/.{80,}/
length( ) >= 80        # ok, not a regex
MM/DD/YY HH:MM:SS
m|(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)|
Changing directories
s(/usr/bin)(/usr/local/bin)g
Expanding %7E (hex) escapes
s/%([0-9A-Fa-f][0-9A-Fa-f])/chr(hex($1))/ge
Deleting C comments (imperfectly)
s{
    /*                    # Match the opening delimiter
    .*?                   # Match a minimal number of characters
    */                    # Match the closing delimiter
}{  }gsx;
Removing leading and trailing whitespace
s/^\s+//;
s/\s+$//;
Turning \ followed by n into a real newline
s/\\n/\n/g;
Removing package portion of fully qualified symbols
s/^.*:://
Dotted quads (most IP addresses)
# XXX: fails on legal IPs 127.1 and 2130706433.
m{
        ^  ( \d | [01]?\d\d | 2[0-4]\d | 25[0-5] )
       \.  ( \d | [01]?\d\d | 2[0-4]\d | 25[0-5] )
       \.  ( \d | [01]?\d\d | 2[0-4]\d | 25[0-5] )
       \.  ( \d | [01]?\d\d | 2[0-4]\d | 25[0-5] )
        $
    }x
Removing leading path from filename
s{^.*/}{  }
Extracting columns setting from TERMCAP
$cols = ( ($ENV{TERMCAP} || " ") =~ m/:co#(\d+):/ ) ? $1 : 80;
Removing directory components from program name and arguments
($name = " $0 @ARGV") =~ s{ /\S+/}{ }g;
Checking your operating system
die "This isn't Linux" unless $^O =~ m/linux/i;
Joining continuation lines in multiline string
s/\n\s+/ /g
Extracting all numbers from a string
@nums = m/(\d+\.?\d*|\.\d+)/g;
Finding all-caps words
@capwords = m/(\b\p{ Upper-case Letter }+\b)/g;
Finding all-lowercase words
@lowords = m/(\b\p{ Lower-case Letter }+\b)/g;
Finding initial-caps word
@icwords = m{
    ( \b
        [\p{ Upper-case Letter }\p{ Title-case Letter }]
        \p{  Lower-case Letter } *
    \b )
}gx;
Finding links in simple HTML
@links = m/<A[^>]+?HREF\s*=\s*["']?([^'" >]+?)['"]?\s*>/ig;
Finding middle initial in $_
$initial = /^\S+\s+(\S)\S*\s+\S/ ? $1 : "";
Changing double verticle prime pairs to curly quotes
s/"([^"]*)"/``$1''/g                        # old way

# next is unicode only
s/"([^"]*)"/\x{201C}\x{201C}$1\x{201D}\x{201D}/g
Extracting sentences (double spaces required between each)
{ local $/ = "";
    while (<>) {
        s/\n/ /g;
        s/ {3,}/  /g;
        push @sentences, m/(\S.*?[!?.])(?= {2}|\Z)/g;
    }
}
YYYY-MM-DD
m/\b(\d{4})-(\d\d)-(\d\d)\b/           # YYYY in $1, MM in $2, DD in $3
North American telephone numbers
m/ ^
      (?:
       1 \s (?: \d\d\d \s)?            # 1, or 1 and area code
       |                               # ... or ...
       \(\d\d\d\) \s                   # area code with parens
       |                               # ... or ...
       (?: \+\d\d?\d? \s)?             # optional +country code
       \d\d\d ([\s\-])                 # and area code
      )
      \d\d\d (\s|\1)                   # prefix (and area code separator)
      \d\d\d\d                         # exchange
      $
 /x
Exclamations
m/\boh\s+my\s+gh?o(d(dess(es)?|s?)|odness|sh)\b/i
Extracting lines regardless of line terminator
push(@lines, $1) while $input =~ s{
    ^                                # gobble from front

    (
          .                         # begin $1: any single char (/s)
          ?*                         # but minimally matching even none
    )

    (?:                           # make capturing if saving terminators
          \x0D \x0A                # CRLF
      |   \x0A                 # LF
      |   \x0D                # CR
      |   \x0C                # FF
# (see http://www.unicode.org/reports/tr13/tr13-9.html)
      |   \x{2028}                # Unicode LS
      |   \x{2029}                # Unicode PS
    )
}{  }sx;                        # consumes $input

Or use split:

@lines = split m{
  (?:                           # make capturing if saving terminators
        \x0D \x0A                # CRLF
    |   \x0A                 # LF
    |   \x0D                # CR
    |   \x0C                # FF
  # (see http://www.unicode.org/reports/tr13/tr13-9.html)
    |   \x{2028}                # Unicode LS
    |   \x{2029}                # Unicode PS
  )
}x, $input;
Previous | Home | Next
6.22. Program: tcgrep | Book Index | 7. File Access
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 7. File Access

Contents:

Introduction
Opening a File
Opening Files with Unusual Filenames
Expanding Tildes in Filenames
Making Perl Report Filenames in Error Messages
Storing Filehandles into Variables
Writing a Subroutine That Takes Filehandles as Built-ins Do
Caching Open Output Filehandles
Printing to Many Filehandles Simultaneously
Opening and Closing File Descriptors by Number
Copying Filehandles
Creating Temporary Files
Storing a File Inside Your Program Text
Storing Multiple Files in the DATA Area
Writing a Unix-Style Filter Program
Modifying a File in Place with a Temporary File
Modifying a File in Place with the -i Switch
Modifying a File in Place Without a Temporary File
Locking a File
Flushing Output
Doing Non-Blocking I/O
Determining the Number of Unread Bytes
Reading from Many Filehandles Without Blocking
Reading an Entire Line Without Blocking
Program: netlock
Program: lockarea

Alfred, Lord Tennyson, Locksley Hall

I the heir of all ages, in the foremost files of time.

7.0. Introduction

Nothing is more central to data processing than the file. As with everything else in Perl, easy things are easy and hard things are possible. Common tasks (opening files, reading data, writing data) use simple I/O functions and operators, whereas fancier functions do hard things like non-blocking I/O and file locking.

This chapter deals with the mechanics of file access: opening a file, telling subroutines which files to work with, locking files, and so on. Chapter 8 deals with techniques for working with the contents of a file: reading, writing, shuffling lines, and other operations you can do once you have access to the file.

Here's Perl code for printing all lines from the file /usr/local/widgets/data that contain the word "blue":

open(INPUT, "<", "/acme/widgets/data")
    or die "Couldn't open /acme/widgets/data for reading: $!\n";
while (<INPUT>) {
    print if /blue/;
}
close(INPUT);

7.0.1. Getting a Handle on the File

Central to file access in Perl is the filehandle, like INPUT in the previous code example. Filehandles are symbols inside your Perl program that you associate with an external file, usually using the open function. Whenever your program performs an input or output operation, it provides that operation with an internal filehandle, not an external filename. It's the job of open to make that association, and of close to break it. Actually, any of several functions can be used to open files, and handles can refer to entities beyond mere files on disk; see Recipe 7.1 for details.

While users think of open files in terms of those files' names, Perl programs do so using their filehandles. But as far as the operating system itself is concerned, an open file is nothing more than a file descriptor, which is a small, non-negative integer. The fileno function divulges the system file descriptor of its filehandle argument. Filehandles are enough for most file operations, but for when they aren't, Recipe 7.9 turns a system file descriptor into a filehandle you can use from Perl.

Like the names for labels, subroutines, and packages, those for filehandles are unadorned symbols like INPUT, not variables like $input. However, with a few syntactic restrictions, Perl also accepts in lieu of a named filehandle a scalar expression that evaluates to a filehandle—or to something that passes for a filehandle, such as a typeglob, a reference to a typeglob, or an IO object. Typically, this entails storing the filehandle's typeglob in a scalar variable and then using that variable as an indirect filehandle. Code written this way can be simpler than code using named filehandles, because now that you're working with regular variables instead of names, certain untidy and unobvious issues involving quoting, scoping, and packages all become clearer.

As of the v5.6 release, Perl can be coaxed into implicitly initializing variables used as indirect filehandles. If you supply a function expecting to initialize a filehandle (like open) with an undefined scalar, that function automatically allocates an anonymous typeglob and stores its reference into the previously undefined variable—a tongue-twisting description normally abbreviated to something more along the lines of, "Perl autovivifies filehandles passed to open as undefined scalars."

my $input;                            # new lexical starts out undef
open($input, "<", "/acme/widgets/data")
    or die "Couldn't open /acme/widgets/data for reading: $!\n";
while (<$input>) {
    print if /blue/;
}
close($input);                        # also occurs when $input GC'd

For more about references and their autovivification, see Chapter 11. That chapter deals more with customary data references, though, than it does with exotics like the typeglob references seen here.

Having open autovivify a filehandle is only one of several ways to get indirect filehandles. We show different ways of loading up variables with named filehandles and several esoteric equivalents for later use as indirect filehandles in Recipe 7.5.

Some recipes in this chapter use filehandles along with the standard IO::Handle module, and sometimes with the IO::File module. Object constructors from these classes return new objects for use as indirect filehandles anywhere a regular handle would go, such as with built-ins like print, readline, close, <FH>, etc. You can likewise invoke any IO::Handle method on your regular, unblessed filehandles. This includes autovivified handles and even named ones like INPUT or STDIN, although none of these has been blessed as an object.

Method invocation syntax is visually noisier than the equivalent Perl function call, and incurs some performance penalty compared with a function call (where an equivalent function exists). We generally restrict our method use to those providing functionality that would otherwise be difficult or impossible to achieve in pure Perl without resorting to modules.

For example, the blocking method sets or disables blocking on a filehandle, a pleasant alternative to the Fcntl wizardry that at least one of the authors and probably most of the readership would prefer not having to know. This forms the basis of Recipe 7.20.

Most methods are in the IO::Handle class, which IO::File inherits from, and can even be applied directly to filehandles that aren't objects. They need only be something that Perl will accept as a filehandle. For example:

STDIN->blocking(0);                  # invoke on named handle
open($fh, "<", $filename) or die;    # first autovivify handle, then...
$fh->blocking(0);                    # invoke on unblessed typeglob ref

Like most names in Perl, including those of subroutines and global variables, named filehandles reside in packages. That way, two packages can have filehandles of the same name. When unqualified by package, a named filehandle has a full name that starts with the current package. Writing INPUT is really main::INPUT in the main package, but it's SomeMod::INPUT if you're in a hypothetical SomeMod package.

The built-in filehandles STDIN, STDOUT, and STDERR are special. If they are left unqualified, the main package rather than the current one is used. This is the same exception to normal rules for finding the full name that occurs with built-in variables like @ARGV and %ENV, a topic discussed in the Introduction to Chapter 12.

Unlike named filehandles, which are global symbols within the package, autovivified filehandles implicitly allocated by Perl are anonymous (i.e., nameless) and have no package of their own. More interestingly, they are also like other references in being subject to automatic garbage collection. When a variable holding them goes out of scope and no other copies or references to that variable or its value have been saved away somewhere more lasting, the garbage collection system kicks in, and Perl implicitly closes the handle for you (if you haven't yet done so yourself). This is important in large or long-running programs, because the operating system imposes a limit on how many underlying file descriptors any process can have open—and usually also on how many descriptors can be open across the entire system.

In other words, just as real system memory is a finite resource that you can exhaust if you don't carefully clean up after yourself, the same is true of system file descriptors. If you keep opening new filehandles forever without ever closing them, you'll eventually run out, at which point your program will die if you're lucky or careful, and malfunction if you're not. The implicit close during garbage collection of autoallocated filehandles spares you the headaches that can result from less than perfect bookkeeping.

For example, these two functions both autovivify filehandles into distinct lexical variables of the same name:

sub versive {
    open(my $fh, "<", $SOURCE)
        or die "can't open $SOURCE: $!";
    return $fh;
}

sub apparent {
    open(my $fh, ">", $TARGET)
        or die "can't open $TARGET: $!";
    return $fh;
}

my($from, to) = ( versive( ), apparent( ) );

Normally, the handles in $fh would be closed implicitly when each function returns. But since both functions return those values, the handles will stay open a while longer. They remain open until explicitly closed, or until the $from and $to variables and any copies you make all go out of scope—at which point Perl dutifully tidies up by closing them if they've been left open.

For buffered handles with internal buffers containing unwritten data, a more valuable benefit shows up. Because a flush precedes a close, this guarantees that all data finally makes it to where you thought it was going in the first place.[11] For global filehandle names, this implicit flush and close takes place on final program exit, but it is not forgotten.[12]

[11]Or at least tries to; currently, no error is reported if the implicit write syscall should fail at this stage, which might occur if, for example, the filesystem the open file was on has run out of space.

[12]Unless you exit by way of an uncaught signal, either by exec ing another program or by calling POSIX::_exit( ).

7.0.2. Standard Filehandles

Every program starts with three standard filehandles already open: STDIN, STDOUT, and STDERR. STDIN, typically pronounced standard in, represents the default source for data flowing into a program. STDOUT, typically pronounced standard out, represents the default destination for data flowing out from a program. Unless otherwise redirected, standard input will be read directly from your keyboard, and standard output will be written directly to your screen.

One need not be so direct about matters, however. Here we tell the shell to redirect your program's standard input to datafile and its standard output to resultsfile, all before your program even starts:

% program < datafile > resultsfile

Suppose something goes wrong in your program that you need to report. If your standard output has been redirected, the person running your program probably wouldn't notice a message that appeared in this output. These are the precise circumstances for which STDERR, typically pronounced standard error, was devised. Like STDOUT, STDERR is initially directed to your screen, but if you redirect STDOUT to a file or pipe, STDERR's destination remains unchanged. That way you always have a standard way to get warnings or errors through to where they're likely to do some good.

Unlike STDERR for STDOUT, for STDIN there's no preopened filehandle for times when STDIN has been redirected. That's because this need arises much less frequently than does the need for a coherent and reliable diagnostic stream. Rarely, your program may need to ask something of whoever ran it and read their response, even in the face of redirection. The more(1) and less(1) programs do this, for example, because their STDIN s are often pipes from other programs whose long output you want to see a page at a time. On Unix systems, open the special file /dev/tty, which represents the controlling device for this login session. The open fails if the program has no controlling tty, which is the system's way of reporting that there's no one for your program to communicate with.

This arrangement makes it easy to plug the output from one program into the input of the next, and so on down the line.

% first | second | third

That means to apply the first program to the input of the second, and the output of the second as the input of the third. You might not realize it at first, but this is the same logic as seen when stacking functions calls like third(second(first( ))), although the shell's pipeline is a bit easier to read because the transformations proceed from left to right instead of from inside the expression to outside.

Under the uniform I/O interface of standard input and output, each program can be independently developed, tested, updated, and executed without risk of one program interfering with another, but they will still easily interoperate. They act as tools or parts used to build larger constructs, or as separate stages in a larger manufacturing process. Like having a huge stock of ready-made, interchangeable parts on hand, they can be reliably assembled into larger sequences of arbitrary length and complexity. If the larger sequences (call them scripts) are given names by being placed into executable scripts indistinguishable from the store-bought parts, they can then go on to take part in still larger sequences as though they were basic tools themselves.

An environment where every data-transformation program does one thing well and where data flows from one program to the next through redirectable standard input and output streams is one that strongly encourages a level of power, flexibility, and reliability in software design that could not be achieved otherwise. This, in a nutshell, is the so-called tool-and-filter philosophy that underlies the design of not only the Unix shell but the entire operating system. Although problem domains do exist where this model breaks down—and Perl owes its very existence to plugging one of several infelicities the model forces on you—it is a model that has nevertheless demonstrated its fundamental soundness and scalability for nearly 30 years.

7.0.3. I/O Operations

Perl's most common operations for file interaction are open, print, <FH> to read a record, and close. Perl's I/O functions are documented in Chapter 29 of Programming Perl, and in the perlfunc(1) and perlopentut(1) manpages. The next chapter details I/O operations like <FH>, print, seek, and tell. This chapter focuses on open and how you access the data, rather than what you do with the data.

Arguably the most important I/O function is open. You typically pass it two or three arguments: the filehandle, a string containing the access mode indicating how to open the file (for reading, writing, appending, etc.), and a string containing the filename. If two arguments are passed, the second contains both the access mode and the filename jammed together. We use this conflation of mode and path to good effect in Recipe 7.14.

To open /tmp/log for writing and to associate it with the filehandle LOGFILE, say:

open(LOGFILE, "> /tmp/log")     or die "Can't write /tmp/log: $!";

The three most common access modes are < for reading, > for overwriting, and >> for appending. The open function is discussed in more detail in Recipe 7.1. Access modes can also include I/O layers like :raw and :encoding(iso-8859-1). Later in this Introduction we discuss I/O layers to control buffering, deferring until Chapter 8 the use of I/O layers to convert the contents of files as they're read.

When opening a file or making virtually any other system call,[13] checking the return value is indispensable. Not every open succeeds; not every file is readable; not every piece of data you print reaches its destination. Most programmers check open, seek, tell, and close in robust programs. You might want to check other functions, too.

[13]The term system call denotes a call into your operating system kernel. It is unrelated to the C and Perl function that's actually named system. We'll therefore often call these syscalls, after the C and Perl function of that name.

If a function is documented to return an error under such and such conditions, and you don't check for these conditions, then this will certainly come back to haunt you someday. The Perl documentation lists return values from all functions and operators. Pay special attention to the glyph-like annotations in Chapter 29 of Programming Perl that are listed on the righthand side next to each function call entry—they tell you at a glance which variables are set on error and which conditions trigger exceptions.

Typically, a function that's a true system call fails by returning undef, except for wait, waitpid, and syscall, which all return -1 on failure. You can find the system error message as a string and its corresponding numeric code in the $! variable. This is often used in die or warn messages.

The most common input operation in Perl is <FH>, the line input operator. Instead of sitting in the middle of its operands the way infix operators are, the line input operator surrounds its filehandle operand, making it more of a circumfix operator, like parentheses. It's also known as the angle operator because of the left- and right-angle brackets that compose it, or as the readline function, since that's the underlying Perl core function that it calls.

A record is normally a line, but you can change the record terminator, as detailed in Chapter 8. If FH is omitted, it defaults to the special filehandle, ARGV. When you read from this handle, Perl opens and reads in succession data from those filenames listed in @ARGV, or from STDIN if @ARGV is empty. Customary and curious uses of this are described in Recipe 7.14.

At one abstraction level, files are simply streams of octets; that is, of eight-bit bytes. Of course, hardware may impose other organizations, such as blocks and sectors for files on disk or individual IP packets for a TCP connection on a network, but the operating system thankfully hides such low-level details from you.

At a higher abstraction level, files are a stream of logical characters independent of any particular underlying physical representation. Because Perl programs most often deal with text strings containing characters, this is the default set by open when accessing filehandles. See the Introduction to Chapter 8 or Recipe 8.11 for how and when to change that default.

Each filehandle has a numeric value associated with it, typically called its seek offset, representing the position at which the next I/O operation will occur. If you're thinking of files as octet streams, it's how many octets you are from the beginning of the file, with the starting offset represented by 0. This position is implicitly updated whenever you read or write non-zero-length data on a handle. It can also be updated explicitly with the seek function.

Text files are a slightly higher level of abstraction than octet streams. The number of octets need not be identical to the number of characters. Unless you take special action, Perl's filehandles are logical streams of characters, not physical streams of octets. The only time those two numbers (characters and octets) are the same in text files is when each character read or written fits comfortably in one octet (because all code points are below 256), and when no special processing for end of line (such as conversion between "\cJ\cM" and "\n") occurs. Only then do logical character position and physical byte position work out to be the same.

This is the sort of file you have with ASCII or Latin1 text files under Unix, where no fundamental distinction exists between text and binary files, which significantly simplifies programming. Unfortunately, 7-bit ASCII text is no longer prevalent, and even 8-bit encodings of ISO 8859-n are quickly giving way to multibyte-encoded Unicode text.

In other words, because encoding layers such as ":utf8" and translation layers such as ":crlf" can change the number of bytes transferred between your program and the outside world, you cannot sum up how many characters you've transferred to infer your current file position in bytes. As explained in Chapter 1, characters are not bytes—at least, not necessarily and not dependably. Instead, you must use the tell function to retrieve your current file position. For the same reason, only values returned from tell (and the number 0) are guaranteed to be suitable for passing to seek.

In Recipe 7.17, we read the entire contents of a file opened in update mode into memory, change our internal copy, and then seek back to the beginning of that file to write those modifications out again, thereby overwriting what we started with.

When you no longer have use for a filehandle, close it. The close function takes a single filehandle and returns true if the filehandle could be successfully flushed and closed, and returns false otherwise. You don't need to explicitly close every filehandle. When you open a filehandle that's already open, Perl implicitly closes it first. When your program exits, any open filehandles also get closed.

These implicit closes are for convenience, not stability, because they don't tell you whether the syscall succeeded or failed. Not all closes succeed, and even a close on a read-only file can fail. For instance, you could lose access to the device because of a network outage. It's even more important to check the close if the file was opened for writing; otherwise, you wouldn't notice if the filesystem filled up.

close(FH)           or die "FH didn't close: $!";

Closing filehandles as soon as you're done with them can also aid portability to non-Unix platforms, because some have problems in areas such as reopening a file before closing it and renaming or removing a file while it's still open. These operations pose no problem to POSIX systems, but others are less accommodating.

The paranoid programmer even checks the close on standard output stream at the program's end, lest STDOUT had been redirected from the command line and the output filesystem filled up. Admittedly, your runtime system should take care of this for you, but it doesn't.

Checking standard error, though, is more problematic. After all, if STDERR fails to close, what are you planning to do about it? Well, you could determine why the close failed to see whether there's anything you might do to correct the situation. You could even load up the Sys::Syslog module and call syslog( ), which is what system daemons do, since they don't otherwise have access to a good STDERR stream.

STDOUT is the default filehandle used by the print, printf, and write functions if no filehandle argument is passed. Change this default with select, which takes the new default output filehandle and returns the previous one. The new output filehandle must have already been opened before calling select:

$old_fh = select(LOGFILE);                  # switch to LOGFILE for output
print "Countdown initiated ...\n";
select($old_fh);                            # return to original output
print "You have 30 seconds to reach minimum safety distance.\n";

Some of Perl's special variables change the behavior of the currently selected output filehandle. Most important is $|, which controls output buffering for each filehandle. Flushing output buffers is explained in Recipe 7.19.

Perl has functions for buffered and unbuffered I/O. Although there are some exceptions (see the following table), you shouldn't mix calls to buffered and unbuffered I/O functions. That's because buffered functions may keep data in their buffers that the unbuffered functions can't know about. The following table shows the two sets of functions you should not mix. Functions on a particular row are only loosely associated; for instance, sysread doesn't have the same semantics as <FH>, but they are on the same row because they both read from a filehandle. Repositioning is addressed in Chapter 8, but we also use it in Recipe 7.17.

Action

Buffered

Unbuffered

input

<FH>,readline

sysread

output

print

syswrite

repositioning

seek, tell

sysseek

As of Perl v5.8 there is a way to mix these functions: I/O layers. You can't turn on buffering for the unbuffered functions, but you can turn off buffering for the unbuffered ones. Perl now lets you select the implementation of I/O you wish to use. One possible choice is :unix, which makes Perl use unbuffered syscalls rather than your stdio library or Perl's portable reimplementation of stdio called perlio. Enable the unbuffered I/O layer when you open the file with:

open(FH, "<:unix", $filename)  or die;

Having opened the handle with the unbuffered layer, you can now mix calls to Perl's buffered and unbuffered I/O functions with impunity because with that I/O layer, in reality there are no buffered I/O functions. When you print, Perl is then really using the equivalent of syswrite. More information can be found in Recipe 7.19.

Previous | Home | Next
6.23. Regular Expression Grab Bag | Book Index | 7.1. Opening a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.1. Opening a File

7.1.1. Problem

You want to read or write a file from Perl.

7.1.2. Solution

Use open with two arguments for convenience or with three arguments for precision. Use sysopen for access to low-level features.

The open function takes arguments specifying the internal filehandle to open, the external filename, and some indication of how to open it (the access mode). Called with only two arguments, the second comprises both path and mode:

open(SOURCE, "< $path")
    or die "Couldn't open $path for reading: $!\n";

open(SINK, "> $path")
    or die "Couldn't open $path for writing: $!\n";

When called with three (or more) arguments, the mode is split out from the path, lest there be any ambiguity between one and the other:

open(SOURCE, "<", $path)
    or die "Couldn't open $path for reading: $!\n";

open(SINK, ">", $path)
    or die "Couldn't open $path for writing: $!\n";

The sysopen function takes either three or four arguments: filehandle, filename, file-access flags, plus an optional permissions value. The flags argument is a number constructed from constants provided by the Fcntl module:

use Fcntl;

sysopen(SOURCE, $path, O_RDONLY)
    or die "Couldn't open $path for reading: $!\n";

sysopen(SINK, $path, O_WRONLY, 0600)
    or die "Couldn't open $path for writing: $!\n";

If you pass open or sysopen a scalar variable that's undefined, Perl fills in that variable with a new, anonymous filehandle.

open(my $fh, "<", $path)
    or die "Couldn't open $path for reading: $!\n";

7.1.3. Discussion

All input and output goes through filehandles, regardless of whether filehandles are mentioned. Filehandles aren't exclusively connected to regular files in the filesystem—they're also used to communicate with other programs (see Chapter 16) and for network communication (see Chapter 17). The open function can also be used to manipulate file descriptors, as discussed in Recipe 7.9.

The open function quickly and conveniently solves the problem of associating a filehandle with a file. It permits a shorthand for common access modes (reading, writing, reading and writing, appending) passed in with the filename. It doesn't let you control the permissions that files are created with or even whether files are created. For this level of control, you need sysopen, which uses constants provided by the Fcntl module to control individual settings like read, write, create, and truncate.

Most programmers meet open long before they meet sysopen. Table 7-1 shows how open file-access modes (the "Filename" column) correspond to sysopen constants ("O_ flags") and to the fopen(3) strings that IO::File->new can take ("Char"). "Read" and "Write" indicate that the filehandle may be read from or written to. "Append" means no matter where you are in the file, output goes to the end of the file (on most systems). "Create" indicates whether the open statement creates a file if one having the given name doesn't already exist. "Trunc" indicates open will clobber any existing data if the file already exists.

Table 7-1. File-access modes

Filename | Read | Write | Append | Create | Trunc | O_flags | Char
< file | yes | no | no | no | no | RDONLY | "r"
> file | no | yes | no | yes | yes | WRONLY TRUNC CREAT | "w"
>> file | no | yes | yes | yes | no | WRONLY APPEND CREAT | "a"
+< file | yes | yes | no | no | no | RDWR | "r+"
+> file | yes | yes | no | yes | yes | RDWR TRUNC CREAT | "w+"
+>> file | yes | yes | yes | yes | no | RDWR APPEND CREAT | "a+"

Here's a tip: you almost never want to use +> or +>>. The first clobbers your file before you can read it, and the second one can be confusing. Although you can read from anywhere with +>>, many systems jump to the end of the file when you write.

The sysopen function takes either three or four arguments:

sysopen(FILEHANDLE, $name, $flags)         or die "Can't open $name : $!";
sysopen(FILEHANDLE, $name, $flags, $perms) or die "Can't open $name : $!";

$name is the name of the file, without any < or + funny business. $flags is a number, formed by ORing together separate values for O_CREAT, O_WRONLY, O_TRUNC, etc. Availability of particular O_* constants depends on your operating system, so consult the online documentation for this (usually open(2), but not always), or look in /usr/include/fcntl.h. Common ones are:

O_RDONLY | Read only
O_WRONLY | Write only
O_RDWR | Read and write
O_CREAT | Create the file if it doesn't exist
O_EXCL | Fail if the file already exists
O_APPEND | Append to the file
O_TRUNC | Truncate the file
O_NONBLOCK | Non-blocking access

Less common O_* flags sometimes available include O_SHLOCK, O_EXLOCK, O_BINARY, O_NOCTTY, and O_SYNC. Consult your open(2) manpage or its local equivalent for details.

If you omit the $perms argument to sysopen, Perl uses the octal value 0666. These permissions values need to be in octal and are modified by your process's current umask. A umask value is a number representing disabled permissions bits—if your umask were 027 (group can't write; others can't read, write, or execute), then passing sysopen 0666 would create a file with mode 0640 (mathematically, 0666 & ~027 is 0640).

If umask seems confusing, here's some advice: supply a creation mode of 0666 for regular files and one of 0777 for directories and executable files. This gives users a choice: if they want protected files, they can choose process umasks of 022, 027, or even the particularly antisocial mask of 077. Programs should rarely if ever make policy decisions better left to the user. One exception, though, is files that should be kept private: mail files, web browser cookies, .rhosts files, and so on. In short, seldom if ever use 0644 as argument to sysopen because that takes away the user's option to have a more permissive umask.

Here are examples of open and sysopen in action.

To open for reading:

open(FH, "<", $path)                                or die $!;
sysopen(FH, $path, O_RDONLY)                        or die $!;

To open for writing, create a new file if needed, or else truncate an old one:

open(FH, ">", $path)                                or die $!;
sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT)        or die $!;
sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT, 0600)  or die $!;

To open for writing, create a new file, but that file must not previously exist:

sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT)         or die $!;
sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT, 0600)   or die $!;

To open for appending, creating it if necessary:

open(FH, ">>", $path)                               or die $!;
sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT)       or die $!;
sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT, 0600) or die $!;

To open for appending, where the file must exist:

sysopen(FH, $path, O_WRONLY|O_APPEND)               or die $!;

To open for update, where the file must exist:

open(FH, "+<", $path)                               or die $!;
sysopen(FH, $path, O_RDWR)                          or die $!;

To open for update, but create a new file if necessary:

sysopen(FH, $path, O_RDWR|O_CREAT)                  or die $!;
sysopen(FH, $path, O_RDWR|O_CREAT, 0600)            or die $!;

To open for update, where the file must not exist:

sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT)           or die $!;
sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT, 0600)     or die $!;

We use a creation mask of 0600 here only to show how to create a private file. The argument is normally omitted.

7.1.4. See Also

The open, sysopen, and umask functions in perlfunc(1) and Chapter 29 of Programming Perl; the perlopentut(1) manpage; the documentation for the standard IO::File and Fcntl modules (also in Chapter 32 of Programming Perl); your system's open(2), fopen(3), and umask(2) manpages; Recipe 7.2; Recipe 9.11

Previous | Home | Next
7. File Access | Book Index | 7.2. Opening Files with Unusual Filenames
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.2. Opening Files with Unusual Filenames

7.2.1. Problem

You want to open a file with a funny filename, such as "-", or one that starts with <, >, or |; has leading or trailing whitespace; or ends with |. You don't want these to trigger open's do-what-I-mean behavior, since in this case, that's not what you mean.

7.2.2. Solution

When open is called with three arguments, not two, placing the mode in the second argument:

open(HANDLE, "<", $filename)          or die "cannot open $filename : $!\n";

Or simply use sysopen:

sysopen(HANDLE, $filename, O_RDONLY)   or die "cannot open $filename: $!\n";

7.2.3. Discussion

When open is called with three arguments, the access mode and the filename are kept separate. But when called with only two arguments, open has to extract the access mode and the filename from a single string. If your filename begins with the same characters used to specify an access mode, open could easily do something unexpected. Imagine the following code:

$filename = shift @ARGV;
open(INPUT, $filename)               or die "Couldn't open $filename : $!\n";

If the user gave ">/etc/passwd" as the filename on the command line, this code would attempt to open /etc/passwd for writing. We can try to give an explicit mode, say for writing:

open(OUTPUT, ">$filename")
    or die "Couldn't open $filename for writing: $!\n";

but even this would let the user give a filename of ">data", and the code would append to the file data instead of erasing the old contents.

The easiest solution is to pass three arguments to open, where the second argument is the mode and the third the path. Now there can be neither confusion nor subterfuge.

open(OUTPUT, ">", $filename)
    or die "Couldn't open $filename for writing: $!\n";

Another solution is sysopen, which also takes the mode and filename as distinct arguments:

use Fcntl;                          # for file constants

sysopen(OUTPUT, $filename, O_WRONLY|O_TRUNC)
    or die "Can't open $filename for writing: $!\n";

This special way that open interprets filenames, sometimes referred to as magic open, is a matter of convenience—and usually a good thing. You don't have to worry about a space or two between the access mode and the path. You never have to use the special case of "-" to mean standard input or output. If you write a filter and use a simple open, users can pass "gzip -dc bible.gz|" as a filename, and your filter will automatically run the decoding program.

It's only those programs that run under special privilege that should worry about security with open. When designing programs that will be run on someone else's behalf, such as setuid programs or CGI scripts, the prudent programmer always considers whether the user can supply their own filename and thereby cajole what would otherwise appear to be a normal open used for simple reading into overwriting a file or even running another program. Perl's -T command-line flag to enable taint-checking would take care of this.

In versions of Perl without three-argument open (those before v5.6.0), one had little recourse but to resort to the following sort of chicanery to cope with filenames with leading or trailing whitespace:

$file =~ s#^(\s)#./$1#;
open(OUTPUT, "> $file\0")
        or die "Couldn't open $file for OUTPUT : $!\n";

The substitution protects initial whitespace (this cannot occur in fully specified filenames like "/etc/passwd", but only in relative filenames like ">passwd"). The NUL byte (ASCII 0, "\0") isn't considered part of the filename by open, but it does prevent trailing whitespace from being ignored.

7.2.4. See Also

The open and sysopen functions in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 7.1; Recipe 7.14; Recipe 16.2; Recipe 19.4; Recipe 19.5

Previous | Home | Next
7.1. Opening a File | Book Index | 7.3. Expanding Tildes in Filenames
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.3. Expanding Tildes in Filenames

7.3.1. Problem

You want to open filenames like ~username/blah or ~/.mailrc, but open doesn't interpret the tilde to mean a home directory.

7.3.2. Solution

Either use the glob function:

open(FH, glob("~joebob/somefile")) || die "Couldn't open file: $!";

or expand the filename manually with a substitution:

$filename =~ s{ ^ ~ ( [^/]* ) }
              { $1
                    ? (getpwnam($1))[7]
                    : ( $ENV{HOME} || $ENV{LOGDIR}
                         || (getpwuid($<))[7]
                       )
}ex;

7.3.3. Discussion

There is a useful convention, begun with the Unix csh shell and propagated widely by web addresses of the form http://www.example.com/~user/, that ~ in a filename represents a user's home directory. Thus:

    ~              # current user's home directory
    ~/blah         # file blah in current user's home directory
    ~user          # a particular user's home directory
    ~user/blah     # file blah in a particular user's home directory

Unfortunately, Perl's open function does not expand wildcards, including tildes. As of the v5.6 release, Perl internally uses the File::Glob module when you use the glob operator. So all you need to do is glob the result first.

open(MAILRC, "<", "~/.mailrc")           # WRONG: tilde is a shell thing
    or die "can't open ~/.mailrc: $!";

open(MAILRC, "<", glob("~/.mailrc"))     # so expand tilde first
    or die "can't open ~/.mailrc: $!";

The alternative solution, the substitution, uses /e to evaluate the replacement as Perl code. If a username follows the tilde, it's stored in $1, which getpwnam uses to extract the user's home directory out of the return list. This directory becomes the replacement string. If the tilde was not followed by a username, substitute in either the current HOME environment variable or the LOGDIR one. If neither of those is valid, look up the effective user ID's home directory.

You could spell glob('~gnat') as <~gnat>, but that would look too much like a read from a filehandle, so don't do that.

7.3.4. See Also

The glob and getpwnam functions in perlfunc(1) and Chapter 29 of Programming Perl; your system's getpwnam(2) manpage; Recipe 9.6

Previous | Home | Next
7.2. Opening Files with Unusual Filenames | Book Index | 7.4. Making Perl Report Filenames in Error Messages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.4. Making Perl Report Filenames in Error Messages

7.4.1. Problem

Your program works with files, but Perl's errors and warnings only report the last used filehandle, not the name of the file.

7.4.2. Solution

Use the filename as the filehandle:

open($path, "<", $path)
    or die "Couldn't open $path for reading : $!\n";

7.4.3. Discussion

Ordinarily, error messages say:

Argument "3\n" isn't numeric in multiply at tallyweb line 16, <LOG> chunk 17.

The filehandle LOG doesn't help much because you don't know which file the handle was connected to. By using the filename itself as indirect filehandle, Perl produces more informative errors and warnings:

Argument "3\n" isn't numeric in multiply at tallyweb
   line 16, </usr/local/data/mylog3.dat> chunk 17.

Unfortunately, this doesn't work with strict refs turned on because the variable $path doesn't really have a filehandle in it, only a string that sometimes behaves like one. The chunk number mentioned in warnings and error messages is the current value of the $. variable.

7.4.4. See Also

Recipe 7.1; the open function in perlfunc(1) and Chapter 29 of Programming Perl

Previous | Home | Next
7.3. Expanding Tildes in Filenames | Book Index | 7.5. Storing Filehandles into Variables
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.5. Storing Filehandles into Variables

7.5.1. Problem

You want to use a filehandle like a normal variable so you can pass it to or return it from a function, store it in a data structure, and so on.

7.5.2. Solution

The easiest way to get a filehandle into a variable is to have open put it there for you:

open(my $fh, "<", $filename)      or die "$0: can't open $filename: $!";

To store named filehandles into a variable or pass them into or out of a function, use typeglob notation (*FH):

$variable = *FILEHANDLE;        # save in variable
subroutine(*FILEHANDLE);        # or pass directly

sub subroutine {
    my $fh = shift;
    print $fh "Hello, filehandle!\n";
}

7.5.3. Discussion

If you pass an undefined scalar variable as the first argument to open, Perl allocates an anonymous typeglob and stores a reference to that typeglob in that scalar, effectively creating filehandles on demand. Like all other references, autovivified filehandles are subject to garbage collection, so this code doesn't leak a filehandle:

{
    open(my $fh, "< /etc/motd") or die;
    local $/;          # slurp mode
    $text = <$fh>;
}

When Perl reaches the end of the block, $fh goes out of scope. As explained earlier in the Introduction, because that variable contained the last reference to the anonymous filehandle created by open, the variable is garbage collected and the filehandle implicitly closed.

Autovivified filehandles, being anonymous and already held in variables, don't help you to understand how to pass named filehandles as function parameters or store them in variables, including elements of arrays or hashes. By named filehandles, we mean those of the form FH, including all predefined handles, such as STDIN and ARGV. So let's look at what FH is and how to extract a scalar value from it to use for all of those things.

Named filehandles used in:

print STDERR "stuff\n";
$input = <STDIN>;
open(TTY, "+<", "/dev/tty");
if (eof(ARGV)) { .... }

are names, not variables. They're like subroutines in that way. This makes them inconvenient to pass around or store into data structures. Assuming you follow the prudent advice to compile all your code under use strict by default, normally you can't get away with this:

$fh = SOMEHANDLE;
somefunc(SOMEHANDLE);

because, absent declarations to the contrary, SOMEHANDLE is in both of these cases an unquoted string, which is forbidden by use strict. Even if you aren't using strict subs, you'll get into trouble if you try to pass your handle into a subroutine that was compiled under strict refs or in a different package than the calling code was compiled in.

The four named handles (STDERR, STDIN, TTY, and ARGV) we showed earlier didn't require special handling, but not because they are built-ins themselves; TTY, in fact, is not. Rather, they were okay because the built-in operations using them as arguments are all prototyped to take a filehandle argument.

So you must do one of two things. You could use a prototype for the function as explained in Recipe 7.6. Otherwise, you must use something that Perl will accept in lieu of a filehandle name. Acceptable substitutes include strings, typeglobs, references to typeglobs, and an I/O object, all of which may be stored into variables or passed into a function for later use as indirect filehandles.

somefunc(   SOMEHANDLE     );       # only w/ somefunc(*) proto
somefunc(  "SOMEHANDLE"    );       # an quoted string
somefunc(  *SOMEHANDLE     );       # a typeglob
somefunc( \*SOMEHANDLE     );       # ref to a typeglob
somefunc(  *SOMEHANDLE{IO} );       # an I/O object

Using a quoted string for the named handle has potential problems, as already explained, although this can work if the code is careful enough (again, see the next recipe). Better to use typeglob notation, either directly using *SOMEHANDLE or by reference using \*SOMEHANDLE:

somefunc(*SOMEHANDLE);
$fh = *SOMEHANDLE;  # or indirectly via a variable
somefunc($fh);

print $fh "data\n";

Typeglob notation spares you quoting or qualifying the handle name. It may help to conceptualize the asterisk as the type symbol for a filehandle. Like the little colored balls from high school chemistry that stood for atomic particles, it's not really true, but it is a convenient mental shorthand. By the time you understand where this model breaks down, you won't need it anymore.

If you assign any of the four alternate forms for named filehandles into a scalar variable, you can use that variable as an indirect filehandle wherever you would use a named filehandle.

However, complex expressions and subscripts into hashes or arrays cannot be used directly with built-ins like print, printf, or the line input operator. These are syntactically illegal and won't even compile:

@fd = (*STDIN, *STDOUT, *STDERR);
print $fd[1] "Type it: ";                           # WRONG
$got = <$fd[0]>                                     # WRONG
print $fd[2] "What was that: $got";                 # WRONG

With print and printf, you can get around this by using a block, returning an expression where you would place the filehandle:

print  { $fd[1] } "funny stuff\n";
printf { $fd[1] } "Pity the poor %x.\n", 3_735_928_559;
Pity the poor deadbeef.

That block is a proper block in all senses, so you can put more complicated code there. This sends the message out to one of two places:

$ok = -x "/bin/cat";
print { $ok ? $fd[1] : $fd[2]  } "cat stat $ok\n";
print { $fd[ 1 + ($ok || 0) ]  } "cat stat $ok\n";

This is so-called "indirect object" notation, discussed at length in Chapter 13. This restriction against using anything but simple scalar variables in the indirect object slot holds true for any sort of object. As with user-created objects, infix arrow notation avoids syntactic snafus here. If you have the IO::Handle module loaded, or anything that inherits from it, use an expression that produces the filehandle as though it were a proper object to invoke methods from that class:

$fd[1]->print("funny stuff\n");
($ok ? $fd[1] : $fd[2])->print("cat stat $ok\n");

This approach of treating print and printf like object methods calls won't work for the line input operator. Assuming you've been storing typeglobs in your structure as we did previously, the built-in readline function reads records just as <FH> does. Given the preceding initialization of @fd, this would work:

$got = readline($fd[0]);

or, with IO::Handle available, you can use the getline method:

$got = $fd[0]->getline( );

IO::Handle doesn't replace the readline function using just one method—it uses two, one per context. If you prefer readline's context-dependent behavior, you could always do this, adding something to the class on the fly:

sub IO::Handle::readline {
    my $fh = shift;
    if (wantarray) {
        return $fh->getlines( );
    } else {
        return $fh->getline( );
    }
}

7.5.4. See Also

The open function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 7.1; the documentation with the standard IO::Handle module (also in Chapter 32 of Programming Perl); and the "Typeglobs and Filehandles" sections of Chapter 2 of Programming Perl

Previous | Home | Next
7.4. Making Perl Report Filenames in Error Messages | Book Index | 7.6. Writing a Subroutine That Takes Filehandles as Built-ins Do
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.6. Writing a Subroutine That Takes Filehandles as Built-ins Do

7.6.1. Problem

You can pass a bareword filehandle to Perl functions like eof, and you'd like to write similar subroutines of your own.

7.6.2. Solution

Use the Symbol module's qualify_to_ref in conjunction with a * prototype on the subroutine:

use Symbol qw(qualify_to_ref);

sub my_eof (*) {
  my $handle = shift;
  $handle = qualify_to_ref($handle, caller( ));
  # use $handle
}

7.6.3. Discussion

The * prototype tells Perl that the function expects a bareword filehandle as its argument. This lets you call the function like so:

my_eof(HANDLE);

This works even when use strict 'subs' is in effect. The function receives a string as its argument, though. To safely use the argument as a filehandle, you need the Symbol module to turn it into a reference to a typeglob. And since typeglob refs can be used wherever you'd use named filehandles, store that reference in a scalar variable and use the variable as an indirect filehandle within your subroutine.

If you pass in a filehandle that is already a reference to a typeglob, like those autovivified by open, Perl and qualify_to_ref still do the right thing:

open(my $fh, "<", $filename) or die;
my_eof($fh);

This technique is used in Recipe 7.23.

7.6.4. See Also

The documentation for the standard module Symbol (also in Chapter 32 of Programming Perl); the "Prototypes" section in the perlsub(1) manpage (also in Chapter 6 of Programming Perl); Recipe 7.23

Previous | Home | Next
7.5. Storing Filehandles into Variables | Book Index | 7.7. Caching Open Output Filehandles
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.7. Caching Open Output Filehandles

7.7.1. Problem

You need more output files open simultaneously than your system allows.

7.7.2. Solution

Use the standard FileCache module:

use FileCache;
cacheout ($path);         # each time you use a filehandle
print $path "output";

7.7.3. Discussion

FileCache's cacheout function lets you work with more output files than your operating system lets you have open at any one time. If you use it to open an existing file that FileCache is seeing for the first time, the file is truncated to length zero, no questions asked. However, in its opening and closing of files in the background, cacheout tracks files it has opened before and does not overwrite them, but appends to them instead. This does not create directories for you, so if you give it /usr/local/dates/merino.ewe to open but the directory /usr/local/dates doesn't exist, cacheout will die.

The cacheout function checks the value of the C-level constant NOFILE from the standard system include file sys/param.h to determine how many concurrently open files are allowed on your system. This value can be incorrect on some systems and even missing on a few (for instance, on those where the maximum number of open file descriptors is a process resource limit that can be set with the limit or ulimit commands). If cacheout can't get a value for NOFILE, set $FileCache::cacheout_maxopen to be four less than the correct value, or choose a reasonable number by trial and error.

Example 7-1 splits an xferlog file (created by most FTP servers nowadays) into separate files, each named after the authenticated user. Fields in xferlog files are space-separated, with the fourth field from the last holding the authenticated username.

Example 7-1. splitwulog

  #!/usr/bin/perl
  # splitwulog - split wuftpd log by authenticated user
  use FileCache;
  $outdir = "/var/log/ftp/by-user";
  while (<>) {
      unless (defined ($user = (split)[-4])) {
         warn "Invalid line: $.\n";
         next;
      }
      $path = "$outdir/$user";
      cacheout $path;
      print $path $_;

  }

7.7.4. See Also

Documentation for the standard FileCache module (also in Chapter 32 of Programming Perl); the open function in perlfunc(1) and in Chapter 29 of Programming Perl

Previous | Home | Next
7.6. Writing a Subroutine That Takes Filehandles as Built-ins Do | Book Index | 7.8. Printing to Many Filehandles Simultaneously
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.8. Printing to Many Filehandles Simultaneously

7.8.1. Problem

You need to output the same data to several different filehandles.

7.8.2. Solution

If you want to do it without forking, write a foreach loop that iterates across the filehandles:

foreach $filehandle (@FILEHANDLES) {
    print $filehandle $stuff_to_print;
}

If you don't mind forking, open a filehandle that's a pipe to a tee program:

open(MANY, "| tee file1 file2 file3 > /dev/null")   or die $!;
print MANY "data\n"                                 or die $!;
close(MANY)                                         or die $!;

If you don't have a tee program handy, use the IO::Tee module from CPAN:

use IO::Tee;
$tee = IO::Tee->new(@FILEHANDLES);
print $tee $stuff_to_print;

7.8.3. Discussion

A filehandle sends output to one file or program only. To duplicate output to several places, you must call print multiple times or make a filehandle connected to a program like tee, which distributes its input elsewhere. If you use the first option, it's probably easiest to put the filehandles in a list or array and loop through them (see Recipe 7.5):

for $fh (*FH1, *FH2, *FH3)      { print $fh "whatever\n" }

However, if your system supports the tee(1) program, or if you've installed the Perl version from Recipe 8.25, you may open a pipe to tee and let it do the work of copying the file to several places. Remember that tee normally also copies its output to STDOUT, so you must redirect tee's standard output to /dev/null if you don't want an extra copy:

open (FH, "| tee file1 file2 file3 >/dev/null");
print FH "whatever\n";

You could even redirect your own STDOUT to the tee process, and then you're able to use a regular print directly:

# make STDOUT go to three files, plus original STDOUT
open (STDOUT, "| tee file1 file2 file3") or die "Teeing off: $!\n";
print "whatever\n"                       or die "Writing: $!\n";
close(STDOUT)                            or die "Closing: $!\n";

The IO::Tee module from CPAN gives you a single filehandle (an object of the IO::Tee class) that you can write to. The object prints to many different filehandles whatever you print to it. Pass destination filehandles to the constructor:

use IO::Tee;

$t = IO::Tee->new(*FH1, *FH2, *FH3);
print $t "Hello, world\n";
print $t "Goodbye, universe\n";

In addition to print, you can do any I/O operation you like to an IO::Tee filehandle. For example, if you close $t in the preceding example, the close will return true if FH1, FH2, and FH3 were all successfully closed.

7.8.4. See Also

The print function in perlfunc(1) and in Chapter 29 of Programming Perl; the "Typeglobs and Filehandles" sections of Chapter 2 of Programming Perl; the documentation for the CPAN module IO::Tee; we use this technique in Recipe 8.25 and Recipe 13.15

Previous | Home | Next
7.7. Caching Open Output Filehandles | Book Index | 7.9. Opening and Closing File Descriptors by Number
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.9. Opening and Closing File Descriptors by Number

7.9.1. Problem

You know which file descriptors you'd like to do I/O on, but Perl requires filehandles, not descriptor numbers.

7.9.2. Solution

To open the file descriptor, supply open with "<&=" or "<&" as the part of the file access mode, combined with a directional arrow:

open(FH, "<&=", $FDNUM)       # open FH to the descriptor itself
open(FH, "<&",  $FDNUM);      # open FH to a copy of the descriptor

Or use the IO::Handle module's new_from_fd class method:

use IO::Handle;
$fh = IO::Handle->new_from_fd($FDNUM, "r");

To close a file descriptor by number, either use the POSIX::close function or open it first as shown previously.

7.9.3. Discussion

Occasionally you have a file descriptor but no filehandle. Perl's I/O system uses filehandles instead of file descriptors, so you have to make a new filehandle from an already open file descriptor. The "<&", ">&", and "+<&" access modes to open do this for reading, writing, and updating, respectively. Adding an equals sign to these—making them "<&=", ">&=", and "+<&="—is more parsimonious of file descriptors and nearly always what you want. That's because the underlying implementation of Perl's open statement uses only a C-level fdopen(3) function from the C library, not a dup2(2) syscall that calls the kernel.

The new_from_fd IO::Handle object method is equivalent to:

use IO::Handle;

$fh = new IO::Handle;
$fh->fdopen($FDNUM, "r");            # open fd 3 for reading

Here's how you'd open file descriptors that the MH mail system feeds its child processes. It identifies them in the environment variable MHCONTEXTFD:

$fd = $ENV{MHCONTEXTFD};
open(MHCONTEXT, "<&=", $fd)   or die "couldn't fdopen $fd: $!";
# after processing
close(MHCONTEXT)              or die "couldn't close context file: $!";

Closing a file descriptor by number is even rarer. If you've already opened a filehandle for the file descriptor you want to close, simply use Perl's close function on the filehandle. If don't have a filehandle for that file descriptor, the POSIX::close function closes a file descriptor by number:

use POSIX;

POSIX::close(3);              # close fd 3

7.9.4. See Also

The open function in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard POSIX and IO::Handle modules (also in Chapter 32 of Programming Perl); your system's fdopen(3) manpages

Previous | Home | Next
7.8. Printing to Many Filehandles Simultaneously | Book Index | 7.10. Copying Filehandles
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.10. Copying Filehandles

7.10.1. Problem

You want a copy of a filehandle.

7.10.2. Solution

To create an alias for a named filehandle, say:

*ALIAS = *ORIGINAL;

Use open with the & file access mode to create an independent copy of the file descriptor for that filehandle:

open(OUTCOPY, ">&STDOUT")        or die "Couldn't dup STDOUT: $!";
open(INCOPY,  "<&STDIN")         or die "Couldn't dup STDIN : $!";

Use open with the &= mode to create an alias for that filehandle or file descriptor:

open(OUTALIAS, ">&=STDOUT")      or die "Couldn't alias STDOUT: $!";
open(INALIAS,  "<&=STDIN")       or die "Couldn't alias STDIN : $!";
open(BYNUMBER, ">&=5")           or die "Couldn't alias file descriptor 5: $!";

With other types of filehandles (typeglobs, objects), use the same technique with a three-argument open:

open(my $copy, "<&",  $original) or die "Couldn't alias original: $!";
open(my $copy, "<&=", $original) or die "Couldn't alias original: $!";

7.10.3. Discussion

If you create an alias for a filehandle with typeglobs, only one Perl I/O object is still being accessed. If you close one of these aliased filehandles, the I/O object is closed. Any further attempt to use a copy of that filehandle fails, silently by default or, if you have warnings enabled, with the warning "print on closed filehandle". When alternating access through aliased filehandles, writes work as you'd expect because there are no duplicated stdio data structures to get out of sync.

If you create a copy of a file descriptor with open(COPY, ">&HANDLE"), you're really calling the dup(2) syscall. You get two independent file descriptors whose file position, locks, and flags are shared, but which have independent stdio buffers. Closing one filehandle doesn't affect its copy. Simultaneously accessing the file through both filehandles is a recipe for disaster. Instead, this technique is normally used to save and restore STDOUT and STDERR:

# take copies of the file descriptors
open(OLDOUT, ">&STDOUT");
open(OLDERR, ">&STDERR");

# redirect stdout and stderr
open(STDOUT, "> /tmp/program.out")  or die "Can't redirect stdout: $!";
open(STDERR, ">&STDOUT")            or die "Can't dup stdout: $!";

# run the program
system($joe_random_program);

# close the redirected filehandles
close(STDOUT)                       or die "Can't close STDOUT: $!";
close(STDERR)                       or die "Can't close STDERR: $!";

# restore stdout and stderr
open(STDERR, ">&OLDERR")            or die "Can't restore stderr: $!";
open(STDOUT, ">&OLDOUT")            or die "Can't restore stdout: $!";

# avoid leaks by closing the independent copies
close(OLDOUT)                       or die "Can't close OLDOUT: $!";
close(OLDERR)                       or die "Can't close OLDERR: $!";

If you create an alias for a file descriptor using open(ALIAS, ">&=HANDLE"), you're really calling the fdopen(3) function from the stdio library or its equivalent. You get a single file descriptor with two stdio buffers accessed through two filehandles. Closing one filehandle closes the file descriptor of any aliases, but not their filehandles—if you tried to print to a filehandle whose alias had been close d, Perl wouldn't give a "print on closed filehandle" warning, even though the print failed. In short, accessing the file through both filehandles is also a recipe for disaster. This is really used only to open a file descriptor by number. See Recipe 7.9 for more information on this.

7.10.4. See Also

The open function in perlfunc(1) and in Chapter 29 of Programming Perl; your system's dup(2) manpage

Previous | Home | Next
7.9. Opening and Closing File Descriptors by Number | Book Index | 7.11. Creating Temporary Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.11. Creating Temporary Files

7.11.1. Problem

You need to create a temporary file and have it deleted automatically when your program exits. For instance, if you needed a temporary configuration file to feed a program you're about to launch, you'd need a name for that file so you could pass that filename along to the utility program. In other cases, you may want a temporary file to write to and read from, but don't need a filename for it.

7.11.2. Solution

Use the tempfile function from the File::Temp module:

use File::Temp qw/ tempdir /;
$fh = tempfile( );  # just the handle

perhaps in conjunction with a temporary directory:

use File::Temp qw/ tempdir /;
# or specify a directory
$dir = tempdir( CLEANUP => 1 );
($fh, $filename) = tempfile( DIR => $dir );

$template = "myprogtempXXXXXX"; # trailing Xs are changed
($fh, $filename) = tempfile( $template, DIR => $dir);
($fh, $filename) = tempfile( $template, SUFFIX => ".data");

7.11.3. Discussion

The File::Temp module's functions are the best way to make temporary files. For one thing, they're extremely easy to use. For another, they're more portable than direct calls to the operating system. But perhaps of greatest importance is the care they take in security matters both various and subtle, especially those involving race conditions.

Although this module provides a handful of slightly different functions for creating a temporary file, most are there simply to support legacy interfaces; few users will need more than the basic tempfile( ) function. This function safely and atomically creates and opens a brand new, empty file in read-write mode. In scalar context, it returns a filehandle to that temporary file; in list context, it returns the handle and pathname of the temporary file:

use File::Temp qw(tempfile);

# just the handle
$fh = tempfile( );

# handle and filename
($fh, $filename) = tempfile( );

The tempfile function optionally accepts an argument containing a template and then named arguments in pairs. Named arguments specify such things as the directory to use instead of the current directory, that a specific file extension should be used, and on systems that support such a thing, whether the tempfile should be immediately unlinked before its handle is returned. (Files whose names have already been deleted from the filesystem are especially difficult for the guys with the black hats to find.) Any trailing X characters in the template are replaced by random characters in the final filename. You might use this feature if you need a temporary file with a specific extension.

($fh, $filename) = tempfile(DIR => $dir);
($fh, $filename) = tempfile($template);
($fh, $filename) = tempfile($template, DIR => $dir);
($fh, $filename) = tempfile($template, SUFFIX => ".dat");
($fh, $filename) = tempfile($template, UNLINK => 1);

Unless you specify OPEN => 0, the temporary file will be deleted automatically when your program finally exits or the file is closed.

In recent releases, Perl's open function offers a simple way to create temporary files whose names you cannot know. Explicitly pass undef as the filename to open:

open(my $fh, "+>", undef)
  or die "$0: can't create temporary file: $!\n";

7.11.4. See Also

The documentation for the standard File::Temp modules (also in Chapter 32 of Programming Perl); the open function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 7.9

Previous | Home | Next
7.10. Copying Filehandles | Book Index | 7.12. Storing a File Inside Your Program Text
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.12. Storing a File Inside Your Program Text

7.12.1. Problem

You have data that you want to bundle with your program and treat as though it were in a file, but you don't want it to be in a different file.

7.12.2. Solution

Use the _ _DATA_ _ or _ _END_ _ tokens after your program code to mark the start of a data block, which can be read inside your program or module from the DATA filehandle.

Use _ _DATA_ _ within a module:

while ( <DATA>) {
    # process the line
}
_ _DATA_ _
# your data goes here

Similarly, use _ _END_ _ within the main program file:

while (<main::DATA>) {
    # process the line
}
_ _END_ _
# your data goes here

7.12.3. Discussion

The _ _DATA_ _ and _ _END_ _ symbols tell the Perl compiler there's nothing more for it to do in the current file. They represent the logical end for code in a module or a program before the physical end-of-file.

Text after _ _DATA_ _ or _ _END_ _ can be read through the per-package DATA filehandle. For example, take the hypothetical module Primes. Text after _ _DATA_ _ in Primes.pm can be read from the Primes::DATA filehandle.

_ _END_ _ behaves as a synonym for _ _DATA_ _ in the main package. Any text occurring after an _ _END_ _ token in a module is completely inaccessible.

This lets you write self-contained programs instead of keeping data in separate files. Often this is used for documentation. Sometimes it's configuration data or old test data that the program was originally developed with, left lying about should it ever be needed again.

Another trick is to use DATA to find out the current program's or module's size or last modification date. On most systems, the $0 variable will contain the full pathname to your running script. On systems where $0 is not correct, you could try the DATA filehandle instead. This can be used to pull in the size, modification date, etc. Put a special token _ _DATA_ _ at the end of the file (and maybe a warning not to delete it), and the DATA filehandle is available to the script itself.

use POSIX qw(strftime);

$raw_time = (stat(DATA))[9];
$size     = -s DATA;
$kilosize = int($size / 1024) . "k";

print "<P>Script size is $kilosize\n";
print strftime("<P>Last script update: %c (%Z)\n", localtime($raw_time));

_ _DATA_ _
DO NOT REMOVE THE PRECEDING LINE.

Everything else in this file will be ignored.

If you want to store more than one file in your program, see Recipe 7.13.

7.12.4. See Also

The "Scalar Value Constructors" section of perldata(1), and the "Other Literal Tokens" section of Chapter 2 of Programming Perl; Recipe 7.13

Previous | Home | Next
7.11. Creating Temporary Files | Book Index | 7.13. Storing Multiple Files in the DATA Area
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.13. Storing Multiple Files in the DATA Area

7.13.1. Problem

You've figured out how to use _ _END_ _ or _ _DATA_ _ to store a virtual file in your source code, but you now want multiple virtual files in one source file.

7.13.2. Solution

Use the Inline::Files module from CPAN. Carefully.

use Inline::Files;

while (<SETUP>) {
  # ...
}

while (<EXECUTION>) {
  # ...
}

_ _SETUP_ _
everything for the SETUP filehandle goes here
_ _EXECUTION_ _
everything for the EXECUTION filehandle goes here

7.13.3. Discussion

One limitation with the _ _DATA_ _ setup is that you can have only one embedded data file per physical file. The CPAN module Inline::Files cleverly circumvents this restriction by providing logical embedded files. It's used like this:

use Inline::Files;

#
#  All your code for the file goes here first, then...
#

_ _ALPHA_ _
This is the data in the first virtual file, ALPHA.

_ _BETA_ _
This is the data in the next virtual file, BETA.

_ _OMEGA_ _
This is the data in yet another virtual file, OMEGA.

_ _ALPHA_ _
This is more data in the second part of virtual file, ALPHA.

The code is expected to read from filehandles whose names correspond to the double-underbarred symbols: here ALPHA, BETA, and OMEGA. You may have more than one section by the same name in the same program, and differently named sections needn't be read in any particular order. These handles work much like the ARGV handle does. For one thing, they're implicitly opened on first usage. For example, using the following code in the designated spot in the preceding code example:

while (<OMEGA>) {
   print "omega data: $_";
}

while (<ALPHA>) {
   print "alpha data: $_";
}

would produce this:

omega data: This is the data in yet another virtual file, OMEGA.
omega data:
alpha data: This is the data in the first virtual file, ALPHA.
alpha data:
alpha data: This is more data in the second part of virtual file, ALPHA.
alpha data:

Also like the ARGV handle, while reading from a particular handle, the list of available virtual files is in the array by that name, and the currently opened virtual file is in the scalar by that name. There's also a hash by that name that holds various bits of status information about that set of virtual files, including the current file, line number, and byte offset. If we used the Perl debugger on this program and dumped out the variables, it might show this:

DB2> \$ALPHA, \@ALPHA, \%ALPHA
0  SCALAR(0x362e34)
   -> '/home/tchrist/inline-demo(00000000000000000291)'
1  ARRAY(0x362e40)
   0  '/home/tchrist/inline-demo(00000000000000000291)'
   1  '/home/tchrist/inline-demo(00000000000000000476)'
2  HASH(0x362edc)
   'file' => undef
   'line' => undef
   'offset' => undef
   'writable' => 1

What's that last line telling us? It tells whether that virtual file is writable. By default, if your script is writable, then so too are the virtual files, and they are opened in read-write mode! Yes, that means you can update them yourself, including even adding new virtual files to your source code simply by running that code. There is absolutely no limit to the mischief or grief that can ensue from this: catastrophes are easy to come by as you accidentally obliterate your painstakingly won data. We therefore implore you to back everything up first. The module itself supports an automatic mechanism for this:

use Inline::Files -backup;

which saves the original in a file with a ".bak" appended to it. You may also specify an explicit backup file:

use Inline::Files -backup => "/tmp/safety_net";

7.13.4. See Also

The documentation for the CPAN module Inline::Files; Recipe 7.12

Previous | Home | Next
7.12. Storing a File Inside Your Program Text | Book Index | 7.14. Writing a Unix-Style Filter Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.14. Writing a Unix-Style Filter Program

7.14.1. Problem

You want to write a program that takes a list of filenames on the command line and reads from STDIN if no filenames were given. You'd like the user to be able to give the file "-" to indicate STDIN or "someprogram |" to indicate the output of another program. You might want your program to modify the files in place or to produce output based on its input.

7.14.2. Solution

Read lines with <>:

while (<>) {
    # do something with the line
}

7.14.3. Discussion

When you say:

while (<>) {
    # ...
 }

Perl translates this into:[14]

[14]Except that the code written here won't work, because ARGV has internal magic.

unshift(@ARGV, "-") unless @ARGV;
while ($ARGV = shift @ARGV) {
    unless (open(ARGV, $ARGV)) {
        warn "Can't open $ARGV: $!\n";
        next;
    }
    while (defined($_ = <ARGV>)) {
        # ...
    }
}

You can access ARGV and $ARGV inside the loop to read more from the filehandle or to find the filename currently being processed. Let's look at how this works.

7.14.3.1. Behavior

If the user supplies no arguments, Perl sets @ARGV to a single string, "-". This is shorthand for STDIN when opened for reading and STDOUT when opened for writing. It's also what lets the user of your program specify "-" as a filename on the command line to read from STDIN.

Next, the file-processing loop removes one argument at a time from @ARGV and copies the filename into the global variable $ARGV. If the file cannot be opened, Perl goes on to the next one. Otherwise, it processes a line at a time. When the file runs out, the loop goes back and opens the next one, repeating the process until @ARGV is exhausted.

The open statement didn't say open(ARGV, "<", $ARGV). There's no extra less-than sign supplied. This allows for interesting effects, like passing the string "gzip -dc file.gz |" as an argument, to make your program read the output of the command "gzip -dc file.gz". See Recipe 16.6 for more about this use of magic open.

You can change @ARGV before or inside the loop. Let's say you don't want the default behavior of reading from STDIN if there aren't any arguments—you want it to default to all C or C++ source and header files. Insert this line before you start processing <ARGV>:

@ARGV = glob("*.[Cch]") unless @ARGV;

Process options before the loop, either with one of the Getopt libraries described in Chapter 15 or manually:

# arg demo 1: Process optional -c flag
if (@ARGV && $ARGV[0] eq "-c") {
    $chop_first++;
    shift;
}

# arg demo 2: Process optional -NUMBER flag
if (@ARGV && $ARGV[0] =~ /^-(\d+)$/) {
    $columns = $1;
    shift;
}

# arg demo 3: Process clustering -a, -i, -n, or -u flags
while (@ARGV && $ARGV[0] =~ /^-(.+)/ && (shift, ($_ = $1), 1)) {
    next if /^$/;
    s/a// && (++$append,      redo);
    die "usage: $0 [-ainu] [filenames] ...\n";
}

Other than its implicit looping over command-line arguments, <> is not special. The special variables controlling I/O still apply; see Chapter 8 for more on them. You can set $/ to set the line terminator, and $. contains the current line (record) number. If you undefine $/, you don't get the concatenated contents of all files at once; you get one complete file each time:

undef $/;
while (<>) {
    # $_ now has the complete contents of
    # the file whose name is in $ARGV
}

If you localize $/, the old value is automatically restored when the enclosing block exits:

{     # create block for local
    local $/;         # record separator now undef
    while (<>) {
        # do something; called functions still have
        # undeffed version of $/
    }
}                             # $/ restored here

Because processing <ARGV> never explicitly closes filehandles, the record number in $. is not reset. If you don't like that, you can explicitly close the file yourself to reset $.:

while (<>) {
    print "$ARGV:$.:$_";
    close ARGV if eof;
}

The eof function defaults to checking the end-of-file status of the last file read. Since the last handle read was ARGV, eof reports whether we're at the end of the current file. If so, we close it and reset the $. variable. On the other hand, the special notation eof( ) with parentheses but no argument checks if we've reached the end of all files in the <ARGV> processing.

7.14.3.2. Command-line options

Perl has command-line options, -n, -p, -a, and -i, to make writing filters and one-liners easier.

The -n option adds the while (<>) loop around your program text. It's normally used for filters like grep or programs that summarize the data they read. The program is shown in Example 7-2.

Example 7-2. findlogin1

  #!/usr/bin/perl
  # findlogin1 - print all lines containing the string "login"
  while (<>) {# loop over files on command line
      print if /login/;
  }

The program in Example 7-2 could be written as shown in Example 7-3.

Example 7-3. findlogin2

  #!/usr/bin/perl -n
  # findlogin2 - print all lines containing the string "login"
  print if /login/;

You can combine the -n and -e options to run Perl code from the command line:

% perl -ne 'print if /login/'

The -p option is like -n but adds a print right before the end of the loop. It's normally used for programs that translate their input, such as the program shown in Example 7-4.

Example 7-4. lowercase1

  #!/usr/bin/perl
  # lowercase - turn all lines into lowercase
  while (<>) {                  # loop over lines on command line
      s/(\p{Letter})/\l$1/g;    # change all letters to lowercase
      print;
  }

The program in Example 7-4 could be written as shown in Example 7-5.

Example 7-5. lowercase2

  #!/usr/bin/perl -p
  # lowercase - turn all lines into lowercase
  s/(\p{Letter})/\l$1/g;# change all letters to lowercase

Or it could be written from the command line as:

% perl -pe 's/(\p{Letter})/\l$1/g'

While using -n or -p for implicit input looping, the special label LINE: is silently created for the whole input loop. That means that from an inner loop, you can skip to the following input record by using next LINE (which is like awk's next statement), or go on to the next file by closing ARGV (which is like awk's nextfile statement). This is shown in Example 7-6.

Example 7-6. countchunks

  #!/usr/bin/perl -n
  # countchunks - count how many words are used.
  # skip comments, and bail on file if _ _END_ _
  # or _ _DATA_ _ seen.
  for (split /\W+/) {
      next LINE if /^#/;
      close ARGV if /_ _(DATA|END)_ _/;
      $chunks++;
  }
  END { print "Found $chunks chunks\n" }

The tcsh keeps a .history file in a format such that every other line contains a commented out timestamp in Epoch seconds:

#+0894382237
less /etc/motd
#+0894382239
vi ~/.exrc
#+0894382242
date
#+0894382242
who
#+0894382288
telnet home

A simple one-liner can render that legible:

% perl -pe 's/^#\+(\d+)\n/localtime($1) . " "/e'
Tue May  5 09:30:37 1998     less /etc/motd
Tue May  5 09:30:39 1998     vi ~/.exrc
Tue May  5 09:30:42 1998     date
Tue May  5 09:30:42 1998     who
Tue May  5 09:31:28 1998     telnet home

The -i option changes each file on the command line. It is described in Recipe 7.16, and is normally used in conjunction with -p.

7.14.4. See Also

perlrun(1), and the "Switches" section of Chapter 19 of Programming Perl; Recipe 7.16; Recipe 16.6

Previous | Home | Next
7.13. Storing Multiple Files in the DATA Area | Book Index | 7.15. Modifying a File in Place with a Temporary File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.15. Modifying a File in Place with a Temporary File

7.15.1. Problem

You need to update a file in place, and you can use a temporary file.

7.15.2. Solution

Read from the original file, write changes to a temporary file, and then rename the temporary back to the original:

open(OLD, "<", $old)        or die "can't open $old: $!";
open(NEW, ">", $new)        or die "can't open $new: $!";
while (<OLD>) {
    # change $_, then...
    print NEW $_            or die "can't write $new: $!";
}
close(OLD)                  or die "can't close $old: $!";
close(NEW)                  or die "can't close $new: $!";
rename($old, "$old.orig")   or die "can't rename $old to $old.orig: $!";
rename($new, $old)          or die "can't rename $new to $old: $!";

This is the best way to update a file "in place."

7.15.3. Discussion

This technique uses little memory compared to the approach that doesn't use a temporary file. It has the added advantages of giving you a backup file and being easier and safer to program.

You can make the same changes to the file using this technique that you can with the version that uses no temporary file. For instance, to insert lines at line 20, say:

while (<OLD>) {
    if ($. =  = 20) {
        print NEW "Extra line 1\n";
        print NEW "Extra line 2\n";
    }
    print NEW $_;
}

To delete lines 20 through 30, say:

while (<OLD>) {
    next if 20 .. 30;
    print NEW $_;
}

Note that rename won't work across filesystems, so you should create your temporary file in the same directory as the file being modified.

The truly paranoid programmer would lock the file during the update. The tricky part is that you have to open the file for writing without destroying its contents before you can get a lock to modify it. Recipe 7.18 shows how to do this.

7.15.4. See Also

Recipe 7.1; Recipe 7.16; Recipe 7.17; Recipe 7.18

Previous | Home | Next
7.14. Writing a Unix-Style Filter Program | Book Index | 7.16. Modifying a File in Place with the -i Switch
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.16. Modifying a File in Place with the -i Switch

7.16.1. Problem

You need to modify a file in place from the command line, and you're too lazy[15] for the file manipulation of Recipe 7.15.

[15]Lazy-as-virtue, not lazy-as-sin.

7.16.2. Solution

Use the -i and -p switches to Perl. Write your program on the command line:

% perl -i.orig -p -e 'FILTER COMMAND' file1 file2 file3 ...

or use the switches in programs:

#!/usr/bin/perl -i.orig -p
# filter commands go here

7.16.3. Discussion

The -i command-line switch modifies each file in place. It creates a temporary file as in the previous recipe, but Perl takes care of the tedious file manipulation for you. Use it with -p (explained in Recipe 7.14) to turn:

while (<>) {
    if ($ARGV ne $oldargv) {           # are we at the next file?
        rename($ARGV, $ARGV . ".orig");
        open(ARGVOUT, ">", $ARGV);     # plus error check
        select(ARGVOUT);
        $oldargv = $ARGV;
    }
    s/DATE/localtime/e;
}
continue{
    print;
}
select (STDOUT);                      # restore default output

into:

% perl -pi.orig -e 's/DATE/localtime/e'

The -i switch takes care of making a backup (say -i instead of -i.orig to discard the original file contents instead of backing them up), and -p makes Perl loop over filenames given on the command line (or STDIN if no files were given).

The preceding one-liner would turn a file containing the following:

Dear Sir/Madam/Ravenous Beast,
    As of DATE, our records show your account
is overdue.  Please settle by the end of the month.
Yours in cheerful usury,
    --A. Moneylender

into:

Dear Sir/Madam/Ravenous Beast,
    As of Sat Apr 25 12:28:33 1998, our records show your account
is overdue.  Please settle by the end of the month.
Yours in cheerful usury,
    --A. Moneylender

This switch makes in-place translators a lot easier to write and to read. For instance, this changes isolated instances of "hisvar" to "hervar" in all C, C++, and yacc files:

% perl -i.old -pe 's{\bhisvar\b}{hervar}g' *.[Cchy]

Turn on and off the -i behavior with the special variable $^I. Set @ARGV, and then use <> as you would with -i on the command line:

# set up to iterate over the *.c files in the current directory,
# editing in place and saving the old file with a .orig extension
local $^I   = ".orig";              # emulate  -i.orig
local @ARGV = glob("*.c");          # initialize list of files
while (<>) {
    if ($. =  = 1) {
        print "This line should appear at the top of each file\n";
    }
    s/\b(p)earl\b/${1}erl/ig;       # Correct typos, preserving case
    print;
} continue {close ARGV if eof}

Beware that creating a backup file under a particular name when that name already exists clobbers the version previously backed up.

7.16.4. See Also

perlrun(1), and the "Switches" section of Chapter 19 of Programming Perl; the $^I and $. variables in perlvar(1), and in Chapter 28 of Programming Perl; the .. operator in the "Range Operator" sections of perlop(1) and Chapter 3 of Programming Perl

Previous | Home | Next
7.15. Modifying a File in Place with a Temporary File | Book Index | 7.17. Modifying a File in Place Without a Temporary File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.17. Modifying a File in Place Without a Temporary File

7.17.1. Problem

You need to insert, delete, or change one or more lines in a file, and you don't want to (or can't) use a temporary file.

7.17.2. Solution

Open the file in update mode ("+<"), read the whole file into an array of lines, change the array, then rewrite the file and truncate it to its current seek pointer.

open(FH, "+<", $FILE)               or die "Opening: $!";
@ARRAY = <FH>;
# change ARRAY here
seek(FH,0,0)                        or die "Seeking: $!";
print FH @ARRAY                     or die "Printing: $!";
truncate(FH,tell(FH))               or die "Truncating: $!";
close(FH)                           or die "Closing: $!";

7.17.3. Discussion

As explained in this chapter's Introduction, the operating system treats files as unstructured streams of bytes. This makes it impossible to insert, modify, or change bits of the file in place. (Except for the special case of fixed-record-length files, discussed in Recipe 8.13.) You can use a temporary file to hold the changed output, or you can read the entire file into memory, change it, and write it back out again.

Reading everything into memory is fine for small files, but doesn't scale well. Trying it on your 800 MB web server log files will either deplete your virtual memory or thrash your machine's VM system. For small files, though, this works:

open(F, "+<", $infile)      or die "can't read $infile: $!";
$out = "";
while (<F>) {
    s/DATE/localtime/eg;
    $out .= $_;
}
seek(F, 0, 0)               or die "can't seek to start of $infile: $!";
print F $out                or die "can't print to $infile: $!";
truncate(F, tell(F))        or die "can't truncate $infile: $!";
close(F)                    or die "can't close $infile: $!";

For other examples of things you can do in-place, look at the recipes in Chapter 8.

This approach is only for the truly determined. It's harder to write, takes more memory (potentially a lot more), doesn't keep a backup file, and may confuse other processes trying to read from the file you're updating. For most purposes, therefore, we suggest it's probably not worth it.

Remember to lock if you're paranoid, careful, or both.

7.17.4. See Also

The seek, truncate, open, and sysopen functions in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 7.15; Recipe 7.16; Recipe 7.18

Previous | Home | Next
7.16. Modifying a File in Place with the -i Switch | Book Index | 7.18. Locking a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.18. Locking a File

7.18.1. Problem

Many processes need to update the same file simultaneously.

7.18.2. Solution

Have all processes honor advisory locking by using flock:

use Fcntl qw(:flock);               # for the LOCK_* constants
open(FH, "+<", $path)               or die "can't open $path: $!";
flock(FH, LOCK_EX)                  or die "can't flock $path: $!";
# update file, then...
close(FH)                           or die "can't close $path: $!";

7.18.3. Discussion

Operating systems vary greatly in the type and reliability of locking techniques available. Perl tries hard to give you something that works, even if your operating system uses its own underlying technique. The flock function takes two arguments: a filehandle and a number representing what to do with the lock on that filehandle. The numbers are normally represented by names, such as LOCK_EX, which you can get from the Fcntl or IO::File modules.

Locks come in two varieties: shared (LOCK_SH) and exclusive (LOCK_EX). Despite what you might infer by "exclusive," processes aren't required to obey locks on files. Another way of saying this is that flock implements advisory locking. It allows processes to let the operating system suspend would-be writers of a file until any readers are finished with it.

Flocking files is like putting up a stoplight at an intersection. It works only if people pay attention to whether the light is red or green—or yellow for a shared lock. The red light doesn't stop traffic; it merely signals that traffic should stop. A desperate, ignorant, or rude person will still go flying through the intersection no matter what the light says. Likewise, flock only blocks out other flockers—not all processes trying to do I/O. Unless everyone is polite, accidents can (and will) happen.

The polite process customarily indicates its intent to read from the file by requesting a LOCK_SH. Many processes can have simultaneous shared locks on the file because they (presumably) won't be changing the data. If a process intends to write to the file, it should request an exclusive lock via LOCK_EX. The operating system then suspends the requesting process until all other processes have released their locks, at which point it grants the lock to the suspended process and unblocks it. You are guaranteed that no other process will be able to successfully run flock(FH, LOCK_EX) on the same file while you hold the lock.

(This is almost—but not quite—like saying there can be only one exclusive lock on the file. Forked children inherit not only their parents' open files, but, on some systems, also any locks held. That means if you hold an exclusive lock and fork without exec ing, your child might also have that same exclusive lock on the file!)

The flock function is therefore by default a blocking operation. You can also acquire a lock without wedging your process by using the LOCK_NB flag when you request a lock. This lets you warn the user that there may be a wait until other processes with locks are done:

unless (flock(FH, LOCK_EX|LOCK_NB)) {
    warn "can't immediately write-lock the file ($!), blocking ...";
    unless (flock(FH, LOCK_EX)) {
        die "can't get write-lock on numfile: $!";
    }
}

If you use LOCK_NB and are refused a LOCK_SH, then you know that someone else has a LOCK_EX and is updating the file. If you are refused a LOCK_EX, then someone holds either a LOCK_SH or a LOCK_EX, so you shouldn't try to update the file.

Locks dissolve when the file is closed, which may not be until your process exits. If you lock or unlock the file, Perl automatically flushes its buffers for you.

Here's how you increment a number in a file, using flock:

use Fcntl qw(:DEFAULT :flock);

sysopen(FH, "numfile", O_RDWR|O_CREAT)
                                    or die "can't open numfile: $!";
flock(FH, LOCK_EX)                  or die "can't write-lock numfile: $!";
# Now we have acquired the lock, it's safe for I/O
$num = <FH> || 0;                   # DO NOT USE "or" THERE!!
seek(FH, 0, 0)                      or die "can't rewind numfile : $!";
truncate(FH, 0)                     or die "can't truncate numfile: $!";
print FH $num+1, "\n"               or die "can't write numfile: $!";
close(FH)                           or die "can't close numfile: $!";

Closing the filehandle flushes the buffers and unlocks the file. The truncate function is discussed in Chapter 8.

File locking is not as easy as you might think—or wish. Because locks are advisory, if one process uses locking and another doesn't, all bets are off. Never use the existence of a file as a locking indication because there exists a race condition between the test for the existence of the file and its creation. Furthermore, because file locking is an intrinsically stateful concept, it doesn't get along well with the stateless model embraced by network filesystems such as NFS. Although some vendors claim that fcntl addresses such matters, practical experience suggests otherwise. The CPAN module File::NFSLock uses a clever scheme to obtain and release locks on files over NFS, which is different from the flock system.

Don't confuse Perl's flock with the SysV function lockf. Unlike lockf, flock locks entire files at once. Perl doesn't support lockf directly, although the CPAN module File::Lock does offer its functionality if your operating system has lockf. The only way in pure Perl to lock a portion of a file is to use the fnctl function, as demonstrated in the lockarea program at the end of this chapter.

7.18.4. See Also

The flock and fcntl functions in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard Fcntl and DB_File modules (also in Chapter 32 of Programming Perl); the documentation for the CPAN modules File::Lock and File::NFSLock; Recipe 7.24; Recipe 7.25

Previous | Home | Next
7.17. Modifying a File in Place Without a Temporary File | Book Index | 7.19. Flushing Output
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.19. Flushing Output

7.19.1. Problem

When printing to a filehandle, output doesn't appear immediately. This is a problem in CGI scripts running on some programmer-hostile web servers where, if the web server sees warnings from Perl before it sees the (buffered) output of your script, it sends the browser an uninformative 500 Server Error. These buffering problems also arise with concurrent access to files by multiple programs and when talking with devices or sockets.

7.19.2. Solution

Disable buffering by setting the per-filehandle variable $| to a true value, customarily 1:

$old_fh = select(OUTPUT_HANDLE);
$| = 1;
select($old_fh);

Or, if you don't mind the expense of loading an IO module, disable buffering by invoking the autoflush method:

use IO::Handle;
OUTPUT_HANDLE->autoflush(1);

This works with indirect filehandles as well:

use IO::Handle;
$fh->autoflush(1);

7.19.3. Discussion

In most stdio implementations, buffering varies with the type of output device. Disk files are block buffered, often with a buffer size of more than 2K. Pipes and sockets are often buffered with a buffer size between ½K and 2K. Serial devices, including terminals, modems, mice, and joysticks, are normally line-buffered; stdio sends the entire line out only when it gets the newline.

Perl's print function does not directly support truly unbuffered output, i.e., a physical write for each individual character. Instead, it supports command buffering, in which one physical write is made after every separate output command. This isn't as hard on your system as no buffering at all, and it still gets the output where you want it, when you want it.

Control output buffering through the $| special variable. Enable command buffering on output handles by setting it to a true value. This does not affect input handles at all; see Recipe 15.6 and Recipe 15.8 for unbuffered input. Set this variable to a false value to use default stdio buffering. Example 7-7 illustrates the difference.

Example 7-7. seeme

  #!/usr/bin/perl -w
  # seeme - demo stdio output buffering
  $| = (@ARGV > 0);      # command buffered if arguments given
  print "Now you don't see it...";
  sleep 2;
  print "now you do\n";

If you call this program with no arguments, STDOUT is not command buffered. Your terminal (console, window, telnet session, whatever) doesn't receive output until the entire line is completed, so you see nothing for two seconds and then get the full line "Now you don't see it ... now you do". If you call the program with at least one argument, STDOUT is command buffered. That means you first see "Now you don't see it...", and then after two seconds you finally see "now you do".

The dubious quest for increasingly compact code has led programmers to use the return value of select, the filehandle that was currently selected, as part of the second select:

select((select(OUTPUT_HANDLE), $| = 1)[0]);

There's another way. The IO::Handle module and any modules that inherit from that class provide three methods for flushing: flush, autoflush, and printflush. All are invoked on filehandles, either as literals or as variables containing a filehandle or reasonable facsimile.

The flush method causes all unwritten output in the buffer to be written out, returning true on failure and false on success. The printflush method is a print followed by a one-time flush. The autoflush method is syntactic sugar for the convoluted antics just shown. It sets the command-buffering property on that filehandle (or clears it if passed an explicit false value), and returns the previous value for that property on that handle. For example:

use FileHandle;

STDERR->autoflush;          # already unbuffered in stdio
$filehandle->autoflush(0);

If you're willing to accept the oddities of indirect object notation covered in Chapter 13, you can even write something reasonably close to English:

use IO::Handle;
# assume REMOTE_CONN is an interactive socket handle,
# but DISK_FILE is a handle to a regular file.
autoflush REMOTE_CONN  1;           # unbuffer for clarity
autoflush DISK_FILE    0;           # buffer this for speed

This avoids the bizarre select business and makes your code much more readable. Unfortunately, your program takes longer to compile because now you're including the IO::Handle module, so dozens of files need to be opened and thousands and thousands of lines must first be read and compiled. For short and simple applications, you might as well learn to manipulate $| directly, and you'll be happy. But for larger applications that already use a class derived from the IO::Handle class, you've already paid the price for the ticket, so you might as well see the show.

To ensure that your output gets where you want it, when you want it, buffer flushing is important. It's particularly important with sockets, pipes, and devices, because you may be trying to do interactive I/O with these—more so, even, because you can't assume line buffering. Consider the program in Example 7-8.

Example 7-8. getpcomidx

  #!/usr/bin/perl -w
  # getpcomidx - fetch www.perl.com's index.html document
  use IO::Socket;
  $sock = new IO::Socket::INET (PeerAddr => "www.perl.com",
                                PeerPort => "http(80)");
  die "Couldn't create socket: $@" unless $sock;
  # the library doesn't support $! setting; it uses $@
  $sock->autoflush(1);
  # Mac *must* have \015\012\015\012 instead of \n\n here.
  # It's a good idea for others, too, as that's the spec,
  # but implementations are encouraged to accept "\cJ\cJ" too,
  # and as far as we've seen, they do.
  $sock->print("GET /index.html http/1.1\n\n");
  $document = join("", $sock->getlines( ));
  print "DOC IS: $document\n";

If you're running at least v5.8 Perl, you can use the new I/O layers mechanism to force unbuffered output. This is available through the :unix layer. If the handle is already open, you can do this:

binmode(STDOUT, ":unix")
    || die "can't binmode STDOUT to :unix: $!";

or you can specify the I/O layer when initially calling open:

open(TTY, ">:unix", "/dev/tty")
    || die "can't open /dev/tty: $!";
print TTY "54321";
sleep 2;
print TTY "\n";

There's no way to control input buffering using the sorts of flushing discussed so far. For that, you need to see Recipe 15.6 and Recipe 15.8.

7.19.4. See Also

The $| entry in perlvar(1), and Chapter 28 of Programming Perl; the documentation for the standard FileHandle and IO::Handle modules (also in Chapter 32 of Programming Perl); the select function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 15.6 and Recipe 15.8

Previous | Home | Next
7.18. Locking a File | Book Index | 7.20. Doing Non-Blocking I/O
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.20. Doing Non-Blocking I/O

7.20.1. Problem

You want to read from or write to a filehandle without the system blocking your process until the program, file, socket, or device at the other end is ready. This is desired less often of regular files than of special files.

7.20.2. Solution

Open the file with sysopen, specifying the O_NONBLOCK option:

use Fcntl;
sysopen(MODEM, "/dev/cua0", O_NONBLOCK|O_RDWR)
    or die "Can't open modem: $!\n";

If you already have an open filehandle, invoke the blocking method from IO::Handle with an argument of 0:

use IO::Handle;
MODEM->blocking(0);  # assume MODEM already opened

Or use the low-level fcntl function:

use Fcntl;

$flags = "";
fcntl(HANDLE, F_GETFL, $flags)
    or die "Couldn't get flags for HANDLE : $!\n";
$flags |= O_NONBLOCK;
fcntl(HANDLE, F_SETFL, $flags)
    or die "Couldn't set flags for HANDLE: $!\n";

7.20.3. Discussion

On a disk file, when no more data can be read because you're at the end of the file, the input operation returns immediately. But suppose the filehandle in question were the user's keyboard or a network connection. In those cases, simply because there's no data there right now doesn't mean there never will be, so the input function normally doesn't return until it gets data. Sometimes, though, you don't want to wait; you want to grab whatever's there and carry on with whatever you were doing.

Once a filehandle has been set for non-blocking I/O, the sysread or syswrite calls that would otherwise block will instead return undef and set $! to EAGAIN:

use Errno;

$rv = syswrite(HANDLE, $buffer, length $buffer);
if (!defined($rv) && $!{EAGAIN}) {
    # would block
} elsif ($rv != length $buffer) {
    # incomplete write
} else {
    # successfully wrote
}

$rv = sysread(HANDLE, $buffer, $BUFSIZ);
if (!defined($rv) && $!{EAGAIN}) {
    # would block
} else {
    # successfully read $rv bytes from HANDLE
}

The O_NONBLOCK constant is part of the POSIX standard, so most machines should support it. We use the Errno module to test for the error EAGAIN. Testing $!{EAGAIN} is the same as testing whether $! = = EAGAIN.

7.20.4. See Also

The sysopen and fcntl functions in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard Errno and IO::Handle modules (also in Chapter 32 of Programming Perl); your system's open(2) and fcntl(2) manpages; Recipe 7.22; Recipe 7.21

Previous | Home | Next
7.19. Flushing Output | Book Index | 7.21. Determining the Number of Unread Bytes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.21. Determining the Number of Unread Bytes

7.21.1. Problem

You want to know how many unread bytes are available for reading from a filehandle.

7.21.2. Solution

Use the FIONREAD ioctl call:

$size = pack("L", 0);
ioctl(FH, $FIONREAD, $size)     or die "Couldn't call ioctl: $!\n";
$size = unpack("L", $size);

# $size bytes can be read

Make sure the input filehandle is unbuffered (because you've used an I/O layer like :unix on it), or use only sysread.

7.21.3. Discussion

The Perl ioctl function is a direct interface to the operating system's ioctl(2) system call. If your system doesn't have the FIONREAD request or the ioctl(2) call, you can't use this recipe. FIONREAD and the other ioctl(2) requests are numeric values normally found lurking in C include files.

Perl's h2ph tool tries to convert C include files to Perl code, which can be require d. FIONREAD ends up defined as a function in the sys/ioctl.ph file:

require "sys/ioctl.ph";

$size = pack("L", 0);
ioctl(FH, FIONREAD( ), $size)    or die "Couldn't call ioctl: $!\n";
$size = unpack("L", $size);

If h2ph wasn't installed or doesn't work for you, you can manually grep the include files:

% grep FIONREAD /usr/include/*/*
/usr/include/asm/ioctls.h:#define FIONREAD      0x541B

If you install Inline::C from CPAN, you can write a C subroutine to obtain the constant for you:

use Inline C;

$FIONREAD = get_FIONREAD( );
# ...

_ _END_ _
_ _C_ _
#include <sys/ioctl.h>

int get_FIONREAD( ) {
  return FIONREAD;
}

If all else fails, write a small C program using the editor of champions:

% cat > fionread.c
#include <sys/ioctl.h>
main( ) {
    printf("%#08x\n", FIONREAD);
}
^D
% cc -o fionread fionread.c
% ./fionread
0x4004667f

Then hardcode it, leaving porting as an exercise to your successor.

$FIONREAD = 0x4004667f;         # XXX: opsys dependent

$size = pack("L", 0);
ioctl(FH, $FIONREAD, $size)     or die "Couldn't call ioctl: $!\n";
$size = unpack("L", $size);

FIONREAD requires a filehandle connected to a stream, which means sockets, pipes, and tty devices all work, but regular files don't.

If this is too much system programming for you, try to think outside the problem. Read from the filehandle in non-blocking mode (see Recipe 7.20). Then, if you manage to read something, that's how much was there waiting to be read. If you couldn't read anything, you know there was nothing to be read. This might get you in trouble with other users (or other processes) who are using the same system, though— because it uses busy-wait I/O, it's a drain on system resources.

7.21.4. See Also

Recipe 7.20; your system's ioctl(2) manpage; the ioctl function in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the Inline::C module from CPAN

Previous | Home | Next
7.20. Doing Non-Blocking I/O | Book Index | 7.22. Reading from Many Filehandles Without Blocking
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.22. Reading from Many Filehandles Without Blocking

7.22.1. Problem

You want to learn whether input is available to be read, rather than blocking until there's input the way <FH> does. This is useful when reading from pipes, sockets, devices, and other programs.

7.22.2. Solution

Use select with a timeout value of 0 seconds if you're comfortable with manipulating bit-vectors representing file descriptor sets:

$rin = "";
# repeat next line for all filehandles to poll
vec($rin, fileno(FH1), 1) = 1;
vec($rin, fileno(FH2), 1) = 1;
vec($rin, fileno(FH3), 1) = 1;

$nfound = select($rout=$rin, undef, undef, 0);
if ($nfound) {
  # input waiting on one or more of those 3 filehandles
  if (vec($rout,fileno(FH1),1)) {
      # do something with FH1
  }
  if (vec($rout,fileno(FH2),1)) {
      # do something with FH2
  }
  if (vec($rout,fileno(FH3),1)) {
      # do something with FH3
  }
}

The IO::Select module provides an abstraction layer to hide bit-vector operations:

use IO::Select;

$select = IO::Select->new( );
# repeat next line for all filehandles to poll
$select->add(*FILEHANDLE);
if (@ready = $select->can_read(0)) {
    # input waiting on the filehandles in @ready
}

7.22.3. Discussion

The select function is really two functions in one. If you call it with one argument, you change the current default output filehandle (see Recipe 7.19). If you call it with four arguments, it tells you which filehandles have input waiting or are ready to receive output. This recipe deals only with four-argument select.

The first three arguments to select are strings containing bit-vectors. Each bit-vector represents a set of file descriptors to inspect for pending input, pending output, and pending expedited data (like out-of-band or urgent data on a socket), respectively. The final argument is the timeout—how long select should spend waiting for status to change. A timeout value of 0 indicates a poll. Timeout can also be a floating-point number of seconds, or undef to wait (block) until status changes:

$rin = "";
vec($rin, fileno(FILEHANDLE), 1) = 1;
$nfound = select($rin, undef, undef, 0);    # just check
if ($nfound) {
    # read ten bytes from FILEHANDLE
    sysread(HANDLE, $data, 10);
    print "I read $data";
}

The IO::Select module hides the bit-vectors from you. IO::Select->new( ) returns a new object on which you invoke the add method to add one or more filehandles to the set. Once you've added the filehandles you are interested in, invoke can_read, can_write, or has_exception. These methods return a list of filehandles that you can safely read from or write to, or that have unread exceptional data (TCP out-of-band data, for example).

If you want to read an entire line of data, you can't use the readline function or the <FH> line input operator (unless you use an unbuffered I/O layer). Otherwise, you'll mix a buffered I/O function with a check that ignores those buffers in user space and cares only about what's buffered in kernel space. This is a big no-no. For details on this and directions for calling sysread on whatever is available on a socket or pipe and then returning immediately, see Recipe 7.23. If you're trying to do non-blocking reads on a terminal line (that is, on a keyboard or other serial line device), see Recipe 15.6 and Recipe 15.8.

7.22.4. See Also

The select function in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard module IO::Select (also in Chapter 32 of Programming Perl); Recipe 7.20; Recipe 7.23

Previous | Home | Next
7.21. Determining the Number of Unread Bytes | Book Index | 7.23. Reading an Entire Line Without Blocking
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.23. Reading an Entire Line Without Blocking

7.23.1. Problem

You need to read a line of data from a handle that select says is ready for reading, but you can't use Perl's normal <FH> operation (readline) in conjunction with select because <FH> may buffer extra data and select doesn't know about those buffers.

7.23.2. Solution

Use the following sysreadline function, like this:

$line = sysreadline(SOME_HANDLE);

In case only a partial line has been sent, include a number of seconds to wait:

$line = sysreadline(SOME_HANDLE, TIMEOUT);

Here's the function to do that:

use IO::Handle;
use IO::Select;
use Symbol qw(qualify_to_ref);

sub sysreadline(*;$) {
    my($handle, $timeout) = @_;
    $handle = qualify_to_ref($handle, caller( ));
    my $infinitely_patient = (@_ =  = 1 || $timeout < 0);
    my $start_time = time( );
    my $selector = IO::Select->new( );
    $selector->add($handle);
    my $line = "";
SLEEP:
    until (at_eol($line)) {
        unless ($infinitely_patient) {
            return $line if time( ) > ($start_time + $timeout);
        }
        # sleep only 1 second before checking again
        next SLEEP unless $selector->can_read(1.0);
INPUT_READY:
        while ($selector->can_read(0.0)) {
            my $was_blocking = $handle->blocking(0);
CHAR:       while (sysread($handle, my $nextbyte, 1)) {
                $line .= $nextbyte;
                last CHAR if $nextbyte eq "\n";
            }
            $handle->blocking($was_blocking);
            # if incomplete line, keep trying
            next SLEEP unless at_eol($line);
            last INPUT_READY;
        }
    }
    return $line;
}
sub at_eol($) { $_[0] =~ /\n\z/ }

7.23.3. Discussion

As described in Recipe 7.22, to determine whether the operating system has data on a particular handle for your process to read, you can use either Perl's built-in select function or the can_read method from the standard IO::Select module.

Although you can reasonably use functions like sysread and recv to get data, you can't use the buffered functions like readline (that is, <FH>), read, or getc. Also, even the unbuffered input functions might still block. If someone connects and sends a character but never sends a newline, your program will block in a <FH>, which expects its input to end in a newline—or in whatever you've assigned to the $/ variable.

We circumvent this by setting the handle to non-blocking mode and then reading in characters until we find "\n". This removes the need for the blocking <FH> call. The sysreadline function in the Solution takes an optional second argument so you don't have to wait forever in case you get a partial line and nothing more.

A far more serious issue is that select reports only whether the operating system's low-level file descriptor is available for I/O. It's not reliable in the general case to mix calls to four-argument select with calls to any of the buffered I/O functions listed in this chapter's Introduction (read, <FH>, seek, tell, etc.). Instead, you must use sysread—and sysseek if you want to reposition the filehandle within the file.

The reason is that select's response does not reflect any user-level buffering in your own process's address space once the kernel has transferred the data. But the <FH>—really Perl's readline( ) function—still uses your underlying buffered I/O system. If two lines were waiting, select would report true only once. You'd read the first line and leave the second one in the buffer. But the next call to select would block because, as far as the kernel is concerned, it's already given you all of the data it had. That second line, now hidden from your kernel, sits unread in an input buffer that's solely in user space.

7.23.4. See Also

The sysread function in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard modules Symbol, IO::Handle, and IO::Select (also in Chapter 32 of Programming Perl); Recipe 7.22

Previous | Home | Next
7.22. Reading from Many Filehandles Without Blocking | Book Index | 7.24. Program: netlock
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.24. Program: netlock

When locking files, we recommend that you use flock when possible. However, on some systems, flock's locking strategy is not reliable. For example, perhaps the person who built Perl on your system configured flock to use a version of file locking that didn't even try to work over the Net, or you're on the increasingly rare system where no flock emulation exists at all.

The following program and module provide a basic implementation of a file locking mechanism. Unlike a normal flock, with this module you lock file names, not file descriptors.

Thus, you can use it to lock directories, domain sockets, and other non-regular files. You can even lock files that don't exist yet. It uses a directory created at the same level in the directory structure as the locked file, so you must be able to write to the enclosing directory of the file you wish to lock. A sentinel file within the lock directory contains the owner of the lock. This is also useful with Recipe 7.15 because you can lock the filename even though the file that has that name changes.

The nflock function takes one or two arguments. The first is the pathname to lock; the second is the optional amount of time to wait for the lock. The function returns true if the lock is granted, returns false if the timeout expired, and raises an exception should various improbable events occur, such as being unable to write the directory.

Set the $File::LockDir::Debug variable to true to make the module emit messages if it stalls waiting for a lock. If you forget to free a lock and try to exit the program, the module will remove them for you. This won't happen if your program is sent a signal it doesn't trap.

Example 7-9 shows a driver program to demonstrate the File::LockDir module.

Example 7-9. drivelock

  #!/usr/bin/perl -w
  # drivelock - demo File::LockDir module
  use strict;
  use File::LockDir;
  $SIG{INT} = sub { die "outta here\n" };
  $File::LockDir::Debug = 1;
  my $path = shift                            or die "usage: $0 <path>\n";
  unless (nflock($path, 2)) {
      die "couldn't lock $path in 2 seconds\n";
  }
  sleep 100;
  nunflock($path);

The module itself is shown in Example 7-10. For more on building your own modules, see Chapter 12.

Example 7-10. File::LockDir

  package File::LockDir;
  # module to provide very basic filename-level
  # locks.  No fancy systems calls.  In theory,
  # directory info is sync'd over NFS.  Not
  # stress tested.
  use strict;
  use Exporter;
  our (@ISA, @EXPORT);
  @ISA      = qw(Exporter);
  @EXPORT   = qw(nflock nunflock);
  our ($Debug, $Check);
  $Debug  ||= 0;  # may be predefined
  $Check  ||= 5;  # may be predefined
  use Cwd;
  use Fcntl;
  use Sys::Hostname;
  use File::Basename;
  use File::stat;
  use Carp;
  my %Locked_Files = ( );
  # usage: nflock(FILE; NAPTILL)
  sub nflock($;$) {
      my $pathname = shift;
      my $naptime  = shift || 0;
      my $lockname = name2lock($pathname);
      my $whosegot = "$lockname/owner";
      my $start    = time( );
      my $missed   = 0;
      my $owner;
      # if locking what I've already locked, return
      if ($Locked_Files{$pathname}) {
          carp "$pathname already locked";
          return 1
      }
      if (!-w dirname($pathname)) {
          croak "can't write to directory of $pathname";
      }
      while (1) {
          last if mkdir($lockname, 0777);
          confess "can't get $lockname: $!" if $missed++ > 10
                          && !-d $lockname;
          if ($Debug) {{
              open($owner, "< $whosegot") || last; # exit "if"!
              my $lockee = <$owner>;
              chomp($lockee);
              printf STDERR "%s $0\[$$]: lock on %s held by %s\n",
                  scalar(localtime), $pathname, $lockee;
              close $owner;
          }}
          sleep $Check;
          return if $naptime && time > $start+$naptime;
      }
      sysopen($owner, $whosegot, O_WRONLY|O_CREAT|O_EXCL)
            or croak "can't create $whosegot: $!";
      printf $owner "$0\[$$] on %s since %s\n",
              hostname( ), scalar(localtime);
      close($owner)
            or croak "close $whosegot: $!";
      $Locked_Files{$pathname}++;
      return 1;
  }
  # free the locked file
  sub nunflock($) {
      my $pathname = shift;
      my $lockname = name2lock($pathname);
      my $whosegot = "$lockname/owner";
      unlink($whosegot);
      carp "releasing lock on $lockname" if $Debug;
      delete $Locked_Files{$pathname};
      return rmdir($lockname);
  }
  # helper function
  sub name2lock($) {
      my $pathname = shift;
      my $dir  = dirname($pathname);
      my $file = basename($pathname);
      $dir = getcwd( ) if $dir eq ".";
      my $lockname = "$dir/$file.LOCKDIR";
      return $lockname;
  }
  # anything forgotten?
  END {
      for my $pathname (keys %Locked_Files) {
          my $lockname = name2lock($pathname);
          my $whosegot = "$lockname/owner";
          carp "releasing forgotten $lockname";
          unlink($whosegot);
          rmdir($lockname);
      }
  }
  1;
Previous | Home | Next
7.23. Reading an Entire Line Without Blocking | Book Index | 7.25. Program: lockarea
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.25. Program: lockarea

Perl's flock function only locks complete files, not regions of the file. Although fcntl supports locking of a file's regions, this is difficult to access from Perl, largely because no one has written an XS module that portably packs up the necessary structure.

The program in Example 7-11 implements fcntl, but only for the three architectures it already knows about: SunOS, BSD, and Linux. If you're running something else, you'll have to figure out the layout of the flock structure. We did this by eyeballing the C-language sys/fcntl.h #include file—and running the c2ph program to figure out alignment and typing. This program, while included with Perl, only works on systems with a strong Berkeley heritage, like those listed above. As with Unix—or Perl itself—you don't have to use c2ph, but it sure makes life easier if you can.

The struct_flock function in the lockarea program packs and unpacks in the proper format for the current architectures by consulting the $^O variable, which contains your current operating system name. There is no struct_flock function declaration. It's just aliased to the architecture-specific version. Function aliasing is discussed in Recipe 10.14.

The lockarea program opens a temporary file, clobbering any existing contents and writing a screenful (80 by 23) of blanks. Each line is the same length.

The program then forks one or more times and lets the child processes try to update the file at the same time. The first argument, N, is the number of times to fork to produce 2 ** N processes. So lockarea 1 makes two children, lockarea 2 makes four, lockarea 3 makes eight, lockarea 4 makes sixteen, etc. The more kids, the more contention for the locks.

Each process picks a random line in the file, locks that line only, and then updates it. It writes its process ID into the line, prepended with a count of how many times the line has been updated:

4: 18584 was just here

If the line was already locked, then when the lock is finally granted, that line is updated with a message telling which process was in the way of this process:

29: 24652 ZAPPED 24656

A fun demo is to run the lockarea program in the background and the rep program from Chapter 15, watching the file change. Think of it as a video game for systems programmers.

% lockarea 5 &
% rep -1 'cat /tmp/lkscreen'

When you interrupt the original parent, usually with Ctrl-C or by sending it a SIGINT from the command line, it kills all of its children by sending its entire process group a signal.

Example 7-11. lockarea

  #!/usr/bin/perl -w
    # lockarea - demo record locking with fcntl

    use strict;

    my $FORKS = shift || 1;
    my $SLEEP = shift || 1;

    use Fcntl;
    use POSIX qw(:unistd_h);
    use Errno;

    my $COLS = 80;
    my $ROWS = 23;

    # when's the last time you saw *this* mode used correctly?
    open(FH, "+> /tmp/lkscreen")            or  die $!;

    select(FH);
    $| = 1;
    select STDOUT;

    # clear screen
    for (1 .. $ROWS) {
        print FH " " x $COLS, "\n";
    }

    my $progenitor = $$;
    fork( ) while $FORKS-- > 0;

    print "hello from $$\n";

    if ($progenitor =  = $$) {
        $SIG{INT} = \&infanticide;
    } else {
        $SIG{INT} = sub { die "goodbye from $$" };
    }

    while (1) {
        my $line_num = int rand($ROWS);
        my $line;
        my $n;

        # move to line
        seek(FH, $n = $line_num * ($COLS+1), SEEK_SET)              or next;

        # get lock
        my $place = tell(FH);
        my $him;
        next unless defined($him = lockplace(*FH, $place, $COLS));

        # read line
        read(FH, $line, $COLS) =  = $COLS                             or next;
        my $count = ($line =~ /(\d+)/) ? $1 : 0;
        $count++;

        # update line
        seek(FH, $place, 0)                                         or die $!;
        my $update = sprintf($him
                          ? "%6d: %d ZAPPED %d"
                          : "%6d: %d was just here",
                      $count, $$, $him);
        my $start = int(rand($COLS - length($update)));
        die "XXX" if $start + length($update) > $COLS;
        printf FH "%*.*s\n", -$COLS, $COLS, " " x $start . $update;

        # release lock and go to sleep
        unlockplace(*FH, $place, $COLS);
        sleep $SLEEP if $SLEEP;
    }
    die "NOT REACHED";                              # just in case

    # lock($handle, $offset, $timeout) - get an fcntl lock
        sub lockplace {
        my ($fh, $start, $till) = @_;
        ##print "$$: Locking $start, $till\n";
        my $lock = struct_flock(F_WRLCK, SEEK_SET, $start, $till, 0);
        my $blocker = 0;
        unless (fcntl($fh, F_SETLK, $lock)) {
            die "F_SETLK $$ @_: $!" unless $!{EAGAIN} || $!{EDEADLK};
            fcntl($fh, F_GETLK, $lock)          or die "F_GETLK $$ @_: $!";
            $blocker = (struct_flock($lock))[-1];
            ##print "lock $$ @_: waiting for $blocker\n";
            $lock = struct_flock(F_WRLCK, SEEK_SET, $start, $till, 0);
            unless (fcntl($fh, F_SETLKW, $lock)) {
                warn "F_SETLKW $$ @_: $!\n";
                return;  # undef
            }
        }
        return $blocker;
        }

    # unlock($handle, $offset, $timeout) - release an fcntl lock
    sub unlockplace {
        my ($fh, $start, $till) = @_;
        ##print "$$: Unlocking $start, $till\n";
        my $lock = struct_flock(F_UNLCK, SEEK_SET, $start, $till, 0);
        fcntl($fh, F_SETLK, $lock) or die "F_UNLCK $$ @_: $!";
    }

    # OS-dependent flock structures

    # Linux struct flock
    #   short l_type;
    #   short l_whence;
    #   off_t l_start;
    #   off_t l_len;
    #   pid_t l_pid;
    BEGIN {
          # c2ph says: typedef='s2 l2 i', sizeof=16
          my $FLOCK_STRUCT = "s s l l i";

          sub linux_flock {
              if (wantarray) {
                  my ($type, $whence, $start, $len, $pid) =
                      unpack($FLOCK_STRUCT, $_[0]);
                  return ($type, $whence, $start, $len, $pid);
              } else {
                  my ($type, $whence, $start, $len, $pid) = @_;
                  return pack($FLOCK_STRUCT,
                          $type, $whence, $start, $len, $pid);
              }
          }

    }

    # SunOS struct flock:
    #   short   l_type;         /* F_RDLCK, F_WRLCK, or F_UNLCK */
    #   short   l_whence;       /* flag to choose starting offset */
    #   long    l_start;        /* relative offset, in bytes */
    #   long    l_len;          /* length, in bytes; 0 means lock to EOF */
    #   short   l_pid;          /* returned with F_GETLK */
    #   short   l_xxx;          /* reserved for future use */
    BEGIN {
          # c2ph says: typedef='s2 l2 s2', sizeof=16
          my $FLOCK_STRUCT = "s s l l s s";

          sub sunos_flock {
              if (wantarray) {
                  my ($type, $whence, $start, $len, $pid, $xxx) =
                      unpack($FLOCK_STRUCT, $_[0]);
                  return ($type, $whence, $start, $len, $pid);
              } else {
                  my ($type, $whence, $start, $len, $pid) = @_;
                  return pack($FLOCK_STRUCT,
                          $type, $whence, $start, $len, $pid, 0);
              }
          }

    }

    # (Free)BSD struct flock:
    #   off_t   l_start;        /* starting offset */
    #   off_t   l_len;          /* len = 0 means until end-of-file */
    #   pid_t   l_pid;          /* lock owner */
    #   short   l_type;         /* lock type: read/write, etc. */
    #   short   l_whence;       /* type of l_start */
    BEGIN {
          # c2ph says: typedef="q2 i s2", size=24
          my $FLOCK_STRUCT = "ll ll i s s";   # XXX: q is ll

          sub bsd_flock {
              if (wantarray) {
                  my ($xxstart, $start, $xxlen, $len, $pid, $type, $whence) =
                      unpack($FLOCK_STRUCT, $_[0]);
                  return ($type, $whence, $start, $len, $pid);
              } else {
                  my ($type, $whence, $start, $len, $pid) = @_;
                  my ($xxstart, $xxlen) = (0,0);
                  return pack($FLOCK_STRUCT,
                      $xxstart, $start, $xxlen, $len, $pid, $type, $whence);
              }
          }
    }

    # alias the fcntl structure at compile time
    BEGIN {
          for ($^O) {
              *struct_flock =                do                           {

                                      /bsd/  &&  \&bsd_flock
                                             ||
                                  /linux/    &&    \&linux_flock
                                             ||
                                /sunos/      &&      \&sunos_flock
                                             ||
                        die "unknown operating system $^O, bailing out";
              };
          }
    }

    # install signal handler for children
    BEGIN {
          my $called = 0;

          sub infanticide {
              exit if $called++;
              print "$$: Time to die, kiddies.\n" if $$ =  = $progenitor;
              my $job = getpgrp( );
              $SIG{INT} = "IGNORE";
              kill -2, $job if $job;  # killpg(SIGINT, job)
              1 while wait > 0;
              print "$$: My turn\n" if $$ =  = $progenitor;
              exit;
          }

    }

    END { &infanticide }
Previous | Home | Next
7.24. Program: netlock | Book Index | 8. File Contents
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 8. File Contents

Contents:

Introduction
Reading Lines with Continuation Characters
Counting Lines (or Paragraphs or Records) in a File
Processing Every Word in a File
Reading a File Backward by Line or Paragraph
Trailing a Growing File
Picking a Random Line from a File
Randomizing All Lines
Reading a Particular Line in a File
Processing Variable-Length Text Fields
Removing the Last Line of a File
Processing Binary Files
Using Random-Access I/O
Updating a Random-Access File
Reading a String from a Binary File
Reading Fixed-Length Records
Reading Configuration Files
Testing a File for Trustworthiness
Treating a File as an Array
Setting the Default I/O Layers
Reading or Writing Unicode from a Filehandle
Converting Microsoft Text Files into Unicode
Comparing the Contents of Two Files
Pretending a String Is a File
Program: tailwtmp
Program: tctee
Program: laston
Program: Flat File Indexes

Mike O'Dell, only half jokingly

The most brilliant decision in all of Unix was the choice of a single character for the newline sequence.

8.0. Introduction

Before the Unix Revolution, every kind of data source and destination was inherently different. Getting two programs merely to understand each other required heavy wizardry and the occasional sacrifice of a virgin stack of punch cards to an itinerant mainframe repairman. This computational Tower of Babel made programmers dream of quitting the field to take up a less painful hobby, like autoflagellation.

These days, such cruel and unusual programming is largely behind us. Modern operating systems work hard to provide the illusion that I/O devices, network connections, process control information, other programs, the system console, and even users' terminals are all abstract streams of bytes called files. This lets you easily write programs that don't care where their input came from or where their output goes.

Because programs read and write streams of simple text, every program can communicate with every other program. It is difficult to overstate the power and elegance of this approach. No longer dependent upon troglodyte gnomes with secret tomes of JCL (or COM) incantations, users can now create custom tools from smaller ones by using simple command-line I/O redirection, pipelines, and backticks.

8.0.1 Basic Operations

Treating files as unstructured byte streams necessarily governs what you can do with them. You can read and write sequential, fixed-size blocks of data at any location in the file, increasing its size if you write past the current end. Perl uses an I/O library that emulates C's stdio(3) to implement reading and writing of variable-length records like lines, paragraphs, and words.

What can't you do to an unstructured file? Because you can't insert or delete bytes anywhere but at end-of-file, you can't easily change the length of, insert, or delete records. An exception is the last record, which you can delete by truncating the file to the end of the previous record. For other modifications, you need to use a temporary file or work with a copy of the file in memory. If you need to do this a lot, a database system may be a better solution than a raw file (see Chapter 14). Standard with Perl as of v5.8 is the Tie::File module, which offers an array interface to files of records. We use it in Recipe 8.4.

The most common files are text files, and the most common operations on text files are reading and writing lines. Use the line-input operator, <FH> (or the internal function implementing it, readline), to read lines, and use print to write them. These functions can also read or write any record that has a specific record separator. Lines are simply variable-length records that end in "\n".

The <FH> operator returns undef on error or when end of the file is reached, so use it in loops like this:

while (defined ($line = <DATAFILE>)) {
    chomp $line;
    $size = length($line);
    print "$size\n";                # output size of line
}

Because this operation is extremely common in Perl programs that process lines of text, and that's an awful lot to type, Perl conveniently provides some shorter aliases for it. If all shortcuts are taken, this notation might be too abstract for the uninitiated to guess what it's really doing. But it's an idiom you'll see thousands of times in Perl, so you'll soon get used to it. Here are increasingly shortened forms, where the first line is the completely spelled-out version:

while (defined ($line = <DATAFILE>))       { ... }
while ($line = <DATAFILE>)                 { ... }
while (<DATAFILE>)                         { ... }

In the second line, the explicit defined test needed for detecting end-of-file is omitted. To make everyone's life easier, you're safe to skip that defined test, because when the Perl compiler detects this situation, it helpfully puts one there for you to guarantee your program's correctness in odd cases. This implicit addition of a defined occurs on all while tests that do nothing but assign to one scalar variable the result of calling readline, readdir, or readlink. As <FH> is just shorthand for readline(FH), it also counts.

We're not quite done shortening up yet. As the third line shows, you can also omit the variable assignment completely, leaving just the line input operator in the while test. When you do that here in a while test, it doesn't simply discard the line it just read as it would anywhere else. Instead, it reads lines into the special global variable $_. Because so many other operations in Perl also default to $_, this is more useful than it might initially appear.

while (<DATAFILE>) {
    chomp;
    print length( ), "\n";             # output size of line
}

In scalar context, <FH> reads just the next line, but in list context, it reads all remaining lines:

@lines = <DATAFILE>;

Each time <FH> reads a record from a filehandle, it increments the special variable $. (the "current input record number"). This variable is reset only when close is called explicitly, which means that it's not reset when you reopen an already opened filehandle.

Another special variable is $/, the input record separator. It is set to "\n" by default. You can set it to any string you like; for instance, "\0" to read null-terminated records. Read entire paragraphs by setting $/ to the empty string, "". This is almost like setting $/ to "\n\n", in that empty lines function as record separators. However, "" treats two or more consecutive empty lines as a single record separator, whereas "\n\n" returns empty records when more than two consecutive empty lines are read. Undefine $/ to read the rest of the file as one scalar:

undef $/;
$whole_file = <FILE>;               # "slurp" mode

The -0 option to Perl lets you set $/ from the command line:

% perl -040 -e '$word = <>; print "First word is $word\n";'

The digits after -0 are the octal value of the single character to which $/ is to be set. If you specify an illegal value (e.g., with -0777), Perl will set $/ to undef. If you specify -00, Perl will set $/ to "". The limit of a single octal value means you can't set $/ to a multibyte string; for instance, "%%\n" to read fortune files. Instead, you must use a BEGIN block:

% perl -ne 'BEGIN { $/="%%\n" } chomp; print if /Unix/i' fortune.dat

Use print to write a line or any other data. The print function writes its arguments one after another and doesn't automatically add a line or record terminator by default.

print HANDLE "One", "two", "three"; # "Onetwothree"
print "Baa baa black sheep.\n";     # Sent to default output handle

There is no comma between the filehandle and the data to print. If you put a comma in there, Perl gives the error message "No comma allowed after filehandle". The default output handle is STDOUT. Change it with the select function. (See the Introduction to Chapter 7.)

8.0.2. Newlines

All systems use the virtual "\n" to represent a line terminator, called a newline. There is no such thing as a newline character; it is a platform-independent way of saying "whatever your string library uses to represent a line terminator." On Unix, VMS, and Windows, this line terminator in strings is "\cJ" (the Ctrl-J character). Versions of the old Macintosh operating system before Mac OS X used "\cM". As a Unix variant, Mac OS X uses "\cJ".

Operating systems also vary in how they store newlines in files. Unix also uses "\cJ" for this. On Windows, though, lines in a text file end in "\cM\cJ". If your I/O library knows you are reading or writing a text file, it will automatically translate between the string line terminator and the file line terminator. So on Windows, you could read four bytes ("Hi\cM\cJ") from disk and end up with three in memory ("Hi\cJ" where "\cJ" is the physical representation of the newline character). This is never a problem on Unix, as no translation needs to happen between the disk's newline ("\cJ") and the string's newline ("\cJ").

Terminals, of course, are a different kettle of fish. Except when you're in raw mode (as in system("stty raw")), the Enter key generates a "\cM" (carriage return) character. This is then translated by the terminal driver into a "\n" for your program. When you print a line to a terminal, the terminal driver notices the "\n" newline character (whatever it might be on your platform) and turns it into the "\cM\cJ" (carriage return, line feed) sequence that moves the cursor to the start of the line and down one line.

Even network protocols have their own expectations. Most protocols prefer to receive and send "\cM\cJ" as the line terminator, but many servers also accept merely a "\cJ". This varies between protocols and servers, so check the documentation closely!

The important notion here is that if the I/O library thinks you are working with a text file, it may be translating sequences of bytes for you. This is a problem in two situations: when your file is not text (e.g., you're reading a JPEG file) and when your file is text but not in a byte-oriented ASCII-like encoding (e.g., UTF-8 or any of the other encodings the world uses to represent their characters). As if this weren't bad enough, some systems (again, MS-DOS is an example) use a particular byte sequence in a text file to indicate end-of-file. An I/O library that knows about text files on such a platform will indicate EOF when that byte sequence is read.

Recipe 8.11 shows how to disable any translation that your I/O library might be doing.

8.0.3. I/O Layers

With v5.8, Perl I/O operations are no longer simply wrappers on top of stdio. Perl now has a flexible system (I/O layers) that transparently filters multiple encodings of external data. In Chapter 7 we met the :unix layer, which implements unbuffered I/O. There are also layers for using your platform's stdio (:stdio) and Perl's portable stdio implementation (:perlio), both of which buffer input and output. In this chapter, these implementation layers don't interest us as much as the encoding layers built on top of them.

The :crlf layer converts a carriage return and line feed (CRLF, "\cM\cJ") to "\n" when reading from a file, and converts "\n" to CRLF when writing. The opposite of :crlf is :raw, which makes it safe to read or write binary data from the filehandle. You can specify that a filehandle contains UTF-8 data with :utf8, or specify an encoding with :encoding(...). You can even write your own filter in Perl that processes data being read before your program gets it, or processes data being written before it is sent to the device.

It's worth emphasizing: to disable :crlf, specify the :raw layer. The :bytes layer is sometimes misunderstood to be the opposite of :crlf, but they do completely different things. The former refers to the UTF-8ness of strings, and the latter to the behind-the-scenes conversion of carriage returns and line feeds.

You may specify I/O layers when you open the file:

open($fh, "<:raw:utf8", $filename);                  # read UTF-8 from the file
open($fh, "<:encoding(shiftjis)", $filename);        # shiftjis japanese encoding
open(FH,  "+<:crlf", $filename);                     # convert between CRLF and \n

Or you may use binmode to change the layers of an existing handle:

binmode($fh, ":raw:utf8");
binmode($fh, ":raw:encoding(shiftjis)");
binmode(FH,  "<:raw:crlf");

Because binmode pushes onto the stack of I/O layers, and the facility for removing layers is still evolving, you should always specify a complete set of layers by making the first layer be :raw as follows:

binmode(HANDLE, ":raw");                     # binary-safe
binmode(HANDLE);                             # same as :raw
binmode(HANDLE, ":raw :utf8");               # read/write UTF-8
binmode(HANDLE, ":raw :encoding(shiftjis)"); # read/write shiftjis

Recipe 8.18, Recipe 8.19, and Recipe 8.20 show how to manipulate I/O layers.

8.0.4. Advanced Operations

Use the read function to read a fixed-length record. It takes three arguments: a filehandle, a scalar variable, and the number of characters to read. It returns undef if an error occurred or else returns the number of characters read.

$rv = read(HANDLE, $buffer, 4096)
        or die "Couldn't read from HANDLE : $!\n";
# $rv is the number of bytes read,
# $buffer holds the data read

To write a fixed-length record, just use print.

The truncate function changes the length (in bytes) of a file, which can be specified as a filehandle or as a filename. It returns true if the file was successfully truncated, false otherwise:

truncate(HANDLE, $length)           or die "Couldn't truncate: $!\n";
truncate("/tmp/$$.pid", $length)    or die "Couldn't truncate: $!\n";

Each filehandle keeps track of where it is in the file. Reads and writes occur from this point, unless you've specified the O_APPEND flag (see Recipe 7.1). Fetch the file position for a filehandle with tell, and set it with seek. Because the library rewrites data to preserve the illusion that "\n" is the line terminator, and also because you might be using characters with code points above 255 and therefore requiring a multibyte encoding, you cannot portably seek to offsets calculated simply by counting characters. Unless you can guarantee your file uses one byte per character, seek only to offsets returned by tell.

$pos = tell(DATAFILE);
print "I'm $pos bytes from the start of DATAFILE.\n";

The seek function takes three arguments: the filehandle, the offset (in bytes) to go to, and a numeric argument indicating how to interpret the offset. 0 indicates an offset from the start of the file (like the value returned by tell); 1, an offset from the current location (a negative number means move backward in the file, a positive number means move forward); and 2, an offset from end-of-file.

seek(LOGFILE, 0, 2)         or die "Couldn't seek to the end: $!\n";
seek(DATAFILE, $pos, 0)     or die "Couldn't seek to $pos: $!\n";
seek(OUT, -20, 1)           or die "Couldn't seek back 20 bytes: $!\n";

So far we've been describing buffered I/O. That is, readline or <FH>, print, read, seek, and tell are all operations that use buffering for speed and efficiency. This is their default behavior, although if you've specified an unbuffered I/O layer for that handle, they won't be buffered. Perl also provides an alternate set of I/O operations guaranteed to be unbuffered no matter what I/O layer is associated with the handle. These are sysread, syswrite, and sysseek, all discussed in Chapter 7.

The sysread and syswrite functions are different in appearance from their <FH> and print counterparts. Both take a filehandle to act on: a scalar variable to either read into or write out from, and the number of characters to transfer. (With binary data, this is the number of bytes, not characters.) They also accept an optional fourth argument, the offset from the start of the scalar variable at which to start reading or writing:

$written = syswrite(DATAFILE, $mystring, length($mystring));
die "syswrite failed: $!\n" unless $written =  = length($mystring);
$read = sysread(INFILE, $block, 256, 5);
warn "only read $read bytes, not 256" if 256 != $read;

The syswrite call sends the contents of $mystring to DATAFILE. The sysread call reads 256 characters from INFILE and stores 5 characters into $block, leaving intact the 5 characters it skipped. Both sysread and syswrite return the number of characters transferred, which could be different than the amount of data you were attempting to transfer. Maybe the file didn't have as much data as you thought, so you got a short read. Maybe the filesystem that the file lives on filled up. Maybe your process was interrupted partway through the write. Stdio takes care of finishing the transfer in cases of interruption, but if you use raw sysread and syswrite calls, you must finish up yourself. See Recipe 9.3 for an example.

The sysseek function doubles as an unbuffered replacement for both seek and tell. It takes the same arguments as seek, but it returns the new position on success and undef on error. To find the current position within the file:

$pos = sysseek(HANDLE, 0, 1);       # don't change position
die "Couldn't sysseek: $!\n" unless defined $pos;

These are the basic operations available to you. The art and craft of programming lies in using these basic operations to solve complex problems such as finding the number of lines in a file, reversing lines in a file, randomly selecting a line from a file, building an index for a file, and so on.

Previous | Home | Next
7.25. Program: lockarea | Book Index | 8.1. Reading Lines with Continuation Characters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.1. Reading Lines with Continuation Characters

8.1.1. Problem

You have a file with long lines split over two or more lines, with backslashes to indicate that a continuation line follows. You want to rejoin those split lines. Makefiles, shell scripts, and many other scripting or configuration languages let you break a long line into several shorter ones in this fashion.

8.1.2. Solution

Build up the complete lines one at a time until reaching one without a backslash:

while (defined($line = <FH>) ) {
    chomp $line;
    if ($line =~ s/\\$//) {
        $line .= <FH>;
        redo unless eof(FH);
    }
    # process full record in $line here
}

8.1.3. Discussion

Here's an example input file:

DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \
        $(TEXINFOS) $(INFOS) $(MANS) $(DATA)
DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \
        $(TEXINFOS) $(INFO_DEPS) $(MANS) $(DATA) \
        $(EXTRA_DIST)

You'd like to process that file a record at a time with the escaped newlines ignored. The first record would then be the first two lines, the second record the next three lines, etc.

Here's how the algorithm works. The while loop reads lines one at a time. The substitution operator s/// tries to remove a trailing backslash. If the substitution fails, we've found a line without a backslash at the end. Otherwise, read another record, concatenate it onto the accumulating $line variable, and use redo to jump back to just inside the opening brace of the while loop. This lands us back on the chomp.

A frequent problem with files intended to be in this format arises when unnoticed spaces or tabs follow the backslash before the newline. The substitution that found continuation lines would be more forgiving if written this way:

if ($line =~ s/\\\s*$//) {
    # as before
}

Unfortunately, even if your program is forgiving, surely others will not be. Remember to be liberal in what you accept, but conservative in what you produce.

8.1.4. See Also

The chomp function in perlfunc(1) and in Chapter 29 of Programming Perl; the redo keyword in the "Loop Control" sections of perlsyn(1) and Chapter 4 of Programming Perl

Previous | Home | Next
8. File Contents | Book Index | 8.2. Counting Lines (or Paragraphs or Records) in a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.2. Counting Lines (or Paragraphs or Records) in a File

8.2.1. Problem

You need to compute the number of lines in a file.

8.2.2. Solution

Many systems have a wc program to count lines in a file:

$count = `wc -l < $file`;
die "wc failed: $?" if $?;
chomp($count);

You could also open the file and read line-by-line until the end, counting lines as you go:

open(FILE, "<", $file) or die "can't open $file: $!";
$count++ while <FILE>;
# $count now holds the number of lines read

Here's the fastest solution, assuming your line terminator really is "\n":

$count += tr/\n/\n/ while sysread(FILE, $_, 2 ** 20);

8.2.3. Discussion

Although you can use -s $file to determine the file size in bytes, you generally cannot use it to derive a line count. See the Introduction in Chapter 9 for more on -s.

If you can't or don't want to call another program to do your dirty work, you can emulate wc by opening up and reading the file yourself:

open(FILE, "<", $file) or die "can't open $file: $!";
$count++ while <FILE>;
# $count now holds the number of lines read

Another way of writing this is:

open(FILE, "<", $file) or die "can't open $file: $!";
for ($count=0; <FILE>; $count++) { }

If you're not reading from any other files, you don't need the $count variable in this case. The special variable $. holds the number of lines read since a filehandle was last explicitly close d:

1 while <FILE>;
$count = $.;

This reads in all records in the file, then discards them.

To count paragraphs, set the global input record separator variable $/ to the empty string ("") before reading to make the input operator (<FH>) read a paragraph at a time.

$/ = "";            # enable paragraph mode for all reads
open(FILE, "<", $file) or die "can't open $file: $!";
1 while <FILE>;
$para_count = $.;

The sysread solution reads the file a megabyte at a time. Once end-of-file is reached, sysread returns 0. This ends the loop, as does undef, which would indicate an error. The tr operation doesn't really substitute \n for \n in the string; it's an old idiom for counting occurrences of a character in a string.

8.2.4. See Also

The tr operator in perlop(1) and Chapter 5 of Programming Perl; your system's wc(1) manpage; the $/ entry in perlvar(1), and in the "Special Variables in Alphabetical Order" section of Chapter 28 of Programming Perl; the Introduction to Chapter 9

Previous | Home | Next
8.1. Reading Lines with Continuation Characters | Book Index | 8.3. Processing Every Word in a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.3. Processing Every Word in a File

8.3.1. Problem

You need to do something to every word in a file, similar to the foreach function of csh.

8.3.2. Solution

Either split each line on whitespace:

while (<>) {
    for $chunk (split) {
        # do something with $chunk
    }
}

or use the m//g operator to pull out one chunk at a time:

while (<>) {
    while ( /(\w[\w'-]*)/g ) {
        # do something with $1
    }
}

8.3.3. Discussion

Decide what you mean by "word." Sometimes you want anything but whitespace, sometimes you want only program identifiers, and sometimes you want English words. Your definition governs which regular expression to use.

The preceding two approaches work differently. Patterns are used in the first approach to decide what is not a word. In the second, they're used to decide what is a word.

With these techniques, it's easy to make a word frequency counter. Use a hash to store how many times each word has been seen:

# Make a word frequency count
%seen = ( );
while (<>) {
    while ( /(\w[\w'-]*)/g ) {
        $seen{lc $1}++;
    }
}

# output hash in a descending numeric sort of its values
foreach $word ( sort { $seen{$b} <=> $seen{$a} } keys %seen) {
    printf "%5d %s\n", $seen{$word}, $word;
}

To make the example program count line frequency instead of word frequency, omit the second while loop and use $seen{lc $_}++ instead:

# Line frequency count
%seen = ( );
while (<>) {
    $seen{lc $_}++;
}
foreach $line ( sort { $seen{$b} <=> $seen{$a} } keys %seen ) {
    printf "%5d %s", $seen{$line}, $line;
}

Odd things that may need to be considered as words include "M.I.T.", "Micro$oft", "o'clock", "49ers", "street-wise", "and/or", "&", "c/o", "St.", "Tschüß", and "Niño". Bear this in mind when you choose a pattern to match. The last two require you to place a use locale in your program and then use \w for a word character in the current locale, or else use the Unicode letter property if you have Unicode text:

/(\p{Letter}[\p{Letter}'-]*)/

8.3.4. See Also

perlre(1); the split function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 6.3; Recipe 6.23

Previous | Home | Next
8.2. Counting Lines (or Paragraphs or Records) in a File | Book Index | 8.4. Reading a File Backward by Line or Paragraph
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.4. Reading a File Backward by Line or Paragraph

8.4.1. Problem

You want to process each line or paragraph of a text file in reverse.

8.4.2. Solution

Read all lines into an array, then process that array from the end to the start:

@lines = <FILE>;
while ($line = pop @lines) {
    # do something with $line
}

Or store an array of lines in reverse order:

@lines = reverse <FILE>;
foreach $line (@lines) {
    # do something with $line
}

Or use the Tie::File module (standard as of v5.8):

use Tie::File;
tie(@lines, "Tie::File", $FILENAME, mode => 0)
    or die "Can't tie $FILENAME: $!";
$max_lines = $#lines;
for ($i = $max_lines; $i; $i--) {
    # do something with $lines[$i], eg line number them:
    printf "%5d  %s\n", $i+1, $lines[$i],
}

8.4.3. Discussion

The limitations of file access mentioned in this chapter's Introduction prevent reading a line at a time starting from the end. You must read the lines into memory, then process them in reverse order. This requires at least as much available memory as the size of the file, unless you use tricks like Tie::File does.

The first technique moves through the array of lines in reverse order. This destructively processes the array, popping an element off the end of the array each time through the loop. We could do it non-destructively with:

for ($i = $#lines; $i != -1; $i--) {
    $line = $lines[$i];
}

The second approach generates an array of lines already in reverse order. This array can then be processed non-destructively. We get the reversed lines because the assignment to @lines confers list context on the return from reverse, and reverse confers list context on its argument of <FILE>, which returns a list of all lines in the file.

These approaches are easily extended to paragraphs just by changing $/:

# this enclosing block keeps local $/ temporary
{
    local $/ = "";
    @paragraphs = reverse <FILE>;
}

foreach $paragraph (@paragraphs) {
    # do something
}

The Tie::File module lets you treat the file as an array of lines. The solution then becomes simply iterating through the array a line at a time from the end back to the start. It's much slower than reading everything into memory and reversing it, but works on files too big to fit into memory all at once. Be careful, though: Tie::File will rewrite the file if you change the contents of the tied @lines, so don't do that. In our example, assigning @lines = reverse(@lines) would reverse the file on disk! By opening the file with mode O_RDONLY (0), you can avoid that possibility. The default mode is O_RDWR | O_CREAT. Also, Tie::File cannot emulate the paragraph semantics of setting $/ to the empty string ("").

8.4.4. See Also

The reverse function in perlfunc(1) and in Chapter 29 of Programming Perl; the $/ entry in perlvar(1), and in Chapter 28 of Programming Perl; the documentation for the standard Tie::File module; Recipe 4.11; Recipe 1.7

Previous | Home | Next
8.3. Processing Every Word in a File | Book Index | 8.5. Trailing a Growing File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.5. Trailing a Growing File

8.5.1. Problem

You want to read from a continually growing file, but the read fails when you reach the current end-of-file.

8.5.2. Solution

Read until end-of-file. Sleep, clear the EOF flag, and read some more. Repeat until interrupted. To clear the EOF flag, either use seek:

for (;;) {
    while (<FH>) { .... }
    sleep $SOMETIME;
    seek(FH, 0, 1);
}

or use the IO::Handle module's clearerr method:

use IO::Handle;

for (;;) {
    while (<FH>) { .... }
    sleep $SOMETIME;
    FH->clearerr( );
}

8.5.3. Discussion

When you read until end-of-file, an internal flag is set that prevents further reading. The most direct way to clear this flag is the clearerr method, if supported: it's in the IO::Handle modules.

$naptime = 1;

use IO::Handle;
open (LOGFILE, "/tmp/logfile") or die "can't open /tmp/logfile: $!";
for (;;) {
    while (<LOGFILE>) { print }     # or appropriate processing
    sleep $naptime;
    LOGFILE->clearerr( );            # clear stdio error flag
}

Because Perl v5.8 ships with its own stdio implementation, that simple approach should almost always work. On the rare system where it doesn't work, you may need to use seek. The seek code given in the Solution tries to move zero bytes from the current position, which nearly always works. It doesn't change the current position, but it should clear the end-of-file condition on the handle so that the next <LOGFILE> operation picks up new data.

If that still doesn't work, perhaps because it relies on features of your I/O implementation, you may need to use the following seek code, which remembers the old file position explicitly and returns there directly.

for (;;) {
    for ($curpos = tell(LOGFILE); <LOGFILE>; $curpos = tell(LOGFILE)) {
        # process $_ here
    }
    sleep $naptime;
    seek(LOGFILE, $curpos, 0);  # seek to where we had been
}

On some kinds of filesystems, the file could be removed while you are reading it. If so, there's probably little reason to continue checking whether it grows. To make the program exit in that case, stat the handle and make sure its link count (the third field in the return list) hasn't gone to 0:

exit if (stat(LOGFILE))[3] =  = 0

If you're using the File::stat module, you could write that more readably as:

use File::stat;
exit if stat(*LOGFILE)->nlink =  = 0;

The CPAN module File::Tail lets you tie a filehandle so that the read operation blocks at the end of the file until more data is available:

use File::Tail;

tie *FH, "File::Tail", (name => $FILENAME);
while (<FH>) {
  # do something with line read
}

The <FH> operator in this case never returns undef to indicate end-of-file.

8.5.4. See Also

The seek and tell functions in perlfunc(1) and in Chapter 29 of Programming Perl; your system's tail(1) and stdio(3) manpages; the documentation for the standard File::stat module (also in Chapter 32 of Programming Perl); the documentation for the CPAN module File::Tail

Previous | Home | Next
8.4. Reading a File Backward by Line or Paragraph | Book Index | 8.6. Picking a Random Line from a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.6. Picking a Random Line from a File

8.6.1. Problem

You want to return a random line from a file.

8.6.2. Solution

Use rand and $. (the current line number) to decide which line to print:

srand;
rand($.) < 1 && ($line = $_) while <>;
# $line is the random line

8.6.3. Discussion

This is a beautiful example of a solution that may not be obvious. We read every line in the file but don't have to store them all in memory. This is great for large files. Each line has a 1 in N (where N is the number of lines read so far) chance of being selected.

Here's a replacement for fortune using this algorithm:

$/ = "%%\n";
@ARGV = ("/usr/share/games/fortunes") unless @ARGV;
srand;
rand($.) < 1 && ($adage = $_) while <>;
print $adage;

If you know line offsets (for instance, you've created an index) and the number of lines, you can randomly select a line and jump to its offset in the file, but you usually don't have such an index.

Here's a more rigorous explanation of how the algorithm works. The function call rand ($.) picks a random number between 0 and the current line number. Therefore, you have a one in N chance, that is, Figure , of keeping the Nth line. Therefore you've a 100% chance of keeping the first line, a 50% chance of keeping the second, a 33% chance of keeping the third, and so on. The question is whether this is fair for all N, where N is any positive integer.

First, some concrete examples, then abstract ones.

Obviously, a file with one line (N=1) is fair: you always keep the first line because Figure = 100%, making it fair for files of 1 line. For a file with two lines, N=2. You always keep the first line; then when reaching the second line, you have a 50% chance of keeping it. Thus, both lines have an equal chance of being selected, which shows that N=2 is fair. For a file with three lines, N=3. You have a one-third chance, 33%, of keeping that third line. That leaves a two-thirds chance of retaining one of the first two out of the three lines. But we've already shown that for those first two lines there's a 50-50 chance of selecting either one. 50 percent of two-thirds is one-third. Thus, you have a one-third chance of selecting each of the three lines of the file.

In the general case, a file of N+1 lines will choose the last line Figure times and one of the previous N lines Figure times. Dividing Figure by N leaves us with Figure for each the first N lines in our N+1 line file, and also Figure for line number N+1. The algorithm is therefore fair for all N, where N is a positive integer.

We've managed to fairly choose a random line from a file with speed directly proportional to the size of the file, but using no more memory than it takes to hold the longest line, even in the worst case.

8.6.4. See Also

The $. entry in perlvar(1) and in Chapter 28 of Programming Perl; Recipe 2.6; Recipe 2.7

Previous | Home | Next
8.5. Trailing a Growing File | Book Index | 8.7. Randomizing All Lines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.7. Randomizing All Lines

8.7.1. Problem

You want to copy a file and randomly reorder its lines.

8.7.2. Solution

Read all lines into an array, shuffle the array using List::Util's shuffle function, and write the shuffled lines back out:

use List::Util qw(shuffle);

while (<INPUT>) {
    push(@lines, $_);
}
@lines = shuffle(@lines);
foreach (@reordered) {
    print OUTPUT $_;
}

8.7.3. Discussion

The easiest approach is to read all lines into memory and shuffle them there. Because you don't know where lines start in the file, you can't just shuffle a list of line numbers and then extract lines in the order they'll appear in the shuffled file. Even if you did know the byte offsets of the start of each line, it would probably still be slower because you'd be seek ing around in the file instead of sequentially reading it from start to finish.

If you have a version of Perl older than v5.8, you can download the List::Util module from CPAN.

8.7.4. See Also

The documentation for the standard List::Util module; Recipe 2.6; Recipe 2.7; Recipe 4.18

Previous | Home | Next
8.6. Picking a Random Line from a File | Book Index | 8.8. Reading a Particular Line in a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.8. Reading a Particular Line in a File

8.8.1. Problem

You want to extract a single line from a file.

8.8.2. Solution

The simplest solution is to read the lines until you get to the one you want:

# looking for line number $DESIRED_LINE_NUMBER
$. = 0;
do { $LINE = <HANDLE> } until $. =  = $DESIRED_LINE_NUMBER || eof;

If you are going to be doing this a lot and the file fits into memory, read the file into an array:

@lines = <HANDLE>;
$LINE = $lines[$DESIRED_LINE_NUMBER];

The standard (as of v5.8) Tie::File ties an array to a file, one line per array element:

use Tie::File;
use Fcntl;

tie(@lines, Tie::File, $FILE, mode => O_RDWR)
  or die "Cannot tie file $FILE: $!\n";
$line = $lines[$sought - 1];

If you have the DB_File module, its DB_RECNO access method ties an array to a file, one line per array element:

use DB_File;
use Fcntl;

$tie = tie(@lines, DB_File, $FILE, O_RDWR, 0666, $DB_RECNO) or die
    "Cannot open file $FILE: $!\n";
# extract it
$line = $lines[$sought - 1];

8.8.3. Discussion

Each strategy has different features, useful in different circumstances. The linear access approach is easy to write and best for short files. The Tie::File module gives good performance, regardless of the size of the file or which line you're reading (and is pure Perl, so doesn't require any external libraries). The DB_File mechanism has some initial overhead, but later accesses are faster than with linear access, so use it for long files that are accessed more than once and are accessed out of order.

It is important to know whether you're counting lines from 0 or 1. The $. variable is 1 after the first line is read, so count from 1 when using linear access. The index mechanism uses many offsets, so count from 0. Tie::File and DB_File treat the file's records as an array indexed from 0, so count lines from 0.

Here are three different implementations of the same program, print_line. The program takes two arguments: a filename and a line number to extract.

The version in Example 8-1 simply reads lines until it finds the one it's looking for.

Example 8-1. print_line-v1

  #!/usr/bin/perl -w
  # print_line-v1 - linear style

  @ARGV =  = 2 or die "usage: print_line FILENAME LINE_NUMBER\n";

  ($filename, $line_number) = @ARGV;
  open(INFILE, "<", $filename)
    or die "Can't open $filename for reading: $!\n";
  while (<INFILE>) {
      $line = $_;
      last if $. =  = $line_number;
  }
  if ($. != $line_number) {
      die "Didn't find line $line_number in $filename\n";
  }
  print;

The Tie::File version is shown in Example 8-2.

Example 8-2. print_line-v2

  #!/usr/bin/perl -w
  # print_line-v2 - Tie::File style
  use Tie::File;
  use Fcntl;
  @ARGV =  = 2 or die "usage: print_line FILENAME LINE_NUMBER\n";
  ($filename, $line_number) = @ARGV;
  tie @lines, Tie::File, $filename, mode => O_RDWR
      or die "Can't open $filename for reading: $!\n";
  if (@lines > $line_number) {
      die "Didn't find line $line_number in $filename\n";
  }
  print "$lines[$line_number-1]\n";

The DB_File version in Example 8-3 follows the same logic as Tie::File.

Example 8-3. print_line-v3

  #!/usr/bin/perl -w
  # print_line-v3 - DB_File style
  use DB_File;
  use Fcntl;

  @ARGV =  = 2 or die "usage: print_line FILENAME LINE_NUMBER\n";
  ($filename, $line_number) = @ARGV;
  $tie = tie(@lines, DB_File, $filename, O_RDWR, 0666, $DB_RECNO)
      or die "Cannot open file $filename: $!\n";

  unless ($line_number < $tie->length) {
      die "Didn't find line $line_number in $filename\n"
  }

  print $lines[$line_number-1];                        # easy, eh?

If you will be retrieving lines by number often and the file doesn't fit into memory, build a byte-address index to let you seek directly to the start of the line using the techniques in Recipe 8.27.

8.8.4. See Also

The documentation for the standard Tie::File and DB_File modules (also in Chapter 32 of Programming Perl); the tie function in perlfunc(1) and in Chapter 29 of Programming Perl; the entry on $. in perlvar(1) and in Chapter 28 of Programming Perl; Recipe 8.27

Previous | Home | Next
8.7. Randomizing All Lines | Book Index | 8.9. Processing Variable-Length Text Fields
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.9. Processing Variable-Length Text Fields

8.9.1. Problem

You want to extract variable-length fields from your input.

8.9.2. Solution

Use split with a pattern matching the field separators.

# given $RECORD with field separated by a pattern,
# extract a list of fields
@FIELDS = split(/PATTERN/, $RECORD);

8.9.3. Discussion

The split function takes up to three arguments: PATTERN, EXPRESSION, and LIMIT. The LIMIT parameter is the maximum number of fields to split into. (If the input contains more fields, they are returned unsplit in the final list element.) If LIMIT is omitted, all fields (except any final empty ones) are returned. EXPRESSION gives the string value to split. If EXPRESSION is omitted, $_ is split. PATTERN is a pattern matching the field separator. If PATTERN is omitted, contiguous stretches of whitespace are used as the field separator and leading empty fields are silently discarded.

If your input field separator isn't a fixed string, you might want split to return the field separators as well as the data by using parentheses in PATTERN to save the field separators. For instance:

split(/([+-])/, "3+5-2");

returns the values:

(3, "+", 5, "-", 2)

To split colon-separated records in the style of the /etc/passwd file, use:

@fields = split(/:/, $RECORD);

The classic application of split is whitespace-separated records:

@fields = split(/\s+/, $RECORD);

If $RECORD started with whitespace, this last use of split would have put an empty string into the first element of @fields because split would consider the record to have an initial empty field. If you didn't want this, you could use this special form of split:

@fields = split(" ", $RECORD);

This behaves like split with a pattern of /\s+/, but ignores leading whitespace.

When the record separator can appear in the record, you have a problem. The usual solution is to escape occurrences of the record separator in records by prefixing them with a backslash. See Recipe 1.18.

8.9.4. See Also

The split function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 1.18

Previous | Home | Next
8.8. Reading a Particular Line in a File | Book Index | 8.10. Removing the Last Line of a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.10. Removing the Last Line of a File

8.10.1. Problem

You'd like to remove the last line from a file.

8.10.2. Solution

Use the standard (as of v5.8) Tie::File module and delete the last element from the tied array:

use Tie::File;

tie @lines, Tie::File, $file        or die "can't update $file: $!";
delete $lines[-1];

8.10.3. Discussion

The Tie::File solution is the most efficient solution, at least for large files, because it doesn't have to read through the entire file to find the last line and doesn't read the entire file into memory. It is, however, considerably slower for small files than code you could implement yourself by hand. That doesn't mean you shouldn't use Tie::File; it just means you've optimized for programmer time instead of for computer time.

If you don't have Tie::File and can't install it from CPAN, read the file a line at a time and keep track of the byte address of the last line you've seen. When you've exhausted the file, truncate to the last address you saved:

open (FH, "+<", $file)              or die "can't update $file: $!";
while (<FH>) {
    $addr = tell(FH) unless eof(FH);
}
truncate(FH, $addr)                 or die "can't truncate $file: $!";

Remembering the offset is more efficient than reading the whole file into memory because it holds only one given line at a time. Although you still have to grope your way through the whole file, you can use this technique on files larger than available memory.

8.10.4. See Also

The documentation for the standard Tie::File module; the truncate and tell functions in perlfunc(1) and in Chapter 29 of Programming Perl; your system's open(2) and fopen(3) manpages; Recipe 8.18

Previous | Home | Next
8.9. Processing Variable-Length Text Fields | Book Index | 8.11. Processing Binary Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.11. Processing Binary Files

8.11.1. Problem

You want to read 8-bit binary data as 8-bit binary data, i.e., neither as characters in a particular encoding nor as a text file with any newline or end-of-file conversions that your I/O library might want to do.

8.11.2. Solution

Use the binmode function on the filehandle:

binmode(HANDLE);

8.11.3. Discussion

The binmode function lets you specify new I/O layers for a filehandle. The default layer to specify is :raw, which removes any layers that would interfere with binary data. The Solution is thus equivalent to:

binmode(HANDLE, ":raw");

except that explicitly specifying :raw only works on Perl 5.8 and later. The one-argument form of binmode works on all versions of Perl.

Because Perl makes :crlf the default if you are on an operating system that needs it, you should rarely (if ever) need to specify :crlf in your program. Furthermore, it's generally not wise to add or remove the :crlf layer once you've begun reading from the file, as there may be data already read into buffers that you can't unread. You can, however, safely change the :encoding(...) layer midstream (when parsing XML, for example).

You should get into the habit of calling binmode when you open a binary file. This will make your program portable to systems that might (un)helpfully translate bytes in your binary file into something unusable.

You may specify the I/O layers when you open a filehandle, rather than using binmode after the fact:

open(FH, "< :raw", $filename);       # binary mode

Specify the default set of layers for all subsequently opened input and output filehandles with the open pragma:

use open IN => ":raw";      # binary files

8.11.4. See Also

The PerlIO(3) manpage; the open and binmode functions in perlfunc(1) and in Chapter 29 of Programming Perl; your system's open(2) and fopen(3) manpages

Previous | Home | Next
8.10. Removing the Last Line of a File | Book Index | 8.12. Using Random-Access I/O
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.12. Using Random-Access I/O

8.12.1. Problem

You have to read a binary record from the middle of a large file but don't want to read a record at a time to get there.

8.12.2. Solution

Once you know the record's size, multiply it by the record number to get the byte address, and then seek to that byte address and read the record:

$ADDRESS = $RECSIZE * $RECNO;
seek(FH, $ADDRESS, 0) or die "seek:$!";
read(FH, $BUFFER, $RECSIZE);

8.12.3. Discussion

The Solution assumes the first record has a RECNO of 0. If you're counting from one, use:

$ADDRESS = $RECSIZE * ($RECNO-1);

This is best applied to binary data. Applying it to text files assumes you have a constant character width and constant line length. This rules out most Unicode encodings, any kind of Windows text file, and any text file where lines can have different lengths.

8.12.4. See Also

The seek function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 8.13

Previous | Home | Next
8.11. Processing Binary Files | Book Index | 8.13. Updating a Random-Access File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.13. Updating a Random-Access File

8.13.1. Problem

You want to read an old record from a binary file, change its values, and write back the record.

8.13.2. Solution

After read ing the old record, pack up the updated values, seek to the previous address, and write it back.

use Fcntl;                          # for SEEK_SET and SEEK_CUR

$ADDRESS = $RECSIZE * $RECNO;
seek(FH, $ADDRESS, SEEK_SET)        or die "Seeking: $!";
read(FH, $BUFFER, $RECSIZE) =  = $RECSIZE
                                    or die "Reading: $!";
@FIELDS = unpack($FORMAT, $BUFFER);
# update fields, then
$BUFFER = pack($FORMAT, @FIELDS);
seek(FH, -$RECSIZE, SEEK_CUR)       or die "Seeking: $!";
print FH $BUFFER;
close FH                            or die "Closing: $!";

8.13.3. Discussion

You don't have to use anything fancier than print in Perl to output a record. Remember that the opposite of read is not write but print, although oddly enough, the opposite of sysread is syswrite.

The example program shown in Example 8-4, weekearly, takes one argument: the user whose record you want to backdate by a week. (Of course, in practice, you wouldn't really want to (nor be able to!) mess with the system accounting files.) This program requires write access to the file to be updated, since it opens the file in update mode. After fetching and altering the record, it packs it up again, skips backward in the file one record, and writes it out.

Example 8-4. weekearly

  #!/usr/bin/perl -w
  # weekearly -- set someone's login date back a week
  use User::pwent;
  use IO::Seekable;

  $typedef = "L A12 A16";         # linux fmt; sunos is "L A8 A16"
  $sizeof  = length(pack($typedef, ( )));
  $user    = shift(@ARGV) || $ENV{USER} || $ENV{LOGNAME};

  $address = getpwnam($user)->uid * $sizeof;

  open (LASTLOG, "+<:raw", "/var/log/lastlog")
      or die "can't update /var/log/lastlog: $!";
  seek(LASTLOG, $address, SEEK_SET)
      or die "seek failed: $!";
  read(LASTLOG, $buffer, $sizeof) =  = $sizeof
      or die "read failed: $!";

  ($time, $line, $host) = unpack($typedef, $buffer);
  $time  -= 24 * 7 * 60 * 60;         # back-date a week
  $buffer = pack($typedef, $time, $line, $time);

  seek(LASTLOG, -$sizeof, SEEK_CUR)   # backup one record
      or die "seek failed: $!";
  print LASTLOG $record;

  close(LASTLOG)
      or die "close failed: $!";

8.13.4. See Also

The PerlIO(3) manpage; the open, seek, read, pack, and unpack functions in the perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 8.12; Recipe 8.14

Previous | Home | Next
8.12. Using Random-Access I/O | Book Index | 8.14. Reading a String from a Binary File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.14. Reading a String from a Binary File

8.14.1. Problem

You want to read a NUL-terminated string from a file, starting at a particular address.

8.14.2. Solution

Ensure you're working with a binary file, set $/ to an ASCII NUL, and read the string with <>:

binmode(FH);                        # binary mode
$old_rs = $/;                       # save old $/
$/ = "\0";                          # ASCII 0: NUL
seek(FH, $addr, SEEK_SET)           or die "Seek error: $!\n";
$string = <FH>;                     # read string
chomp $string;                      # remove NUL
$/ = $old_rs;                       # restore old $/

You can use local to save and restore $/:

{
    local $/ = "\0";
    # ...
}                           # $/ is automatically restored

8.14.3. Discussion

The example program shown in Example 8-5, bgets, accepts a filename and one or more byte addresses as arguments. Decimal, octal, or hexadecimal addresses may be specified. For each address, the program reads and prints the null- or EOF-terminated string at that position.

Example 8-5. bgets

  #!/usr/bin/perl -w
  # bgets - get a string from an address in a binary file
  use IO::Seekable;
  use open IO => ":raw";              # binary mode on all opened handles
  ($file, @addrs) = @ARGV             or die "usage: $0 file addr ...";
  open(FH, $file)                     or die "cannot open $file: $!";
  $/ = "\000";
  foreach $addr (@addrs) {
      $addr = oct $addr if $addr =~ /^0/;
      seek(FH, $addr, SEEK_SET)
          or die "can't seek to $addr in $file: $!";
      printf qq{%#x %#o %d "%s"\n}, $addr, $addr, $addr, scalar <>;
  }

Example 8-6 is a simple implementation of the Unix strings program.

Example 8-6. strings

  #!/usr/bin/perl -w
  # strings - pull strings out of a binary file
  $/ = "\0";
  use open IO => ":raw";
  while (<>) {
      while (/([\040-\176\s]{4,})/g) {
          print $1, "\n";
      }
  }

8.14.4. See Also

The PerlIO(3) manpage; the seek, getc, and ord functions in perlfunc(1) and in Chapter 29 of Programming Perl; the discussion of qq// in the "Quote and Quote-Like Operators" section of the perlop(1) manpage, and in the "Pick Your Own Quotes" section of Chapter 2 of Programming Perl

Previous | Home | Next
8.13. Updating a Random-Access File | Book Index | 8.15. Reading Fixed-Length Records
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.15. Reading Fixed-Length Records

8.15.1. Problem

You want to read a file whose records have a fixed length.

8.15.2. Solution

Use read and unpack:

# $RECORDSIZE is the length of a record, in bytes.
# $TEMPLATE is the unpack template for the record
# FILE is the file to read from
# @FIELDS is an array, one element per field

until ( eof(FILE) ) {
    read(FILE, $record, $RECORDSIZE) =  = $RECORDSIZE
        or die "short read\n";
    @FIELDS = unpack($TEMPLATE, $record);
}

8.15.3. Discussion

Because the file in question is not a text file, you can't use <FH> or IO::Handle's getline method to read records. Instead, you must simply read a particular number of bytes into a variable. This variable contains one record's data, which you decode using unpack with the appropriate format.

For binary data, the catch is determining that format. When reading data written by a C program, this can mean peeking at C include files or manpages describing the structure layout, and this requires knowledge of C. It also requires that you become unnaturally chummy with your C compiler, because otherwise it's hard to predict field padding and alignment (such as the x2 in the format used in Recipe 8.24). If you're lucky enough to be on a Berkeley Unix system or a system supporting gcc, then you may be able to use the c2ph tool distributed with Perl to cajole your C compiler into helping you with this.

The tailwtmp program at the end of this chapter uses the format described in utmp(5) under Linux, and works on its /var/log/wtmp and /var/run/utmp files. Once you commit to working in binary format, machine dependencies creep in fast. It probably won't work unaltered on your system, but the procedure is still illustrative. Here is the relevant layout from the C include file on Linux:

#define UT_LINESIZE           12
#define UT_NAMESIZE           8
#define UT_HOSTSIZE           16

struct utmp {                       /* here are the pack template codes */
    short ut_type;                  /* s for short, must be padded      */
    pid_t ut_pid;                   /* i for integer                    */
    char ut_line[UT_LINESIZE];      /* A12 for 12-char string           */
    char ut_id[2];                  /* A2, but need x2 for alignment    */
    time_t ut_time;                 /* l for long                       */
    char ut_user[UT_NAMESIZE];      /* A8 for 8-char string             */
    char ut_host[UT_HOSTSIZE];      /* A16 for 16-char string           */
    long ut_addr;                   /* l for long                       */
};

Once you figure out the binary layout, feed that (in this case, "s x2 i A12 A2 x2 l A8 A16 l") to pack with an empty field list to determine the record's size. Remember to check the return value of read to make sure you got the number of bytes you asked for.

If your records are text strings, use the "a" or "A" unpack templates.

Fixed-length records are useful in that the nth record begins at byte offset SIZE * (n-1) in the file, where SIZE is the size of a single record. See the indexing code in Recipe 8.8 for an example.

8.15.4. See Also

The unpack, pack, and read functions in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 1.1

Previous | Home | Next
8.14. Reading a String from a Binary File | Book Index | 8.16. Reading Configuration Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.16. Reading Configuration Files

8.16.1. Problem

You want to allow users of your program to change its behavior through configuration files.

8.16.2. Solution

Either process a file in trivial VAR=VALUE format, setting a hash key-value pair for each setting:

while (<CONFIG>) {
    chomp;                  # no newline
    s/#.*//;                # no comments
    s/^\s+//;               # no leading white
    s/\s+$//;               # no trailing white
    next unless length;     # anything left?
    my ($var, $value) = split(/\s*=\s*/, $_, 2);
    $User_Preferences{$var} = $value;
}

or better yet, treat the config file as full Perl code:

do "$ENV{HOME}/.progrc";

8.16.3. Discussion

The first solution lets you read config files in a trivial format like this (comments and empty lines are allowed):

# set class C net
NETMASK = 255.255.255.0
MTU     = 296

DEVICE  = cua1
RATE    = 115200
MODE    = adaptive

After you're done, you can pull in a setting by using something like $User_Preferences{"RATE"} to find the value 115200. If you wanted the config file to set the global variable by that name, instead of assigning to the hash, use this:

no strict "refs";
$$var = $value;

and the $RATE variable would contain 115200.

The second solution uses do to pull in raw Perl code directly. When used with an expression instead of a block, do interprets the expression as a filename. This is nearly identical to using require, but without risk of taking a fatal exception. In the second format, the config file would look like:

# set class C net
$NETMASK = "255.255.255.0";
$MTU     = 0x128;
# Brent, please turn on the modem
$DEVICE  = "cua1";
$RATE    = 115_200;
$MODE    = "adaptive";

If you don't see the point of having extra punctuation and live code, consider this: you can have all of Perl at your disposal. You can now add arbitrary logic and tests to your simple assignments:

if ($DEVICE =~ /1$/) {
    $RATE =  28_800;
} else {
    $RATE = 115_200;
}

Many programs support system and personal configuration files. If you want the user's choices to override the system ones, load the user file second:

$APPDFLT = "/usr/local/share/myprog";

do "$APPDFLT/sysconfig.pl";
do "$ENV{HOME}/.myprogrc";

If you want to ignore the system config file when the user has his own, test the return value of the do.

do "$APPDFLT/sysconfig.pl"
    or
do "$ENV{HOME}/.myprogrc";

You might wonder what package those files are compiled in. They will be in the same package that do itself was compiled into. Typically you'll direct users to set particular variables, which, being unqualified globals, will end up in the current package. If you'd prefer unqualified variables go into a particular package, do this:

{ package Settings; do "$ENV{HOME}/.myprogrc" }

As with a file read using require or use, those read using do count as a separate and unrelated lexical scope. That means the configuration file can't access its caller's lexical (my) variables, nor can the caller find any such variables that might have been set in the file. It also means that the user's code isn't held accountable to a lexically scoped pragma like use strict or use warnings, which may be in effect in the caller.

If you don't want clean partitioning of variable visibility, you can get the config file's code executed in your own lexical scope. If you have a cat program or its technical equivalent handy, you could write yourself a hand-rolled do:

eval `cat $ENV{HOME}/.myprogrc`;

We've never actually seen anyone (except Larry Wall himself) use that approach in production code.

For one thing, do is a lot easier to type. Also, it respects the @INC path, which is normally searched if a full path is not specified, but, unlike using a require, no implicit error checking happens under do. This means you don't have to wrap it in an eval to catch exceptions that would otherwise cause your program to die, because do already functions as an eval.

You can still check for errors on your own if you'd like:

$file = "someprog.pl";
unless ($return = do $file) {
    warn "couldn't parse $file: $@"         if $@;
    warn "couldn't do $file: $!"            unless defined $return;
    warn "couldn't run $file"               unless $return;
}

This is much simpler for the programmer to source in code than it would be to invent and then parse a complicated, new syntax. It's also much easier on the users than forcing them to learn the syntax rules of yet another configuration file. Even better, you give the user access to a powerful algorithmic programming language.

One reasonable concern is security. How do you know that the file hasn't been tampered with by someone other than the user? The traditional approach here is to do nothing, trusting the directory and file permissions. Nine times out of ten, this is also the right approach. Most projects just aren't worth being that paranoid over. For those that are, see the next recipe.

8.16.4. See Also

The eval and require functions in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 8.17

Previous | Home | Next
8.15. Reading Fixed-Length Records | Book Index | 8.17. Testing a File for Trustworthiness
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.17. Testing a File for Trustworthiness

8.17.1. Problem

You want to read from a file, perhaps because it has configuration information. You want to use the file only if it can't be written to (or perhaps not even be read from) by anyone else than its owner.

8.17.2. Solution

Use the stat function to retrieve ownership and file permissions information. You can use the built-in version, which returns a list:

( $dev, $ino, $mode, $nlink,
  $uid, $gid, $rdev, $size,
  $atime, $mtime, $ctime,
  $blksize, $blocks )       = stat($filename)
        or die "no $filename: $!";

$mode &= 07777;             # discard file type info

Or you can use the by-name interface:

use File::stat;

$info = stat($filename)     or die "no $filename: $!";
if ($info->uid =  = 0) {
    print "Superuser owns $filename\n";
}
if ($info->atime > $info->mtime) {
    print "$filename has been read since it was written.\n";
}

8.17.3. Discussion

Usually you trust users to set file permissions as they wish. If they want others to read their files, or even to write to them, that's their business. Applications such as editors, mailers, and shells are often more discerning, though, refusing to evaluate code in configuration files if anyone but the owner can write to them. This helps avoid Trojan horse attacks. Security-minded programs such as ftp and ssh may even reject config files that can be read by anyone but their owner.

If the file is writable by someone other than the owner or is owned by someone other than the current user or the superuser, it shouldn't be trusted. To figure out file ownership and permissions, the stat function is used. The following function returns true if the file is deemed safe and false otherwise. If the stat fails, undef is returned.

use File::stat;

sub is_safe {
    my $path = shift;
    my $info = stat($path);
    return unless $info;

    # owner neither superuser nor me
    # the real uid is in stored in the $< variable
    if (($info->uid != 0) && ($info->uid != $<)) {
        return 0;
    }

    # check whether group or other can write file.
    # use 066 to detect either reading or writing
    if ($info->mode & 022) {   # someone else can write this
        return 0 unless -d _;  # non-directories aren't safe
            # but directories with the sticky bit (01000) are
        return 0 unless $info->mode & 01000;
    }
    return 1;
}

A directory is considered safe even if others can write to it, provided its mode 01000 (owner delete only) bit is set.

Careful programmers also ensure that no enclosing directory is writable. This is due to systems with the "chown giveaway" problem in which any user can give away a file they own to make it owned by someone else. The following function handles that by using the is_safe function to check every enclosing directory up to the root if it detects that you have the chown problem, for which it queries the POSIX::sysconf. If you don't have an unrestricted version of chown, the is_verysafe subroutine just calls is_safe. If you do have the problem, it walks up the filesystem tree until it reaches the root.

use Cwd;
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
sub is_verysafe {
    my $path = shift;
    return is_safe($path) if sysconf(_PC_CHOWN_RESTRICTED);
    $path = getcwd( ) . "/" . $path if $path !~ m{^/};
    do {
        return unless is_safe($path);
        $path =~ s#([^/]+|/)$##;               # dirname
        $path =~ s#/$## if length($path) > 1;  # last slash
    } while length $path;

    return 1;
}

To use this in a program, try something like this:

$file = "$ENV{HOME}/.myprogrc";
readconfig($file) if is_safe($file);

This has potential for a race condition, because it's presumed that the hypothetical readconfig function will open the file. Between the time when is_safe checks the file's stats and when readconfig opens it, something wicked could theoretically occur. To avoid this, pass is_safe the already open filehandle, which is set up to handle this:

$file = "$ENV{HOME}/.myprogrc";
if (open(FILE, "<", $file)) {
    readconfig(*FILE) if is_safe(*FILE);
}

You would still have to arrange for readconfig to accept a filehandle instead of a filename, though.

8.17.4. See Also

The stat function in perlfunc(1) and in Chapter 29 of Programming Perl; documentation for the standard POSIX and File::stat modules; Recipe 8.16

Previous | Home | Next
8.16. Reading Configuration Files | Book Index | 8.18. Treating a File as an Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.18. Treating a File as an Array

8.18.1. Problem

Your file contains a list of lines or records, and you'd like to be able to use Perl's powerful array operations to access and manipulate the file.

8.18.2. Solution

Use the Tie::File module, standard with v5.8 of Perl:

use Tie::File;
use Fcntl;

tie @data, Tie::File, $FILENAME or die "Can't tie to $filename : $!\n";
# use array operations on @data to work with the file

8.18.3. Discussion

The Tie::File module makes a file appear to be an array, one record per element. You can then fetch and assign to elements of the array, use array functions like push and splice, use negative indices, or reverse it, and in every instance you're really working with the data on disk.

If you don't specify how Tie::File should open the file, it is opened for read and write access and created if it doesn't exist. To specify a particular access mode (see Recipe 7.1), pass the Fcntl mode with the mode parameter when you tie. For example:

use Fcntl;
tie(@data, Tie::File, $filename, mode => O_RDONLY)
  or die "Can't open $filename for reading: $!\n";

When you alter the array, the file is rewritten on disk. For example, if you change the length of an element, all records later in the file must be copied to make the change. Take this code:

foreach (@data) {
  s/Perl Cookbook/Perl Cookbook (2nd edition)/g;
}

That's close because you change the length of record 0, forcing a copy of records 1..N. Then you change the length of record 1, forcing a copy of records 2..N. It's better to defer the update until all changes have been made and then have Tie::File update the file in one single write. To do this, call a method on the object behind the tied array:

(tied @data)->defer;                     # defer updates
foreach (@data) {
  s/Perl Cookbook/Perl Cookbook (2nd edition)/g;
}
(tied @data)->flush;

Exactly how much rewriting to defer is governed by how much memory you let Tie::File use, because the only way to keep track of changes without updating the file is to store those changes in memory. The Tie::File manpage shows how to change options for memory use.

8.18.4. See Also

Recipe 8.4; Recipe 8.8; Recipe 8.10

Previous | Home | Next
8.17. Testing a File for Trustworthiness | Book Index | 8.19. Setting the Default I/O Layers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.19. Setting the Default I/O Layers

8.19.1. Problem

You want to ensure all files opened by your program use a particular set of I/O layers. For example, you know that every file will contain UTF-8 data.

8.19.2. Solution

Use the open pragma:

use open IO => ":raw:utf8";

8.19.3. Discussion

You can easily specify I/O layers when you open a filehandle directly, but that doesn't help you when the filehandle is opened by someone else's code (possibly even the Perl core). The open pragma lets you specify a default set of layers for every open that doesn't specify its own layers.

The open module also offers separate IN and OUT control for input and output handles. For example, to read bytes and emit UTF-8:

use open "IN" => ":bytes", "OUT" => ":utf8";

The :std option tells open to apply the input and output layers to STDIN and STDOUT/STDERR. For example, the following code makes input handles read Greek (ISO 8859-7) and output handles write in the UTF-8 Unicode encoding. Then it applies the same layers to STDIN, STDOUT, and STDERR:

use open "IN" => ":encoding(Greek)",     # reading Greek
         "OUT" => ":utf8",               # writing 8-bit data in Unicode UTF-8,
         ":std";                         # STDIN is Greek,

8.19.4. See Also

The documentation for the standard open pragma; Recipe 8.12 and Recipe 8.19

Previous | Home | Next
8.18. Treating a File as an Array | Book Index | 8.20. Reading or Writing Unicode from a Filehandle
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.20. Reading or Writing Unicode from a Filehandle

8.20.1. Problem

You have a file containing text in a particular encoding and when you read data from that into a Perl string, Perl treats it as a series of 8-bit bytes. You'd like to work with characters instead of bytes because your encoding characters can take more than one byte. Also, if Perl doesn't know about your encoding, it may fail to identify certain characters as letters. Similarly, you may want to output text in a particular encoding.

8.20.2. Solution

Use I/O layers to tell Perl that data from that filehandle is in a particular encoding.

open(my $ifh, "<:encoding(ENCODING_NAME)", $filename);
open(my $ofh, ">:encoding(ENCODING_NAME)", $filename);

8.20.3. Discussion

Perl's text manipulation functions handle UTF-8 strings just as well as they do 8-bit data—they just need to know what type of data they're working with. Each string in Perl is internally marked as either UTF-8 or 8-bit data. The encoding(...) layer converts data between variable external encodings and the internal UTF-8 within Perl. This is done by way of the Encode module.

In the section on Unicode Support in Perl back in the Introduction to Chapter 1, we explained how under Unicode, every different character had a different code point (i.e., a different number) associated with it. Assigning all characters unique code points solves many problems. No longer does the same number, like 0xC4, represent one character under one character repertoire (e.g., a LATIN CAPITAL LETTER A WITH DIAERESIS under ISO-8859-1) and a different character in another repertoire (e.g., a GREEK CAPITAL LETTER DELTA under ISO-8859-7).

This neatly solves many problems, but still leaves one important issue: the precise format used in memory or disk for each code point. If most code points fit in 8 bits, it would seem wasteful to use, say, a full 32 bits for each character. But if every character is the same size as every other character, the code is easier to write and may be faster to execute.

This has given rise to different encoding systems for storing Unicode, each offering distinct advantages. Fixed-width encodings fit every code point into the same number of bits, which simplifies programming but at the expense of some wasted space. Variable-width encodings use only as much space as each code point requires, which saves space but complicates programming.

One further complication is combined characters, which may look like single letters on paper but in code require multiple code points. When you see a capital A with two dots above it (a diaeresis) on your screen, it may not even be character U+00C4. As explained in Recipe 1.8, Unicode supports the idea of combining characters, where you start with a base character and add non-spacing marks to it. U+0308 is a "COMBINING DIAERESIS", so you could use a capital A (U+0041) followed by U+0308, or A\x{308} to produce the same output.

The following table shows the old ISO 8859-1 way of writing a capital A with a diaeresis, in which the logical character code and the physical byte layout enjoyed an identical representation, and the new way under Unicode. We'll include both ways of writing that character: one precomposed in one code point and the other using two code points to create a combined character.

 | Old way | New way
 | Ä | A | Ä | Ä
Character(s) | 0xC4 | U+0041 | U+00C4 | U+0041 U+0308
Character repertoire | ISO 8859-1 | Unicode | Unicode | Unicode
Character code(s) | 0xC4 | 0x0041 | 0x00C4 | 0x0041 0x0308
Encoding | — | UTF-8 | UTF-8 | UTF-8
Byte(s) | 0xC4 | 0x41 | 0xC3 0x84 | 0x41 0xCC 0x88

The internal format used by Perl is UTF-8, a variable-width encoding system. One reason for this choice is that legacy ASCII requires no conversion for UTF-8, looking in memory exactly as it did before—just one byte per character. Character U+0041 is just 0x41 in memory. Legacy data sets don't increase in size, and even those using Western character sets like ISO 8859-n grow only slightly, since in practice you still have a favorable ratio of regular ASCII characters to 8-bit accented characters.

Just because Perl uses UTF-8 internally doesn't preclude using other formats externally. Perl automatically converts all data between UTF-8 and whatever encoding you've specified for that handle. The Encode module is used implicitly when you specify an I/O layer of the form ":encoding(....)". For example:

binmode(FH, ":encoding(UTF-16BE)")
    or die "can't binmode to utf-16be: $!";

or directly in the open:

open(FH, "< :encoding(UTF-32)", $pathname)
    or die "can't open $pathname: $!";

Here's a comparison of actual byte layouts of those two sequences, both representing a capital A with diaeresis, under several other popular formats:

 | U+00C4 | U+0041 U+0308
UTF-8 | c3 84 | 41 cc 88
UTF-16BE | 00 c4 | 00 41 03 08
UTF-16LE | c4 00 | 41 00 08 03
UTF-16 | fe ff 00 c4 | fe ff 00 41 03 08
UTF-32LE | c4 00 00 00 | 41 00 00 00 08 03 00 00
UTF-32BE | 00 00 00 c4 | 00 00 00 41 00 00 03 08
UTF-32 | 00 00 fe ff 00 00 00 c4 | 00 00 fe ff 00 00 00 41 00 00 03 08

This can chew up memory quickly. It's also complicated by the fact that some computers are big-endian, others little-endian. So fixed-width encoding formats that don't specify their endian-ness require a special byte-ordering sequence ("FF EF" versus "EF FF"), usually needed only at the start of the stream.

If you're reading or writing UTF-8 data, use the :utf8 layer. Because Perl natively uses UTF-8, the :utf8 layer bypasses the Encode module for performance.

The Encode module understands many aliases for encodings, so ascii, US-ascii, and ISO-646-US are synonymous. Read the Encode::Supported manpage for a list of available encodings. Perl supports not only standard Unicode names but vendor-specific names, too; for example, iso-8859-1 is cp850 on DOS, cp1252 on Windows, MacRoman on a Mac, and hp-roman8 on NeXTstep. The Encode module recognizes all of these as names for the same encoding.

8.20.4. See Also

The documentation for the standard Encode module; the Encode::Supported manpage; Recipe 8.12 and Recipe 8.19

Previous | Home | Next
8.19. Setting the Default I/O Layers | Book Index | 8.21. Converting Microsoft Text Files into Unicode
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.21. Converting Microsoft Text Files into Unicode

8.21.1. Problem

You have a text file written on a Microsoft computer that looks like garbage when displayed. How do you fix this?

8.21.2. Solution

Set the encoding layer appropriately when reading to convert this into Unicode:

binmode(IFH, ":encoding(cp1252)")
    || die "can't binmode to cp1252 encoding: $!";

8.21.3. Discussion

Suppose someone sends you a file in cp1252 format, Microsoft's default in-house 8-bit character set. Files in this format can be annoying to read—while they might claim to be Latin1, they are not, and if you look at them with Latin1 fonts loaded, you'll get garbage on your screen. A simple solution is as follows:

open(MSMESS, "< :crlf :encoding(cp1252)", $inputfile)
    || die "can't open $inputfile: $!";

Now data read from that handle will be automatically converted into Unicode when you read it in. It will also be processed in CRLF mode, which is needed on systems that don't use that sequence to indicate end of line.

You probably won't be able to write out this text as Latin1. That's because cp1252 includes characters that don't exist in Latin1. You'll have to leave it in Unicode, and displaying Unicode properly may not be as easy as you wish, because finding tools to work with Unicode is something of a quest in its own right. Most web browsers support ISO 10646 fonts; that is, Unicode fonts (see http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html). Whether your text editor does is a different matter, although both emacs and vi (actually, vim, not nvi) have mechanisms for handling Unicode. The authors used the following xterm(1) command to look at text:

xterm -n unicode -u8 -fn -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso10646-1

But many open questions still exist, such as cutting and pasting of Unicode data between windows.

The www.unicode.org site has help for finding and installing suitable tools for a variety of platforms, including both Unix and Microsoft systems.

You'll also need to tell Perl it's alright to emit Unicode. If you don't, you'll get a warning about a "Wide character in print" every time you try. Assuming you're running in an xterm like the one shown previously (or its equivalent for your system) that has Unicode fonts available, you could just do this:

binmode(STDOUT, ":utf8");

But that requires the rest of your program to emit Unicode, which might not be convenient. When writing new programs specifically designed for this, though, it might not be too much trouble.

As of v5.8.1, Perl offers a couple of other means of getting this effect. The -C command-line switch controls some Unicode features related to your runtime environment. This way you can set those features on a per-command basis without having to edit the source code.

The -C switch can be followed by either a number or a list of option letters. Some available letters, their numeric values, and effects are as follows:

Letter

Number

Meaning

I

1

STDIN is assumed to be in UTF-8

O

2

STDOUT will be in UTF-8

E

4

STDERR will be in UTF-8

S

7

I + O + E

i

8

UTF-8 is the default PerlIO layer for input streams

o

16

UTF-8 is the default PerlIO layer for output streams

D

24

i + o

A

32

the @ARGV elements are expected to be strings encoded in UTF-8

You may use letters or numbers. If you use numbers, you have to add them up. For example, -COE and -C6 are synonyms of UTF-8 on both STDOUT and STDERR.

One last approach is to use the PERL_UNICODE environment variable. If set, it contains the same value as you would use with -C. For example, with the xterm that has Unicode fonts loaded, you could do this in a POSIX shell:

sh% export PERL_UNICODE=6

or this in the csh:

csh% setenv PERL_UNICODE 6

The advantage of using the environment variable is that you don't have to edit the source code as the pragma would require, and you don't even need to change the command invocation as setting -C would require.

8.21.4. See Also

The perlrun(1),
encoding(3), PerlIO(3), and
Encode(3) manpages

Previous | Home | Next
8.20. Reading or Writing Unicode from a Filehandle | Book Index | 8.22. Comparing the Contents of Two Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.22. Comparing the Contents of Two Files

8.22.1. Problem

You have two files and want to see whether they're the same or different.

8.22.2. Solution

Use the standard File::Compare module with filenames, typeglobs, or any indirect filehandles:

use File::Compare;

if (compare($FILENAME_1, $FILENAME_2) =  = 0) {
  # they're equal
}

if (compare(*FH1, *FH2) =  = 0) {
  # they're equal
}

if (compare($fh1, $fh2) =  = 0) {
  # they're equal
}

8.22.3. Discussion

The File::Compare module (standard as of v5.8 and available on CPAN if you have an earlier version of Perl) compares two files for equality. The compare function, exported by default, returns 0 when the files are equal, 1 when they differ, and -1 when any error occurs during reading.

To compare more than two filehandles, simply loop, comparing two at a time:

# ensure all filehandles in @fh hold the same data
foreach $fh (@fh[1..$#fh]) {
  if (compare($fh[0], $fh)) {
    # $fh differs
  }
}

If you want details of exactly how two files differ, use the Text::Diff module from CPAN:

use Text::Diff;

$diff = diff(*FH1, *FH2);
$diff = diff($FILENAME_1, $FILENAME_2, { STYLE => "Context" });

In addition to filehandles, diff can also take filenames, strings, and even arrays of records. Pass a hash of options as the third argument. The STYLE option controls the type of output returned; it can be "Unified" (the default), "Context", or "OldStyle". You can even write your own class for custom diff formats.

The value returned by diff is a string similar to the output of the diff(1) program. This string is in valid diff format, suitable for feeding into patch(1). Although Text::Diff will not always produce the same output as GNU diff, byte for byte, its diffs are nevertheless correct.

8.22.4. See Also

The documentation for the standard File::Compare module; the documentation for the CPAN module Text::Diff; the diff(1) and patch(1) manpages.

Previous | Home | Next
8.21. Converting Microsoft Text Files into Unicode | Book Index | 8.23. Pretending a String Is a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.23. Pretending a String Is a File

8.23.1. Problem

You have data in string, but would like to treat it as a file. For example, you have a subroutine that expects a filehandle as an argument, but you would like that subroutine to work directly on the data in your string instead. Additionally, you don't want to write the data to a temporary file.

8.23.2. Solution

Use the scalar I/O in Perl v5.8:

open($fh, "+<", \$string);   # read and write contents of $string

8.23.3. Discussion

Perl's I/O layers include support for input and output from a scalar. When you read a record with <$fh>, you are reading the next line from $string. When you write a record with print, you change $string. You can pass $fh to a function that expects a filehandle, and that subroutine need never know that it's really working with data in a string.

Perl respects the various access modes in open for strings, so you can specify that the strings be opened as read-only, with truncation, in append mode, and so on:

open($fh, "<",  \$string);   # read only
open($fh, ">",  \$string);   # write only, discard original contents
open($fh, "+>", \$string);   # read and write, discard original contents
open($fh, "+<", \$string);   # read and write, preserve original contents

These handles behave in all respects like regular filehandles, so all I/O functions work, such as seek, truncate, sysread, and friends.

8.23.4. See Also

The open function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 8.12 and Recipe 8.19

Previous | Home | Next
8.22. Comparing the Contents of Two Files | Book Index | 8.24. Program: tailwtmp
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.24. Program: tailwtmp

Every time a user logs into or out of a Unix system, a record is added to the wtmp file. You can't use the normal tail program on it, because the file is in binary format. The tailwtmp program in Example 8-7 knows the format of the binary file and shows every new record as it appears. You'll have to adjust the pack format for your own system.

Example 8-7. tailwtmp

  #!/usr/bin/perl -w
  # tailwtmp - watch for logins and logouts;
  # uses linux utmp structure, from utmp(5)
  $typedef = "s x2 i A12 A4 l A8 A16 l";
  $sizeof = length pack($typedef, ( ) );
  use IO::File;
  open(WTMP, "< :raw", "/var/log/wtmp") or die "can't open /var/log/wtmp: $!";
  seek(WTMP, 0, SEEK_END);
  for (;;) {
          while (read(WTMP, $buffer, $sizeof) =  = $sizeof) {
          ($type, $pid,  $line, $id, $time, $user, $host, $addr)
              = unpack($typedef, $buffer);
          next unless $user && ord($user) && $time;
          printf "%1d %-8s %-12s %2s %-24s %-16s %5d %08x\n",
              $type,$user,$line,$id,scalar(localtime($time)),
              $host,$pid,$addr;
      }
      for ($size = -s WTMP; $size =  = -s WTMP; sleep 1) {  }
      WTMP->clearerr( );
  }
Previous | Home | Next
8.23. Pretending a String Is a File | Book Index | 8.25. Program: tctee
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.25. Program: tctee

Not all systems support the classic tee program for splitting output pipes to multiple destinations. This command sends the output from someprog to /tmp/output and to the mail pipe beyond:

% someprog | tee /tmp/output | Mail -s "check this" user@host.org

This program helps not only users who aren't on Unix systems and don't have a regular tee; it also helps those who are, because it offers features not found on other versions of tee.

The four flag arguments are -i to ignore interrupts, -a to append to output files, -u for unbuffered output, and -n to omit copying the output on to standard out.

Because this program uses Perl's magic open, you can specify pipes as well as files.

% someprog | tctee f1 "|cat -n" f2 ">>f3"

That sends the output from someprog to the files f1 and f2, appends it to f3, sends a copy to the program cat -n, and also produces the stream on standard output.

The program in Example 8-8 is one of many venerable Perl programs written nearly a decade ago that still runs perfectly well. If written from scratch now, we'd probably use strict, warnings, and ten to thirty thousand lines of modules. But if it ain't broke . . .

Example 8-8. tctee

  #!/usr/bin/perl
  # tctee - clone that groks process tees
  # perl3 compatible, or better.

  while ($ARGV[0] =~ /^-(.+)/ && (shift, ($_ = $1), 1)) {
      next if /^$/;
      s/i// && (++$ignore_ints, redo);
      s/a// && (++$append,      redo);
      s/u// && (++$unbuffer,    redo);
      s/n// && (++$nostdout,    redo);
      die "usage $0 [-aiun] [filenames] ...\n";
  }

  if ($ignore_ints) {
      for $sig ("INT", "TERM", "HUP", "QUIT") { $SIG{$sig} = "IGNORE"; }
  }

  $SIG{"PIPE"} = "PLUMBER";
  $mode = $append ? ">>" : ">";
  $fh = "FH000";

  unless ($nostdout) {
      %fh = ("STDOUT", "standard output"); # always go to stdout
  }

  $| = 1 if $unbuffer;

  for (@ARGV) {
      if (!open($fh, (/^[^>|]/ && $mode) . $_)) {
          warn "$0: cannot open $_: $!\n"; # like sun's; i prefer die
          $status++;
          next;
      }
      select((select($fh), $| = 1)[0]) if $unbuffer;
      $fh{$fh++} = $_;
  }

  while (<STDIN>) {
      for $fh (keys %fh) {
          print $fh $_;
      }
  }

  for $fh (keys %fh) {
      next if close($fh) || !defined $fh{$fh};
      warn "$0: couldnt close $fh{$fh}: $!\n";
      $status++;
  }

  exit $status;

  sub PLUMBER {
      warn "$0: pipe to \"$fh{$fh}\" broke!\n";
      $status++;
      delete $fh{$fh};
  }
Previous | Home | Next
8.24. Program: tailwtmp | Book Index | 8.26. Program: laston
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.26. Program: laston

When you log in to a Unix system, it tells you when you last logged in. That information is stored in a binary file called lastlog. Each user has their own record; UID 8 is at record 8, UID 239 at record 239, and so on. To find out when a given user last logged in, convert their login name to a number, seek to their record in that file, read, and unpack. Doing so with shell tools is hard, but with the laston program, it's easy. Here's an example:

% laston gnat
gnat  UID 314 at Mon May 25 08:32:52 2003 on ttyp0 from below.perl.com

The program in Example 8-9 is much newer than the tctee program in Example 8-8, but it's less portable. It uses the Linux binary layout of the lastlog file. You'll have to change this for other systems.

Example 8-9. laston

  #!/usr/bin/perl -w
  # laston - find out when given user last logged on
  use User::pwent;
  use IO::Seekable qw(SEEK_SET);

  open (LASTLOG, "< :raw", "/var/log/lastlog")
      or die "can't open /var/log/lastlog: $!";

  $typedef = "L A12 A16";  # linux fmt; sunos is "L A8 A16"
  $sizeof  = length(pack($typedef, ( )));

  for $user (@ARGV) {
      $U = ($user =~ /^\d+$/) ? getpwuid($user) : getpwnam($user);
      unless ($U) { warn "no such uid $user\n"; next; }
      seek(LASTLOG, $U->uid * $sizeof, SEEK_SET) or die "seek failed: $!";
      read(LASTLOG, $buffer, $sizeof) =  = $sizeof        or next;
      ($time, $line, $host) = unpack($typedef, $buffer);
      printf "%-8s UID %5d %s%s%s\n", $U->name, $U->uid,
            $time ? ("at " . localtime($time)) : "never logged in",
            $line && " on $line",
            $host && " from $host";

  }
Previous | Home | Next
8.25. Program: tctee | Book Index | 8.27. Program: Flat File Indexes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.27. Program: Flat File Indexes

It sometimes happens that you need to jump directly to a particular line number in a file, but the lines vary in length, so you can't use Recipe 8.12. Although you could start at the beginning of the file and read every line, this is inefficient if you're making multiple queries.

The solution is to build an index of fixed-width records, one per line. Each record contains the offset in the data file of the corresponding line. The subroutine in Example 8-10 takes the data file and a filehandle to send the index to. It reads a record at a time and prints the current offset in the file to the index, packed into a big-ending unsigned 32-bit integer; see the documentation for the pack function in perlfunc(1) for alternative storage types.

Example 8-10. build_index

  # usage: build_index(*DATA_HANDLE, *INDEX_HANDLE)
  sub build_index {
      my $data_file  = shift;
      my $index_file = shift;
      my $offset     = 0;

      while (<$data_file>) {
          print $index_file pack("N", $offset);
          $offset = tell($data_file);
      }
  }

Once you have an index, it becomes easy to read a particular line from the data file. Jump to that record in the index, read the offset, and jump to that position in the data file. The next line you read will be the one you want. Example 8-11 returns the line, given the line number and the index and data file handles.

Example 8-11. line_with_index

  # usage: line_with_index(*DATA_HANDLE, *INDEX_HANDLE, $LINE_NUMBER)
  # returns line or undef if LINE_NUMBER was out of range
  sub line_with_index {
      my $data_file   = shift;
      my $index_file  = shift;
      my $line_number = shift;
      my $size;               # size of an index entry
      my $i_offset;           # offset into the index of the entry
      my $entry;              # index entry
      my $d_offset;           # offset into the data file
      $size = length(pack("N", 0));
      $i_offset = $size * ($line_number-1);
      seek($index_file, $i_offset, 0) or return;
      read($index_file, $entry, $size);
      $d_offset = unpack("N", $entry);
      seek($data_file, $d_offset, 0);
      return scalar(<$data_file>);
  }

To use these subroutines, just say:

open($fh,  "<", $file)         or die "Can't open $file for reading: $!\n";
open($index, "+>", $file.idx)
  or die "Can't open $file.idx for read/write: $!\n";
build_index($fh, $index);
$line = line_with_index($file, $index, $seeking);

The next step is to cache the index file between runs of the program, so you're not building it each time. This is shown in Example Recipe 8.12. Then add locking for concurrent access, and check time stamps on the files to see whether a change to the data file has made an old index file out of date.

Example 8-12. cache_line_index

  #!/usr/bin/perl -w
  # cache_line_index - index style
  # build_index and line_with_index from above
  @ARGV =  = 2 or
      die "usage: print_line FILENAME LINE_NUMBER";

  ($filename, $line_number) = @ARGV;
  open(my $orig, "<", $filename)
          or die "Can't open $filename for reading: $!";

  # open the index and build it if necessary
  # there's a race condition here: two copies of this
  # program can notice there's no index for the file and
  # try to build one.  This would be easily solved with
  # locking
  $indexname = "$filename.index";
  sysopen(my $idx, $indexname, O_CREAT|O_RDWR)
           or die "Can't open $indexname for read/write: $!";
  build_index($orig, $idx) if -z $indexname;  # XXX: race unless lock

  $line = line_with_index($orig, $idx, $line_number);
  die "Didn't find line $line_number in $filename" unless defined $line;
  print $line;
Previous | Home | Next
8.26. Program: laston | Book Index | 9. Directories
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 9. Directories

Contents:

Introduction
Getting and Setting Timestamps
Deleting a File
Copying or Moving a File
Recognizing Two Names for the Same File
Processing All Files in a Directory
Globbing, or Getting a List of Filenames Matching a Pattern
Processing All Files in a Directory Recursively
Removing a Directory and Its Contents
Renaming Files
Splitting a Filename into Its Component Parts
Working with Symbolic File Permissions Instead of Octal Values
Program: symirror
Program: lst

Chris Torek

Unix has its weak points, but its file system is not one of them.

9.0. Introduction

To fully understand directories, you need to be acquainted with the underlying mechanics. The following explanation is slanted toward the Unix filesystem, for whose syscalls and behavior Perl's directory access routines were designed, but it is applicable to some degree to most other platforms.

A filesystem consists of two parts: a set of data blocks where the contents of files and directories are kept, and an index to those blocks. Each entity in the filesystem has an entry in the index, be it a plain file, a directory, a link, or a special file like those in /dev. Each entry in the index is called an inode (short for index node). Since the index is a flat index, inodes are addressed by number.

A directory is a specially formatted file, whose inode entry marks it as a directory. A directory's data blocks contain a set of pairs. Each pair consists of the name of something in that directory and the inode number of that thing. The data blocks for /usr/bin might contain:

Name | Inode
bc | 17
du | 29
nvi | 8
pine | 55
vi | 8

Every directory is like this, even the root directory (/). To read the file /usr/bin/vi, the operating system reads the inode for /, reads its data blocks to find the entry for /usr, reads /usr's inode, reads its data block to find /usr/bin, reads /usr/bin's inode, reads its data block to find /usr/bin/vi, reads /usr/bin/vi's inode, and then reads the data from its data block.

The name in a directory entry isn't fully qualified. The file /usr/bin/vi has an entry with the name vi in the /usr/bin directory. If you open the directory /usr/bin and read entries one by one, you get filenames like patch, rlogin, and vi instead of fully qualified names like /usr/bin/patch, /usr/bin/rlogin, and /usr/bin/vi.

The inode has more than a pointer to the data blocks. Each inode also contains the type of thing it represents (directory, plain file, etc.), the size of the thing, a set of permissions bits, owner and group information, the time the thing was last modified, the number of directory entries that point to this inode, and so on.

Some operations on files change the contents of the file's data blocks; others change just the inode. For instance, appending to or truncating a file updates its inode by changing the size field. Other operations change the directory entry that points to the file's inode. Changing a file's name changes only the directory entry; it updates neither the file's data nor its inode.

Three fields in the inode structure contain the last access, change, and modification times: atime, ctime, and mtime. The atime field is updated each time the pointer to the file's data blocks is followed and the file's data is read. The mtime field is updated each time the file's data changes. The ctime field is updated each time the file's inode changes. The ctime is not creation time; there is no way under standard Unix to find a file's creation time.

Reading a file changes its atime only. Changing a file's name doesn't change atime, ctime, or mtime, because the directory entry changed (it does change the atime and mtime of the directory the file is in, though). Truncating a file doesn't change its atime (because we haven't read; we've just changed the size field in its directory entry), but it does change its ctime because we changed its size field and its mtime because we changed its contents (even though we didn't follow the pointer to do so).

We can access the inode of a file or directory by calling the built-in function stat on its name. For instance, to get the inode for /usr/bin/vi, say:

@entry = stat("/usr/bin/vi") or die "Couldn't stat /usr/bin/vi : $!";

To get the inode for the directory /usr/bin, say:

@entry = stat("/usr/bin")    or die "Couldn't stat /usr/bin : $!";

You can stat filehandles, too:

@entry = stat(INFILE)        or die "Couldn't stat INFILE : $!";

The stat function returns a list of the values of the fields in the directory entry. If it couldn't get this information (for instance, if the file doesn't exist), it returns an empty list. It's this empty list we test for using the or die construct. Be careful of using || die because that throws the expression into scalar context, in which case stat only reports whether it worked. It doesn't return the list of values. The underscore ( _ ) cache referred to later will still be updated, though.

The values returned by stat are listed in Table 9-1.

Table 9-1. Stat return values

Element | Abbreviation | Description
0 | dev | Device number of filesystem
1 | ino | Inode number (the "pointer" field)
2 | mode | File mode (type and permissions)
3 | nlink | Number of (hard) links to the file
4 | uid | Numeric user ID of file's owner
5 | gid | Numeric group ID of file's owner
6 | rdev | The device identifier (special files only)
7 | size | Total size of file, in bytes
8 | atime | Last access time, in seconds, since the Epoch
9 | mtime | Last modify time, in seconds, since the Epoch
10 | ctime | Inode change time, in seconds, since the Epoch
11 | blksize | Preferred block size for filesystem I/O
12 | blocks | Actual number of blocks allocated

The standard File::stat module provides a named interface to these values. It overrides the stat function, so instead of returning the preceding array, it returns an object with a method for each attribute:

use File::stat;

$inode = stat("/usr/bin/vi");
$ctime = $inode->ctime;
$size  = $inode->size;

In addition, Perl provides operators that call stat and return one value only (see Table 9-2). These are collectively referred to as the -X operators because they all take the form of a dash followed by a single character. They're modeled on the shell's test operators.

Table 9-2. File test operators

-X | Stat field | Meaning
-r | mode | File is readable by effective UID/GID
-w | mode | File is writable by effective UID/GID
-x | mode | File is executable by effective UID/GID
-o | mode | File is owned by effective UID
-R | mode | File is readable by real UID/GID
-W | mode | File is writable by real UID/GID
-X | mode | File is executable by real UID/GID
-O | mode | File is owned by real UID
-e |  | File exists
-z | size | File has zero size
-s | size | File has nonzero size (returns size)
-f | mode,rdev | File is a plain file
-d | mode,rdev | File is a directory
-l | mode | File is a symbolic link
-p | mode | File is a named pipe (FIFO)
-S | mode | File is a socket
-b | rdev | File is a block special file
-c | rdev | File is a character special file
-t | rdev | Filehandle is opened to a tty
-u | mode | File has setuid bit set
-g | mode | File has setgid bit set
-k | mode | File has sticky bit set
-T | N/A | File is a text file
-B | N/A | File is a binary file (opposite of -T)
-M | mtime | Age of file in days when script started
-A | atime | Same for access time
-C | ctime | Same for inode change time (not creation)

The stat and the -X operators cache the values that the stat(2) syscall returned. If you then call stat or a -X operator with the special filehandle _ (a single underscore), it won't call stat again but will instead return information from its cache. This lets you test many properties of a single file without calling stat(2) many times or introducing a race condition:

open(F, "<", $filename )
    or die "Opening $filename: $!\n";
unless (-s F && -T _) {
    die "$filename doesn't have text in it.\n";
}

The stat call just returns the information in one inode, though. How do we list the directory contents? For that, Perl provides opendir, readdir, and closedir:

opendir(DIRHANDLE, "/usr/bin") or die "couldn't open /usr/bin : $!";
while ( defined ($filename = readdir(DIRHANDLE)) ) {
    print "Inside /usr/bin is something called $filename\n";
}
closedir(DIRHANDLE);

These directory-reading functions are designed to look like the file open and close functions. Where open takes a filehandle, though, opendir takes a directory handle. They may look the same to you (the same bare word), but they occupy different namespaces. Therefore, you could open(BIN, "/a/file") and opendir(BIN, "/a/dir"), and Perl won't get confused. You might, but Perl won't. Because filehandles and directory handles are different, you can't use the <> operator to read from a directory handle (<> calls readline on the filehandle).

Similar to what happens with open and the other functions that initialize filehandles, you can supply opendir an undefined scalar variable where the directory handle is expected. If the function succeeds, Perl initializes that variable with a reference to a new, anonymous directory handle.

opendir(my $dh, "/usr/bin") or die;
while (defined ($filename = readdir($dh))) {
  # ...
}
closedir($dh);

Just like any other autovivified reference, when this one is no longer used (for example, when it goes out of scope and no other references to it are held), Perl automatically deallocates it. And just as close is implicitly called on filehandles autovivified through open at that point, directory handles autovivified through opendir have closedir called on them, too.

Filenames in a directory aren't necessarily stored alphabetically. For an alphabetical list of files, read the entries and sort them yourself.

The separation of directory information from inode information can create some odd situations. Operations that update the directory—such as linking, unlinking, or renaming a file—all require write permission only on the directory, not on the file. This is because the name of a file is actually something the directory calls that file, not a property inherent to the file itself. Only directories hold names of files; files are ignorant of their own names. Only operations that change information in the file data itself demand write permission on the file. Lastly, operations that alter the file's permissions or other metadata are restricted to the file's owner or the superuser. This can lead to the interesting situation of being able to delete (i.e., unlink from its directory) a file you can't read, or write to a file you can't delete.

Although these situations may make the filesystem structure seem odd at first, they're actually the source of much of Unix's power. Links, two filenames that refer to the same file, are now extremely simple. The two directory entries just list the same inode number. The inode structure includes a count of the number of directory entries referring to the file (nlink in the values returned by stat). This lets the operating system store and maintain only one copy of the modification times, size, and other file attributes. When one directory entry is unlink ed, data blocks are deleted only if the directory entry was the last one that referred to the file's inode—and no processes still have the file open. You can unlink an open file, but its disk space won't be released until the last close.

Links come in two forms. The kind described previously, where two directory entries list the same inode number (like vi and nvi in the earlier table), are called hard links. The operating system cannot tell the first directory entry of a file (the one created when the file was created) from any subsequent hard links to it. The other kind, soft or symbolic links, are very different. A soft link is a special type of file whose data block stores the filename the file is linked to. Soft links have a different mode value, indicating they're not regular files. The operating system, when asked to open a soft link, instead opens the filename contained in the data block.

9.0.1. Executive Summary

Filenames are kept in a directory, separate from the size, protections, and other metadata kept in an inode.

The stat function returns the inode information (metadata).

opendir, readdir, and friends provide access to filenames in a directory through a directory handle.

Directory handles look like filehandles, but they are not the same. In particular, you can't use <> on directory handles.

Permissions on a directory determine whether you can read and write the list of filenames. Permissions on a file determine whether you can change the file's metadata or contents.

Three different times are stored in an inode. None of them is the file's creation time.

Previous | Home | Next
8.27. Program: Flat File Indexes | Book Index | 9.1. Getting and Setting Timestamps
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.1. Getting and Setting Timestamps

9.1.1. Problem

You need to retrieve or alter when a file was last modified (written or changed) or accessed (read).

9.1.2. Solution

Use stat to get those times and utime to set them. Both functions are built into Perl:

($READTIME, $WRITETIME) = (stat($filename))[8,9];

utime($NEWREADTIME, $NEWWRITETIME, $filename);

9.1.3. Discussion

As explained in the Introduction, three different times are associated with an inode in the traditional Unix filesystem. Of these, any user can set the atime and mtime with utime, assuming the user has write access to the parent directory of the file. There is effectively no way to change the ctime. This example shows how to call utime:

$SECONDS_PER_DAY = 60 * 60 * 24;
($atime, $mtime) = (stat($file))[8,9];
$atime -= 7 * $SECONDS_PER_DAY;
$mtime -= 7 * $SECONDS_PER_DAY;

utime($atime, $mtime, $file)
    or die "couldn't backdate $file by a week w/ utime: $!";

You must call utime with both atime and mtime values. If you want to change only one, you must call stat first to get the other:

$mtime = (stat $file)[9];
utime(time, $mtime, $file);

This is easier to understand if you use File::stat:

use File::stat;
utime(time, stat($file)->mtime, $file);

Use utime to make it appear as though you never touched a file at all (beyond its ctime being updated). For example, to edit a file, use the program in Example 9-1.

Example 9-1. uvi

  #!/usr/bin/perl -w
  # uvi - vi a file without changing its access times

  $file = shift or die "usage: uvi filename\n";
  ($atime, $mtime) = (stat($file))[8,9];
  system($ENV{EDITOR} || "vi", $file);
  utime($atime, $mtime, $file)
      or die "couldn't restore $file to orig times: $!";

9.1.4. See Also

The stat and utime functions in perlfunc(1) and in Chapter 29 of Programming Perl; the standard File::stat module (also in Chapter 32 of Programming Perl); your system's utime(3) manpage

Previous | Home | Next
9. Directories | Book Index | 9.2. Deleting a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.2. Deleting a File

9.2.1. Problem

You want to delete a file. Perl's delete function isn't what you want.

9.2.2. Solution

Use Perl's unlink function:

unlink($FILENAME)                 or die "Can't delete $FILENAME: $!\n";
unlink(@FILENAMES) =  = @FILENAMES    or die "Couldn't unlink all of @FILENAMES: $!\n";

9.2.3. Discussion

The unlink function takes its name from the Unix syscall. Perl's unlink takes a list of filenames and returns the number of filenames successfully deleted. This return value can then be tested with || or or:

unlink($file) or die "Can't unlink $file: $!";

unlink doesn't report which filenames it couldn't delete, only how many it deleted. Here's one way to test for successful deletion of many files and report the number deleted:

unless (($count = unlink(@filelist)) =  = @filelist) {
    warn "could only delete $count of "
            . (@filelist) . " files";
}

A foreach over @filelist would permit individual error messages.

Under Unix, deleting a file from a directory requires write access to the directory,[16] not to the file, because it's the directory you're changing. Under some circumstances, you could remove a file you couldn't write to or write to a file you couldn't remove.

[16]Unless the sticky bit, mode 01000, is turned on for the directory, which further restricts deletions to be by the file's owner only. Shared directories such as /tmp are usually mode 01777 for security reasons.

If you delete a file that some process still has open, the operating system removes the directory entry but doesn't free up data blocks until all processes have closed the file. This is how the tmpfile function in File::Temp works (see Recipe 7.11).

9.2.4. See Also

The unlink function in perlfunc(1) and in Chapter 29 of Programming Perl; your system's unlink(2) manpage; Recipe 7.11

Previous | Home | Next
9.1. Getting and Setting Timestamps | Book Index | 9.3. Copying or Moving a File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.3. Copying or Moving a File

9.3.1. Problem

You need to copy a file, but Perl has no built-in copy function.

9.3.2. Solution

Use the copy function from the standard File::Copy module:

use File::Copy;
copy($oldfile, $newfile);

You can do it by hand:

open(IN,  "<", $oldfile)                    or die "can't open $oldfile: $!";
open(OUT, ">", $newfile)                    or die "can't open $newfile: $!";

$blksize = (stat IN)[11] || 16384;          # preferred block size?
while (1) {
    $len = sysread IN, $buf, $blksize);
    if (!defined $len) {
        next if $! =~ /^Interrupted/;       # ^Z and fg on EINTR
        die "System read error: $!\n";
    }
    last unless $len;

    $offset = 0;
    while ($len) {          # Handle partial writes.
        defined($written = syswrite OUT, $buf, $len, $offset)
            or die "System write error: $!\n";
        $len    -= $written;
        $offset += $written;
    };
}

close(IN);
close(OUT);

or you can call your system's copy program:

system("cp $oldfile $newfile");       # unix
system("copy $oldfile $newfile");     # dos, vms

9.3.3. Discussion

The File::Copy module provides copy and move functions. These are more convenient than resorting to low-level I/O calls and more portable than calling system. This version of move works across file-system boundaries; the standard Perl built-in rename (usually) does not.

use File::Copy;

copy("datafile.dat", "datafile.bak")
    or die "copy failed: $!";

move("datafile.dat", "datafile.new")
    or die "move failed: $!";

Because these functions return only a simple success status, you can't easily tell which file prevented the copy or move from working. Copying the files manually lets you pinpoint which files didn't copy, but it fills your program with complex sysread s and syswrite s.

9.3.4. See Also

Documentation for the standard File::Copy module (also in Chapter 32 of Programming Perl); the rename, read, and syswrite functions in perlfunc(1) and in Chapter 29 of Programming Perl

Previous | Home | Next
9.2. Deleting a File | Book Index | 9.4. Recognizing Two Names for the Same File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.4. Recognizing Two Names for the Same File

9.4.1. Problem

You want to determine whether two filenames in a list correspond to the same file on disk (because of hard and soft links, two filenames can refer to a single file). You might do this to make sure that you don't change a file you've already worked with.

9.4.2. Solution

Maintain a hash, keyed by the device and inode number of the files you've seen. The values are the names of the files:

%seen = ( );

sub do_my_thing {
    my $filename = shift;
    my ($dev, $ino) = stat $filename;

    unless ($seen{$dev, $ino}++) {
        # do something with $filename because we haven't
        # seen it before
    }
}

9.4.3. Discussion

A key in %seen is made by combining the device number ($dev) and inode number ($ino) of each file. Files that are the same will have the same device and inode numbers, so they will have the same key.

If you want to maintain a list of all files of the same name, instead of counting the number of times seen, save the name of the file in an anonymous array.

foreach $filename (@files) {
    ($dev, $ino) = stat $filename;
    push( @{ $seen{$dev,$ino} }, $filename);
}

foreach $devino (sort keys %seen) {
    ($dev, $ino) = split(/$;/o, $devino);
    if (@{$seen{$devino}} > 1) {
        # @{$seen{$devino}} is a list of filenames for the same file
    }
}

The $; variable contains the separator string using the old multidimensional associative array emulation syntax, $hash{$x,$y,$z}. It's still a one-dimensional hash, but it has composite keys. The key is really join($; => $x, $y, $z). The split separates them again. Although you'd normally just use a real multilevel hash directly, here there's no need, and it's cheaper not to.

9.4.4. See Also

The $; ($SUBSEP) variable in perlvar(1), and in the "Special Variables" section of Chapter 28 of Programming Perl; the stat function in perlfunc(1) and in Chapter 29 of Programming Perl; Chapter 5

Previous | Home | Next
9.3. Copying or Moving a File | Book Index | 9.5. Processing All Files in a Directory
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.5. Processing All Files in a Directory

9.5.1. Problem

You want to do something to each file in a particular directory.

9.5.2. Solution

Use opendir to open the directory and readdir to retrieve every filename:

opendir(DIR, $dirname) or die "can't opendir $dirname: $!";
while (defined($file = readdir(DIR))) {
    # do something with "$dirname/$file"
}
closedir(DIR);

9.5.3. Discussion

The opendir, readdir, and closedir functions operate on directories as open, <>, and close operate on files. Both use handles, but the directory handles used by opendir and friends are different from the filehandles used by open and friends. In particular, you can't use <> on a directory handle.

In scalar context, readdir returns the next filename in the directory until it reaches the end of the directory, when it returns undef. In list context it returns the rest of the filenames in the directory or an empty list if there were no files left. As explained in this chapter's Introduction, the filenames returned by readdir do not include the directory name. When you work with the filenames returned by readdir, you must either move to the right directory first or prepend the directory to the filename.

This shows one way of prepending:

$dir = "/usr/local/bin";
print "Text files in $dir are:\n";
opendir(BIN, $dir) or die "Can't open $dir: $!";
while( $file = readdir BIN) {
    print "$file\n" if -T "$dir/$file";
}
closedir(BIN);

The readdir function will return the special directories "." (the directory itself) and ".." (the parent of the directory). Most people skip those files with code like:

while ( defined ($file = readdir BIN) ) {
    next if $file =~ /^\.\.?$/;     # skip . and ..
    # ...
}

Like filehandles, bareword directory handles are per-package constructs. You can use the local *DIRHANDLE syntax to get a new bareword directory handle. Alternatively, pass an undefined scalar as the first argument to opendir and Perl will put a new indirect directory handle into that scalar:

opendir my $dh, $directory or die;
while (defined ($filename = readdir($dh))) {
  # ...
}
closedir $dh;

Or, finally, you can use DirHandle to get an object-oriented view of a directory handle. The following code uses DirHandle and produces a sorted list of plain files that aren't dotfiles (that is, their names don't begin with a "."):

use DirHandle;

sub plainfiles {
   my $dir = shift;
   my $dh = DirHandle->new($dir)   or die "can't opendir $dir: $!";
   return sort                       # sort pathnames
          grep {    -f     }         # choose only "plain" files
          map  { "$dir/$_" }         # create full paths
          grep {  !/^\./   }         # filter out dot files
          $dh->read( );             # read all entries
}

DirHandle's read method behaves just like readdir, returning all remaining filenames. The bottom grep returns only those that don't begin with a period. The map turns the filenames returned by read into fully qualified filenames, and the top grep filters out directories, links, etc. The resulting list is then sort ed and returned.

In addition to readdir, there's also rewinddir (to move the directory handle back to the start of the filename list), seekdir (to move to a specific offset in the list), and telldir (to find out how far from the start of the list you are).

9.5.4. See Also

The closedir, opendir, readdir, rewinddir, seekdir, and telldir functions in perlfunc(1) and in Chapter 29 of Programming Perl; documentation for the standard DirHandle module (also in Chapter 32 of Programming Perl)

Previous | Home | Next
9.4. Recognizing Two Names for the Same File | Book Index | 9.6. Globbing, or Getting a List of Filenames Matching a Pattern
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.6. Globbing, or Getting a List of Filenames Matching a Pattern

9.6.1. Problem

You want to get a list of filenames similar to those produced by MS-DOS's *.* and Unix's *.h. This is called globbing, and the filename wildcard expression is called a glob, or occasionally a fileglob to distinguish it from a typeglob.

9.6.2. Solution

Perl provides globbing with the semantics of the Unix C shell through the glob keyword and <>:

@list = <*.c>;
@list = glob("*.c");

You can also use readdir to extract the filenames manually:

opendir(DIR, $path);
@files = grep { /\.c$/ } readdir(DIR);
closedir(DIR);

9.6.3. Discussion

In versions of Perl before v5.6, Perl's built-in glob and <WILDCARD> notation (not to be confused with <FILEHANDLE>) ran an external program (often the csh shell) to get the list of filenames. This led to globbing being tarred with security and performance concerns. As of v5.6, Perl uses the File::Glob module to glob files, which solves the security and performance problems of the old implementation. Globs have C shell semantics on non-Unix systems to encourage portability. In particular, glob syntax isn't regular expression syntax—glob uses ? to mean "any single character" and * to mean "zero or more characters," so glob("f?o*") matches flo and flood but not fo.

For complex rules about which filenames you want, roll your own selection mechanism using readdir and regular expressions.

At its simplest, an opendir solution uses grep to filter the list returned by readdir:

@files = grep { /\.[ch]$/i } readdir(DH);

As always, the filenames returned don't include the directory. When you use the filename, prepend the directory name to get the full pathname:

opendir(DH, $dir)        or die "Couldn't open $dir for reading: $!";

@files = ( );
while( defined ($file = readdir(DH)) ) {
    next unless /\.[ch]$/i;

    my $filename = "$dir/$file";
    push(@files, $filename) if -T $filename;
}

The following example combines directory reading and filtering with the efficient sorting technique from Recipe 4.16. It sets @dirs to a sorted list of the subdirectories in a directory whose names are all numeric:

@dirs = map  { $_->[1] }                # extract pathnames
        sort { $a->[0] <=> $b->[0] }    # sort names numeric
        grep { -d $_->[1] }             # path is a dir
        map  { [ $_, "$path/$_" ] }     # form (name, path)
        grep { /^\d+$/ }                # just numerics
        readdir(DIR);                   # all files

Recipe 4.16 explains how to read these strange-looking constructs. As always, formatting and documenting your code can make it much easier to read and understand.

9.6.4. See Also

The opendir, readdir, closedir, grep, map, and sort functions in perlfunc(1) and in Chapter 29 of Programming Perl; documentation for the standard DirHandle module (also in Chapter 32 of Programming Perl); the "I/O Operators" section of perlop(1), and the "Filename Globbing Operator" section of Chapter 2 of Programming Perl; we talk more about globbing in Recipe 6.9; Recipe 9.5

Previous | Home | Next
9.5. Processing All Files in a Directory | Book Index | 9.7. Processing All Files in a Directory Recursively
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.7. Processing All Files in a Directory Recursively

9.7.1. Problem

You want to do something to each file and subdirectory in a particular directory.

9.7.2. Solution

Use the standard File::Find module.

use File::Find;
sub process_file {
    # do whatever;
}
find(\&process_file, @DIRLIST);

9.7.3. Discussion

File::Find provides a convenient way to process a directory recursively. It does the directory scans and recursion for you. All you do is pass find a code reference and a list of directories. For each file in those directories, recursively, find calls your function.

Before calling your function, find by default changes to the directory being visited, whose path relative to the starting directory is stored in the $File::Find::dir variable. $_ is set to the basename of the file being visited, and the full path of that file can be found in $File::Find::name. Your code can set $File::Find::prune to true to tell find not to descend into the directory just seen.

This simple example demonstrates File::Find. We give find an anonymous subroutine that prints the name of each file visited and adds a / to the names of directories:

@ARGV = qw(.) unless @ARGV;
use File::Find;
find sub { print $File::Find::name, -d && "/", "\n" }, @ARGV;

The -d file test operator returns the empty string '' if it fails, making the && return that, too. But if -d succeeds, the && returns "/", which is then printed.

The following program prints the total bytes occupied by everything in a directory, including subdirectories. It gives find an anonymous subroutine to keep a running sum of the sizes of each file it visits. That includes all inode types, including the sizes of directories and symbolic links, not just regular files. Once the find function returns, the accumulated sum is displayed.

use File::Find;
@ARGV = (".") unless @ARGV;
my $sum = 0;
find sub { $sum += -s }, @ARGV;
print "@ARGV contains $sum bytes\n";

This code finds the largest single file within a set of directories:

use File::Find;
@ARGV = (".") unless @ARGV;
my ($saved_size, $saved_name) = (-1, "");
sub biggest {
    return unless -f && -s _ > $saved_size;
    $saved_size = -s _;
    $saved_name = $File::Find::name;
}
find(\&biggest, @ARGV);
print "Biggest file $saved_name in @ARGV is $saved_size bytes long.\n";

We use $saved_size and $saved_name to keep track of the name and the size of the largest file visited. If we find a file bigger than the largest seen so far, we replace the saved name and size with the current ones. When the find finishes, the largest file and its size are printed out, rather verbosely. A more general tool would probably just print the filename, its size, or both. This time we used a named function rather than an anonymous one because the function was getting big.

It's simple to change this to find the most recently changed file:

use File::Find;
@ARGV = (".") unless @ARGV;
my ($age, $name);
sub youngest {
    return if defined $age && $age > (stat($_))[9];
    $age = (stat(_))[9];
    $name = $File::Find::name;
}
find(\&youngest, @ARGV);
print "$name " . scalar(localtime($age)) . "\n";

The File::Find module doesn't export its $name variable, so always refer to it by its fully qualified name. Example 9-2 is more a demonstration of namespace munging than of recursive directory traversal, although it does find all directories. It makes $name in our current package an alias for the one in File::Find, which is essentially how Exporter works. Then it declares its own version of find with a prototype so it can be called like grep or map.

Example 9-2. fdirs

  #!/usr/bin/perl -lw
  # fdirs - find all directories
  @ARGV = qw(.) unless @ARGV;
  use File::Find ( );
  sub find(&@) { &File::Find::find }
  *name = *File::Find::name;
  find { print $name if -d } @ARGV;

Our own find only calls the find in File::Find, which we were careful not to import by specifying an ( ) empty list in the use statement. Rather than write this:

find sub { print $File::Find::name if -d }, @ARGV;

we can write the more pleasant:

find { print $name if -d } @ARGV;

9.7.4. See Also

The documentation for the standard File::Find and Exporter modules (also in Chapter 32 of Programming Perl); your system's find(1) manpage; Recipe 9.6

Previous | Home | Next
9.6. Globbing, or Getting a List of Filenames Matching a Pattern | Book Index | 9.8. Removing a Directory and Its Contents
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.8. Removing a Directory and Its Contents

9.8.1. Problem

You want to remove a directory tree recursively without using rm -r.

9.8.2. Solution

Use the finddepth function from File::Find, shown in Example 9-3.

Example 9-3. rmtree1

  #!/usr/bin/perl
  # rmtree1 - remove whole directory trees like rm -r
  use File::Find;
  die "usage: $0 dir ..\n" unless @ARGV;
  find {
      bydepth   => 1,
      no_chdir  => 1,
      wanted    => sub {
          if (!-l && -d _) {
              rmdir     or warn "couldn't rmdir directory $_: $!";
          } else {
              unlink    or warn "couldn't unlink file $_: $!";
          }
      }
  } => @ARGV;

Or use rmtree from File::Path, as shown in Example 9-4.

Example 9-4. rmtree2

  #!/usr/bin/perl
  # rmtree2 - remove whole directory trees like rm -r
  use File::Path;
  die "usage: $0 dir ..\n" unless @ARGV;
  foreach $dir (@ARGV) {
      rmtree($dir);
  }
WARNING:

These programs remove an entire directory tree. Use with extreme caution!

9.8.3. Discussion

The File::Find module supports an alternate interface in which find's first argument is a hash reference containing options and their settings. The bydepth option is the same as calling finddepth instead of find. This is guaranteed to visit all files beneath a directory before the directory itself, just what we need to remove a directory and its contents. The no_chdir option stops find from descending into directories during processing; under this option, $_ is the same as $File::Find::name. Finally, the wanted option takes a code reference, our old wanted( ) function.

We use two different functions, rmdir and unlink; both default to $_ if no argument is provided. The unlink function deletes only files, and rmdir deletes only empty directories. We need to use finddepth or the bydepth option to make sure we've first removed the directory's contents before we rmdir the directory itself.

We first check that the file isn't a symbolic link before determining whether it's a directory, because -d returns true for both a real directory and a symbolic link to a directory. stat, lstat, and file test operators like -d all use the syscall stat(2), which returns the file meta-information stored in the file's inode. These functions and operators cache that information in the special underscore (_) filehandle. This permits tests on the same file while avoiding redundant syscalls that would return the same information, slowly.

According to POSIX, if the directory is either the root directory (the mount point for the filesystems or the result of a chroot(2) syscall) or the current working directory of any process, it is unspecified whether the rmdir syscall succeeds, or whether it fails and sets errno ($! in Perl) to EBUSY ("Device busy"). Many systems tolerate the latter condition, but few the former.

9.8.4. See Also

The unlink, rmdir, lstat, and stat functions in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard File::Find module (also in Chapter 32 of Programming Perl); your system's rm(1) and stat(2) manpages; the -X section of perlfunc(1), and the "Named Unary and File Test Operators" section of Chapter 3 of Programming Perl

Previous | Home | Next
9.7. Processing All Files in a Directory Recursively | Book Index | 9.9. Renaming Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.9. Renaming Files

9.9.1. Problem

You have many files whose names you want to change.

9.9.2. Solution

Use a foreach loop and the rename function:

foreach $file (@NAMES) {
    my $newname = $file;
    # change $newname
    rename($file, $newname) or
        warn "Couldn't rename $file to $newname: $!\n";
}

9.9.3. Discussion

This is straightforward. rename takes two arguments. The first is the filename to change, and the second is its new name. Perl's rename is a frontend to the operating system's rename syscall, which typically won't rename files across filesystem boundaries.

A small change turns this into a generic rename script, such as the one by Larry Wall shown in Example 9-5.

Example 9-5. rename

  #!/usr/bin/perl -w
  # rename - Larry's filename fixer
  $op = shift or die "Usage: rename expr [files]\n";
  chomp(@ARGV = <STDIN>) unless @ARGV;
  for (@ARGV) {
      $was = $_;
      eval $op;
      die $@ if $@;
      rename($was,$_) unless $was eq $_;
  }

This script's first argument is Perl code that alters the filename (stored in $_) to reflect how you want the file renamed. It can do this because it uses an eval to do the hard work. It also skips rename calls when the filename is untouched. This lets you simply use wildcards like rename EXPR * instead of making long lists of filenames.

Here are five examples of calling the rename program from the shell:

% rename 's/\.orig$//'  *.orig
% rename "tr/A-Z/a-z/ unless /^Make/"  *
% rename '$_ .= ".bad"'  *.f
% rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i'  *
% find /tmp -name "*~" -print | rename 's/^(.+)~$/.#$1/'

The first shell command removes a trailing ".orig" from each filename.

The second converts uppercase to lowercase. Because a translation is used rather than the lc function, this conversion won't be locale-aware. To fix that, you'd have to write:

% rename 'use locale; $_ = lc($_) unless /^Make/' *

The third appends ".bad" to each Fortran file ending in ".f", something many of us have wanted to do for a long time.

The fourth prompts the user for the change. Each file's name is printed to standard output and a response read from standard input. If the user types something starting with a "y" or "Y", any "foo" in the filename is changed to "bar".

The fifth uses find to locate files in /tmp that end with a tilde. It renames these so that instead of ending with a tilde, they start with a dot and a pound sign. In effect, this switches between two common conventions for backup files.

The rename script exemplifies the powerful Unix tool-and-filter philosophy. Even though we could have created a dedicated command for lowercase conversion, it's nearly as easy to write a flexible, reusable tool by embedding an eval. By reading filenames from standard input, we don't have to build in the recursive directory walk. Instead, we just use find, which performs this function well. There's no reason to recreate the wheel, although using File::Find we could have.

9.9.4. See Also

The rename function in perlfunc(1) and in Chapter 29 of Programming Perl; your system's mv(1) and rename(2) manpages; the documentation for the standard File::Find module (also in Chapter 32 of Programming Perl)

Previous | Home | Next
9.8. Removing a Directory and Its Contents | Book Index | 9.10. Splitting a Filename into Its Component Parts
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.10. Splitting a Filename into Its Component Parts

9.10.1. Problem

You want to extract a filename, its enclosing directory, or the extension(s) from a string that contains a full pathname.

9.10.2. Solution

Use routines from the standard File::Basename module.

use File::Basename;

$base = basename($path);
$dir  = dirname($path);
($base, $dir, $ext) = fileparse($path);

9.10.3. Discussion

The standard File::Basename module contains routines to split up a filename. dirname and basename supply the directory and filename portions, respectively:

$path = "/usr/lib/libc.a";
$file = basename($path);
$dir  = dirname($path);

print "dir is $dir, file is $file\n";
# dir is /usr/lib, file is libc.a

The fileparse function can extract the extension. Pass fileparse the path to decipher and a regular expression that matches the extension. You must supply a pattern because an extension isn't necessarily dot-separated. Consider ".tar.gz": is the extension ".tar", ".gz", or ".tar.gz"? By specifying the pattern, you control which you get.

$path = "/usr/lib/libc.a";
($name,$dir,$ext) = fileparse($path,'\..*');

print "dir is $dir, name is $name, extension is $ext\n";
# dir is /usr/lib/, name is libc, extension is .a

By default, these routines parse pathnames using your operating system's normal conventions for directory separators by consulting the $^O ($OSNAME) variable, which holds a string identifying the platform you're running on. That value was determined when Perl was built and installed. You can change the default by calling the fileparse_set_fstype routine. This alters the behavior of subsequent calls to the File::Basename functions:

fileparse_set_fstype("MacOS");
$path = "Hard%20Drive:System%20Folder:README.txt";
($name,$dir,$ext) = fileparse($path,'\..*');

print "dir is $dir, name is $name, extension is $ext\n";
# dir is Hard%20Drive:System%20Folder, name is README, extension is .txt

To pull out just the extension, you might use this:

sub extension {
    my $path = shift;
    my $ext = (fileparse($path,'\..*'))[2];
    $ext =~ s/^\.//;
    return $ext;
}

When called on a file like source.c.bak, this returns an extension of "c.bak", not just "bak". If you want ".bak" returned, use '\.[^.]*' as the second argument to fileparse (this will, of course, leave the filename as source.c).

When passed a pathname with a trailing directory separator, such as "lib/", fileparse considers the directory name to be "lib/", whereas dirname considers it to be ".".

9.10.4. See Also

The documentation for the standard File::Basename module (also in Chapter 32 of Programming Perl); the entry for $^O ($OSNAME) in perlvar(1), and in the "Special Variables in Alphabetical Order" section of Chapter 28 of Programming Perl

Previous | Home | Next
9.9. Renaming Files | Book Index | 9.11. Working with Symbolic File Permissions Instead of Octal Values
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.11. Working with Symbolic File Permissions Instead of Octal Values

9.11.1. Problem

You want to print, inspect, or change permissions on a file or directory, but you don't want to specify the permissions in octal (e.g., 0644, 0755). You want to print permissions as ls(1) shows them (e.g., -rwx-r-xr-x) and specify permissions changes in the way that chmod(1) does (e.g., g-w to remove write access for the group).

9.11.2. Solution

Use the CPAN module Stat::lsMode to convert numeric permissions to a string:

use Stat::lsMode;

$lsmode = file_mode($pathname);

Use the CPAN module File::chmod to manipulate symbolic permissions:

use File::chmod;

chmod("g=rw,o=-w", @files);    # group can read/write, others can't write
chmod("-rwxr-xr--", @files);   # ls-style permissions

9.11.3. Discussion

The Stat::lsMode module provides functions for generating ls-style permissions strings. The file_mode function takes a pathname and returns a permissions string. This string is false if the pathname doesn't exist or Perl can't stat it. If all goes well, you get a string like "drwxr-x---" for a directory or "-rwxr-x----" for a file. For more fine-grained control, Stat::lsMode offers format_mode, which takes a numeric permissions value and returns the 10-character ls-style string.

Notice the leading d and - in those strings. This indicates the type of file whose permissions you're inspecting: - means regular file, d means directory, l means symbolic link, and so on. The format_perms function from Stat::lsMode does the same job as format_mode, but it returns a nine-character string, which does not have the type indicator. For example:

use Stat::lsMode;
print file_mode("/etc"), "\n";
print format_mode((stat "/etc")[2]), "\n";
drwxr-xr-x
r-xr-xr-x

The File::chmod module gives you a chmod that accepts these nine-character permissions strings:

use File::chmod;
chmod("rwxr-xr-x", @files);

These strings are three clusters of three characters. The three clusters represent what the user, group, and others can do to the file (respectively). The three characters represent reading, writing, and executing, with a dash (-) in a column indicating the corresponding permission is denied to the group. So in "rwxrw-r--", the owner can read, write, and execute; users in the same group as the file can read and write but not execute; and everyone else can only read.

You can specify relative changes to the permissions for a particular file; for example, g-w removes write permission from the group. The first letter(s) indicates whose permissions are being changed (user, group, other, or a combination). Then comes a + or - to indicate adding or removing permissions, or = to indicate you're specifying the complete set of permissions. Then you specify some or all of rwx. You can join these with commas to form relative permissions; for example, g-w,o+x (remove write from group, add execute to other). If you omit the u, g, or o, then the change applies to everyone.

Here are some valid permissions changes and what they do:

u=                  remove all permissions for the user
g=r                 group can only read
g+wx                group can also write and execute
g=rwx,o=rx          group can do all, other can only read and execute
=rwx                everybody can do everything

So you can now say:

chmod("u=", @files);  # remove all permissions for the user on @files
chmod("g=r", @files);
chmod("g+wx", @files);
chmod("g=rwx,o-rx", @files);
chmod("=rwx", @files);

File::chmod also provides functions for seeing what the new permission would be without actually making the change. See the File::chmod documentation for more details.

9.11.4. See Also

The documentation for the CPAN modules File::chmod and Stat::lsMode; the chmod and stat functions in perlfunc(1)

Previous | Home | Next
9.10. Splitting a Filename into Its Component Parts | Book Index | 9.12. Program: symirror
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.12. Program: symirror

The program in Example 9-6 recursively duplicates a directory tree, making a shadow forest full of symlinks pointing back at the real files.

Example 9-6. symirror

#!/usr/bin/perl
# symirror - build spectral forest of symlinks

use warnings;
use strict;

use Cwd         qw(realpath);
use File::Find  qw(find);

die "usage: $0 realdir mirrordir" unless @ARGV == 2;

our $SRC = realpath $ARGV[0];
our $DST = realpath $ARGV[1];

my $oldmask = umask 077;        # in case was insanely uncreatable
chdir $SRC                      or die "can't chdir $SRC: $!";
unless (-d $DST) {
    mkdir($DST, 0700)           or die "can't mkdir $DST: $!";
}
find {
    wanted      => \&shadow,
    postprocess => \&fixmode,
} => ".";
umask $oldmask;

sub shadow {
    (my $name = $File::Find::name) =~ s!^\./!!;     # correct name
    return if $name eq ".";
    if (-d) { # make a real dir; we'll copy mode later
        mkdir("$DST/$name", 0700)
                        or die "can't mkdir $DST/$name: $!";
    } else {  # all else gets symlinked
        symlink("$SRC/$name", "$DST/$name")
                        or die "can't symlink $SRC/$name to $DST/$name: $!";
    }
}

sub fixmode {
    my $dir = $File::Find::dir;
    my $mode = (stat("$SRC/$dir"))[2] & 07777;
    chmod($mode, "$DST/$dir")
        or die "can't set mode on $DST/$dir: $!";
}
Previous | Home | Next
9.11. Working with Symbolic File Permissions Instead of Octal Values | Book Index | 9.13. Program: lst
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.13. Program: lst

Have you ever wondered what the newest or biggest files within a directory are? The standard ls program has options for listing out directories sorted in time order (the -t flag) and for recursing into subdirectories (the -R flag). However, it pauses at each directory to display the sorted contents of just that directory. It doesn't descend through all subdirectories first and then sort everything it found.

The following lst program does that. Here's an example using its -l flag to get a long listing:

% lst -l /etc
12695 0600      1     root    wheel      512 Fri May 29 10:42:41 1998
    /etc/ssh_random_seed
12640 0644      1     root    wheel    10104 Mon May 25  7:39:19 1998
    /etc/ld.so.cache
12626 0664      1     root    wheel    12288 Sun May 24 19:23:08 1998
    /etc/psdevtab
12304 0644      1     root     root      237 Sun May 24 13:59:33 1998
    /etc/exports
12309 0644      1     root     root     3386 Sun May 24 13:24:33 1998
    /etc/inetd.conf
12399 0644      1     root     root    30205 Sun May 24 10:08:37 1998
    /etc/sendmail.cf
18774 0644      1     gnat  perldoc     2199 Sun May 24  9:35:57 1998
    /etc/X11/XMetroconfig
12636 0644      1     root    wheel      290 Sun May 24  9:05:40 1998
    /etc/mtab
12627 0640      1     root     root        0 Sun May 24  8:24:31 1998
    /etc/wtmplock
12310 0644      1     root  tchrist       65 Sun May 24  8:23:04 1998
    /etc/issue
....

/etc/X11/XMetroconfig showed up in the middle of the listing for /etc because it wasn't just for /etc, but for everything within that directory, recursively.

Other supported options include sorting on read time instead of write time using -u and sorting on size rather than time with -s. The -i flag takes the list of filenames from standard input instead of recursing with find. That way, if you already had a list of filenames, you could feed them to lst for sorting.

The program is shown in Example 9-7.

Example 9-7. lst

  #!/usr/bin/perl
  # lst - list sorted directory contents (depth first)

  use Getopt::Std;
  use File::Find;
  use File::stat;
  use User::pwent;
  use User::grent;

  getopts("lusrcmi")                            or die << DEATH;
  Usage: $0 [-mucsril] [dirs ...]
   or    $0 -i [-mucsrl] < filelist

  Input format:
      -i  read pathnames from stdin
  Output format:
      -l  long listing
  Sort on:
      -m  use mtime (modify time) [DEFAULT]
      -u  use atime (access time)
      -c  use ctime (inode change time)
      -s  use size for sorting
  Ordering:
      -r  reverse sort
  NB: You may only use select one sorting option at a time.
  DEATH

  unless ($opt_i || @ARGV) { @ARGV = (".") }

  if ($opt_c + $opt_u + $opt_s + $opt_m > 1) {
      die "can only sort on one time or size";
  }

  $IDX = "mtime";
  $IDX = "atime" if $opt_u;
  $IDX = "ctime" if $opt_c;
  $IDX = "size"  if $opt_s;

  $TIME_IDX = $opt_s ? "mtime" : $IDX;

  *name = *File::Find::name;  # forcibly import that variable

  # the $opt_i flag tricks wanted into taking
  # its filenames from ARGV instead of being
  # called from find.

  if ($opt_i) {
       *name = *_;  # $name now alias for $_
       while (<>) { chomp; &wanted; }   # ok, not stdin really
  }  else {
      find(\&wanted, @ARGV);
  }

  # sort the files by their cached times, youngest first
  @skeys = sort { $time{$b} <=> $time{$a} } keys %time;

  # but flip the order if -r was supplied on command line
  @skeys = reverse @skeys if $opt_r;

  for (@skeys) {
      unless ($opt_l) {  # emulate ls -l, except for permissions
          print "$_\n";
          next;
      }
      $now = localtime $stat{$_}->$TIME_IDX( );
      printf "%6d %04o %6d %8s %8s %8d %s %s\n",
              $stat{$_}->ino( ),
              $stat{$_}->mode( ) & 07777,
              $stat{$_}->nlink( ),
              user($stat{$_}->uid( )),
              group($stat{$_}->gid( )),
              $stat{$_}->size( ),
              $now, $_;
  }

  # get stat info on the file, saving the desired
  # sort criterion (mtime, atime, ctime, or size)
  # in the %time hash indexed by filename.
  # if they want a long list, we have to save the
  # entire stat object in %stat.  yes, this is a
  # hash of objects
  sub wanted {
      my $sb = stat($_);  # XXX: should be stat or lstat?
      return unless $sb;
      $time{$name} = $sb->$IDX( );  # indirect method call
      $stat{$name} = $sb if $opt_l;
  }

  # cache user number to name conversions; don't worry
  # about the apparently extra call, as the system caches the
  # last one called all by itself
  sub user {
      my $uid = shift;
      $user{$uid} = getpwuid($uid) ? getpwuid($uid)->name : "#$uid"
          unless defined $user{$uid};
      return $user{$uid};
  }

  # cache group number to name conversions; ditto on unworryness
  sub group {
      my $gid = shift;
      $group{$gid} = getgrgid($gid) ? getgrgid($gid)->name : "#$gid"
          unless defined $group{$gid};
      return $group{$gid};

  }
Previous | Home | Next
9.12. Program: symirror | Book Index | 10. Subroutines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 10. Subroutines

Contents:

Introduction
Accessing Subroutine Arguments
Making Variables Private to a Function
Creating Persistent Private Variables
Determining Current Function Name
Passing Arrays and Hashes by Reference
Detecting Return Context
Passing by Named Parameter
Skipping Selected Return Values
Returning More Than One Array or Hash
Returning Failure
Prototyping Functions
Handling Exceptions
Saving Global Values
Redefining a Function
Trapping Undefined Function Calls with AUTOLOAD
Nesting Subroutines
Writing a Switch Statement
Program: Sorting Your Mail

W. H. Auden, "Three Songs for St Cecilia's Day"

Composing mortals with immortal fire.

10.0. Introduction

To avoid the dangerous practice of copying and pasting code, larger programs reuse chunks of code as subroutines and functions. We'll use the terms subroutine and function interchangeably because Perl doesn't distinguish between the two. Even object-oriented methods are just subroutines that are called using a special syntax, described in Chapter 13.

A subroutine is declared with the sub keyword. Here's a simple subroutine definition:

sub hello {
    $greeted++;          # global variable
    print "hi there!\n";
}

The typical way of calling that subroutine is:

hello( );                 # call subroutine hello with no arguments/parameters

Because Perl compiles your program before executing it, it doesn't matter where subroutines are declared. Definitions don't have to be in the same file as your main program. They can be pulled in from other files using the do, require, or use operators, as described in Chapter 12. They can even be created on the fly using eval or AUTOLOAD, or generated using closures, which can act as function templates.

If you are familiar with other programming languages, several characteristics of Perl's functions may surprise you if you're unprepared for them. Most recipes in this chapter illustrate how to be aware of—and to take advantage of—these properties.

  • Perl functions have no formal, named parameters, but this is not necessarily a bad thing. See Recipe 10.1 and Recipe 10.7.

  • All variables are global unless declared otherwise. See Recipe 10.2, Recipe 10.3, and Recipe 10.13 for details.

  • Passing or returning more than one array or hash normally causes them to lose their separate identities. See Recipe 10.5, Recipe 10.8, Recipe 10.9, and Recipe 10.11 to avoid this.

  • A function can know in which context it was called, how many arguments it was called with, and even which other function called it. See Recipe 10.4 and Recipe 10.6 to find out how.

  • Perl's undef value can be used to signal an error return from the function because no valid string, number, or reference ever has that value. Recipe 10.10 covers subtle pitfalls with undef you should avoid, and Recipe 10.12 shows how to deal with other catastrophic conditions.

  • Perl supports interesting operations on functions that you might not see in other languages, such as anonymous functions, creating functions on the fly, and calling them indirectly using function pointers. See Recipe 10.14 and Recipe 10.16 for these esoteric topics.

  • Calling a function as $x = &func; does not supply any arguments, but rather provides direct access to its caller's @_ array! If you omit the ampersand and use either func( ) or func, then a new and empty @_ is provided instead.

  • Historically, Perl hasn't provided a construct like C's switch or the shell's case for multiway branching. The switch function shown in Recipe 10.17 takes care of that for you.

Previous | Home | Next
9.13. Program: lst | Book Index | 10.1. Accessing Subroutine Arguments
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.1. Accessing Subroutine Arguments

10.1.1. Problem

You have written a function that takes arguments supplied by its caller, and you need to access those arguments.

10.1.2. Solution

The special array @_ holds the values passed in as the function's arguments. Thus, the first argument to the function is in $_[0], the second in $_[1], and so on. The number of arguments is simply scalar(@_).

For example:

sub hypotenuse {
    return sqrt( ($_[0] ** 2) + ($_[1] ** 2) );
}

$diag = hypotenuse(3,4);  # $diag is 5

Most subroutines start by copying arguments into named private variables for safer and more convenient access:

sub hypotenuse {
    my ($side1, $side2) = @_;
    return sqrt( ($side1 ** 2) + ($side2 ** 2) );
}

10.1.3. Discussion

It's been said that programming has only three nice numbers: zero, one, and however many you please. Perl's subroutine mechanism was designed to facilitate writing functions with as many—or as few—elements in the parameter and return lists as you wish. All incoming parameters appear as separate scalar values in the special array @_, which is automatically local to each function (see Recipe 10.13). To return a value or values from a subroutine, use the return statement with arguments. If there is no return statement, the return value is the result of the last evaluated expression.

Here are some sample calls to the hypotenuse function defined in the Solution:

print hypotenuse(3, 4), "\n";               # prints 5

@a = (3, 4);
print hypotenuse(@a), "\n";                 # prints 5

If you look at the arguments used in the second call to hypotenuse, it might appear that only one argument was passed: the array @a. This isn't what happens—the elements of @a are copied into the @_ array separately. Similarly, if you called a function with (@a, @b), you'd be giving it all arguments from both arrays. This is the same principle of flattened lists at work as in:

@both = (@men, @women);

The scalars in @_ are implicit aliases for the ones passed in, not copies. That means changing the elements of @_ in a subroutine changes the values in the subroutine's caller. This is a holdover from before Perl had proper references.

You can write functions that leave their arguments intact by copying the arguments to private variables like this:

@nums = (1.4, 3.5, 6.7);
@ints = int_all(@nums);        # @nums unchanged
sub int_all {
    my @retlist = @_;          # make safe copy for return
    for my $n (@retlist) { $n = int($n) }
    return @retlist;
}

You can also write functions that change their caller's variables:

@nums = (1.4, 3.5, 6.7);
trunc_em(@nums);               # @nums now (1,3,6)
sub trunc_em {
    for (@_) { $_ = int($_) }  # truncate each argument
}

Don't pass constants as arguments to a function that intends to modify those arguments; for example, don't call trunc_em(1.4, 3.5, 6.7). If you do, you'll get a runtime exception to the effect of Modification of a read-only value attempted at ....

The built-in functions chop and chomp are like that; they modify their caller's variables and return something else entirely. Beginning Perl programmers who notice regular functions that all return some new value—including int, uc, and readline— without modifying those functions' arguments sometimes incorrectly infer that chop and chomp work similarly. This leads them to write code like:

$line = chomp(<>);                  # WRONG

$removed_chars = chop($line);       # RIGHT
$removed_count = chomp($line);      # RIGHT

until they get the hang of how this pair really works. Given the vast potential for confusion, you might want to think twice before modifying @_ in your own subroutines, especially if you also intend to provide a distinct return value.

10.1.4. See Also

Chapter 6 of Programming Perl and perlsub(1)

Previous | Home | Next
10. Subroutines | Book Index | 10.2. Making Variables Private to a Function
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.2. Making Variables Private to a Function

10.2.1. Problem

Your subroutine needs temporary variables. You shouldn't use global variables, because another subroutine might also use the same variables.

10.2.2. Solution

Use my to declare a variable private to a region of your program:

sub somefunc {
    my $variable;                 # $variable is invisible outside somefunc( )
    my ($another, @an_array, %a_hash);     # declaring many variables at once

    # ...
}

10.2.3. Discussion

The my operator confines a variable to a particular region of code in which it can be used and accessed. Outside that region, it can't be accessed. This region is called its scope.

Variables declared with my have lexical scope, meaning that they exist only within a specific textual region of code. For instance, the scope of $variable in the Solution is the function it was defined in, somefunc. The variable is created when somefunc is entered, and it is destroyed when the function returns. The variable can be accessed only from inside the function, not from outside.

A lexical scope is usually a block of code with braces around it, such as those defining the body of the somefunc subroutine or those marking the code blocks of if, while, for, foreach, and eval. An entire source file and the string argument to eval are each a lexical scope;[17] think of them as blocks with invisible braces delimiting their confines. Because a lexical scope is most often found as a brace-delimited block, when discussing lexical variables we sometimes say that they are visible only in their block, but what we really mean is that they're visible only in their scope.

[17]Although not of the same sort: the eval scope is a nested scope, just like a nested block, but the file scope is unrelated to any other.

The code that can legally access a my variable is determined statically at compile time and never changes, and so lexical scoping is sometimes referred to as static scoping, especially when in contrast to dynamic scoping, a topic we'll cover in Recipe 10.13.

You can combine a my declaration with an assignment. Use parentheses when defining more than one variable:

my ($name, $age) = @ARGV;
my $start        = fetch_time( );

These lexical variables behave as you would expect of a local variable. Nested blocks can see lexicals declared in enclosing, outer blocks, but not in unrelated blocks:

my ($a, $b) = @pair;
my $c = fetch_time( );

sub check_x {
    my $x = $_[0];
    my $y = "whatever";
    run_check( );
    if ($condition) {
        print "got $x\n";
    }
}

In the preceding code, the if block inside the function can access the private $x variable. However, the run_check function called from within that scope cannot access $x or $y, because run_check was presumably defined in another scope. However, check_x can access $a, $b, or $c from the outer scope because the function was defined in the same scope as those three variables.

Don't nest definitions of named subroutines. If you do, they won't get the right bindings of the lexical variables. Recipe 10.16 shows how to cope with this restriction.

When a lexical variable goes out of scope, its storage is freed unless a reference to the variable still exists, as with @arguments in the following code:

sub save_array {
    my @arguments = @_;
    push(our @Global_Array, \@arguments);
}

This code creates a new array each time save_array is called, so you don't have to worry that it'll reuse the same array each time the function is called.

Perl's garbage collection system knows not to deallocate things until they're no longer used. This is why you can return a reference to a private variable without leaking memory.

10.2.4. See Also

The section on "Scoped Declarations" in Chapter 4 of Programming Perl and the section on "Private Variables via my( )" in perlsub(1)

Previous | Home | Next
10.1. Accessing Subroutine Arguments | Book Index | 10.3. Creating Persistent Private Variables
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.3. Creating Persistent Private Variables

10.3.1. Problem

You want a variable to retain its value between calls to a subroutine but not be visible outside that routine. For instance, you'd like your function to keep track of how many times it was called.

10.3.2. Solution

Wrap the function in another block, then declare my variables in that block's scope rather than in the function's:

{
    my $variable;
    sub mysub {
        # ... accessing $variable
    }
}

If the variables require initialization, make that block an INIT so the variable is guaranteed to be set before the main program starts running:

INIT {
    my $variable = 1;                       # initial value
    sub othersub {
      # ... accessing $variable
    }
}

10.3.3. Discussion

Unlike local[18] variables in C or C++, Perl's lexical variables don't necessarily get recycled just because their scope has exited. If something more permanent is still aware of the lexical, it will stick around. In this code, mysub uses $variable, so Perl doesn't reclaim the variable when the block around the definition of mysub ends.

[18]Technically speaking, auto variables.

Here's how to write a counter:

{
    my $counter;
    sub next_counter { return ++$counter }
}

Each time next_counter is called, it increments and returns the $counter variable. The first time next_counter is called, $counter is undefined, so it behaves as though it were 0 for the ++. The variable is not part of next_counter's scope, but rather part of the block surrounding it. No code from outside can change $counter except by calling next_counter.

Generally, you should use an INIT for the extra scope. Otherwise, you could call the function before its variables were initialized.

INIT {
    my $counter = 42;
    sub next_counter { return ++$counter }
    sub prev_counter { return --$counter }
}

This technique creates the Perl equivalent of C's static variables. Actually, it's a little better: rather than being limited to just one function, both functions share their private variable.

10.3.4. See Also

The sections on "Closures" in Chapter 8 of Programming Perl and on "Avante-Garde Compiler, Retro Interpreter" in Chapter 18 of Programming Perl; the section on "Private Variables via my( )" in perlsub(1); the section on "Package Constructors and Destructors" in perlmod(1); Recipe 11.4

Previous | Home | Next
10.2. Making Variables Private to a Function | Book Index | 10.4. Determining Current Function Name
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.4. Determining Current Function Name

10.4.1. Problem

You want to determine the name of the currently running function. This is useful for creating error messages that don't need to be changed if you copy and paste the subroutine code.

10.4.2. Solution

Use the caller function:

$this_function = (caller(0))[3];

10.4.3. Discussion

Code can always determine the current source line number via the special symbol _ _LINE_ _, the current file via _ _FILE_ _, and the current package via _ _PACKAGE_ _. But no such symbol for the current subroutine name exists, let alone the name for the subroutine that called this one.

The built-in function caller handles all of these. In scalar context it returns the calling function's package name, but in list context it returns much more. You can also pass it a number indicating how many frames (nested subroutine calls) back you'd like information about: 0 is your own function, 1 is your caller, and so on.

Here's the full syntax, where $i is how far back you're interested in:

($package, $filename, $line, $subr, $has_args, $wantarray
#   0         1         2       3       4          5
 $evaltext, $is_require, $hints, $bitmask
#   6         7            8       9
)= caller($i);

Here's what each of those return values means:

$package
The package in which the code was compiled.

$filename
The name of the file in which the code was compiled, reporting -e if launched from that command-line switch, or - if the script was read from standard input.

$line
The line number from which that frame was called.

$subr
The name of that frame's function, including its package. Closures are indicated by names like main::_ _ANON_ _, which are not callable. In an eval, it contains (eval).

$has_args
Whether the function had its own @_ variable set up. It may be that there are no arguments, even if true. The only way for this to be false is if the function was called using the &fn notation instead of fn( ) or &fn( ).

$wantarray
The value the wantarray function would return for that stack frame; either true, false but defined, or else undefined. This tells whether the function was called in list, scalar, or void context (respectively).

$evaltext
The text of the current eval STRING, if any.

$is_require
Whether the code is currently being loaded by a do, require, or use.

$hints, $bitmask
These both contain pragmatic hints that the caller was compiled with. Consider them to be for internal use only by Perl itself.

Rather than using caller directly as in the Solution, you might want to write functions instead:

$me  = whoami( );
$him = whowasi( );

sub whoami  { (caller(1))[3] }
sub whowasi { (caller(2))[3] }

These use arguments of 1 and 2 for parent and grandparent functions because the call to whoami or whowasi would itself be frame number 0.

10.4.4. See Also

The wantarray and caller functions in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 10.6

Previous | Home | Next
10.3. Creating Persistent Private Variables | Book Index | 10.5. Passing Arrays and Hashes by Reference
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.5. Passing Arrays and Hashes by Reference

10.5.1. Problem

You want to pass a function more than one array or hash and have each remain distinct. For example, you want to put the algorithm from Recipe 4.8 into a subroutine. This subroutine must then be called with two arrays that remain distinct.

10.5.2. Solution

Pass arrays and hashes by reference, using the backslash operator:

array_diff( \@array1, \@array2 );

10.5.3. Discussion

See Chapter 11 for more about manipulation of references. Here's a subroutine that expects array references, along with code to call it correctly:

@a = (1, 2);
@b = (5, 8);
@c = add_vecpair( \@a, \@b );
print "@c\n";
6 10

sub add_vecpair {                      # assumes both vectors the same length
    my ($x, $y) = @_;                  # copy in the array references
    my @result;

    for (my $i=0; $i < @$x; $i++) {
      $result[$i] = $x->[$i] + $y->[$i];
    }

    return @result;
}

A potential problem with this function is that it doesn't verify the number and types of arguments passed into it. You could check explicitly this way:

unless (@_ =  = 2 && ref($x) eq 'ARRAY' && ref($y) eq 'ARRAY') {
    die "usage: add_vecpair ARRAYREF1 ARRAYREF2";
}

If all you plan to do is die on error (see Recipe 10.12), you can sometimes omit this check, since dereferencing the wrong kind of reference triggers an exception anyway. However, good defensive programming style encourages argument validation for all functions.

10.5.4. See Also

The sections on "Passing References" and on "Prototypes" in Chapter 6 of Programming Perl and on "Pass by Reference" in perlsub(1); Recipe 10.11; Chapter 11; Chapter 8 of Programming Perl

Previous | Home | Next
10.4. Determining Current Function Name | Book Index | 10.6. Detecting Return Context
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.6. Detecting Return Context

10.6.1. Problem

You want to know in which context your function was called. This lets one function do different things, depending on how its return value or values are used, just like many of Perl's built-in functions.

10.6.2. Solution

Use the wantarray( ) function, which has three possible return values, depending on how the current function was called:

if (wantarray( )) {
    # list context
}
elsif (defined wantarray( )) {
    # scalar context
}
else {
    # void context
}

10.6.3. Discussion

Many built-in functions act differently when called in scalar context than they do when called in list context. A user-defined function can learn which context it was called in by checking wantarray. List context is indicated by a true return value. If wantarray returns a value that is false but defined, then the function's return value will be used in scalar context. If wantarray returns undef, your function isn't being asked to provide any value at all.

if (wantarray( )) {
    print "In list context\n";
    return @many_things;
} elsif (defined wantarray( )) {
    print "In scalar context\n";
    return $one_thing;
} else {
    print "In void context\n";
    return;  # nothing
}

mysub( );                    # void context

$a = mysub( );               # scalar context
if (mysub( )) {  }           # scalar context

@a = mysub( );               # list context
print mysub( );              # list context

10.6.4. See Also

The return and wantarray functions in Chapter 29 of Programming Perl and in perlfunc(1)

Previous | Home | Next
10.5. Passing Arrays and Hashes by Reference | Book Index | 10.7. Passing by Named Parameter
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.7. Passing by Named Parameter

10.7.1. Problem

You want to make a function with many parameters that are easy to call so that programmers remember what the arguments do, rather than having to memorize their order.

10.7.2. Solution

Name each parameter in the call:

thefunc(INCREMENT => "20s", START => "+5m", FINISH => "+30m");
thefunc(START => "+5m", FINISH => "+30m");
thefunc(FINISH => "+30m");
thefunc(START => "+5m", INCREMENT => "15s");

Then in the subroutine, create a hash loaded up with default values plus the array of named pairs.

sub thefunc {
    my %args = (
        INCREMENT   => '10s',
        FINISH      => 0,
        START       => 0,
        @_,         # argument pair list goes here
    );
    if ($args{INCREMENT}  =~ /m$/ ) { ... }
}

10.7.3. Discussion

Functions whose arguments require a particular order work well for short argument lists, but as the number of parameters increases, it's awkward to make some optional or have default values. You can only leave out trailing arguments, never initial ones.

A more flexible approach allows the caller to supply arguments using name-value pairs. The first element of each pair is the argument name; the second, its value. This makes for self-documenting code because you can see the parameters' intended meanings without having to read the full function definition. Even better, programmers using your function no longer have to remember argument order, and they can leave unspecified any extraneous, unused arguments.

This works by having the function declare a private hash variable to hold the default parameter values. Put the current arguments, @_, after the default values, so the actual arguments override the defaults because of the order of the values in the assignment.

A common variation on this is to preface the parameter name with a hyphen, intended to evoke the feel of command-line parameters:

thefunc(-START => "+5m", -INCREMENT => "15s");

Ordinarily the hyphen isn't part of a bareword, but the Perl tokenizer makes an exception for the => operator to permit this style of function argument.

10.7.4. See Also

Chapter 4

Previous | Home | Next
10.6. Detecting Return Context | Book Index | 10.8. Skipping Selected Return Values
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.8. Skipping Selected Return Values

10.8.1. Problem

You have a function that returns many values, but you only care about some of them. The stat function is a classic example: you often want only one value from its long return list (mode, for instance).

10.8.2. Solution

Either assign to a list that has undef in some positions:

($a, undef, $c) = func( );

or else take a slice of the return list, selecting only what you want:

($a, $c) = (func( ))[0,2];

10.8.3. Discussion

Using dummy temporary variables is wasteful; plus it feels artificial and awkward:

($dev,$ino,$DUMMY,$DUMMY,$uid) = stat($filename);

A nicer style is to use undef instead of dummy variables to discard a value:

($dev,$ino,undef,undef,$uid)   = stat($filename);

Or you can take a slice, picking up just the values you care about:

($dev,$ino,$uid,$gid)   = (stat($filename))[0,1,4,5];

If you want to put an expression into list context and discard all of its return values (calling it simply for side effects), you can assign this to the empty list:

( ) = some_function( );

This last strategy is rather like a list version of the scalar operator—it calls the function in list context, even in a place it wouldn't otherwise do so. You can get just a count of return values this way:

$count = ( ) = some_function( );

or you can call it in list context and make sure it returns some non-zero number of items (which you immediately discard) like this:

if (( ) = some_function( ))  { .... }

If you hadn't assigned to the empty list, the Boolean context of the if test would have called the function in scalar context.

10.8.4. See Also

The section on "List Values and Arrays" in Chapter 2 of Programming Perl and perlsub(1); Recipe 3.1

Previous | Home | Next
10.7. Passing by Named Parameter | Book Index | 10.9. Returning More Than One Array or Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.9. Returning More Than One Array or Hash

10.9.1. Problem

You want a function to return more than one array or hash, but the return list flattens into just one long list of scalars.

10.9.2. Solution

Return references to the hashes or arrays:

($array_ref, $hash_ref) = somefunc( );

sub somefunc {
    my @array;
    my %hash;

    # ...

    return ( \@array, \%hash );
}

10.9.3. Discussion

Just as all arguments collapse into one flat list of scalars, return values do, too. Functions that want to return multiple, distinct arrays or hashes need to return those by reference, and the caller must be prepared to receive references. If a function wants to return three separate hashes, for example, it should use one of the following:

sub fn {
    .....
    return (\%a, \%b, \%c); # or
    return \(%a,  %b,  %c); # same thing
}

The caller must expect a list of hash references returned by the function. It cannot just assign to three hashes.

(%h0, %h1, %h2)  = fn( );    # WRONG!
@array_of_hashes = fn( );    # eg: $array_of_hashes[2]{"keystring"}
($r0, $r1, $r2)  = fn( );    # eg: $r2->{"keystring"}

10.9.4. See Also

The general discussions on references in Chapter 11, and in Chapter 8 of Programming Perl; Recipe 10.5

Previous | Home | Next
10.8. Skipping Selected Return Values | Book Index | 10.10. Returning Failure
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.10. Returning Failure

10.10.1. Problem

You want to return a value indicating that your function failed.

10.10.2. Solution

Use a bare return statement without any argument, which returns undef in scalar context and the empty list ( ) in list context.

return;

10.10.3. Discussion

A return without an argument means:

sub empty_retval {
    return ( wantarray ? ( ) : undef );
}

You can't use just return undef, because in list context you will get a list of one value: undef. If your caller says:

if (@a = yourfunc( )) { ... }

then the "error" condition will be perceived as true because @a will be assigned (undef) and then evaluated in scalar context. This yields 1, the number of elements assigned to @a, which is true. You could use the wantarray function to see what context you were called in, but a bare return is a clear and tidy solution that always works:

unless ($a = sfunc( )) { die "sfunc failed" }
unless (@a = afunc( )) { die "afunc failed" }
unless (%a = hfunc( )) { die "hfunc failed" }

Some of Perl's built-in functions have a peculiar return value. Both fcntl and ioctl have the curious habit of returning the string "0 but true" in some circumstances. (This magic string is conveniently exempt from nagging warnings about improper numerical conversions.) This has the advantage of letting you write code like this:

ioctl(....) or die "can't ioctl: $!";

That way, code doesn't have to check for a defined zero as distinct from the undefined value, as it would for the read or glob functions. "0 but true" is zero when used numerically. It's rare that this kind of return value is needed. A more common (and spectacular) way to indicate failure in a function is to raise an exception, as described in Recipe 10.12.

10.10.4. See Also

The undef, wantarray, and return functions in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 10.12

Previous | Home | Next
10.9. Returning More Than One Array or Hash | Book Index | 10.11. Prototyping Functions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.11. Prototyping Functions

10.11.1. Problem

You want to use function prototypes so the compiler can check your argument types.

10.11.2. Solution

Perl has something of a prototype facility, but it isn't what you're thinking. Perl's function prototypes are more like a context coercion used to write functions that behave like some Perl built-ins, such as push and pop.

10.11.3. Discussion

Manually checking the validity of a function's arguments can't happen until runtime. If you make sure the function is declared before it is used, you can tickle the compiler into using a very limited form of prototype checking. But don't confuse Perl's function prototypes with those found in any other language.

A Perl function prototype is zero or more spaces, backslashes, or type characters enclosed in parentheses after the subroutine definition or name. A backslashed type symbol means that the argument is passed by reference, and the argument in that position must start with that type character.

A prototype can impose context on the prototyped function's arguments. This is done when Perl compiles your program. But this does not always mean that Perl checks the number or type of arguments; since a scalar prototype is like inserting a scalar in front of just one argument, sometimes an implicit conversion occurs instead. For example, if Perl sees func(3, 5) for a function prototyped as sub func ($), it will stop with a compile-time error. But if it sees func(@array) with the same prototype, it will merely put @array into scalar context instead of complaining that you passed an array, but it wanted a scalar.

This is so important that it bears repeating: don't use Perl prototypes expecting the compiler to check type and number of arguments for you. It does a little bit of that, sometimes, but mostly it's about helping you type less, and sometimes to emulate the calling and parsing conventions of built-in functions.

10.11.3.1. Omitting parentheses

Ordinarily your subroutines take a list of arguments, and you can omit parentheses on the function call if the compiler has already seen a declaration or definition for that function:

@results = reverse myfunc 3, 5;

Without prototypes, this is the same as:

@results = reverse(myfunc(3, 5));

Without parentheses, Perl puts the righthand side of the subroutine call into list context. You can use prototypes to change this behavior. Here is a function that's prototyped to take just one argument:

sub myfunc($);
@results = reverse myfunc 3, 5;

Now this is the same as:

@results = reverse(myfunc(3), 5);

Notice how the scalar prototype has altered the Perl parser! It grabs only the next thing it sees, leaving what remains for whatever other function is looking for arguments.

A void prototype like:

sub myfunc( );

will also alter the parser, causing no arguments to be passed to the function. This works just like the time built-in.

That means that in the absence of parentheses, you cannot know what is going on by casual inspection. Things that look the same can quietly behave completely differently from one another. Consider these declarations and assignments:

sub fn0( );
sub fn1($);
sub fnN(@);

$x = fn0 + 42;
$x = fn1 + 42;

$y = fnN fn1 + 42, fn0 + 42;
$y = fnN fn0 + 42, fn1 + 42;

$z = fn1 fn1 + 42, fn1 + 42;
$z = fnN fnN + 42, fnN + 42;

Astonishingly enough, those are parsed by the Perl compiler as though they'd been written this way:

$x = fn0( ) + 42;
$x = fn1(42);

$y = fnN(fn1(42), fn0( ) + 42);
$y = fnN(fn0( ) + 42, fn1(42));

$z = fn1(fn1(42)), fn1(42);
$z = fnN(fnN(42, fnN(42)));

Without first looking closely at the prototypes and then thinking really hard about how Perl's parser works, you'd never be able to predict that. Maintainability would suffer horribly.

This is one strong argument for using more parentheses than might be demanded by purely precedential concerns (or, alternatively, this is an argument for avoiding prototypes).

10.11.3.2. Mimicking built-ins

The other common use of prototypes is to give the convenient pass-without-flattening behavior of built-in functions like push and shift. When you call push as push(@array, 1, 2, 3) the function gets a reference to @array instead of the actual array. This is accomplished by backslashing the @ character in the prototype:

sub mypush (\@@) {
  my $array_ref = shift;
  my @remainder = @_;

  # ...
}

The \@ in the prototype says "require the first argument to begin with an @ character, and pass it by reference." The second @ says "the rest of the arguments are a (possibly empty) list." A backslash in a prototype requires that the argument actually begin with the literal type character, which can sometimes be annoying. You can't even use the conditional ?: construct to pick which array to pass:

mypush( $x > 10 ? @a : @b, 3, 5 );           # WRONG

Instead, you must play games with references:

mypush( @{ $x > 10 ? \@a : \@b }, 3, 5 );    # RIGHT (but ugly)

Here's an hpush function that works like push, but on hashes. It uses a list of key-value pairs to add to an existing hash, overwriting any previous values associated with those keys.

sub hpush(\%@) {
    my $href = shift;
    while ( my ($k, $v) = splice(@_, 0, 2) ) {
        $href->{$k} = $v;
    }
}
hpush(%pieces, "queen" => 9, "rook" => 5);

You may also backslash several argument types simultaneously by using the \[ ] notation:

sub mytie ( \[$@%&*] $; @ )

That function accepts any of the five types and passes it by reference, followed by one mandatory scalar context argument and optional trailing list of remaining arguments.

You can discover a particular function's prototype using the prototype built-in function. For example, calling prototype("hpush") given the previous definition would return the string "\%@". You can even find out a built-in's prototype this way—if it has one, that is. Not all core built-ins can be emulated. For those that can, the prototype function returns what their built-in prototype is. Since you can always call a core built-in function like int as CORE::int, built-ins are deemed to reside in package CORE. For example:

for $func (qw/int reverse keys push open print/) {
    printf "Prototype for %s is %s\n", $func,
        prototype("CORE::$func") || "UNAVAILABLE";
}

Prototype for int is ;$
Prototype for reverse is @
Prototype for keys is \%
Prototype for push is \@@
Prototype for open is *;$@
Prototype for print is UNAVAILABLE

10.11.4. See Also

The prototype function in perlfunc(1); the section on "Prototypes" in Chapter 6 of Programming Perl and in perlsub(1); Recipe 10.5

Previous | Home | Next
10.10. Returning Failure | Book Index | 10.12. Handling Exceptions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.12. Handling Exceptions

10.12.1. Problem

How do you safely call a function that might raise an exception? How do you create a function that raises an exception?

10.12.2. Solution

Sometimes you encounter a problem so exceptional that merely returning an error isn't strong enough, because the caller could unintentionally ignore the error. Use die STRING from your function to trigger an exception:

die "some message";         # raise exception

The caller can wrap the function call in an eval to intercept that exception, then consult the special variable $@ to see what happened:

eval { func( ) };
if ($@) {
    warn "func raised an exception: $@";
}

10.12.3. Discussion

Raising exceptions is not a facility to be used lightly. Most functions should return an error using a bare return statement. Wrapping every call in an exception trap is tedious and unsightly, removing the appeal of using exceptions in the first place.

But, on rare occasions, failure in a function should cause the entire program to abort. Rather than calling the irrecoverable exit function, you should call die instead, which at least gives the programmer the chance to cope. If no exception handler has been installed via eval, then the program aborts at that point.

To detect this, wrap the call to the function with a block eval. The $@ variable will be set to the offending exception if one occurred; otherwise, it will be false.

eval { $val = func( ) };
warn "func blew up: $@" if $@;

Any eval catches all exceptions, not just specific ones. Usually you should propagate unexpected exceptions to an enclosing handler. For example, suppose your function raised an exception containing the string "Full moon!". You could safely trap that exception while letting others through by inspecting the $@ variable. Calling die without an argument uses the contents of $@ to construct a new exception string.

eval { $val = func( ) };
if ($@ && $@ !~ /Full moon!/) {
    die;    # re-raise unknown errors
}

If the function is part of a module, consider using the Carp module and call croak or confess instead of die. The only difference between die and croak is that with croak, the error appears to be from the caller's perspective, not the module's. The confess function, on the other hand, creates a full stack backtrace of who called whom and with what arguments.

Another intriguing possibility is for the function to detect that its return value is being completely ignored because the function was called in a void context. If that were returning an error indication would be useless, so raise an exception instead.

if (defined wantarray( )) {
        return;
} else {
    die "pay attention to my error!";
}

Of course, just because it's not voided doesn't mean the return value is being dealt with appropriately. But if it is voided, it's certainly not being checked.

There are CPAN modules that offer alternative ways of handling exceptions. The Error module offers try, catch, and throw notation instead of eval and die:

use Error ':try';
try {
   something( );
}
catch Error::Database with {
   my $e = shift;
   warn "Problem in " . $e->{'-database'} . " (caught)\n";
};

Error offers try, catch ... with, except, otherwise, and finally blocks for maximum flexibility in error handling. The Exception::Class module from CPAN lets you create classes of exceptions and objects to represent specific exceptions. The two modules can be combined so that you can catch these exception objects.

10.12.4. See Also

The $@ ($EVAL_ERROR) variable in Chapter 28 of Programming Perl and perlvar(1); the die and eval functions in Chapter 29 of Programming Perl and perlfunc(1); the documentation for the CPAN modules Error and Exception::Class; Recipe 10.15; Recipe 12.2; Recipe 16.21

Previous | Home | Next
10.11. Prototyping Functions | Book Index | 10.13. Saving Global Values
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.13. Saving Global Values

10.13.1. Problem

You need to temporarily save away the value of a global variable.

10.13.2. Solution

Use the local operator to save a previous global value, automatically restoring it when the current block exits:

our $age = 18;          # declare and set global variable
if (CONDITION) {
    local $age = 23;
    func( );         # sees temporary value of 23
} # Perl restores the old value at block exit

10.13.3. Discussion

Despite its name, Perl's local operator does not create a local variable. That's what my does. Instead, local merely preserves an existing value for the duration of its enclosing block. Hindsight shows that if local had been called save_value instead, much confusion could have been avoided.

Three places where you must use local instead of my are:

  1. You need to give a global variable a temporary value, especially $_.

  2. You need to create a local file or directory handle or a local function.

  3. You want to temporarily change just one element of an array or hash.

10.13.3.1. Using local( ) for temporary values for globals

The first situation is more apt to happen with predefined, built-in variables than with user variables. Often these are variables that Perl consults for hints for its high-level operations. In particular, any function that uses $_, implicitly or explicitly, should certainly have a local $_. This is annoyingly easy to forget to do. See Recipe 13.15 for one solution to this.

Another common target for local is the $/ variable, a global that implicitly affects the behavior of the readline operator used in <FH> operations.

$para = get_paragraph(*FH);        # pass filehandle glob
$para = get_paragraph(*FH);        # pass filehandle by glob reference
$para = get_paragraph(*IO{FH});    # pass filehandle by IO reference
sub get_paragraph {
    my $fh = shift;
    local $/ = '';
    my $paragraph = <$fh>;
    chomp($paragraph);
    return $paragraph;
}

10.13.3.2. Using local( ) for local handles

The second situation used to arise whenever you needed a local filehandle or directory handle—or more rarely, a local function.

$contents = get_motd( );
sub get_motd {
    local *MOTD;
    open(MOTD, "/etc/motd")        or die "can't open motd: $!";
    local $/ = undef;  # slurp full file;
    local $_ = <MOTD>;
    close (MOTD);
    return $_;
}

If you wanted to return the open filehandle, you'd use:

return *MOTD;

However, in modern releases of Perl, you would make use of the filehandle autovivification property:

$contents = get_motd( );
sub get_motd {
    my $motd;  # this will be filled in by the next line
    open($motd, "/etc/motd")        or die "can't open motd: $!";
    local $/ = undef;  # slurp full file;
    return scalar <$motd>;
}

When the function returns, the anonymous filehandle is automatically closed for you. However, if you'd chosen to return $motd, then it wouldn't be. This is explained more fully in the Introduction to Chapter 7.

10.13.3.3. Using local( ) on parts of aggregates

The third situation is exceedingly rare, except for one common case. Because the local operator is really a "save value" operator, you can use it to save off just one element of an array or hash, even if that array or hash is itself a lexical!

my @nums = (0 .. 5);
sub first {
    local $nums[3] = 3.14159;
    second( );
}
sub second {
    print "@nums\n";
}
second( );
0 1 2 3 4 5
first( );
0 1 2 3.14159 4 5

The only common use for this kind of thing is for temporary signal handlers.

sub first {
    local $SIG{INT} = 'IGNORE';
    second( );
}

Now while second is running, interrupt signals are ignored. When first returns, the previous value of $SIG{INT} is automatically restored.

Although a lot of old code uses local, it's definitely something to steer clear of when it can be avoided. Because local still manipulates the values of global variables, not local variables, you'll run afoul of use strict unless you declared the globals using our or the older use vars.

The local operator produces dynamic scoping or runtime scoping. This is in contrast with the other kind of scoping Perl supports, which is much more easily understood. That's the kind of scoping that my provides, known as lexical scoping, or sometimes as static or compile-time scoping.

With dynamic scoping, a variable is accessible if it's found in the current scope—or in the scope of any frames (blocks) in its entire subroutine call stack, as determined at runtime. Any functions called have full access to dynamic variables, because they're still globals, just ones with temporary values. Only lexical variables are safe from such tampering.

Old code that says:

sub func {
    local($x, $y) = @_;
    #....
}

can almost always be replaced without ill effect by the following:

sub func {
    my($x, $y) = @_;
    #....
}

The only case where code can't be so upgraded is when it relies on dynamic scoping. That would happen if one function called another, and the latter relied upon access to the former's temporary versions of the global variables $x and $y. Code that handles global variables and expects strange action at a distance instead of using proper parameters is fragile at best. Good programmers avoid this kind of thing like the plague. (The solution is to explicitly pass values as parameters, rather than storing them in shared global variables.)

If you come across old code that uses:

&func(*Global_Array);
sub func {
    local(*aliased_array) = shift;
    for (@aliased_array) { .... }
}

this should probably be changed into something like this:

func(\@Global_Array);
sub func {
    my $array_ref  = shift;
    for (@$array_ref) { .... }
}

They're using the old pass-the-typeglob strategy devised before Perl supported proper references. It's not a pretty thing.

10.13.4. See Also

The local, my, and our functions in Chapter 29 of Programming Perl and perlfunc(1); Chapter 6 of Programming Perl; the section on "Scoped Declarations" in Chapter 4 of Programming Perl; the sections on "Private Variables via my( )" and "Temporary Values via local( )" in perlsub(1); Recipe 10.2; Recipe 10.16

Previous | Home | Next
10.12. Handling Exceptions | Book Index | 10.14. Redefining a Function
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.14. Redefining a Function

10.14.1. Problem

You want to temporarily or permanently redefine a function, but functions can't be assigned to.

10.14.2. Solution

To redefine a function, assign a new code reference to the typeglob of the name of that function. Use local if you want this redefinition to be temporary.

undef &grow;                       # silence -w complaints of redefinition
*grow = \&expand;
grow( );                          # calls expand( )

{
    local *grow = \&shrink;        # only until this block exists
    grow( );                      # calls shrink( )
}

10.14.3. Discussion

Unlike a variable (but like named filehandles, directory handles, and formats), a named function cannot be directly assigned to. It's just a name and doesn't vary. You can manipulate it almost as though it were a variable, because you can directly manipulate the runtime symbol table using typeglobs like *foo to produce interesting aliasing effects.

Assigning a reference to a typeglob changes what is accessed the next time a symbol of the referent's type is needed. This is what the Exporter does when you import a function or variable from one package into another. Since this is direct manipulation of the package symbol table, it works only on package variables (globals), not lexicals.

*one::var = \%two::Table;   # make %one::var alias for %two::Table
*one::big = \&two::small;   # make &one::big alias for &two::small

A typeglob is one of those things you can only use local on, not my. If you do use local, the aliasing effect is then limited to the duration of the current block.

local *fred = \&barney;     # temporarily alias &fred to &barney

If the value assigned to a typeglob is not a reference but itself another typeglob, then all types by that name are aliased. The types aliased in a full typeglob assignment are scalar, array, hash, function, filehandle, directory handle, and format. That means that assigning *Top = *Bottom would make the current package variable $Top an alias for $Bottom, @Top for @Bottom, %Top for %Bottom, and &Top for &Bottom. It would even alias the corresponding file and directory handles and formats! You probably don't want to do this.

Use assignments to typeglobs together with closures to clone a bunch of similar functions cheaply and easily. Imagine you wanted a function for HTML generation to help with colors. For example:

$string = red("careful here");
print $string;
<FONT COLOR='red'>careful here</FONT>

You could write the red function this way:

sub red { "<FONT COLOR='red'>@_</FONT>" }

If you need more colors, you could do something like this:

sub color_font {
    my $color = shift;
    return "<FONT COLOR='$color'>@_</FONT>";
}
sub red    { color_font("red", @_)     }
sub green  { color_font("green", @_)   }
sub blue   { color_font("blue", @_)    }
sub purple { color_font("purple", @_)  }
# etc

The similar nature of these functions suggests that there may be a way to factor out the common bit. To do this, use an assignment to an indirect typeglob. If you're running with the highly recommended use strict pragma, you must first disable strict "refs" for that block.

@colors = qw(red blue green yellow orange purple violet);
for my $name (@colors) {
    no strict 'refs';
    *$name = sub { "<FONT COLOR='$name'>@_</FONT>" };
}

These functions all seem independent, but the real code was compiled only once. This technique saves on compile time and memory use. To create a proper closure, any variables in the anonymous subroutine must be lexicals. That's the reason for the my on the loop iteration variable.

This is one of the few places where giving a prototype to a closure is sensible. If you wanted to impose scalar context on the arguments of these functions (probably not a wise idea), you could have written it this way instead:

*$name = sub ($) { "<FONT COLOR='$name'>$_[0]</FONT>" };

However, since prototype checking happens at compile time, the preceding assignment happens too late to be useful. So, put the whole loop of assignments within a BEGIN block, forcing it to occur during compilation. You really want to use a BEGIN here, not an INIT, because you're doing something that you want the compiler itself to notice right away, not something for the interpreter to do just before your program runs.

10.14.4. See Also

The sections on "Symbol Tables" in Chapter 10 of Programming Perl and in perlmod(1); the sections on "Closures" and "Symbol Table References" in Chapter 8 of Programming Perl; the discussion of closures in perlref(1); Recipe 10.11; Recipe 11.4

Previous | Home | Next
10.13. Saving Global Values | Book Index | 10.15. Trapping Undefined Function Calls with AUTOLOAD
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.15. Trapping Undefined Function Calls with AUTOLOAD

10.15.1. Problem

You want to intercept calls to undefined functions so you can handle them gracefully.

10.15.2. Solution

Declare a function called AUTOLOAD for the package whose undefined function calls you'd like to trap. While running, that package's $AUTOLOAD variable contains the name of the undefined function being called.

10.15.3. Discussion

Another strategy for creating similar functions is to use a proxy function. If you call an undefined function, instead of automatically raising an exception, you can trap the call. If the function's package has a function named AUTOLOAD, then this function is called in its place, with the special package global $AUTOLOAD set to the package-qualified function name. The AUTOLOAD subroutine can then do whatever that function would do.

sub AUTOLOAD {
    my $color = our $AUTOLOAD;
    $color =~ s/.*:://;
    return "<FONT COLOR='$color'>@_</FONT>";
}
#note: sub chartreuse isn't defined.
print chartreuse("stuff");

When the nonexistent main::chartreuse function is called, rather than raising an exception, main::AUTOLOAD is called with the same arguments as you passed chartreuse. The package variable $AUTOLOAD would contain the string main::chartreuse because that's the function it's proxying.

The technique using typeglob assignments shown in Recipe 10.14 is faster and more flexible than using AUTOLOAD. It's faster because you don't have to run the copy and substitute. It's more flexible because it lets you do this:

{
    local *yellow = \&violet;
    local (*red, *green) = (\&green, \&red);
    print_stuff( );
}

While print_stuff( ) is running, including from within any functions it calls, anything printed in yellow will come out violet, and the red and green texts will exchange colors.

Aliasing subroutines like this won't handle calls to undefined subroutines. AUTOLOAD does.

10.15.4. See Also

The section on "Autoloading" in Chapter 10 of Programming Perl and in perlsub(1); the documentation for the standard modules AutoLoader and AutoSplit; Recipe 10.12; Recipe 12.11; Recipe 13.12

Previous | Home | Next
10.14. Redefining a Function | Book Index | 10.16. Nesting Subroutines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.16. Nesting Subroutines

10.16.1. Problem

You want subroutines to nest, such that one subroutine is visible and callable only from another. When you try the obvious approach of nesting sub FOO { sub BAR { } ... }, Perl gives warnings about variables that will not stay shared.

10.16.2. Solution

Instead of making the inner functions normal subroutines, make them closures and temporarily assign their references to the typeglob of the right name to create a localized function.

10.16.3. Discussion

If you use nested subroutines in other programming languages with their own private variables, you'll have to work at it a bit in Perl. The intuitive coding of this kind of thing gives the warning "will not stay shared." For example, this won't work:

sub outer {
    my $x = $_[0] + 35;
    sub inner { return $x * 19 }   # WRONG
    return $x + inner( );
}

The following is a workaround:

sub outer {
    my $x = $_[0] + 35;
    local *inner = sub { return $x * 19 };
    return $x + inner( );
}

Now inner( ) can be called only from within outer( ) because of the temporary assignments of the closure. Once called, it has normal access to the lexical variable $x from the scope of outer( ).

This essentially creates a function local to another function, something not directly supported in Perl; however, the programming isn't always clear.

10.16.4. See Also

The sections on "Symbol Tables" in Chapter 10 in Programming Perl and in perlmod(1); the sections on "Closures" and "Symbol Table References" in Chapter 8 of Programming Perl and the discussion of closures in perlref(1); Recipe 10.13; Recipe 11.4

Previous | Home | Next
10.15. Trapping Undefined Function Calls with AUTOLOAD | Book Index | 10.17. Writing a Switch Statement
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.17. Writing a Switch Statement

10.17.1. Problem

You want to write a multiway branch statement, much as you can in C using its switch statement or in the shell using case—but Perl seems to support neither.

10.17.2. Solution

Use the Switch module, standard as of the v5.8 release of Perl.

use Switch;
switch ($value) {
    case 17         { print "number 17"       }
    case "snipe"    { print "a snipe"         }
    case /[a-f]+/i  { print "pattern matched" }
    case [1..10,42] { print "in the list"     }
    case (@array)   { print "in the array"    }
    case (%hash)    { print "in the hash"     }
    else            { print "no case applies" }
}

10.17.3. Discussion

The Switch module extends Perl's basic syntax by providing a powerful and flexible switch construct. In fact, it's so powerful and flexible that instead of a complete description of how it works, we'll instead provide examples of some common uses. For the full story, make sure to consult the documentation that accompanies the module.

A switch takes an argument and a mandatory block, within which can occur any number of case s. Each of those case s also takes an argument and a mandatory block. The arguments to each case can vary in type, allowing (among many other things) any or all of string, numeric, or regex comparisons against the switch's value. When the case is an array or hash (or reference to the same), the case matches if the switch value corresponds to any of the array elements or hash keys. If no case matches, a trailing else block will be executed.

Unlike certain languages' multiway branching constructs, here once a valid case is found and its block executed, control transfers out of the enclosing switch. In other words, there's no implied fall-through behavior the way there is in C. This is considered desirable because even the best of programmers will occasionally forget about fall-through.

However, this is Perl, so you can have your cake and eat it, too. Just use a next from within a switch to transfer control to the next case. Consider:

%traits = (pride => 2, sloth => 3, hope => 14);
switch (%traits) {
    case "impatience"                      { print "Hurry up!\n";       next }
    case ["laziness","sloth"]              { print "Maybe tomorrow!\n"; next }
    case ["hubris","pride"]                { print "Mine's best!\n";    next }
    case ["greed","cupidity","avarice"]    { print "More more more!";   next }
}

Maybe tomorrow!
Mine's best!

Because each case has a next, it doesn't just do the first one it finds, but goes on for further tests. The next can be conditional, too, allowing for conditional fall through.

You might have noticed something else interesting about that previous example: the argument to the switch wasn't a scalar; it was the %traits hash. It turns out that you can switch on other things than scalars. In fact, both case and switch accept nearly any kind of argument. The behavior varies depending on the particular combination. Here, the strings from each of those case s are taken as keys to index into the hash we're switch ing on.

If you find yourself preferring fall-through as the default, you can have that, too:

use Switch 'fallthrough';
%traits = (pride => 2, sloth => 3, hope => 14);
switch (%traits) {
    case "impatience"                      { print "Hurry up!\n"        }
    case ["laziness","sloth"]              { print "Maybe tomorrow!\n"  }
    case ["hubris","pride"]                { print "Mine's best!\n"     }
    case ["greed","cupidity","avarice"]    { print "More more more!"    }
}

One area where a bunch of cascading ifs would still seem to excel is when each test involves a different expression, and those expressions are more complex than a simple string, numeric, or pattern comparison. For example:

if    ($n % 2 =  = 0) { print "two "   }
elsif ($n % 3 =  = 0) { print "three " }
elsif ($n % 5 =  = 0) { print "five "  }
elsif ($n % 7 =  = 0) { print "seven " }

Or if you want more than one test to be able to apply, you can do this with fall-through behavior:

if ($n % 2 =  = 0) { print "two "   }
if ($n % 3 =  = 0) { print "three " }
if ($n % 5 =  = 0) { print "five "  }
if ($n % 7 =  = 0) { print "seven " }

Perl's switch can handle this too, but you have to be a bit more careful. For a case item to be an arbitrary expression, wrap that expression in a subroutine. That subroutine is called with the switch argument as the subroutine's argument. If the subroutine returns a true value, then the case is satisfied.

use Switch 'fallthrough';
$n = 30;
print "Factors of $n include: ";
switch ($n) {
    case sub{$_[0] % 2 =  = 0} { print "two "   }
    case sub{$_[0] % 3 =  = 0} { print "three " }
    case sub{$_[0] % 5 =  = 0} { print "five "  }
    case sub{$_[0] % 7 =  = 0} { print "seven " }
}

That's pretty cumbersome to write—and to read—but with a little bit of highly magical syntactic sugar, even that clumsiness goes away. If you import the _ _ subroutine (yes, that really is a double underscore), you can use that in an expression as the case target, and the _ _ will represent the value being switch ed on. For example:

use Switch qw( _ _  fallthrough );
$n = 30;
print "Factors of $n include: ";
switch ($n) {
    case _ _ % 2 =  = 0 { print "two "     }
    case _ _ % 3 =  = 0 { print "three "   }
    case _ _ % 5 =  = 0 { print "five "    }
    case _ _ % 7 =  = 0 { print "seven "   }
}
print "\n";

Due to the way that _ _ is implemented, some restrictions on its use apply. The main one is that your expression can't use && or || in it.

Here's one final trick with switch. This time, instead of having a scalar in the switch and subroutines in the case s, let's do it the other way around. You can switch on a subroutine reference; each case value will be passed into that subroutine, and if the sub returns a true value, then the case is deemed to have matched and its code block executed. That makes the factor example read:

use Switch qw(fallthrough);
$n = 30;
print "Factors of $n include: ";
switch (sub {$n % $_[0] =  = 0} ) {
    case 2 { print "two "   }
    case 3 { print "three " }
    case 5 { print "five "  }
    case 7 { print "seven " }
}

This is probably the most aesthetically pleasing way of writing it, since there's no longer duplicate code on each line.

WARNING:

The Switch module uses a facility called source filters to emulate behavior anticipated in Perl6 (whenever that might be). This has been known to cause mysterious compilation errors if you use constructs in your code you were warned against. You should therefore pay very close attention to the section on "Dependencies, Bugs, and Limitations" in the Switch manpage.

10.17.4. See Also

The documentation for the Switch module; the perlsyn(1) manpage's section on "Basic BLOCKs and Switch Statements"; the section on "Case Statements" in Chapter 4 of Programming Perl

Previous | Home | Next
10.16. Nesting Subroutines | Book Index | 10.18. Program: Sorting Your Mail
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.18. Program: Sorting Your Mail

The program in Example 10-1 sorts a mailbox by subject by reading input a paragraph at a time, looking for one with a "From" at the start of a line. When it finds one, it searches for the subject, strips it of any "Re: " marks, and stores its lowercased version in the @sub array. Meanwhile, the messages themselves are stored in a corresponding @msgs array. The $msgno variable keeps track of the message number.

Example 10-1. bysub1

  #!/usr/bin/perl
  # bysub1 - simple sort by subject
  my(@msgs, @sub);
  my $msgno = -1;
  $/ = '';                    # paragraph reads
  while (<>) {
      if (/^From/m) {
          /^Subject:\s*(?:Re:\s*)*(.*)/mi;
          $sub[++$msgno] = lc($1) || '';
      }
      $msgs[$msgno] .= $_;
  }
  for my $i (sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msgs)) {
      print $msgs[$i];
  }

That sort is only sorting array indices. If the subjects are the same, cmp returns 0, so the second part of the || is taken, which compares the message numbers in the order they originally appeared.

If sort were fed a list like (0,1,2,3), that list would get sorted into a different permutation, perhaps (2,1,3,0). We iterate across them with a for loop to print out each message.

Example 10-2 shows how an awk programmer might code this program, using the -00 switch to read paragraphs instead of lines.

Example 10-2. bysub2

  #!/usr/bin/perl -n00
  # bysub2 - awkish sort-by-subject
  INIT { $msgno = -1 }
  $sub[++$msgno] = (/^Subject:\s*(?:Re:\s*)*(.*)/mi)[0] if /^From/m;
  $msg[$msgno] .= $_;
  END { print @msg[ sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msg) ] }

Perl programmers have used parallel arrays like this since Perl 1. Keeping each message in a hash is a more elegant solution, though. We'll sort on each field in the hash, by making an anonymous hash as described in Chapter 11.

Example 10-3 is a program similar in spirit to Example 10-1 and Example 10-2.

Example 10-3. bysub3

  #!/usr/bin/perl -00
  # bysub3 - sort by subject using hash records
  use strict;
  my @msgs = ( );
  while (<>) {
      push @msgs, {
          SUBJECT => /^Subject:\s*(?:Re:\s*)*(.*)/mi,
          NUMBER  => scalar @msgs,   # which msgno this is
          TEXT    => '',
      } if /^From/m;
      $msgs[-1]{TEXT} .= $_;
  }

  for my $msg (sort {
                          $a->{SUBJECT} cmp $b->{SUBJECT}
                                         ||
                          $a->{NUMBER}  <=> $b->{NUMBER}
                    } @msgs
           )
  {
      print $msg->{TEXT};
  }

Once you have real hashes, adding further sorting criteria is simple. A common way to sort a folder is subject major, date minor order. The hard part is figuring out how to parse and compare dates. Date::Manip does this, returning a string you can compare; however, the datesort program in Example 10-4, which uses Date::Manip, runs more than 10 times slower than the previous one. Parsing dates in unpredictable formats is extremely slow.

Example 10-4. datesort

  #!/usr/bin/perl -00
  # datesort - sort mbox by subject then date
  use strict;
  use Date::Manip;
  my @msgs = ( );
  while (<>) {
      next unless /^From/m;
      my $date = '';
      if (/^Date:\s*(.*)/m) {
          ($date = $1) =~ s/\s+\(.*//;  # library hates (MST)
          $date = ParseDate($date);
      }
      push @msgs, {
          SUBJECT => /^Subject:\s*(?:Re:\s*)*(.*)/mi,
          DATE    => $date,
          NUMBER  => scalar @msgs,
          TEXT    => '',
      };
  } continue {
      $msgs[-1]{TEXT} .= $_;
  }

  for my $msg (sort {
                          $a->{SUBJECT} cmp $b->{SUBJECT}
                                         ||
                          $a->{DATE}    cmp $b->{DATE}
                                         ||
                          $a->{NUMBER}  <=> $b->{NUMBER}

                    } @msgs
           )
  {
      print $msg->{TEXT};
  }

Example 10-4 is written to draw attention to the continue block. When a loop's end is reached, either because it fell through to that point or got there from a next, the whole continue block is executed. It corresponds to the third portion of a three-part for loop, except that the continue block isn't restricted to an expression. It's a full block, with separate statements.

10.18.1. See Also

The sort function in Chapter 29 of Programming Perl and in perlfunc(1); the discussion of the $/ ($RS, $INPUT_RECORD_SEPARATOR) variable in Chapter 28 of Programming Perl, in perlvar(1), and in the Introduction to Chapter 8; Recipe 3.7; Recipe 4.16; Recipe 5.10; Recipe 11.9

Previous | Home | Next
10.17. Writing a Switch Statement | Book Index | 11. References and Records
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 11. References and Records

Contents:

Introduction
Taking References to Arrays
Making Hashes of Arrays
Taking References to Hashes
Taking References to Functions
Taking References to Scalars
Creating Arrays of Scalar References
Using Closures Instead of Objects
Creating References to Methods
Constructing Records
Reading and Writing Hash Records to Text Files
Printing Data Structures
Copying Data Structures
Storing Data Structures to Disk
Transparently Persistent Data Structures
Coping with Circular Data Structures Using Weak References
Program: Outlines
Program: Binary Trees

Shakespeare, Othello, Act II, scene i

With as little a web as this will I ensnare as great a fly as Cassio.

11.0. Introduction

Perl provides three fundamental data types: scalars, arrays, and hashes. It's certainly possible to write many programs without complex records, but most programs need something more sophisticated than simple variables and lists.

Perl's three built-in types combine with references to produce arbitrarily complex and powerful data structures. Selecting the proper data structure and algorithm can make the difference between an elegant program that does its job quickly and an ungainly concoction that's glacially slow to execute and consumes system resources voraciously.

The first part of this chapter shows how to create and use plain references. The second part shows how to create higher-order data structures out of references.

11.0.1. References

To grasp the concept of references, you must first understand how Perl stores values in variables. Each defined variable has associated with it a name and the address of a chunk of memory. This idea of storing addresses is fundamental to references because a reference is a value that holds the location of another value. The scalar value that contains the memory address is called a reference. Whatever value lives at that memory address is called its referent. See Figure 11-1.

Figure 11-1. Reference and referent

The referent could be any built-in type (scalar, array, hash, ref, code, or glob) or a user-defined type based on one of the built-ins.

Referents in Perl are typed. This means, for example, that you can't treat a reference to an array as though it were a reference to a hash. Attempting to do so raises a runtime exception. No mechanism for type casting exists in Perl. This is considered a feature.

So far, it may look as though a reference were little more than a raw address with strong typing. But it's far more than that. Perl takes care of automatic memory allocation and deallocation (garbage collection) for references, just as it does for everything else. Every chunk of memory in Perl has a reference count associated with it, representing how many places know about that referent. The memory used by a referent is not returned to the process's free pool until its reference count reaches zero. This ensures that you never have a reference that isn't valid—no more core dumps and general protection faults from mismanaged pointers as in C.

Freed memory is returned to Perl for later use, but few operating systems reclaim it and decrease the process's memory footprint. This is because most memory allocators use a stack, and if you free up memory in the middle of the stack, the operating system can't take it back without moving the rest of the allocated memory around. That would destroy the integrity of your pointers and blow XS code out of the water.

To follow a reference to its referent, preface the reference with the appropriate type symbol for the data you're accessing. For instance, if $sref is a reference to a scalar, you can say:

print $$sref;    # prints the scalar value that the reference $sref refers to
$$sref = 3;      # assigns to $sref's referent

To access one element of an array or hash whose reference you have, use the infix pointer-arrow notation, as in $rv->[37] or $rv->{"wilma"}. Besides dereferencing array references and hash references, the arrow is also used to call an indirect function through its reference, as in $code_ref->("arg1", "arg2"); this is discussed in Recipe 11.4. If you're using an object, use an arrow to call a method, $object->methodname("arg1", "arg2"), as shown in Chapter 13.

Perl's syntax rules make dereferencing complex expressions tricky—it falls into the category of "hard things that should be possible." Mixing right associative and left associative operators doesn't work out well. For example, $$x[4] is the same as $x->[4]; that is, it treats $x as a reference to an array and then extracts element number four from that. This could also have been written ${$x}[4]. If you really meant "take the fifth element of @x and dereference it as a scalar reference," then you need to use ${$x[4]}. Avoid putting two type signs ($@%&) side-by-side, unless it's simple and unambiguous like %hash = %$hashref.

In the simple cases using $$sref in the previous example, you could have written:

print ${$sref};             # prints the scalar $sref refers to
${$sref} = 3;               # assigns to $sref's referent

For safety, some programmers use this notation exclusively.

When passed a reference, the ref function returns a string describing its referent. (It returns false if passed a non-reference.) This string is usually one of SCALAR, ARRAY, HASH, or CODE, although the other built-in types of GLOB, REF, IO, Regexp, and LVALUE also occasionally appear. If you call ref on a non-reference, it returns an empty string. If you call ref on an object (a reference whose referent has been blessed), it returns the class the object was blessed into: CGI, IO::Socket, or even ACME::Widget.

Create references in Perl by using a backslash on things already there, or dynamically allocate new things using the [ ], { }, and sub { } composers. The backslash operator is simple to use: put it before whatever you want a reference to. For instance, if you want a reference to the contents of @array, just say:

$aref = \@array;

You can even create references to constant values; future attempts to change the value of the referent cause a runtime exception:

$pi = \3.14159;
$$pi = 4;           # runtime error

11.0.2. Anonymous Data

Using a backslash to produce references to existing, named variables is simple enough for implementing pass-by-reference semantics in subroutine calls, but for creating complex data structures on the fly, it quickly becomes cumbersome. You don't want to be bogged down by having to invent a unique name for each subsection of the large, complex data structure. Instead, you allocate new, nameless arrays and hashes (or scalars or functions) on demand, growing your structure dynamically.

Explicitly create anonymous arrays and hashes with the [ ] and { } composers. This notation allocates a new array or hash, initializes it with any data values listed between the pair of square or curly brackets, and returns a reference to the newly allocated aggregate:

$aref = [ 3, 4, 5 ];                                # new anonymous array
$href = { "How" => "Now", "Brown" => "Cow" };       # new anonymous hash

Perl also implicitly creates anonymous data types through autovivification. This occurs when you indirectly store data through a variable that's currently undefined; that is, you treat that variable as though it holds the reference type appropriate for that operation. When you do so, Perl allocates the needed array or hash and stores its reference in the previously undefined variable.

undef $aref;
@$aref = (1, 2, 3);
print $aref;
ARRAY(0x80c04f0)

See how we went from an undefined variable to one with an array reference in it without explicitly assigning that reference? Perl filled in the reference for us. This property lets code like the following work correctly, even as the first statement in your program, all without declarations or allocations:

$a[4][23][53][21] = "fred";
print $a[4][23][53][21];
fred
print $a[4][23][53];
ARRAY(0x81e2494)
print $a[4][23];
ARRAY(0x81e0748)
print $a[4];
ARRAY(0x822cd40)

Table 11-1 shows mechanisms for producing references to both named and anonymous scalars, arrays, hashes, functions, and typeglobs. (See the discussion of filehandle autovivification in the Introduction to Chapter 7 for a discussion of anonymous filehandles.)

Table 11-1. Syntax for named and anonymous values

Reference to

Named

Anonymous

Scalar

\$scalar

\do{my $anon}

Array

\@array

[ LIST ]

Hash

\%hash

{ LIST }

Code

\&function

sub { CODE }

Glob

*symbol

open(my $handle, ...); $handle

Figure 11-2 and Figure 11-3 illustrate the differences between named and anonymous values. Figure 11-2 shows named values, and Figure 11-3 shows anonymous ones.

Figure 11-2. Named values

Figure 11-3. Anonymous values

In other words, saying $a = \$b makes $$a and $b the same piece of memory. If you say $$a = 3, then $b is set to 3, even though you only mentioned $a by name, not $b.

All references evaluate to true when used in Boolean context. That way a subroutine that normally returns a reference can indicate an error by returning undef.

sub cite {
  my (%record, $errcount);
   ...
   return $errcount ? undef( ) : ‰record;
}

$op_cit = cite($ibid)       or die "couldn't make a reference";

Without an argument, undef produces an undefined value. But passed a variable or function as its argument, the undef operator renders that variable or function undefined when subsequently tested with the defined function. However, this does not necessarily free memory, call object destructors, etc. It just decrements its referent's reference count by one.

my ($a, $b) = ("Thing1", "Thing2");
$a = \$b;
undef $b;

Memory isn't freed yet, because you can still reach "Thing2" indirectly using its reference in $a. "Thing1", however, is completely gone, having been recycled as soon as $a was assigned \$b.

Although memory allocation in Perl is sometimes explicit and sometimes implicit, memory deallocation is nearly always implicit. You don't routinely have cause to undefine variables. Just let lexical variables (those declared with my) evaporate when their scope terminates; the next time you enter that scope, those variables will be new again. For global variables (those declared with our, fully-qualified by their package name, or imported from a different package) that you want reset, it normally suffices to assign the empty list to an aggregate variable or a false value to a scalar one.

It has been said that there exist two opposing schools of thought regarding memory management in programming. One school holds that memory management is too important a task to be left to the programming language, while the other judges it too important to be left to the programmer. Perl falls solidly in the second camp, since if you never have to remember to free something, you can never forget to do so. As a rule, you need rarely concern yourself with freeing any dynamically allocated storage in Perl,[19] because memory management—garbage collection, if you would—is fully automatic. Recipe 11.15 and Recipe 13.13, however, illustrate exceptions to this rule.

[19]External subroutines compiled in C notwithstanding.

11.0.3. Records

The predominant use of references in Perl is to circumvent the restriction that arrays and hashes may hold scalars only. References are scalars, so to make an array of arrays, make an array of array references. Similarly, hashes of hashes are implemented as hashes of hash references, arrays of hashes as arrays of hash references, hashes of arrays as hashes of array references, and so on.

Once you have these complex structures, you can use them to implement records. A record is a single logical unit comprising various different attributes. For instance, a name, an address, and a birthday might compose a record representing a person. C calls such things structs, and Pascal calls them RECORDs. Perl doesn't have a particular name for these because you can implement this notion in different ways.

The most common technique in Perl is to treat a hash as a record, where the keys of the hash are the record's field names and the values of the hash are those fields' values.

For instance, we might create a "person" record like this:

$person = { "Name"     => "Leonhard Euler",
            "Address"  => "1729 Ramanujan Lane\nMathworld, PI 31416",
            "Birthday" => 0x5bb5580,
       };

Because $person is a scalar, it can be stored in an array or hash element, thus creating groups of people. Now apply the array and hash techniques from Chapter 4 and Chapter 5 to sort the sets, merge hashes, pick a random record, and so on.

The attributes of a record, including the "person" record, are always scalars. You can certainly use numbers as readily as strings there, but that's no great trick. The real power play happens when you use even more references for values in the record. "Birthday", for instance, might be stored as an anonymous array with three elements: day, month, and year. You could then say $person->{"Birthday"}->[0] to access just the day field. Or a date might be represented as a hash record, which would then lend itself to access such as $person->{"Birthday"}->{"day"}. Adding references to your collection of skills makes possible many more complex and useful programming strategies.

At this point, we've conceptually moved beyond simple records. We're now creating elaborate data structures that represent complicated relationships between the data they hold. Although we can use these to implement traditional data structures like linked lists, recipes in the second half of this chapter don't deal specifically with any particular structure. Instead, they give generic techniques for loading, printing, copying, and saving generic data structures. The final program example demonstrates creating binary trees.

11.0.4. See Also

Chapters 8 and 9 of Programming Perl;
perlref(1), perlreftut(1),
perllol(1), and perldsc(1)

Previous | Home | Next
10.18. Program: Sorting Your Mail | Book Index | 11.1. Taking References to Arrays
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.1. Taking References to Arrays

11.1.1. Problem

You need to manipulate an array by reference.

11.1.2. Solution

To get a reference to an array:

$aref               = \@array;
$anon_array         = [1, 3, 5, 7, 9];
$anon_copy          = [ @array ];
@$implicit_creation = (2, 4, 6, 8, 10);

To deference an array reference, precede it with an at sign (@):

push(@$anon_array, 11);

Or use a pointer arrow plus a bracketed subscript for a particular element:

$two = $implicit_creation->[0];

To get the last index number by reference, or the number of items in that referenced array:

$last_idx  = $#$aref;
$num_items = @$aref;

Or defensively embracing and forcing context:

$last_idx  = $#{ $aref };
$num_items = scalar @{ $aref };

11.1.3. Discussion

Here are array references in action:

# check whether $someref contains a simple array reference
if (ref($someref) ne "ARRAY") {
    die "Expected an array reference, not $someref\n";
}

print "@{$array_ref}\n";        # print original data

@order = sort @{ $array_ref };  # sort it

push @{ $array_ref }, $item;    # append new element to orig array

If you can't decide whether to use a reference to a named array or to create a new one, here's a simplistic guideline that will prove right more often than not. Only take a reference to an existing array to return the reference out of scope, thereby creating an anonymous array, or to pass the array by reference to a function. For virtually all other cases, use [@array] to create a new array reference with a copy of the old values.

Automatic reference counting and the backslash operator make a powerful combination:

sub array_ref {
    my @array;
    return \@array;
}

$aref1 = array_ref( );
$aref2 = array_ref( );

Each time array_ref is called, the function allocates a new piece of memory for @array. If we hadn't returned a reference to @array, its memory would have been freed when its block, the subroutine, ended. But here a reference to @array is still accessible, so Perl doesn't free that storage, and we wind up with a reference to a piece of memory no longer accessible through the symbol table. Such a piece of memory is called anonymous because it has no name associated with it.

To access a particular element of the array referenced by $aref, you could write $$aref[4], but $aref->[4] is the same thing, and clearer.

print $array_ref->[$N];         # access item in position N (best)
print $$array_ref[$N];          # same, but confusing
print ${$array_ref}[$N];        # same, but still confusing, and ugly to boot

If you have an array reference, you can only access a slice of the referenced array in this way:

@$pie[3..5];                    # array slice, but a little confusing to read
@{$pie}[3..5];                  # array slice, easier (?) to read

Array slices, even when accessed through array references, are assignable. In the next line, the array dereference happens first, then the slice:

@{$pie}[3..5] = ("blackberry", "blueberry", "pumpkin");

An array slice is just syntactic sugar for a list of individual array elements. Because you can't take a reference to a list, you can't take a reference to an array slice:

$sliceref = \@{$pie}[3..5];     # WRONG!

To iterate through the entire array, loop with foreach or for:

foreach $item ( @{$array_ref} ) {
    # $item has data
}

for ($idx = 0; $idx <= $#{ $array_ref }; $idx++) {
    # $array_ref->[$idx] has data
}

11.1.4. See Also

Chapters 8 and 9 of Programming Perl;
perlref(1), perlreftut(1),
and perllol(1); Recipe 2.13; Recipe 4.6

Previous | Home | Next
11. References and Records | Book Index | 11.2. Making Hashes of Arrays
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.2. Making Hashes of Arrays

11.2.1. Problem

For each key in a hash, only one scalar value is allowed, but you'd like to use one key to store and retrieve multiple values. That is, you'd like the value to produce a list.

11.2.2. Solution

Use references to arrays as the hash values. Use push to append:

push(@{ $hash{"KEYNAME"} }, "new value");

Then, dereference the value as an array reference when printing out the hash:

foreach $string (keys %hash) {
    print "$string: @{$hash{$string}}\n";
}

11.2.3. Discussion

You can only store scalar values in a hash. References, however, are scalars. This solves the problem of storing multiple values for one key by making $hash{$key} a reference to an array containing the values for $key. Normal hash operations acting on individual scalar values (insertion, deletion, iteration, and testing for existence) are now written with array operations acting on lists of values (like push, splice, and foreach).

Here's how to give a key many values:

$hash{"a key"} = [ 3, 4, 5 ];       # anonymous array

Once you have a key with many values, here's how to use them:

@values = @{ $hash{"a key"} };

To append a new value to the array of values associated with a particular key, use push:

push @{ $hash{"a key"} }, $value;

One common application of such data structures is inverting a hash that may have several keys with the same associated value. When inverted, you end up with a hash that has many values for the same key. This is addressed in Recipe 5.9.

Be warned that this:

@residents = @{ $phone2name{$number} };

causes a runtime exception under use strict because you're dereferencing an undefined reference where autovivification won't occur. You must do this instead:

@residents = exists( $phone2name{$number} )
                       ? @{ $phone2name{$number} }
                       : ( );

11.2.4. See Also

The section on "Hashes of Arrays" in Chapter 9 of Programming Perl and in perldsc(1); the section on "Symbolic References" in Chapter 8 of Programming Perl; Recipe 5.9; Tie Example: Make a Hash That Always Appends in Recipe 13.15

Previous | Home | Next
11.1. Taking References to Arrays | Book Index | 11.3. Taking References to Hashes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.3. Taking References to Hashes

11.3.1. Problem

You need to manipulate a hash by reference. This might be because it was passed into a function that way or because it's part of a larger data structure.

11.3.2. Solution

To get a hash reference:

$href = \%hash;
$anon_hash = { "key1" => "value1", "key2" => "value2", ... };
$anon_hash_copy = { %hash };

To dereference a hash reference:

%hash  = %$href;
$value = $href->{$key};
@slice = @$href{$key1, $key2, $key3};  # note: no arrow!
@keys  = keys %$href;

To check whether something is a hash reference:

if (ref($someref) ne "HASH") {
    die "Expected a hash reference, not $someref\n";
}

11.3.3. Discussion

This example prints out all keys and values from two predefined hashes:

foreach $href ( \%ENV, \%INC ) {       # OR: for $href ( \(%ENV,%INC) ) {
    foreach $key ( keys %$href ) {
        print "$key => $href->{$key}\n";
    }
}

Access slices of hashes by reference as you'd access slices of arrays by reference. For example:

@values = @$hash_ref{"key1", "key2", "key3"};

for $val (@$hash_ref{"key1", "key2", "key3"}) {
    $val += 7;   # add 7 to each value in hash slice
}

11.3.4. See Also

The Introductionin Chapter 5; Chapter 8 of Programming Perl; perlref(1); Recipe 11.9

Previous | Home | Next
11.2. Making Hashes of Arrays | Book Index | 11.4. Taking References to Functions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.4. Taking References to Functions

11.4.1. Problem

You need to manipulate a subroutine by reference. This might happen if you need to create a signal handler, a Tk callback, or a hash of function pointers.

11.4.2. Solution

To get a code reference:

$cref = \&func;
$cref = sub { ... };

To call a code reference:

@returned = $cref->(@arguments);
@returned = &$cref(@arguments);

11.4.3. Discussion

If the name of a function is func, you can produce a reference to it by prefixing its name with \&. You can also dynamically allocate anonymous functions using the sub { } notation. These code references can be stored just like any other reference.

It is possible to store the name of a function in a variable, such as:

$funcname = "thefunc";
&$funcname( );

but that's not a very good solution for several reasons. First, it uses symbolic references, not real (hard) references, and so is forbidden under the use strict "refs" pragma. Symbolic references to variables are usually a bad idea, since they can't access lexical variables, only globals, and aren't reference counted. Second, as written it doesn't include package information, so if executed in a different package, it would try to call the wrong function. Finally, in the odd case that the function were redefined at some point, the symbolic reference would get whatever the current definition for the function was, whereas the hard reference would still access the old definition.

Instead of placing the name of the function in the variable, use the backslash operator to create a reference to the function. This is the normal way to store a function in a variable or pass along to another function. You can mix and match references to named functions with references to unnamed ones:

my %commands = (
    "happy" => \&joy,
    "sad"   => \&sullen,
    "done"  => sub { die "See ya!" },
    "mad"   => \&angry,
);

print "How are you? ";
chomp($string = <STDIN>);
if ($commands{$string}) {
    $commands{$string}->( );
} else {
    print "No such command: $string\n";
}

If you create an anonymous function that refers to a lexical (my) variable from an enclosing scope, reference counting ensures that the lexical variable is never deallocated so long as that function reference exists:

sub counter_maker {
    my $start = 0;
    return sub {                      # this is a closure
        return $start++;              # lexical from enclosing scope
    };
}

$counter = counter_maker( );

for ($i = 0; $i < 5; $i ++) {
    print &$counter, "\n";
}

Even though counter_maker has ended and $start gone out of scope, Perl doesn't free the variable, because the anonymous subroutine referenced by $counter still has a reference to $start. If we call counter_maker again, it'll return another, different anonymous subroutine reference that uses a different $start:

$counter1 = counter_maker( );
$counter2 = counter_maker( );

for ($i = 0; $i < 5; $i ++) {
    print &$counter1, "\n";
}

print &$counter1, " ", &$counter2, "\n";

1
2
3
4
5 0

Closures are often used in callback routines. In graphical and other event-based programming, you associate code with a keypress, mouse click, window expose event, etc. The code will be called much later, probably from an entirely different scope. Variables mentioned in the closure must be available when it's finally called. To work properly, such variables must be lexicals, not globals.

Another use for closures is function generators, that is, functions that create and return brand-new functions. The counter_maker function is such a function generator. Here's another simple one:

sub timestamp {
    my $start_time = time( );
    return sub { return time( ) - $start_time };
}
$early = timestamp( );
sleep 20;
$later = timestamp( );
sleep 10;
printf "It's been %d seconds since early.\n", $early->( );
printf "It's been %d seconds since later.\n", $later->( );
It's been 30 seconds since early.
It's been 10 seconds since later.

Each call to timestamp generates and returns a brand-new function. The timestamp function creates a lexical called $start_time that contains the current clock time (in epoch seconds). Every time that closure is called, it returns how many seconds have elapsed since it was created by subtracting its starting time from the current time.

11.4.4. See Also

The section on "Closures" in Chapter 8 of Programming Perl and the discussion on closures in perlref(1); Recipe 10.11; Recipe 11.4

Previous | Home | Next
11.3. Taking References to Hashes | Book Index | 11.5. Taking References to Scalars
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.5. Taking References to Scalars

11.5.1. Problem

You want to create and manipulate a reference to a scalar value.

11.5.2. Solution

To create a reference to a scalar variable, use the backslash operator:

$scalar_ref = \$scalar;       # get reference to named scalar

To create a reference to an anonymous scalar value (a value that isn't in a variable), assign to a dereferenced undefined variable:

undef $anon_scalar_ref;
$$anon_scalar_ref = 15;

This creates a reference to a constant scalar:

$anon_scalar_ref = \15;

Use ${...} to dereference:

print ${ $scalar_ref };       # dereference it
${ $scalar_ref } .= "string"; # alter referent's value

11.5.3. Discussion

If you want to create many new anonymous scalars, use a subroutine that returns a reference to a lexical variable out of scope, as explained in this chapter's Introduction:

sub new_anon_scalar {
    my $temp;
    return \$temp;
}

Dereference a scalar reference by prefacing it with $ to get at its contents:

$sref = new_anon_scalar( );
$$sref = 3;
print "Three = $$sref\n";
@array_of_srefs = ( new_anon_scalar( ), new_anon_scalar( ) );
${ $array[0] } = 6.02e23;
${ $array[1] } = "avocado";
print "\@array contains: ", join(", ", map { $$_ } @array ), "\n";

Notice we put braces around $array[0] and $array[1]. If we tried to say $$array[0], the tight binding of dereferencing would turn it into $array->[0]. It would treat $array as an array reference and return the element at index zero.

Here are other examples where it is safe to omit the braces:

$var        = `uptime`;     # $var holds text
$vref       = \$var;        # $vref "points to" $var
if ($$vref =~ /load/) {  }    # look at $var, indirectly
chomp $$vref;               # alter $var, indirectly

As mentioned in the Introduction, you may use the ref built-in to inspect a reference for its referent's type. Calling ref on a scalar reference returns the string "SCALAR":

# check whether $someref contains a simple scalar reference
if (ref($someref) ne "SCALAR") {
    die "Expected a scalar reference, not $someref\n";
}

11.5.4. See Also

Chapters 8 and 9 of Programming Perl and perlref(1)

Previous | Home | Next
11.4. Taking References to Functions | Book Index | 11.6. Creating Arrays of Scalar References
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.6. Creating Arrays of Scalar References

11.6.1. Problem

You want to create and manipulate an array of references to scalars. This arises when you pass variables by reference to a function so the function can change their values.

11.6.2. Solution

To create an array, either backslash each scalar in the list to store in the array:

@array_of_scalar_refs = ( \$a, \$b );

or simply backslash the entire list, taking advantage of the backslash operator's distributive property:

@array_of_scalar_refs = \( $a, $b );

To get or set the value of an element of the list, use ${ ... }:

${ $array_of_scalar_refs[1] } = 12;         # $b = 12

11.6.3. Discussion

In the following examples, @array is a simple array containing references to scalars (an array of references is not a reference to an array). To access the original data indirectly, braces are mandatory.

($a, $b, $c, $d) = (1 .. 4);        # initialize
@array =  (\$a, \$b, \$c, \$d);     # refs to each scalar
@array = \( $a,  $b,  $c,  $d);     # same thing!
@array = map { \my $anon } 0 .. 3;  # allocate 4 anon scalar refs

${ $array[2] } += 9;                # $c now 12

${ $array[ $#array ] } *= 5;        # $d now 20
${ $array[-1] }        *= 5;        # same; $d now 100

$tmp   = $array[-1];                # using temporary
$$tmp *= 5;                         # $d now 500

The two assignments to @array are equivalent—the backslash operator is distributive across a list. So preceding a list (including a slice or a function's return list, but not an array) with a backslash is the same as applying a backslash to everything in that list. The ensuing code changes the values of the variables whose references were stored in the array.

Here's how to deal with such an array without explicit indexing:

use Math::Trig qw(pi);              # load the constant pi
foreach $sref (@array) {            # prepare to change $a,$b,$c,$d
    ($$sref **= 3) *= (4/3 * pi);   # replace with spherical volumes
}

This code uses the formula for deriving the volume of a sphere:

The $sref loop index variable is each reference in @array, and $$sref is the number itself, that is, the original variables $a, $b, $c, and $d. Changing $$sref in the loop changes those variables as well. First we replace $$sref with its cube, then multiply the resulting value by 4/3π. This takes advantage of the fact that assignment in Perl returns an lvalue, letting you chain assignment operators together as we've done using the **= and *= assignment operators.

Actually, anonymous scalars are pretty useless, given that a scalar value fits in the same space as a scalar reference. That's why there's no explicit composer. Scalar references exist only to allow aliasing—which can be done in other ways.

11.6.4. See Also

The section on "Assignment Operators" in Chapter 3 of Programming Perl and in perlop(1); the section on "Other Tricks You Can Do with Hard References" in Chapter 8 of Programming Perl

Previous | Home | Next
11.5. Taking References to Scalars | Book Index | 11.7. Using Closures Instead of Objects
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.7. Using Closures Instead of Objects

11.7.1. Problem

You want records with private state, behavior, and identity, but you don't want to learn object-oriented programming to accomplish this.

11.7.2. Solution

Write a function that returns (by reference) a hash of code references. These code references are closures created in the same scope, so when they execute, they'll share bindings to the same private variables.

11.7.3. Discussion

Because a closure is a binding of code and data, it can implement what might be thought of as an object.

Here's an example that creates and returns a hash of anonymous functions. mkcounter takes an argument of a seed counter and returns a reference to a hash of code references that you can use to manipulate the counter indirectly.

$c1 = mkcounter(20);
$c2 = mkcounter(77);

printf "next c1: %d\n", $c1->{NEXT}->( );  # 21
printf "next c2: %d\n", $c2->{NEXT}->( );  # 78
printf "next c1: %d\n", $c1->{NEXT}->( );  # 22
printf "last c1: %d\n", $c1->{PREV}->( );  # 21
printf "old  c2: %d\n", $c2->{RESET}->( ); # 77

The code values in the hash references in $c1 and $c2 maintain their own separate state. Here's how to set that up:

sub mkcounter {
    my $count  = shift;
    my $start  = $count;
    my $bundle = {
        "NEXT"   => sub { return ++$count  },
        "PREV"   => sub { return --$count  },
        "GET"    => sub { return $count    },
        "SET"    => sub { $count = shift   },
        "BUMP"   => sub { $count += shift  },
        "RESET"  => sub { $count = $start  },
    };
    $bundle->{"LAST"} = $bundle->{"PREV"};
    return $bundle;
}

Because the lexical variables used by the closures in the $bundle hash reference are returned by the function, they are not deallocated. The next time mkcounter is called, the closures get a different set of variable bindings for the same code. Because no one outside those closures can access these two variables, this assures true privacy.

The assignment right before the return makes both "PREV" and "LAST" values point to the same closure. Depending on your object-oriented background, you might think of these as being two different messages, both implemented using the same method.

The bundle we return is not an object in that it has no obvious inheritance and polymorphism. (Yet.) But it certainly does have state, behavior, and identity, as well as encapsulation.

11.7.4. See Also

The section on "Closures" in Chapter 8 of Programming Perl and the discussion on closures in perlref(1); Recipe 11.4; Recipe 11.9; Chapter 13

Previous | Home | Next
11.6. Creating Arrays of Scalar References | Book Index | 11.8. Creating References to Methods
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.8. Creating References to Methods

11.8.1. Problem

You want to store a reference to a method.

11.8.2. Solution

Create a closure that makes the proper method call on the appropriate object.

11.8.3. Discussion

When you ask for a reference to a method, you're asking for more than just a raw function pointer. You also need to record which object the method needs to be called upon as the object contains the data the method will work with. The best way to do this is using a closure. Assuming $obj is lexically scoped, you can say:

$mref = sub { $obj->meth(@_) };
# later...
$mref->("args", "go", "here");

Even when $obj goes out of scope, the closure stored in $mref has captured it. Later when it's called indirectly, the correct object is used for the method call.

Be aware that the notation:

$sref = \$obj->meth;

doesn't do what you probably expected. It first calls the method on that object and gives you either a reference to the return value or a reference to the last of the return values if the method returns a list.

The can method from the UNIVERSAL base class, while appealing, is also unlikely to produce what you want.

$cref = $obj->can("meth");

This produces a code ref to the appropriate method (should one be found), but one that carries no object information. Think of it as a raw function pointer. The information about the object is lost. That's why you need a closure to capture both the object state as well as the method to call.

11.8.4. See Also

The discussion on methods in the Introduction to Chapter 13; the section on "Closures" in Chapter 8 of Programming Perl; Recipe 11.7; Recipe 13.8

Previous | Home | Next
11.7. Using Closures Instead of Objects | Book Index | 11.9. Constructing Records
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.9. Constructing Records

11.9.1. Problem

You want to create a record data type.

11.9.2. Solution

Use a reference to an anonymous hash.

11.9.3. Discussion

Suppose you wanted to create a data type that contained various data fields. The easiest way is to use an anonymous hash. For example, here's how to initialize and use that record:

$record = {
    NAME   => "Jason",
    EMPNO  => 132,
    TITLE  => "deputy peon",
    AGE    => 23,
    SALARY => 37_000,
    PALS   => [ "Norbert", "Rhys", "Phineas"],
};

printf "I am %s, and my pals are %s.\n",
    $record->{NAME},
    join(", ", @{$record->{PALS}});

Just having one of these records isn't much fun—you'd like to build larger structures. For example, you might want to create a %byname hash that you could initialize and use this way:

# store record
$byname{ $record->{NAME} } = $record;

# later on, look up by name
if ($rp = $byname{"Aron"}) {        # false if missing
    printf "Aron is employee %d.\n", $rp->{EMPNO};
}

# give jason a new pal
push @{$byname{"Jason"}->{PALS}}, "Theodore";
printf "Jason now has %d pals\n", scalar @{$byname{"Jason"}->{PALS}};

That makes %byname a hash of hashes because its values are hash references. Looking up employees by name would be easy using such a structure. If we find a value in the hash, we store a reference to the record in a temporary variable, $rp, which we then use to get any field we want.

We can use our existing hash tools to manipulate %byname. For instance, we could use the each iterator to loop through it in an arbitrary order:

# Go through all records
while (($name, $record) = each %byname) {
    printf "%s is employee number %d\n", $name, $record->{EMPNO};
}

What about looking employees up by employee number? Just build and use another data structure, an array of hashes called @employees. If your employee numbers aren't consecutive (for instance, they jump from 1 to 159997) an array would be a bad choice. Instead, you should use a hash mapping employee number to record. For consecutive employee numbers, use an array:

# store record
$employees[ $record->{EMPNO} ] = $record;

# lookup by id
if ($rp = $employee[132]) {
    printf "employee number 132 is %s\n", $rp->{NAME};
}

With a data structure like this, updating a record in one place effectively updates it everywhere. For example, this gives Jason a 3.5% raise:

$byname{"Jason"}->{SALARY} *= 1.035;

This change is reflected in all views of these records. Remember that $byname{"Jason"} and $employees[132] both refer to the same record because the references they contain refer to the same anonymous hash.

How would you select all records matching a particular criterion? This is what grep is for. Here's how to get everyone with "peon" in their titles or all 27-year-olds:

@peons   = grep { $_->{TITLE} =~ /peon/i } @employees;
@tsevens = grep { $_->{AGE}   =  = 27 }      @employees;

Each element of @peons and @tsevens is itself a reference to a record, making them arrays of hashes, like @employees.

Here's how to print all records sorted in a particular order, say by age:

# Go through all records
foreach $rp (sort { $a->{AGE} <=> $b->{AGE} } values %byname) {
    printf "%s is age %d.\n", $rp->{NAME}, $rp->{AGE};
    # or with a hash slice on the reference
    printf "%s is employee number %d.\n", @$rp{"NAME","EMPNO"};
}

Rather than take time to sort them by age, you could create another view of these records, @byage. Each element in this array, $byage[27] for instance, would be an array of all records with that age. In effect, this is an array of arrays of hashes. Build it this way:

# use @byage, an array of arrays of records
push @{ $byage[ $record->{AGE} ] }, $record;

Then you could find them all this way:

for ($age = 0; $age <= $#byage; $age++) {
    next unless $byage[$age];
    print "Age $age: ";
    foreach $rp (@{$byage[$age]}) {
        print $rp->{NAME}, " ";
    }
    print "\n";
}

A similar approach is to use map to avoid the foreach loop:

for ($age = 0; $age <= $#byage; $age++) {
    next unless $byage[$age];
    printf "Age %d: %s\n", $age,
        join(", ", map {$_->{NAME}} @{$byage[$age]});

}

11.9.4. See Also

Recipe 4.14; Recipe 11.3

Previous | Home | Next
11.8. Creating References to Methods | Book Index | 11.10. Reading and Writing Hash Records to Text Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.10. Reading and Writing Hash Records to Text Files

11.10.1. Problem

You want to read or write hash records stored in text files.

11.10.2. Solution

Use a simple file format with one field per line:

FieldName: Value

and separate records with blank lines.

11.10.3. Discussion

If you have an array of records that you'd like to store into and retrieve from a text file, you can use a simple format based on mail headers. The format's simplicity requires that the keys have neither colons nor newlines, and the values not have newlines.

This code writes them out:

foreach $record (@Array_of_Records) {
    for $key (sort keys %$record) {
        print "$key: $record->{$key}\n";
    }
    print "\n";
}

Reading them in is easy, too.

$/ = "";                # paragraph read mode
while (<>) {
    my @fields = split /^([^:]+):\s*/m;
    shift @fields;      # for leading null field
    push(@Array_of_Records, { map /(.*)/, @fields });
}

The split acts upon $_, its default second argument, which contains a full paragraph. The pattern looks for start of line (not just start of record, thanks to the /m) followed by one or more non-colons, followed by a colon and optional whitespace. When split's pattern contains parentheses, these are returned along with the values. The return values placed in @fields are in key-value order, with a leading null field we shift off. The braces in the call to push produce a reference to a new anonymous hash, which we copy @fields into. Since that array was stored in order of the needed key-value pairing, this makes for well-ordered hash contents.

All you're doing is reading and writing a plain text file, so you can use related recipes for additional components. You could use Recipe 7.18 to ensure that you have clean, concurrent access; Recipe 1.18 to store colons and newlines in keys and values; and Recipe 11.3 to store more complex structures.

If you are willing to sacrifice the elegance of a plain textfile for a quick, random-access database of records, use a DBM file, as described in Recipe 11.14.

11.10.4. See Also

The split function in perlfunc(1) and Chapter 29 of Programming Perl; Recipe 11.9; Recipe 11.13; Recipe 11.14

Previous | Home | Next
11.9. Constructing Records | Book Index | 11.11. Printing Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.11. Printing Data Structures

11.11.1. Problem

You want to print out a data structure.

11.11.2. Solution

If the output's legibility and layout are important, write your own custom printing routine.

If you are in the Perl debugger, use the x command:

DB<1> $reference = [ { "foo" => "bar" }, 3, sub { print "hello, world\n" } ];
DB<2> x $reference
  0  ARRAY(0x1d033c)
    0  HASH(0x7b390)
       'foo' = 'bar'
    1  3
    2  CODE(0x21e3e4)
       -> &main::_ _ANON_ _[(eval 15)[/usr/local/...perl5db.pl:17]:2]
       in (eval 15)[/usr/local/.../perl5db.pl:17]:2-2

From within your own programs, use the Dumper function from the standard module Data::Dumper:

use Data::Dumper;
print Dumper($reference);

Or if you'd like output formatted in the same style as the Debugger uses:

use Dumpvalue;
Dumpvalue->new->dumpValue($reference);

11.11.3. Discussion

Sometimes you'll want to make a dedicated function for your data structure that delivers a particular output format, but often this is overkill. If you're running under the Perl debugger, the x and X commands provide nice pretty-printing. The x command is more useful because it works on both global and lexical variables, whereas X works only on globals. Pass x a reference to the data structure you want to print.

DB<3> x @INC
  0  ARRAY(0x807d0a8)
     0  '/home/tchrist/perllib'
     1  '/usr/lib/perl5/i686-linux/5.00403'
     2  '/usr/lib/perl5'
     3  '/usr/lib/perl5/site_perl/i686-linux'
     4  '/usr/lib/perl5/site_perl'
     5  '.'

The standard Dumpvalue module provides the Debugger's output formatting using an object-oriented interface. Here's an example:

use Dumpvalue;
Dumpvalue->new->dumpvars("main", "INC");

@INC = (
   0  '/usr/local/lib/perl5/5.8.1/OpenBSD.i386-openbsd'
   1  '/usr/local/lib/perl5/5.8.1'
   2  '/usr/local/lib/perl5/site_perl/5.8.1/OpenBSD.i386-openbsd'
   3  '/usr/local/lib/perl5/site_perl/5.8.1'
   4  '/usr/local/lib/perl5/site_perl/5.8.0/OpenBSD.i386-openbsd'
   5  '/usr/local/lib/perl5/site_perl/5.8.0'
   6  '/usr/local/lib/perl5/site_perl'
   7  '.'
)
%INC = (
   'Dumpvalue.pm' = '/usr/local/lib/perl5/5.8.1/Dumpvalue.pm'>
   'strict.pm' = '/usr/local/lib/perl5/5.8.1/strict.pm'>
)

which is like using the V main INC command in the Debugger. All the output formatting options from the Debugger are available from Dumpvalue. Just pass Dumpvalue->new option pairs:

$dobj = Dumpvalue->new(option1 => value1, option2 => value2);

Options available as of v5.8.1 include arrayDepth, hashDepth, compactDump, veryCompact, globPrint, dumpDBFiles, dumpPackages, dumpReused, tick, quoteHighBit, printUndef, usageOnly, unctrl, subdump, bareStringify, quoteHighBit, and stopDbSignal.

The Data::Dumper module, also included in the standard Perl distribution, has a different approach. It provides a Dumper function that takes a list of references and returns a string with a printable (and eval able) form of those references.

use Data::Dumper; print Dumper(\@INC);
$VAR1 = [
'/usr/local/lib/perl5/5.8.1/OpenBSD.i386-openbsd',
'/usr/local/lib/perl5/5.8.1',
'/usr/local/lib/perl5/site_perl/5.8.1/OpenBSD.i386-openbsd',
'/usr/local/lib/perl5/site_perl/5.8.1',
'/usr/local/lib/perl5/site_perl/5.8.0/OpenBSD.i386-openbsd',
'/usr/local/lib/perl5/site_perl/5.8.0',
'/usr/local/lib/perl5/site_perl', '.'
];

Data::Dumper supports a variety of output formats. Check its documentation for details. Particularly useful is the option to decompile Perl code:

use Data::Dumper;
$Data::Dumper::Deparse = 1;
$a = sub { print "hello, world\n" };
print Dumper($a);
$VAR1 = sub {
                  print 'hello, world';
              };

11.11.4. See Also

The documentation for Data::Dumper; Chapter 20 of Programming Perl or perldebug(1)

Previous | Home | Next
11.10. Reading and Writing Hash Records to Text Files | Book Index | 11.12. Copying Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.12. Copying Data Structures

11.12.1. Problem

You need to copy a complex data structure.

11.12.2. Solution

Use the dclone function from the standard Storable module:

use Storable;

$r2 = dclone($r1);

11.12.3. Discussion

Two types of "copy" are sometimes confused. A surface copy (also known as shallow copy) simply copies references without creating copies of the data behind them:

@original = ( \@a, \@b, \@c );
@surface = @original;

A deep copy creates an entirely new structure with no overlapping references. This copies references to one layer deep:

@deep = map { [ @$_ ] } @original;

If @a, @b, and @c themselves contain references, the preceding map is no longer adequate. Writing your own code to deep-copy structures is laborious and rapidly becomes tiresome.

The Storable module provides a function called dclone that recursively copies its argument:

use Storable qw(dclone);
$r2 = dclone($r1);

This only works on references or blessed objects of type SCALAR, ARRAY, HASH, or CODE;[20] references of type GLOB, IO, and the more esoteric types are not supported. The safeFreeze function from the FreezeThaw module supports even these types when used in the same address space by using a reference cache that could interfere with garbage collection and object destructors under some circumstances.

[20]Believe it or not, it's true. Storable can even serialize closures. See its manpage for how to unthaw these using a Safe compartment.

Because dclone takes and returns references, you must add extra punctuation if you have a hash or arrays to copy:

%newhash = %{ dclone(\%oldhash) };

11.12.4. See Also

The documentation for the standard Storable and Data::Dumper modules, and for the FreezeThaw CPAN module.

Previous | Home | Next
11.11. Printing Data Structures | Book Index | 11.13. Storing Data Structures to Disk
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.13. Storing Data Structures to Disk

11.13.1. Problem

You want to save your large, complex data structure to disk so you don't have to reconstruct it from scratch each time your program runs.

11.13.2. Solution

Use the Storable module's store and retrieve functions:

use Storable;
store(\%hash, "filename");

# later on...
$href = retrieve("filename");        # by ref
%hash = %{ retrieve("filename") };   # direct to hash

11.13.3. Discussion

The Storable module uses C functions and a binary format to walk Perl's internal data structures and lay out its data. It's more efficient than a pure Perl and string-based approach, but it's also more fragile.

The store and retrieve functions expect binary data using the machine's own byte-ordering. This means files created with these functions cannot be shared across different architectures. nstore does the same job store does, but keeps data in canonical (network) byte order, at a slight speed cost:

use Storable qw(nstore);
nstore(\%hash, "filename");
# later ...
$href = retrieve("filename");

No matter whether store or nstore was used, you need to call the same retrieve routine to restore the objects in memory. The producer must commit to portability, but the consumer doesn't have to. Code need only be changed in one place when the producer has a change of heart; the code thus offers a consistent interface for the consumer, who does not need to know or care.

The store and nstore functions don't lock the files they work on. If you're worried about concurrent access, open the file yourself, lock it using Recipe 7.18, and then use store_fd or its slower but machine-independent version nstore_fd.

Here's code to save a hash to a file, with locking. We don't open with the O_TRUNC flag because we have to wait to get the lock before we can clobber the file.

use Storable qw(nstore_fd);
use Fcntl qw(:DEFAULT :flock);
sysopen(DF, "/tmp/datafile", O_RDWR|O_CREAT, 0666)
        or die "can't open /tmp/datafile: $!";
flock(DF, LOCK_EX)                   or die "can't lock /tmp/datafile: $!";
nstore_fd(\%hash, *DF)
    or die "can't store hash\n";
truncate(DF, tell(DF));
close(DF);

Here's code to restore that hash from a file, with locking:

use Storable qw(retrieve_fd);
use Fcntl qw(:DEFAULT :flock);
open(DF, " < /tmp/datafile")      or die "can't open /tmp/datafile: $!";
flock(DF, LOCK_SH)                or die "can't lock /tmp/datafile: $!";
$href = retrieve_fd(*DF);
close(DF);

With care, you can pass large data objects efficiently between processes using this strategy, since a filehandle connected to a pipe or socket is still a byte stream, just like a plain file.

Unlike the various DBM bindings, Storable does not restrict you to using only hashes (or arrays, with DB_File). Arbitrary data structures, including objects, can be stored to disk. The whole structure must be read in or written out in its entirety.

11.13.4. See Also

The section on "Remote Procedure Calls (RPC)" in Chapter 13 of Advanced Perl Programming, by Sriram Srinivasan (O'Reilly); Recipe 11.14

Previous | Home | Next
11.12. Copying Data Structures | Book Index | 11.14. Transparently Persistent Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.14. Transparently Persistent Data Structures

11.14.1. Problem

You have a complex data structure that you want to persist outside your program.

11.14.2. Solution

Use MLDBM and either (preferably) DB_File or else GDBM_File:

use MLDBM qw(DB_File);
use Fcntl;

tie(%hash, "MLDBM", "testfile.db", O_CREAT|O_RDWR, 0666)
    or die "can't open tie to testfile.db: $!";

# ... act on %hash

untie %hash;

11.14.3. Discussion

A hash with 100,000 items in it would undoubtably take considerable time to build. Storing this to disk, either slowly by hand or quickly with Storable, is still an expensive operation in memory and computation.

The DBM modules solve this by tying hashes to disk database files. Rather than reading the whole structure in at once, they only pull in what they need, when they need it. To the user, it looks like a hash that persists across program invocations.

Unfortunately, the values in this persistent hash must be plain strings. You cannot readily use a database file as a backing store for a hash of hashes, a hash of arrays, and so on—just for a hash of strings.

However, the MLDBM module from CPAN allows you to store references in a database. It uses Data::Dumper to stringify these references for external storage:

use MLDBM qw(DB_File);
use Fcntl;
tie(%hash, "MLDBM", "testfile.db", O_CREAT|O_RDWR, 0666)
    or die "can't open tie to testfile.db: $!";

Now you can use %hash to fetch or store complex records from disk. The only drawback is that you can't access the references piecemeal. You have to pull in the reference from the database, work with it, and then store it back.

# this doesn't work!
$hash{"some key"}[4] = "fred";

# RIGHT
$aref = $hash{"some key"};
$aref->[4] = "fred";
$hash{"some key"} = $aref;

11.14.4. See Also

Recipe 11.13

Previous | Home | Next
11.13. Storing Data Structures to Disk | Book Index | 11.15. Coping with Circular Data Structures Using Weak References
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.15. Coping with Circular Data Structures Using Weak References

11.15.1. Problem

You have an inherently self-referential data structure, so Perl's reference-based garbage collection system won't notice when that structure is no longer being used. You want to prevent your program from leaking memory.

11.15.2. Solution

Convert all internal references within the data structure into weak references so they don't increment the reference count.

11.15.3. Description

Perl's memory management system relies on an underlying reference count to know when to reclaim memory. In practice, this works fairly well except for one particular situation: when a variable directly or indirectly points at itself. Consider:

{
    my ($a, $b);
    ($a, $b) = \($b, $a);   # same as (\$b, \$a);
}

The two underlying scalars that $a and $b represent each start out with a reference count of one apiece in the first line of the block. In the second line, those scalars are each initialized to contain a reference to the other variable; $a points to $b and vice versa. Saving a reference increments the underlying reference count on the scalars, so now both refcounts are set to two. As the block exits and those lexical variables become unreachable (by name), both refcounts are decremented by one, leaving one in each—forever. Since the refcounts can never reach zero, memory used by those two underlying scalars will never be reclaimed. You'll leak two scalars every time that block executes; if it's a loop or a subroutine, you could eventually run out of memory.

The standard Devel::Peek module's Dump function shows you underlying reference counts, plus a whole lot more. This code:

use Devel::Peek;
$a = 42;
$b = \$a;
Dump $a;

produces this output:

SV = IV(0xd7cc4) at 0xd72b8
  REFCNT = 2
  FLAGS = (IOK,pIOK)
  IV = 42

The important thing to notice there is that the refcount is two. That's because the scalar can be reached two ways: once via the variable named $a, and then again through dereferencing $b using $$b.

You can produce the same condition, even without using another variable:

{ my $a; $a = \$a; }

This most often occurs when creating a data structure whose elements contain references that directly or indirectly point back to the initial element. Imagine a circular linked list—a ring data structure.

$ring = {
    VALUE => undef,
    NEXT  => undef,
    PREV  => undef,
};
$ring->{NEXT} = $ring;
$ring->{PREV} = $ring;

The underlying hash has an underlying refcount of three, and undef fing $ring or letting it go out of scope will decrement that count only by one, resulting in a whole hash full of memory irrecoverable by Perl.

To address this situation, Perl introduced in its v5.6 release the concept of weak references. A weak reference is just like any other regular reference (meaning a "hard" reference, not a "symbolic" one) except for two critical properties: it no longer contributes to the reference count on its referent, and when its referent is garbage collected, the weak reference itself becomes undefined. These properties make weak references perfect for data structures that hold internal references to themselves. That way those internal references do not count toward the structure's reference count, but external ones still do.

Although Perl supported weak references starting in v5.6, there was no standard weaken( ) function to access them from Perl itself in the standard release. You had to go to CPAN to pull in the WeakRef module. Beginning in v5.8.1, the weaken( ) function is included standard with the Scalar::Util module. That module also provides an is_weak( ) function that reports whether its reference argument has been weakened.

Here's how you would apply weak references to the ring example just given:

use Scalar::Util qw(weaken);

$ring = {
    VALUE => undef,
    NEXT  => undef,
    PREV  => undef,
};
$ring->{NEXT} = $ring;
$ring->{PREV} = $ring;
weaken($ring->{NEXT});
weaken($ring->{PREV});

In Recipe 13.13, we show how to create a circular-linked list data structure that won't leak memory by employing an elaborate trick using a dummy head node and an object-oriented device called a destructor. With weak references, the code becomes much simpler. Here's the same algorithm as that recipe uses, but here using weak references to address the memory-leak issue.

use Scalar::Util qw(weaken);

my $COUNT = 1000;
for (1..20) {
    my $ring = node(100_000 + $_);
    for my $value (1 .. $COUNT) {
       insert_value($ring, $value);
    }
}

# return a node
sub node($) {
    my ($init_value) = @_;
    my $node  = { VALUE => $init_value };
    $node->{NEXT} = $node->{PREV} = $node;
    weaken($node->{NEXT});
    weaken($node->{PREV});
    return $node;
}

# $node = search_ring($ring, $value) : find $value in the ring
# structure in $node
sub search_ring {
    my ($ring, $value) = @_;
    my $node = $ring->{NEXT};
    while ($node != $ring && $node->{VALUE} != $value) {
        $node = $node->{NEXT};
    }
    return $node;
}

# insert_value( $ring, $value ) : insert $value into the ring structure
sub insert_value {
    my ($ring, $value) = @_;
    my $node = { VALUE => $value };
    weaken($node->{NEXT} = $ring->{NEXT});
    weaken($ring->{NEXT}->{PREV} = $node);
    weaken($ring->{NEXT} = $node);
    weaken($node->{PREV} = $ring);
    ++$ring->{COUNT};
}

# delete_value( $ring, $value ) : delete a node from the ring
# structure by value
sub delete_value {
  my ($ring, $value) = @_;
  my $node = search_ring($ring, $value);
  return if $node =  = $ring;
  $ring->delete_node($node);
}

# delete a node from the ring structure
sub delete_node {
  my ($ring, $node) = @_;
  weaken($node->{PREV}->{NEXT} = $node->{NEXT});
  weaken($node->{NEXT}->{PREV} = $node->{PREV});
  --$ring->{COUNT};
}

Every time we store a reference to part of the data structure within that same structure, we weaken the reference so it doesn't count toward the reference count. Otherwise our program's in-core memory footprint would have grown terrifically. You can watch that happen by adding:

system("ps v$$");

within the loop on systems that support the ps(1) program. All it takes to trigger the leak is not weakening any of the four assignments in the insert_value function just shown.

11.15.4. See Also

The algorithms in this recipe derive in part from pages 206-207 of Introduction to Algorithms, by Cormen, Leiserson, and Rivest (MIT Press/McGraw-Hill). See also Recipe 13.13; the section on "Garbage Collection, Circular References, and Weak References" in Chapter 8 of Programming Perl; the documentation for the standard Devel::Peek and Scalar::Util modules

Previous | Home | Next
11.14. Transparently Persistent Data Structures | Book Index | 11.16. Program: Outlines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.16. Program: Outlines

Outlines are a simple (and thus popular) way of structuring data. The hierarchy of detail implied by an outline maps naturally to our top-down way of thinking about the world. The only problem is that it's not obvious how to represent outlined data as a Perl data structure.

Take, for example, this simple outline of some musical genres:

Alternative
.Punk
..Emo
..Folk Punk
.Goth
..Goth Rock
..Glam Goth
Country
.Old Time
.Bluegrass
.Big Hats
Rock
.80s
..Big Hair
..New Wave
.60s
..British
..American

Here we use a period to indicate a subgroup. There are many different formats in which that outline could be output. For example, you might write the genres out in full:

Alternative
Alternative - Punk
Alternative - Punk - Emo
Alternative - Punk - Folk Punk
Alternative - Goth
...

You might number the sections:

1 Alternative
1.1 Punk
1.1.1 Emo
1.1.2 Folk Punk
1.2 Goth
...

or alphabetize:

Alternative
Alternative - Goth
Alternative - Goth - Glam Goth
Alternative - Goth - Goth Rock
Alternative - Punk
Alternative - Punk - Emo
...

or show inheritance:

Alternative
Punk - Alternative
Emo - Punk - Alternative
Folk Punk - Punk - Alternative
Goth - Alternative
Goth Rock - Goth - Alternative
...

These transformations are all much easier than it might seem. The trick is to represent the levels of the hierarchy as elements in an array. For example, you'd represent the third entry in the sample outline as:

@array = ("Alternative", "Goth", "Glam Goth");

Now reformatting the entry is trivial. There's an elegant way to parse the input file to get this array representation:

while (<FH>) {
  chomp;
  $tag[$in = s/\G\.//g] = $_;
  # do something with @tag[0..$in]
}

The substitution deletes leading periods from the current entry, returning how many it deleted. This number indicates the indentation level of the current entry.

Alphabetizing is now simple using the Unix sort program:

$ISA = "-";
open(STDOUT, "|sort -b -t'$ISA' -df");
while (<DATA>) {
    chomp;
    $tag[$in = s/\G\.//g] = $_;
    print join(" $ISA ", @tag[0 .. $in]);
}
close STDOUT;
_ _END_ _
Alternative
.Punk
..Emo
..Folk Punk
.Goth

Numbering the outline is equally simple:

while (<DATA>) {
    chomp;
    $count[$in = s/\G\.//g]++;
    delete @count[($in+1) .. $#count];
    print join(".", @count), " $_";
}
_ _END_ _
Alternative
.Punk
..Emo
..Folk Punk
.Goth
..Goth Rock

Notice that renumbering is our only application where we've deleted elements from the array. This is because we're not keeping names of hierarchy levels in the array; now we're keeping counts. When we go up a level (e.g., from three levels down to a new second-level heading), we reset the counter on the old level.

Previous | Home | Next
11.15. Coping with Circular Data Structures Using Weak References | Book Index | 11.17. Program: Binary Trees
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.17. Program: Binary Trees

Because Perl's built-in data types are already powerful, high-level, dynamic data types in their own right, most code can use what's already provided. If you just want quick lookups, you nearly always want to use a simple hash. As Larry has said, "The trick is to use Perl's strengths rather than its weaknesses."

However, hashes provide no inherent ordering. To traverse the hash in a particular order, you must first extract its keys and then sort them. If you find yourself doing so many times, performance will suffer, but probably not enough to justify the time required to craft a fancy algorithm.

A tree structure provides ordered traversals. How do you write a tree in Perl? First, you grab one of your favorite textbooks on data structures; the authors recommend Cormen et al., as mentioned in Other Books in the Preface. Using an anonymous hash to represent each node in the tree, translate the algorithms in the book into Perl. This is usually much more straightforward than you would imagine.

The program code in Example 11-1 demonstrates an ordered binary tree implementation using anonymous hashes. Each node has three fields: a left child, a right child, and a value. The crucial property of an ordered binary tree is that at every node, all left children have values that are less than the current node value, and all right children have values that are greater.

The main program does three things. First, it creates a tree with 20 random nodes. Then it shows the in-order, pre-order, and post-order traversals of that tree. Finally, it allows the user to enter a key and reports whether that key is in the tree.

The insert function takes advantage of Perl's implicit pass-by-reference behavior on scalars to initialize an empty tree when asked to insert into an empty node. The assignment of the new node back to $_[0] alters the value in its caller.

Although this data structure takes much more memory than a simple hash and the lookups are slower, the ordered traversals themselves are faster.

A B-Tree is not a binary tree; it is a more flexible tree structure normally maintained on disk. DB_File has a BTREE interface (see DB_File(3)), and Mark-Jason Dominus has an excellent article on B-Trees in The Perl Journal, Volume 2, Issue 4, Winter 1997, pp. 35-42.

If you want to learn more about binary trees, Introduction to Algorithms, by Cormen, Leiserson, and Rivest, and Algorithms in C, by Robert Sedgewick, both cover the basic material. But for a treatment of that material cast in native Perl, no book can compare with Mastering Algorithms with Perl, by Orwant, Hietaniemi, and MacDonald.

The program is shown in Example 11-1.

Example 11-1. bintree

  #!/usr/bin/perl -w
  # bintree - binary tree demo program
  use strict;
  my($root, $n);
  # first generate 20 random inserts
  while ($n++ < 20) { insert($root, int(rand(1000)))}
  # now dump out the tree all three ways
  print "Pre order:  ";  pre_order($root);  print "\n";
  print "In order:   ";  in_order($root);   print "\n";
  print "Post order: ";  post_order($root); print "\n";
  # prompt until EOF
  for (print "Search? "; <>; print "Search? ") {
      chomp;
      my $found = search($root, $_);
      if ($found) { print "Found $_ at $found, $found->{VALUE}\n" }
      else        { print "No $_ in tree\n" }
  }
  exit;
  #########################################
  # insert given value into proper point of
  # provided tree.  If no tree provided,
  # use implicit pass by reference aspect of @_
  # to fill one in for our caller.
  sub insert {
      my($tree, $value) = @_;
      unless ($tree) {
          $tree = {  };                       # allocate new node
          $tree->{VALUE}  = $value;
          $tree->{LEFT}   = undef;
          $tree->{RIGHT}  = undef;
          $_[0] = $tree;                          # $_[0] is reference param!
          return;
      }
      if    ($tree->{VALUE} > $value) { insert($tree->{LEFT},  $value) }
      elsif ($tree->{VALUE} < $value) { insert($tree->{RIGHT}, $value) }
      else                            { warn "dup insert of $value\n"  }
                                      # XXX: no dups
  }
  # recurse on left child,
  # then show current value,
  # then recurse on right child.
  sub in_order {
      my($tree) = @_;
      return unless $tree;
      in_order($tree->{LEFT});
      print $tree->{VALUE}, " ";
      in_order($tree->{RIGHT});
  }
  # show current value,
  # then recurse on left child,
  # then recurse on right child.
  sub pre_order {
      my($tree) = @_;
      return unless $tree;
      print $tree->{VALUE}, " ";
      pre_order($tree->{LEFT});
      pre_order($tree->{RIGHT});
  }
  # recurse on left child,
  # then recurse on right child,
  # then show current value.
  sub post_order {
      my($tree) = @_;
      return unless $tree;
      post_order($tree->{LEFT});
      post_order($tree->{RIGHT});
      print $tree->{VALUE}, " ";
  }
  # find out whether provided value is in the tree.
  # if so, return the node at which the value was found.
  # cut down search time by only looking in the correct
  # branch, based on current value.
  sub search {
      my($tree, $value) = @_;
      return unless $tree;
      if ($tree->{VALUE} =  = $value) {
          return $tree;
      }
      search($tree->{ ($value < $tree->{VALUE}) ? "LEFT" : "RIGHT"}, $value)
  }
Previous | Home | Next
11.16. Program: Outlines | Book Index | 12. Packages, Libraries, and Modules
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 12. Packages, Libraries, and Modules

Contents:

Introduction
Defining a Module's Interface
Trapping Errors in require or use
Delaying use Until Runtime
Making Variables Private to a Module
Making Functions Private to a Module
Determining the Caller's Package
Automating Module Cleanup
Keeping Your Own Module Directory
Preparing a Module for Distribution
Speeding Module Loading with SelfLoader
Speeding Up Module Loading with Autoloader
Overriding Built-in Functions
Overriding a Built-in Function in All Packages
Reporting Errors and Warnings Like Built-ins
Customizing Warnings
Referring to Packages Indirectly
Using h2ph to Translate C #include Files
Using h2xs to Make a Module with C Code
Writing Extensions in C with Inline::C
Documenting Your Module with Pod
Building and Installing a CPAN Module
Example: Module Template
Program: Finding Versions and Descriptions of Installed Modules

Jorge Luis Borges, The Theologians

Like all those possessing a library, Aurelian was aware that he was guilty of not knowing his in its entirety.

12.0. Introduction

Imagine that you have two separate programs, both of which work fine by themselves, and you decide to make a third program that combines the best features from the first two. You copy both programs into a new file or cut and paste selected pieces. You find that the two programs had variables and functions with the same names that should remain separate. For example, both might have an init function or a global $count variable. When merged into one program, these separate parts would interfere with each other.

The solution to this problem is packages. Perl uses packages to partition the global namespace. The package is the basis for both traditional modules and object-oriented classes. Just as directories contain files, packages contain identifiers. Every global identifier (variables, functions, file and directory handles, and formats) has two parts: its package name and the identifier proper. These two pieces are separated from one another with a double colon. For example, the variable $CGI::needs_binmode is a global variable named $needs_binmode, which resides in package CGI.

Where the filesystem uses slashes to separate the directory from the filename, Perl uses a double colon. $Names::startup is the variable named $startup in the package Names, whereas $Dates::startup is the $startup variable in package Dates. Saying $startup by itself without a package name means the global variable $startup in the current package. (This assumes that no lexical $startup variable is currently visible. Lexical variables are explained in Chapter 10.) When looking at an unqualified variable name, a lexical takes precedence over a global. Lexicals live in scopes; globals live in packages. If you really want the global instead, you need to fully qualify it.

package is a compile-time declaration that sets the default package prefix for unqualified global identifiers, much as chdir sets the default directory prefix for relative pathnames. This effect lasts until the end of the current scope (a brace-enclosed block, file, or eval). The effect is also terminated by any subsequent package statement in the same scope. (See the following code.) All programs are in package main until they use a package statement to change this.

package Alpha;
$name = "first";

package Omega;
$name = "last";

package main;
print "Alpha is $Alpha::name, Omega is $Omega::name.\n";
Alpha is first, Omega is last.

Unlike user-defined identifiers, built-in variables with punctuation names (like $_ and $.) and the identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC, and SIG are all forced to be in package main when unqualified. That way things like STDIN, @ARGV, %ENV, and $_ are always the same no matter what package you're in; for example, @ARGV always means @main::ARGV, even if you've used package to change the default package. A fully qualified @ElseWhere::ARGV would not, and carries no special built-in meaning. Make sure to localize $_ if you use it in your module.

12.0.2. Modules

The unit of software reuse in Perl is the module, a file containing related functions designed to be used by programs and other modules. Every module has a public interface, a set of variables and functions that outsiders are encouraged to use. From inside the module, the interface is defined by initializing certain package variables that the standard Exporter module looks at. From outside the module, the interface is accessed by importing symbols as a side effect of the use statement. The public interface of a Perl module is whatever is documented to be public. When we talk about modules in this chapter, and traditional modules in general, we mean those that use the Exporter.

The require and use statements load a module into your program, although their semantics vary slightly. require loads modules at runtime, with a check to avoid the redundant loading of a given module. use is like require, with two added properties: compile-time loading and automatic importing.

Modules included with use are processed at compile time, but require processing happens at runtime. This is important because if a module needed by a program is missing, the program won't even start because the use fails during compilation of your script. Another advantage of compile-time use over runtime require is that function prototypes in the module's subroutines become visible to the compiler. This matters because only the compiler cares about prototypes, not the interpreter. (Then again, we don't usually recommend prototypes except for replacing built-in commands, which do have them.)

use is suitable for giving hints to the compiler because of its compile-time behavior. A pragma is a special module that acts as a directive to the compiler to alter how Perl compiles your code. A pragma's name is always all lowercase, so when writing a regular module instead of a pragma, choose a name that starts with a capital letter. Pragmas supported by the v5.8.1 release of Perl include attributes, autouse, base, bigint, bignum, bigrat, bytes, charnames, constant, diagnostics, fields, filetest, if, integer, less, locale, open, overload, sigtrap, sort, strict, subs, utf8, vars, vmsish, and warnings. Each has its own manpage.

The other difference between require and use is that use performs an implicit import on the included module's package. Importing a function or variable from one package to another is a form of aliasing; that is, it makes two different names for the same underlying thing. It's like linking files from another directory into your current one by the command ln /somedir/somefile. Once it's linked in, you no longer have to use the full pathname to access the file. Likewise, an imported symbol no longer needs to be fully qualified by package name (or declared with our or the older use vars if a variable, or with use subs if a subroutine). You can use imported variables as though they were part of your package. If you imported $English::OUTPUT_AUTOFLUSH in the current package, you could refer to it as $OUTPUT_AUTOFLUSH.

The required file extension for a Perl module is .pm. The module named FileHandle would be stored in the file FileHandle.pm. The full path to the file depends on your include path, which is stored in the global @INC variable. Recipe 12.8 shows how to manipulate this array for your own purposes.

If the module name itself contains any double colons, these are translated into your system's directory separator. That means that the File::Find module resides in the file File/Find.pm under most filesystems. For example:

require "FileHandle.pm";            # runtime load
require FileHandle;                 # ".pm" assumed; same as previous
use FileHandle;                     # compile-time load

require "Cards/Poker.pm";           # runtime load
require Cards::Poker;               # ".pm" assumed; same as previous
use Cards::Poker;                   # compile-time load

12.0.3. Import/Export Regulations

The following is a typical setup for a hypothetical module named Cards::Poker that demonstrates how to manage its exports. The code goes in the file named Poker.pm within the directory Cards; that is, Cards/Poker.pm. (See Recipe 12.8 for where the Cards directory should reside.) Here's that file, with line numbers included for reference:

1    package Cards::Poker;
2    use Exporter;
3    @ISA = ("Exporter");
4    @EXPORT = qw(&shuffle @card_deck);
5    @card_deck = ( );                       # initialize package global
6    sub shuffle { }                        # fill-in definition later
7    1;                                     # don't forget this

Line 1 declares the package that the module will put its global variables and functions in. Typically, a module first switches to a particular package so that it has its own place for global variables and functions, one that won't conflict with that of another program. This package name must be written exactly as in the corresponding use statement when the module is loaded.

Don't say package Poker just because the basename of your file is Poker.pm. Rather, say package Cards::Poker because your users will say use Cards::Poker. This common problem is hard to debug. If you don't make the package names specified by the package and use statements identical, you won't see a problem until you try to call imported functions or access imported variables, which will be mysteriously missing.

Line 2 loads in the Exporter module, which manages your module's public interface as described later. Line 3 initializes the special, per-package array @ISA to contain the word "Exporter". When a user says use Cards::Poker, Perl implicitly calls a special method, Cards::Poker->import( ). You don't have an import method in your package, but that's okay, because the Exporter package does, and you're inheriting from it because of the assignment to @ISA (is a). Perl looks at the package's @ISA for resolution of undefined methods. Inheritance is a topic of Chapter 13. You may ignore it for now—so long as you put code like that in lines 2 and 3 into each module you write.

Line 4 assigns the list ('&shuffle', '@card_deck') to the special, per-package array @EXPORT. When someone imports this module, variables and functions listed in that array are aliased into the caller's own package. That way they don't have to call the function Cards::Poke::shuffle(23) after the import. They can just write shuffle(23) instead. This won't happen if they load Cards::Poker with require Cards::Poker; only a use imports.

Lines 5 and 6 set up the package global variables and functions to be exported. (We presume you'll actually flesh out their initializations and definitions more than in these examples.) You're free to add other variables and functions to your module, including ones you don't put in the public interface via @EXPORT. See Recipe 12.1 for more about using the Exporter.

Finally, line 7 is a simple 1, indicating the overall return value of the module. If the last evaluated expression in the module doesn't produce a true value, an exception will be raised. Trapping this is the topic of Recipe 12.2.

Packages group and organize global identifiers. They have nothing to do with privacy. Code compiled in package Church can freely examine and alter variables in package State. Package variables are always global and are used for sharing. But that's okay, because a module is more than just a package; it's also a file, and files count as their own scope. So if you want privacy, use lexical variables instead of globals. This is the topic of Recipe 12.4.

12.0.4. Other Kinds of Library Files

A library is a collection of loosely related functions designed to be used by other programs. It lacks the rigorous semantics of a Perl module. The file extension .pl indicates that it's a Perl library file. Examples include syslog.pl and abbrev.pl. These are included with the standard release for compatibility with prehistoric scripts written under Perl v4 or below.

Perl libraries—or in fact, any arbitrary file with Perl code in it—can be loaded in using do "file.pl" or with require "file.pl". The latter is preferred in most situations, because unlike do, require does implicit error checking. It raises an exception if the file can't be found in your @INC path, doesn't compile, or if it doesn't return a true value when any initialization code is run (the last part is what the 1 was for earlier). Another advantage of require is that it keeps track of which files have already been loaded in the global hash %INC. It doesn't reload the file if %INC indicates that the file has already been read.

Libraries work well when used by a program, but problems arise when libraries use one another. Consequently, simple Perl libraries have been rendered mostly obsolete, replaced by the more modern modules. But some programs still use libraries, usually loading them in with require instead of do.

Other file extensions are occasionally seen in Perl. A .ph is used for C header files that have been translated into Perl libraries using the h2ph tool, as discussed in Recipe 12.17. A .xs indicates an augmented C source file, possibly created by the h2xs tool, which will be compiled by the xsubpp tool and your C compiler into native machine code. This process of creating mixed-language modules is discussed in Recipe 12.18.

So far we've talked only about traditional modules, which export their interface by allowing the caller direct access to particular subroutines and variables. Most modules fall into this category. But some problems—and some programmers—lend themselves to more intricately designed modules: those involving objects. An object-oriented module seldom uses the import-export mechanism at all. Instead, it provides an object-oriented interface full of constructors, destructors, methods, inheritance, and operator overloading. This is the subject of Chapter 13.

12.0.5. Not Reinventing the Wheel

CPAN, the Comprehensive Perl Archive Network, is a gigantic repository of nearly everything about Perl you could imagine, including source, documentation, alternate ports, and above all, modules—some 4,500 of them as of spring of 2003. Before you write a new module, check with CPAN to see whether one already exists that does what you need. Even if one doesn't, something close enough might give you ideas.

CPAN is a replicated archive, currently mirrored on nearly 250 sites. Access CPAN via http://www.cpan.org/. If you just want to poke around, you can manually browse through the directories there. There are many indices, including listings of just new modules and of all modules organized by name, author, or category.

A convenient alternative to picking through thousands of modules is the search engine available at http://search.cpan.org/. You can search for modules by their name or author, but the facility for grepping through all registered modules' documentation is often more useful. That way you don't have download and install a module just to see what it's supposed to do.

12.0.6. See Also

Chapters 10, 11, and 22 of Programming Perl; perlmod(1)

Previous | Home | Next
11.17. Program: Binary Trees | Book Index | 12.1. Defining a Module's Interface
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.1. Defining a Module's Interface

12.1.1. Problem

You want the standard Exporter module to define the external interface to your module.

12.1.2. Solution

In module file YourModule.pm, place the following code. Fill in the ellipses as explained in the Discussion section.

package YourModule;
use strict;
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);

use Exporter;
$VERSION = 1.00;              # Or higher
@ISA = qw(Exporter);

@EXPORT      = qw(...);       # Symbols to autoexport (:DEFAULT tag)
@EXPORT_OK   = qw(...);       # Symbols to export on request
%EXPORT_TAGS = (              # Define names for sets of symbols
    TAG1 => [...],
    TAG2 => [...],
    ...
);

########################
# your code goes here
########################

1;                            # this should be your last line

In other files where you want to use YourModule, choose one of these lines:

use YourModule;               # Import default symbols into my package
use YourModule qw(...);       # Import listed symbols into my package
use YourModule ( );            # Do not import any symbols
use YourModule qw(:TAG1);     # Import whole tag set

12.1.3. Discussion

The standard Exporter module handles the module's external interface. Although you could define your own import method for your package, almost no one does this.

When someone says use YourModule, this does a require "YourModule.pm" statement followed a YourModule->import( ) method call, both during compile time. The import method inherited from the Exporter package looks for global variables in your package to govern its behavior. Because they must be package globals, we've declared them with our to satisfy use strict. These variables are:

$VERSION
When a module is loaded, a minimal required version number can be supplied. If the version isn't at least this high, the use will raise an exception.

use YourModule 1.86;        # If $VERSION < 1.86, fail
@EXPORT
This array contains a list of functions and variables that will be exported into the caller's own namespace so they can be accessed without being fully qualified. Typically, a qw( ) list is used.

@EXPORT = qw(&F1 &F2 @List);
@EXPORT = qw( F1  F2 @List);        # same thing

With the simple use YourModule call the function &F1 can be called as F1( ) rather than YourModule::F1( ), and the array can be accessed as @List instead of @YourModule::List. The ampersand is optional in front of an exported function specification.

To load the module at compile time but request that no symbols be exported, use the special form use Exporter ( ), with empty parentheses.

@EXPORT_OK
This array contains symbols that can be imported if they're specifically asked for. If the array were loaded this way:

@EXPORT_OK = qw(Op_Func %Table);

then the user could load the module like so:

use YourModule qw(Op_Func %Table F1);

and import only the Op_Func function, the %Table hash, and the F1 function. The F1 function was listed in the @EXPORT array. Notice that this does not automatically import F2 or @List, even though they're in @EXPORT. To get everything in @EXPORT plus extras from @EXPORT_OK, use the special :DEFAULT tag, such as:

use YourModule qw(:DEFAULT %Table);
%EXPORT_TAGS
This hash is used by large modules like CGI or POSIX to create higher-level groupings of related import symbols. Its values are references to arrays of symbol names, all of which must be in either @EXPORT or @EXPORT_OK. Here's a sample initialization:

%EXPORT_TAGS = (
        Functions => [ qw(F1 F2 Op_Func) ],
        Variables => [ qw(@List %Table)  ],
);

An import symbol with a leading colon means to import a whole group of symbols. Here's an example:

use YourModule qw(:Functions %Table);

That pulls in all symbols from:

@{ $YourModule::EXPORT_TAGS{Functions} },

that is, it pulls in the F1, F2, and Op_Func functions and then the %Table hash.

Although you don't list it in %EXPORT_TAGS, the implicit tag :DEFAULT automatically means everything in @EXPORT.

You don't have to have all those variables defined in your module. You just need the ones that you expect people to be able to use.

12.1.4. See Also

The "Creating Modules" section of Chapter 11 of Programming Perl; the documentation for the standard Exporter module, also found in Chapter 32 of Programming Perl; Recipe 12.8; Recipe 12.22

Previous | Home | Next
12. Packages, Libraries, and Modules | Book Index | 12.2. Trapping Errors in require or use
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.2. Trapping Errors in require or use

12.2.1. Problem

You need to load in a module that might not be present on your system. This normally results in a fatal exception. You want to detect and trap these failures.

12.2.2. Solution

Wrap the require or use in an eval, and wrap the eval in a BEGIN block:

# no import
BEGIN {
    unless (eval "require $mod; 1") {
        warn "couldn't require $mod: $@";
    }
}

# imports into current package
BEGIN {
    unless (eval "use $mod; 1") {
        warn "couldn't use $mod: $@";
    }
}

12.2.3. Discussion

You usually want a program to fail if it tries to load a module that is missing or doesn't compile. Sometimes, though, you'd like to recover from that error, perhaps trying an alternative module instead. As with any other exception, you insulate yourself from compilation errors with an eval.

You don't want to use eval { BLOCK }, because this traps only runtime exceptions, and use is a compile-time event. Instead, you must use eval "string" to catch compile-time problems as well. Remember, require on a bareword has a slightly different meaning than require on a variable. It adds a ".pm" and translates double-colons into your operating system's path separators, canonically / (as in URLs), but sometimes \, :, or even . on some systems.

If you need to try several modules in succession, stopping at the first one that works, you could do something like this:

BEGIN {
    my($found, @DBs, $mod);
    $found = 0;
    @DBs = qw(Giant::Eenie Giant::Meanie Mouse::Mynie Moe);
    for $mod (@DBs) {
        if (eval "require $mod") {
            $mod->import( );         # if needed
            $found = 1;
            last;
        }
    }
    die "None of @DBs loaded" unless $found;
}

We wrap the eval in a BEGIN block to ensure the module-loading happens at compile time instead of runtime.

12.2.4. See Also

The eval, die, use, and require functions in Chapter 32 of Programming Perl and in perlfunc(1); Recipe 10.12; Recipe 12.3

Previous | Home | Next
12.1. Defining a Module's Interface | Book Index | 12.3. Delaying use Until Runtime
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.3. Delaying use Until Runtime

12.3.1. Problem

You have a module that you don't need to load each time the program runs, or whose inclusion you wish to delay until after the program starts up.

12.3.2. Solution

Either break up the use into its separate require and import components, or else employ the use autouse pragma.

12.3.3. Discussion

Programs that check their arguments and abort with a usage message on error have no reason to load modules they never use. This delays the inevitable and annoys users. But those use statements happen during compilation, not execution, as explained in the Introduction.

Here, an effective strategy is to place argument checking in a BEGIN block before loading the modules. The following is the start of a program that checks to make sure it was called with exactly two arguments, which must be whole numbers, before going on to load the modules it will need:

BEGIN {
    unless (@ARGV =  = 2 && (2 =  = grep {/^\d+$/} @ARGV)) {
        die "usage: $0 num1 num2\n";
    }
}
use Some::Module;
use More::Modules;

A related situation arises in programs that don't always use the same set of modules every time they're run. For example, the factors program from Chapter 2 needs the infinite precision arithmetic library only when the -b command-line flag is supplied. A use statement would be pointless within a conditional because it's evaluated at compile time, long before the if can be checked. So we use a require instead:

if ($opt_b) {
    require Math::BigInt;
}

Because Math::BigInt is an object-oriented module instead of a traditional one, no import was needed. If you have an import list, specify it with a qw( ) construct as you would with use. For example, rather than this:

use Fcntl qw(O_EXCL O_CREAT O_RDWR);

you might say this instead:

require Fcntl;
Fcntl->import(qw(O_EXCL O_CREAT O_RDWR));

Delaying the import until runtime means that the rest of your program is not subject to any imported semantic changes that the compiler would have seen if you'd used a use. In particular, subroutine prototypes and the overriding of built-in functions are not seen in time.

You might want to encapsulate this delayed loading in a subroutine. The following deceptively simple approach does not work:

sub load_module {
    require $_[0];  #WRONG
    import  $_[0];  #WRONG
}

It fails for subtle reasons. Imagine calling require with an argument of "Math::BigFloat". If that's a bareword, the double colon is converted into your operating system's path separator and a trailing .pm is added. But as a simple variable, it's a literal filename. Worse, Perl doesn't have a built-in import function. Instead, there's a class method named import that we're using the dubious indirect object syntax on. As with indirect filehandles, you can use indirect objects only on a plain scalar variable, a bareword, or a block returning the object, not an expression or one element from an array or hash.

A better implementation might look more like:

load_module("Fcntl", qw(O_EXCL O_CREAT O_RDWR));

sub load_module {
    eval "require $_[0]";
    die if $@;
    $_[0]->import(@_[1 .. $#_]);
}

But this still isn't perfectly correct in the general case. It really shouldn't import those symbols into its own package. It should put them into its caller's package. We could account for this, but the whole procedure is getting increasingly messy.

Occasionally, the condition can be reasonably evaluated before runtime, perhaps because it uses only built-in, predefined variables, or because you've arranged to initialize the variables used in the conditional expression at compile time with a BEGIN block. If so, the if pragma comes in handy. The syntax is:

use CONDITION, MODULE;
use CONDITION, MODULE => ARGUMENTS;

As in:

use if $^O =~ /bsd/i, BSD::Resource;
use if $] >= 5.006_01, File::Temp => qw/tempfile tempdir/;

A convenient alternative is the use autouse pragma. This directive can save time on infrequently loaded functions by delaying their loading until they're actually used:

use autouse Fcntl => qw( O_EXCL( ) O_CREAT( ) O_RDWR( ) );

We put parentheses after O_EXCL, O_CREAT, and O_RDWR when we autouse d them but not when we used them or import ed them. The autouse pragma doesn't just take function names; it can also take a prototype for the function. The Fcntl constants are prototyped to take no arguments, so we can use them as barewords in our program without use strict kvetching.

Remember, too, that use strict's checks take place at compile time. If we use Fcntl, the prototypes in the Fcntl module are compiled and we can use the constants without parentheses. If we require or wrap the use in an eval, as we did earlier, we prevent the compiler from reading the prototypes, so we can't use the Fcntl constants without parentheses.

Read the autouse pragma's online documentation to learn its various caveats and provisos.

12.3.4. See Also

Recipe 12.2; the discussion on the import method in the documentation for the standard Exporter module, also found in Chapter 32 of Programming Perl; the documentation for the standard use autouse pragma

Previous | Home | Next
12.2. Trapping Errors in require or use | Book Index | 12.4. Making Variables Private to a Module
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.4. Making Variables Private to a Module

12.4.1. Problem

You want to make a variable private to a package.

12.4.2. Solution

You can't. But you can make them private to the file that the module sits in, which usually suffices.

12.4.3. Discussion

Remember that a package is just a way of grouping variables and functions together, conferring no privacy. Anything in a package is by definition global and accessible from anywhere. Packages only group; they don't hide.

For privacy, only lexical variables will do. A module is implemented in a Module.pm file, with all its globals in the package named Module. Because that whole file is by definition a scope and lexicals are private to a scope, creating file-scoped lexicals is effectively the same thing as a module-private variable.

If you alternate packages within a scope, though, you may be surprised that the scope's lexicals are still visible throughout that scope. That's because a package statement only sets a different prefix for a global identifier; it does not end the current scope, not does it begin a new one.

package Alpha;
my $aa = 10;
   $x = "azure";

package Beta;
my $bb = 20;
   $x = "blue";

package main;
print "$aa, $bb, $x, $Alpha::x, $Beta::x\n";
10, 20, , azure, blue

Was that the output you expected? The two lexicals, $aa and $bb, are still in scope because we haven't left the current block, file, or eval. You might think of globals and lexicals as existing in separate dimensions, forever unrelated to each other. Package statements have nothing to do with lexicals. By setting the current prefix, the first global variable $x is really $Alpha::x, whereas the second $x is now $Beta::x because of the intervening package statement changing the default prefix. Package identifiers, if fully qualified, can be accessed from anywhere, as we've done in the print statement.

So, packages can't have privacy—but modules can because they're in a file, which is always its own scope. Here's a simple module, placed in the file Flipper.pm, that exports two functions, flip_words and flip_boundary. The module provides code to reverse words in a line, and to change the definition of a word boundary.

# Flipper.pm
package Flipper;
use strict;

require Exporter;
use vars qw(@ISA @EXPORT $VERSION);
@ISA     = qw(Exporter);
@EXPORT  = qw(flip_words flip_boundary);
$VERSION = 1.0;

my $Separatrix = " ";  # default to blank; must precede functions

sub flip_boundary {
    my $prev_sep = $Separatrix;
    if (@_) { $Separatrix = $_[0] }
    return $prev_sep;
}
sub flip_words {
    my $line  = $_[0];
    my @words = split($Separatrix, $line);
    return join($Separatrix, reverse @words);
}
1;

This module sets three package variables needed by the Exporter and also initializes a lexical variable at file level called $Separatrix. Again, this variable is private to the file, not to the package. All code beneath its declaration in the same scope (or nested within that scope, as are the functions' blocks) can see $Separatrix perfectly. Even though they aren't exported, global variables could be accessed using the fully qualified name, as in $Flipper::VERSION.

A scope's lexicals cannot be examined or tinkered with from outside that scope, which in this case is the entire file below their point of declaration. You cannot fully qualify lexicals or export them either; only globals can be exported. If someone outside the module needs to look at or change the file's lexicals, they must ask the module itself. That's where the flip_boundary function comes into play, allowing indirect access to the module's private parts.

This module would work the same even if its $Separatrix variable were a package global rather than a file lexical. Someone from the outside could theoretically play with it without the module realizing this. On the other hand, if they really want to that badly, perhaps you should let them do so. Peppering your module with file-scoped lexicals is not necessary. You already have your own namespace (Flipper, in this case) where you can store any identifier you want. That's what it's there for, after all. Good Perl programming style nearly always avoids fully qualified identifiers.

Speaking of style, the case of identifiers used in the Flipper module was not random. Following the Perl style guide, identifiers in all capitals are reserved for those with special meaning to Perl itself. Functions and local variables are all lowercase. The module's persistent variables (either file lexicals or package globals) are capitalized. Identifiers with multiple words have each word separated by an underscore to make them easier to read. We advise against using mixed capitals without underscores—you wouldn't like reading this book without spaces, either.

12.4.4. See Also

The discussion on file-scoped lexicals in perlmod(1); the "Scoped Declarations" section in Chapter 4 of Programming Perl; the section on "Programming with Style" in Chapter 24 of Programming Perl or perlstyle(1); Recipe 10.2; Recipe 10.3

Previous | Home | Next
12.3. Delaying use Until Runtime | Book Index | 12.5. Making Functions Private to a Module
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.5. Making Functions Private to a Module

12.5.1. Problem

You want to make a function private to a package.

12.5.2. Solution

You can't. But you can make a private variable and store a reference to an anonymous function in it.

# this is the file SomeModule.pm
package Some_Module;

my $secret_function = sub {
    # your code here
};

sub regular_function {
    # now call your "private" function via the code ref
    $secret_function->(ARG1, ARG2);
}

12.5.3. Discussion

Even a function that isn't exported can still be accessed by anyone, anywhere if they qualify that function's name with its package. That's because function names are always in the package symbol table, which is globally accessible.

By creating a lexical variable at the file scope, code in that module file below the point of declaration has full access to that variable. Code in other files will not, because those scopes are unrelated. The subroutine created via sub { .... } is anonymous, so there's no name in the symbol table for anyone outside to find. Not even other code in the module can call the function by name, since it doesn't have one, but that code can use the lexical variable to dereference the code reference indirectly.

$secret_function->(ARGS);                # infix deref form
&$secret_function(ARGS);                 # prefix deref form

Curiously, if you really wanted to, you could give this anonymous function a temporary name. Using the technique outlined in Recipe 10.16, assign the code reference to a localized typeglob, like this:

sub module_function {
    local *secret = $secret_function;
    Other_Package::func1( );
    secret(ARG1, ARG2);
    Yet_Another_Package::func2( );
}

Now for the duration of module_function, your previously secret function can be called using a direct function call; no indirection required. However, code outside the module can also find that function. In the example, it doesn't matter whether func1 and func2 are in the module's file scope, because you've made a temporary symbol table entry through which they could get at your secret function. Therefore, if Other_Package::func1 turned around and called Some_Module::secret, it could find it—but only if func1 were called from the module_function in the example. If it were called from some other point, there wouldn't be any secret function in the Some_Module package symbol table, so the attempted function call would fail.

This slightly peculiar behavior, where temporaries' values and visibility depend upon who called whom at runtime, is called dynamic scoping. This is the nature of the local keyword. You can see why we don't usually suggest using it.

12.5.4. See Also

Recipe 12.4; the section on "Dynamically Scoped Variables: local" in Chapter 4 of Programming Perl; the section on "Symbol Tables" in Chapter 10 of Programming Perl

Previous | Home | Next
12.4. Making Variables Private to a Module | Book Index | 12.6. Determining the Caller's Package
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.6. Determining the Caller's Package

12.6.1. Problem

You need to find out the current or calling package.

12.6.2. Solution

To find the current package:

$this_pack = _ _PACKAGE_ _;

To find the caller's package:

$that_pack = caller( );

12.6.3. Discussion

The _ _PACKAGE_ _ symbol returns the package that the code is currently being compiled into. This doesn't interpolate into double-quoted strings:

print "I am in package _ _PACKAGE_ _\n";              # WRONG!
I am in package _ _PACKAGE_ _

Needing to figure out the caller's package arose more often in older code that received as input a string of code to be eval uated, or a filehandle, format, or directory handle name. Consider a call to a hypothetical runit function:

package Alpha;
runit('$line = <TEMP>');

package Beta;
sub runit {
    my $codestr = shift;
    eval $codestr;
    die if $@;
}

Because runit was compiled in a different package than was currently executing, when the eval runs, it acts as though it were passed $Beta::line and Beta::TEMP. The old workaround was to include your caller's package first:

package Beta;
sub runit {
    my $codestr = shift;
    my $hispack = caller;
    eval "package $hispack; $codestr";
    die if $@;
}

That approach works only when $line is a global variable. If it's lexical, that won't help at all. Instead, arrange for runit to accept a reference to a subroutine:

package Alpha;
runit( sub { $line = <TEMP> } );

package Beta;
sub runit {
    my $coderef = shift;
    &$coderef( );
}

This not only works with lexicals, but has the added benefit of checking the code's syntax at compile time, which is a major win.

If all that's being passed in is a filehandle, it's more portable to use the Symbol::qualify function. This function takes a name and package to qualify the name into. If the name needs qualification, it fixes it; otherwise, it's left alone. But that's considerably less efficient than a * prototype.

Here's an example that reads and returns n lines from a filehandle. The function qualifies the handle before working with it.

open (FH, "<", "/etc/termcap")        or die "can't open /etc/termcap: $!";
($a, $b, $c) = nreadline(3, "FH");

use Symbol ( );
use Carp;
sub nreadline {
    my ($count, $handle) = @_;
    my(@retlist,$line);

    croak "count must be > 0" unless $count > 0;
    $handle = Symbol::qualify($handle, (caller( ))[0]);
    croak "need open filehandle" unless defined fileno($handle);

    push(@retlist, $line) while defined($line = <$handle>) && $count--;
    return @retlist;
}

If everyone who called your nreadline function passed the filehandle as a typeglob *FH, as a glob reference *FH, or using FileHandle or IO::Handle objects, you wouldn't need to do this. It's only the possibility of a bare "FH" string that requires qualification.

12.6.4. See Also

The documentation for the standard Symbol module, also found in Chapter 32 of Programming Perl; the descriptions of the special symbols _ _FILE_ _, _ _LINE_ _, and _ _PACKAGE_ _ in perldata(1); Recipe 12.14; Recipe 7.6

Previous | Home | Next
12.5. Making Functions Private to a Module | Book Index | 12.7. Automating Module Cleanup
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.7. Automating Module Cleanup

12.7.1. Problem

You need to create module setup code and cleanup code that gets called automatically, without user intervention.

12.7.2. Solution

For setup code, put executable statements outside subroutine definitions in the module file. For cleanup code, use an END subroutine in that module.

12.7.3. Discussion

In some languages, the programmer must remember to call module initialization code before accessing any of that module's regular functions. Similarly, when the program is done, the programmer may have to call module-specific finalization code.

Not so in Perl. For per-module initialization code, executable statements outside of any subroutines in your module suffice. When the module is loaded in, that code runs right then and there. The user never has to remember to do this, because it's done automatically.

Now, why would you want automatic cleanup code? It depends on the module. You might want to write a shutdown message to a logfile, tell a database server to commit any pending state, refresh a screen, or return the tty to its original state.

Suppose you want a module to log quietly whenever a program using it starts up or finishes. Add code in an END subroutine to run after your program finishes:

$Logfile = "/tmp/mylog" unless defined $Logfile;
open(LF, ">>", $Logfile)
    or die "can't append to $Logfile: $!";
select(((select(LF), $|=1))[0]);  # unbuffer LF
logmsg("startup");

sub logmsg {
    my $now = scalar gmtime;
    print LF "$0 $$ $now: @_\n"
        or die "write to $Logfile failed: $!";
}

END {
    logmsg("shutdown");
    close(LF)
        or die "close $Logfile failed: $!";
}

The first part of code, outside any subroutine declaration, is executed at module load time. The module user doesn't have to do anything special to make this happen. Someone might be unpleasantly surprised, however, if the file couldn't be accessed, since the die would make the use or require fail.

END routines work like exit handlers, such as trap 0 in the shell, atexit in C programming, or global destructors or finalizers in object-oriented languages. All of the ENDs in a program are run in the opposite order that they were loaded; that is, last seen, first run. These get called whether the program finishes through normal process termination by implicitly reaching the end of your main program, through an explicit call to the exit function, or via an uncaught exception such as die or a mistake involving division by zero.

Uncaught signals are a different matter, however. Death by signal does not run your exit handlers. The following pragma takes care of them:

use sigtrap qw(die normal-signals error-signals);

That causes all normal signals and error signals to make your program expire via the die mechanism, effectively converting a signal into an exception and thus permitting your END handlers to run.

You can get fancier, too:

use sigtrap qw(
    die         untrapped normal-signals
    stack-trace any       error-signals
);

That says to die only on an untrapped normal signal, but for error signals, to produce a stack trace before dying—like the confess function from the Carp module.

END also isn't called when a process polymorphs itself via the exec function because you are still in the same process, just a different program. All normal process attributes remain, like process ID and parent PID, user and group IDs, umask, current directory, environment variables, resource limits and accumulated statistics, and open file descriptors (however, see the $^F variable in perlvar(1) or Programming Perl). If it didn't work this way, exit handlers would execute redundantly in programs manually managing their fork and exec calls. This would not be good.

12.7.4. See Also

The standard use sigtrap pragma, also in Chapter 31 of Programming Perl; Chapter 18 of Programming Perl and the section on "Package Constructors and Destructors" in perlmod(1); the $^F ($SYSTEM_FD_MAX) variable in Chapter 28 of Programming Perl and in perldata(1); the fork and exec functions in Chapter 29 of Programming Perl and in perlmod(1)

Previous | Home | Next
12.6. Determining the Caller's Package | Book Index | 12.8. Keeping Your Own Module Directory
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.8. Keeping Your Own Module Directory

12.8.1. Problem

You don't want to install your own personal modules in the standard per-system extension library.

12.8.2. Solution

You have several choices: use Perl's -I command line switch; set your PERL5LIB environment variable; or employ the use lib pragma, possibly in conjunction with the FindBin module.

12.8.3. Discussion

The @INC array contains a list of directories to consult when do, require, or use pulls in code from another file. You can print these out easily from the command line:

% perl -e 'printf "%d %s\n", $i++, $_ for @INC'
0 /usr/local/lib/perl5/5.8.0/OpenBSD.i386-openbsd
1 /usr/local/lib/perl5/5.8.0
2 /usr/local/lib/perl5/site_perl/5.8.0/OpenBSD.i386-openbsd
3 /usr/local/lib/perl5/site_perl/5.8.0
4 /usr/local/lib/perl5/site_perl/5.6.0
5 /usr/local/lib/perl5/site_perl/5.00554
6 /usr/local/lib/perl5/site_perl/5.005
7 /usr/local/lib/perl5/site_perl
8 .

The first two directories, elements 0 and 1 of @INC, are respectively the standard architecture-dependent and architecture-independent directories, which all standard libraries, modules, and pragmas will go into. You have two of them because some modules contain information or formatting that makes sense only on that particular architecture. For example, the Config module contains information that cannot be shared across several architectures, so it goes in the 0th array element. Modules that include compiled C components, such as Socket.so, are also placed there. Most modules, however, go in the platform-independent directory in the 1st element.

The next pair, elements 2 and 3, fulfills roles analogous to elements and 1, but on a site-specific basis. Suppose you have a module that didn't come with Perl, such as one from CPAN or that you wrote yourself. When you or (more likely) your system administrator installs this module, its components go into one of the site-specific directories. You are encouraged to use these for any modules that your entire site should be able to access conveniently.

In this particular configuration, elements 4 -7 are there so that Perl can find any site-specific modules installed under a previous release of Perl. Such directories can be automatically added to @INC when you configure, build, and install a newer Perl release, making it easier to upgrade.

The last standard component, "." (your current working directory), is useful only when developing and testing your software, not when deploying it. If your modules are in the same directory that you last chdir ed to, you're fine. If you're anywhere else, it doesn't work.

So sometimes none of the @INC directories work out. Maybe you have your own personal modules. Perhaps your project group has particular modules that are relevant only to that project. In these cases, you need to augment the standard @INC search.

The first approach involves a command-line flag, -Idirlist. The dirlist is a colon-separated[21] list of one or more directories, which are prepended to the front of the @INC array. This works well for simple command lines, and thus can be used on a per-command basis, such as when you call a quick one-liner from a shell script.

[21]Comma-separated on Mac OS 9.

This technique should not be used in the #! (pound-bang) line. First, it's not much fun to modify each program. More importantly, some older operating systems have bugs related to how long that line can be, typically 32 characters, including the #! part. That means if you have a very long path, such as #!/opt/languages/free/extrabits/perl, you may get the mysterious "Command not found" error. Perl does its best to rescan the line manually, but this is still too dicey to rely on.

Often, a better solution is to set the PERL5LIB environment variable. This can be done in your shell start-up file. Or, your system administrator may want to do so in a systemwide start-up file so all users can benefit. For example, suppose you have all your own modules in a directory called ~/perllib. You would place one of the following lines in your shell start-up file, depending on which shell you use:

# syntax for sh, bash, ksh, or zsh
$ export PERL5LIB=$HOME/perllib

# syntax for csh or tcsh
% setenv PERL5LIB ~/perllib

Probably the most convenient solution from your users' perspective is for you to add a use lib pragma near the top of your script. That way users of the program need take no special action to run that program. Imagine a hypothetical project called Spectre whose programs rely on its own set of libraries. Those programs could have a statement like this at their start:

use lib "/projects/spectre/lib";

What happens when you don't know the exact path to the library? Perhaps you've installed the whole project in an arbitrary path. You could create an elaborate installation procedure to dynamically update the script, but even if you did, paths would still be frozen at installation time. If someone moved the files later, the libraries wouldn't be found.

The FindBin module conveniently solves this problem. This module tries to determine the full path to the executing script's enclosing directory, setting an importable package variable called $Bin to that directory. Typical usage is to look for modules either in the same directory as the program or in a lib directory at the same level.

To demonstrate the first case, suppose you have a program called /wherever/spectre/myprog that needs to look in /wherever/spectre for its modules, but you don't want that path hardcoded.

use FindBin;
use lib $FindBin::Bin;

The second case would apply if your program lives in /wherever/spectre/bin/myprog but needs to look at /wherever/spectre/lib for its modules.

use FindBin qw($Bin);
use lib "$Bin/../lib";

12.8.4. See Also

The documentation for the standard use lib pragma (also in Chapter 31 of Programming Perl) and the standard FindBin module; the discussion of the PERL5LIB environment in perl(1) and the "Environmental Variables" section of Chapter 19 of Programming Perl; your shell's syntax for setting environment variables

Previous | Home | Next
12.7. Automating Module Cleanup | Book Index | 12.9. Preparing a Module for Distribution
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.9. Preparing a Module for Distribution

12.9.1. Problem

You want to prepare your module in standard distribution format so you can easily send your module to a friend. Better yet, you plan to contribute your module to CPAN so everyone can use it.

12.9.2. Solution

It's best to start with Perl's standard h2xs tool. Let's say you want to make a Planets module or an Astronomy::Orbits module. You'd type:

% h2xs -XA -n Planets
% h2xs -XA -n Astronomy::Orbits

These commands make subdirectories called ./Planets/ and ./Astronomy/Orbits/, respectively, where you will find all the components you need to get you started. The -n flag names the module you want to make, -X suppresses creation of XS (external subroutine) components, and -A means the module won't use the AutoLoader.

12.9.3. Discussion

Writing modules is easy—once you know how. Writing a proper module is like filling out a legal contract: it's full of places to initial, sign, and date exactly right. If you miss any, it's not valid. Instead of hiring a contract lawyer, you can get a quick start on writing modules using the h2xs program. This tool gives you a skeletal module file with the right parts filled in, and it also gives you the other files needed to correctly install your module and its documentation or to bundle up for contributing to CPAN or sending off to a friend.

h2xs is something of a misnomer because XS is Perl's external subroutine interface for linking with C or C ++. But the h2xs tool is also extremely convenient for preparing a distribution even when you aren't using the XS interface.

Let's look at the module file that h2xs has made. Because the module is called Astronomy::Orbits, the user specifies not use Orbits but rather use Astronomy::Orbits. Therefore an extra Astronomy subdirectory is made, under which an Orbits subdirectory is placed. Here is the first and perhaps most important line of Orbit.pm:

package Astronomy::Orbits;

This sets the package—the default prefix—on all global identifiers (variables, functions, filehandles, etc.) in the file. Therefore a variable like @ISA is really the global variable @Astronomy::Orbits::ISA.

As we said in the Introduction, you must not make the mistake of saying package Orbits because it's in the file Orbits.pm. The package statement in the module must be exactly match the target of the use or require statement, which means the leading directory portion needs to be there and the characters' case must be the same. Furthermore, it must be installed in an Astronomy subdirectory. The h2xs command will set this all up properly, including the installation rule in the Makefile. But if you're doing this by hand, you must keep this in mind. See Recipe 12.1 for that.

If you plan to use autoloading, described in Recipe 12.11, omit the -A flag to h2xs, which produces lines like this:

require Exporter;
require AutoLoader;
@ISA = qw(Exporter AutoLoader);

If your module is bilingual in Perl and C as described in Recipe 12.18, omit the -X flag to h2xs to produce lines like this:

require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);

Following this is the Exporter's variables as explained in Recipe 12.1. If you're writing an object-oriented module as described in Chapter 13, you probably won't use the Exporter at all.

That's all there is for setup. Now, write your module code. When you're ready to ship it off, use the make dist directive from your shell to bundle it all up into a tar archive for easy distribution. (The name of the make program may vary from system to system.)

% perl Makefile.PL
% make dist

This will leave you with a file whose name is something like Astronomy-Orbits-1.03.tar.Z.

To register as a CPAN developer, check out http://pause.cpan.org.

12.9.4. See Also

http://www.cpan.org to find a mirror near you and directions for submission; h2xs(1); the documentation for the standard Exporter, AutoLoader, AutoSplit, and ExtUtils::MakeMaker modules, also found in Chapter 32 of Programming Perl

Previous | Home | Next
12.8. Keeping Your Own Module Directory | Book Index | 12.10. Speeding Module Loading with SelfLoader
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.10. Speeding Module Loading with SelfLoader

12.10.1. Problem

You'd like to load a very large module quickly.

12.10.2. Solution

Use the SelfLoader module:

require Exporter;
require SelfLoader;
@ISA = qw(Exporter SelfLoader);
#
# other initialization or declarations here
#
_ _DATA_ _
sub abc { .... }
sub def { .... }

12.10.3. Discussion

When you load a module using require or use, the entire module file must be read and compiled (into internal parse trees, not into byte code or native machine code) right then. For very large modules, this annoying delay is unnecessary if you need only a few functions from a particular file.

To address this problem, the SelfLoader module delays compilation of each subroutine until that subroutine is actually called. SelfLoader is easy to use: just place your module's subroutines underneath the _ _DATA_ _ marker so the compiler will ignore them, use a require to pull in the SelfLoader, and include SelfLoader in the module's @ISA array. That's all there is to it. When your module is loaded, the SelfLoader creates stub functions for all routines below _ _DATA_ _. The first time a function gets called, the stub replaces itself by first compiling the real function and then calling it.

There is one significant restriction on modules that employ the SelfLoader (or the AutoLoader for that matter, described in Recipe 12.11). SelfLoaded or AutoLoaded subroutines have no access to lexical variables in the file whose _ _DATA_ _ block they are in because they are compiled via eval in an imported AUTOLOAD block. Such dynamically generated subroutines are therefore compiled in the scope of SelfLoader's or AutoLoader's AUTOLOAD.

Whether the SelfLoader helps or hinders performance depends on how many subroutines the module has, how large they are, and whether they are all called over the lifetime of the program or not.

You should initially develop and test your module without SelfLoader. Commenting out the _ _DATA_ _ line will take care of that, making those functions visible to the compiler.

12.10.4. See Also

The documentation for the standard module SelfLoader; Recipe 12.11

Previous | Home | Next
12.9. Preparing a Module for Distribution | Book Index | 12.11. Speeding Up Module Loading with Autoloader
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.11. Speeding Up Module Loading with Autoloader

12.11.1. Problem

You want to use the AutoLoader module.

12.11.2. Solution

The easiest solution is to use the h2xs facility to create a directory and all the files you need. Here we assume you have your own directory, ~/perllib/, which contains your personal library modules.

% h2xs -Xn Sample
% cd Sample
% perl Makefile.PL LIB=~/perllib
% (edit Sample.pm)
% make install

12.11.3. Discussion

The AutoLoader addresses the same performance issues as the SelfLoader. It also provides stub functions that get replaced by real ones the first time they're called. But instead of looking for functions all in the same file, hidden below a _ _DATA_ _ marker, the AutoLoader expects to find the real definition for each function in its own file. If your Sample.pm module had two functions, foo and bar, then the AutoLoader would expect to find them in Sample/auto/foo.al and Sample/auto/bar.al, respectively. Modules employing the AutoLoader load faster than those using the SelfLoader, but at the cost of extra files, disk space, and complexity.

This setup sounds complicated. If you were doing it manually, it probably would be. Fortunately, h2xs helps out tremendously here. Besides creating a module directory with templates for your Sample.pm file and other files you need, it also generates a Makefile that uses the AutoSplit module to break your module's functions into little files, one function per file. The make install rule installs these so they will be found automatically. All you have to do is put the module functions down below an _ _END_ _ line (rather than a _ _DATA_ _ line as in SelfLoader) that h2xs already created.

As with the SelfLoader, it's easier to develop and test your module without the AutoLoader. Just comment out the _ _END_ _ line while developing it.

The same restrictions about invisibility of file lexicals that apply to modules using the SelfLoader also apply when using the AutoLoader, so using file lexicals to maintain private state doesn't work. If state is becoming that complex and significant an issue, consider writing an object module instead of a traditional one.

12.11.4. See Also

The documentation for the standard module AutoLoader; h2xs(1); Recipe 12.10

Previous | Home | Next
12.10. Speeding Module Loading with SelfLoader | Book Index | 12.12. Overriding Built-in Functions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.12. Overriding Built-in Functions

12.12.1. Problem

You want to replace a standard, built-in function with your own version.

12.12.2. Solution

Import that function from another module into your own namespace.

12.12.3. Discussion

Suppose you want to give a function of your own the same name as one of Perl's core built-ins. If you write:

sub time { "it's howdy doody time" }
print time( );

then you won't get your function called—you'll still get Perl's original, built-in version. You could use an explicit ampersand to call the function:

print &time( );

because that always gets your function, never the built-in. But then you forego any prototype checking and context coercion on the function's arguments. However, there is a way to override that.

Many (but not all) of Perl's built-in functions may be overridden. This is not something to be attempted lightly, but it is possible. You might do this, for example, if you are running on a platform that doesn't support the function that you'd like to emulate. Or, you might want to add your own wrapper around the built-in.

Not all reserved words have the same status. Those that return a negative number in the C-language keyword( ) function in the toke.c file in your Perl source kit may be overridden. Keywords that cannot be overridden as of v5.8.1 are defined, delete, do, else, elsif, eval, exists, for, foreach, format, glob, goto, grep, if, last, local, m, map, my, next, no, our, package, pos, print, printf, prototype, q, qq, qr, qw, qx, redo, require, return, s, scalar, sort, split, study, sub, tie, tied, tr, undef, unless, untie, until, use, while, and y. The rest can.

A standard Perl module that overrides a built-in is Cwd, which can overload chdir. Others are the by-name versions of functions that return lists: File::stat, Net::hostent, Net::netent, Net::protoent, Net::servent, Time::gmtime, Time::localtime, Time::tm, User::grent, and User::pwent. These modules all override built-in functions like stat or getpwnam to return an object that can be accessed using a name, like getpwnam("daemon")->dir. To do this, they have to override the original, list-returning versions of those functions.

Overriding may be done uniquely by importing the function from another package. This import only takes effect in the importing package, not in all possible packages. It's not enough simply to predeclare the function. You have to import it. This is a guard against accidentally redefining built-ins.

Let's say that you'd like to replace the built-in time function, whose return value is in integer seconds, with one that returns a floating-point number instead. You could make a Time::HiRes module with an optionally exported time function as follows:

package Time::HiRes;
use strict;
require Exporter;
use vars qw(@ISA @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(time);

sub time( ) { ..... }  # TBA

Then the user who wants to use this augmented version of time would say something like:

use Time::HiRes qw(time);
$start = time( );
1 while print time( ) - $start, "\n";

This code assumes that your system has a function you can stick in the "TBA" definition shown previously. It just so happens, however, that you don't have to figure that part out, because the Time::HiRes module (which is included standard with the Perl distribution) does indeed behave as we've outlined it here. You can import its time( ) function to get the one that is fancier than the core built-in, just as we did here.

If you don't want to take the trouble to create a full module file, set up its exports, and all the rest of the rigamarole, there's a shortcut approach via the subs pragma. It works like this:

use subs qw(time);
sub time { "it's howdy doody time" }
print time( );

Now you'd get your own function, even without the ampersand.

Even when you override a built-in by importing a function, that built-in is always still accessible if you fully qualify it using the (pseudo)package named CORE. Thus, even if you imported time( ) from FineTime, overriding the built-in, that original built-in can be called as CORE::time( ).

For overriding of methods and operators, see Chapter 13.

12.12.4. See Also

The section on "Overriding Built-in Functions" in Chapter 11 of Programming Perl and in perlsub(1); Recipe 10.11

Previous | Home | Next
12.11. Speeding Up Module Loading with Autoloader | Book Index | 12.13. Overriding a Built-in Function in All Packages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.13. Overriding a Built-in Function in All Packages

12.13.1. Problem

You want to change the definition of a core built-in function within your entire program, not just the current package.

12.13.2. Solution

Manually import, via direct symbol-table manipulation, the function into the CORE::GLOBAL pseudopackage.

*CORE::GLOBAL::int = \&myown_int;

12.13.3. Discussion

The technique demonstrated in the previous recipe only overrides a built-in in a particular package. It doesn't change everything for your whole program, no matter what package that function is called from. To do so would risk changing the behavior of code from modules you didn't write, and which were therefore not prepared for the change.

It has been said that Unix was not designed to stop you from doing stupid things, because that would also stop you from doing clever things. So, too, with Perl. Just because overriding a function in all packages at once might seem, well, imprudent doesn't mean a clever person won't someday find a marvelous use for such a facility.

For example, let's suppose that you've decided that the core int function's behavior of integer truncation, also known as rounding toward zero, is so annoying to your program that you want to provide an alternative by the same name. This would do it:

package Math::Rounding;
use warnings;
use Carp;
use Exporter;
our @EXPORT = qw(int);
our @ISA    = qw(Exporter);

sub int(;$) {
    my $arg = @_ ? shift : $_;
    use warnings FATAL => "numeric";  # promote to die( )ing
    my $result = eval { sprintf("%.0f", $arg) };
    if ($@) {
        die if $@ !~ /isn't numeric/;
        $@ =~ s/ in sprintf.*/ in replacement int/s;
        croak $@;
    } else {
        return $result;
    }
}

Your replacement version uses sprintf( ) to round to the closest integer. It also raises an exception if passed a non-numeric string. A program could access this function either by saying:

use Math::Rounding ( );
$y = Math::Rounding::int($x);

or by importing the function and overriding the built-in:

use Math::Rounding qw(int);
$y = int($x);

However, that only manages to replace the built-in for the current package. To replace it in all packages, at some point during compile time you'll have to execute a line of code like this:

*CORE::GLOBAL::int = \&Math::Rounding::int;

The standard File::Glob module allows you to change Perl's core glob operator using special import tags:

## override the core glob, forcing case sensitivity
use File::Glob qw(:globally :case);
my @sources = <*.{c,h,y}>

## override the core glob forcing case insensitivity
use File::Glob qw(:globally :nocase);
my @sources = <*.{c,h,y}>

The module does this with its own version of import that detects those tags and makes the necessary assignments. You could do this, too. That way, this:

use Math::Rounding qw(-global int);

would make Perl use your replacement version for all calls to int from any package anywhere in your program. Here's a replacement import function that handles this:

sub import {
    if (@_ && $_[1] =~ /^-/) {
        if ($_[1] ne "-global") {
            croak "unknown import pragma";
        }
        splice(@_, 1, 1);              # discard "-global"
        no warnings "once";     # suppress "used only once" warnings
        *CORE::GLOBAL::int = \&int;
    } else {
        die;
    }
    _ _PACKAGE_ _ -> export_to_level(1, @_);
}

The assignment happens only if the first thing to import is "-global". The last line in our import function uses part of the Exporter module's internal API to handle any normal import.

12.13.4. See Also

Recipe 12.12; the section on "Overriding Built-in Functions" in Chapter 11 of Programming Perl and in perlsub(1); the documentation for the standard BSD::Glob module, as well as its source code

Previous | Home | Next
12.12. Overriding Built-in Functions | Book Index | 12.14. Reporting Errors and Warnings Like Built-ins
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.14. Reporting Errors and Warnings Like Built-ins

12.14.1. Problem

You want to generate errors and warnings in your modules, but when you use warn or die, the user sees your own filename and line number. You'd like your functions to act like built-ins and report messages from the perspective of the user's code, not your own.

12.14.2. Solution

The standard Carp module provides functions to do this. Use carp instead of warn. Use croak (for a short message) and confess (for a long message) instead of die.

12.14.3. Discussion

Like built-ins, some of your module's functions generate warnings or errors if all doesn't go well. Think about sqrt: when you pass it a negative number (and you haven't used the Math::Complex module), an exception is raised, producing a message such as "Can't take sqrt of -3 at /tmp/negroot line 17", where /tmp/negroot is the name of your own program. But if you write your own function that die s, perhaps like this:

sub even_only {
    my $n = shift;
    die "$n is not even" if $n & 1;  # one way to test
    #....
}

then the message will say it's coming from the file your even_only function was itself compiled in, rather than from the file the user was in when they called your function. That's where the Carp module comes in handy. Instead of using die, use croak instead:

use Carp;
sub even_only {
    my $n = shift;
    croak "$n is not even" if $n % 2;  # here's another
    #....
}

If you just want to complain about something, but have the message report where in the user's code the problem occurred, call carp instead of warn. For example:

use Carp;
sub even_only {
    my $n = shift;
    if ($n & 1) {         # test whether odd number
        carp "$n is not even, continuing";
        ++$n;
    }
    #....
}

Many built-ins emit warnings only when the -w command-line switch has been used. The $^W variable (which is not meant to be a control character but rather a ^ followed by a W) reflects whether that switch was used. You could choose to grouse only if the user asked for complaints:

carp "$n is not even, continuing" if $^W;

The Carp module provides a third function: confess. This works just like croak, except that it provides a full stack backtrace as it dies, reporting who called whom and with what arguments.

If you're only interested in the error message from carp, croak, and friends, the longmess and shortmess functions offer those:

use Carp;
$self->transplant_organ( ) or
  $self->error( Carp::longmess("Unable to transplant organ") );

12.14.4. See Also

The warn and die functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Carp module, also in Chapter 32 of Programming Perl; Recipe 19.2; the discussion on _ _WARN_ _ and _ _DIE_ _ in the %SIG entry of Chapter 28 of Programming Perl, in perlvar(1), and in Recipe 16.15

Previous | Home | Next
12.13. Overriding a Built-in Function in All Packages | Book Index | 12.15. Customizing Warnings
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.15. Customizing Warnings

12.15.1. Problem

You would like your module to respect its caller's settings for lexical warnings, but you can't inspect the predefined $^W [22] variable to determine those settings.

[22]That's $WARNING if you've use d English.

12.15.2. Solution

Your module should use this pragma:

use warnings::register;

Then from inside your module, use the warnings::enabled function from that module as described in the Discussion to check whether the caller has warnings enabled. This works for both the old-style, global warnings and for lexical warnings set via the use warnings pragma.

12.15.3. Discussion

Perl's -w command-line flag, mirrored by the global $^W variable, suffers from several problems. For one thing, it's an all-or-nothing affair, so if you turn it on for the program, module code included by that program—including code you may not have written—is also affected by it. For another, it's at best cumbersome to control compile-time warnings with it, forcing you to resort to convoluted BEGIN blocks. Finally, suppose you were interested in numeric warnings but not any other sort; you'd have to write a $SIG{_ _WARN_ _} handler to sift through all warnings to find those you did or did not want to see.

Lexical warnings, first introduced in Perl v5.6, address all this and more. By lexical, we mean that their effects are constrained to the lexical scope in which use warnings or no warnings occurs. Lexical warnings pay no attention to the -w command-line switch. Now when you turn warnings on in one scope, such as the main program's file scope, that doesn't enable warnings in modules you load. You can also selectively enable or disable individual categories of warnings. For example:

use warnings qw(numeric uninitialized);

use warnings qw(all);
no warnings qw(syntax);

The warnings::register pragma permits a module to check the warnings preferences of its caller's lexical scope. The pragma also creates a new warning category, taken from the name of the current package. These user-defined warning categories are easily distinguishable from the built-in warning categories because a module's package always starts (or should always start) with an uppercase letter. This way lowercase warning categories, like lowercase module names, are reserved to Perl itself.

Built-in warnings categories are organized into several groups. The all category means all built-in warnings categories, including subcategories such as unsafe, io, syntax, etc. (see Figure 12-1). The syntax category comprises particular warnings categories, such as ambiguous, precedence, and deprecated. These can be added and subtracted at will, but order matters:

Figure 12-1. Warnings categories

use warnings;                 # turn on all warnings
no  warnings "syntax";        # turn off the syntax group
use warnings "deprecated";    # but turn back on deprecated warnings

Back to your module. Suppose you write a module called Whiskey. The Whiskey.pm file begins this way:

package Whiskey;
use warnings::register;

Now code using that module does this:

use Whiskey;
use warnings qw(Whiskey);

It's important to load the module before asking to use warnings for that module. Otherwise, the Whiskey warning category hasn't been registered yet, and you'll raise an exception if you try to use it as a warnings category.

Here's a whimsical Whiskey module:

package Whiskey;

use strict;
use warnings;  # for our own code, not our caller
use warnings::register;

sub drink {
    if (warnings::enabled( ) && (localtime( ))[2] < 12) {
        warnings:warn("Sun not yet over the yardarm");
    }
    print "Merry!\n";
}
sub quaff {
    if (warnings::enabled("deprecated")) {
        warnings::warn("deprecated",
            "quaffing deprecated in favor of chugging");
    }
    &drink;
}
# chuggers care not of the hour
sub chug {
    print "Very merry\n";
}
1;

The Whiskey::drink function uses the warnings::enabled function to check whether its caller has warnings enabled. Any of these in the caller's scope is enough to make that function return true:

use warnings;
use warnings qw(all);  # means same as previous
use warnings qw(Whiskey);

The function will also return true if global warnings are enabled using -w or $^W.

In the Whiskey::quaff function, a specific category of warnings is checked: deprecated. This is enabled if all warnings have been selected, if the syntax warnings have been selected (because deprecated warnings are considered a subcategory of syntax warnings, which is a subcategory of all warnings), or if deprecated warnings have been specifically selected. It will not be enabled just because the caller has enabled Whiskey warnings. Any category you create is considered a subcategory of all, but not of anything else. Check for Whiskey warnings using:

warnings::enabled("Whiskey")

The warnings::warn function is used instead of the warn built-in, in case Whiskey warnings have been promoted into exceptions:

use warnings FATAL => "Whiskey";

12.15.4. See Also

The documentation on the use warnings pragma in Chapter 31 of Programming Perl and perllexwarn(1)

Previous | Home | Next
12.14. Reporting Errors and Warnings Like Built-ins | Book Index | 12.16. Referring to Packages Indirectly
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.16. Referring to Packages Indirectly

12.16.1. Problem

You want to refer to a variable or function in a package unknown until runtime, but syntax like $packname::$varname is illegal.

12.16.2. Solution

Use symbolic references:

{
    no strict "refs";
    $val  = ${ $packname . "::" . $varname };
    @vals = @{ $packname . "::" . $aryname };
    &{ $packname . "::" . $funcname }("args");
    ($packname . "::" . $funcname) -> ("args");
}

12.16.3. Discussion

A package declaration has meaning at compile time. If you don't know the name of the package or variable until runtime, you'll have to resort to symbolic references for direct access to the package symbol table. Assuming you normally run with use strict in effect, you must disable part of it to use symbolic references. Once you've used the no strict "refs" directive in that block, build up a string with the fully qualified name of the variable or function you're interested in. Then dereference this name as though it were a proper Perl reference.

During the prehistoric eras (before Perl 5), programmers were forced to use an eval for this kind of thing:

eval "package $packname; \$'$val = \$$varname"; # set $main'val
die if $@;

As you see, this approach makes quoting difficult. It's also comparatively slow. Fortunately, you never need to do this just to access variables indirectly by name. Symbolic references are a necessary compromise.

Similarly, eval could be used to define functions on the fly. Suppose you wanted to be able to get the base 2 or base 10 logs of numbers:

printf "log2  of 100 is %.2f\n", log2(100);
printf "log10 of 100 is %.2f\n", log10(100);

Perl has only the natural log function. Here's how one could use eval to create these functions at runtime. Here we'll create functions named log2 up through log999:

$packname = "main";
for ($i = 2; $i < 1000; $i++) {
    $logN = log($i);
    eval "sub ${packname}::log$i { log(shift) / $logN }";
    die if $@;
}

Here, at least, you don't need to do that. The following code does the same thing, but instead of compiling a new function 998 times, we compile it only once, as a closure. Then we use symbolic dereferencing of the symbol table to assign the same subroutine reference to many function names:

$packname = "main";
for ($i = 2; $i < 1000; $i++) {
    my $logN = log($i);
    no strict "refs";
    *{"${packname}::log$i"} = sub { log(shift) / $logN };
}

When you assign a reference to a typeglob, you create an alias for just the referent type of that name. That's how the Exporter does its job. The first line in the next code sample manually imports the function name Colors::blue into the current package. The second makes the main::blue function an alias for the Colors::azure function.

*blue       = \&Colors::blue;
*main::blue = \&Colors::azure;

Given the flexibility of typeglob assignments and symbolic references, a full-blown eval "STRING" is nearly always unnecessary for these sorts of indirect namespace manipulation, the last resort of the desperate programmer. The only thing worse would be if it weren't available at all.

12.16.4. See Also

The section on "Symbolic References" in Chapter 8 of Programming Perl and in the start of perlsub(1); Recipe 11.4

Previous | Home | Next
12.15. Customizing Warnings | Book Index | 12.17. Using h2ph to Translate C #include Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.17. Using h2ph to Translate C #include Files

12.17.1. Problem

Someone gave you code that generates the bizarre error message:

Can't locate sys/syscall.ph in @INC (did you run h2ph?)
(@INC contains: /usr/lib/perl5/i686-linux/5.00404 /usr/lib/perl5
/usr/lib/perl5/site_perl/i686-linux /usr/lib/perl5/site_perl .)
at some_program line 7.

You want to know what it means and how to fix it.

12.17.2. Solution

Get your system administrator to do this, running as the superuser:

% cd /usr/include; h2ph sys/syscall.h

However, most include files require other include files, which means you should probably just translate them all:

% cd /usr/include; h2ph *.h */*.h

If that reports too many filenames or misses some that are more deeply nested, try this instead:

% cd /usr/include; find . -name "*.h" -print | xargs h2ph

12.17.3. Discussion

A file whose name ends in .ph has been created by the h2ph tool, which translates C preprocessor directives from C #include files into Perl. The goal is to allow Perl code to access the same constants as C code. h2xs is a better approach in most cases because it provides compiled C code for your modules, not Perl code simulating C code. However, using h2xs requires a lot more programming savvy (at least, for accessing C code) than h2ph does.

When h2ph's translation process works, it's wonderful. When it doesn't, you're probably out of luck. As system architectures and include files become more complex, h2ph fails more frequently. If you're lucky, the constants you need are already in the Fcntl, Socket, or POSIX modules. The POSIX module implements constants from sys/file.h, sys/errno.h, and sys/wait.h, among others. It also allows fancy tty handling, as described in Recipe 15.8.

So what can you do with these .ph files? Here are a few examples. The first uses the pessimally non-portable syscall function to access your operating system's gettimeofday syscall. This implements the FineTime module described in Recipe 12.12.

# file FineTime.pm
package main;
require "sys/syscall.ph";
die "No SYS_gettimeofday in sys/syscall.ph"
    unless defined &SYS_gettimeofday;

package FineTime;
use strict;
require Exporter;
use vars qw(@ISA @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(time);

sub time( ) {
    my $tv = pack("LL", ( ));  # presize buffer to two longs
    syscall(&main::SYS_gettimeofday, $tv, undef) >= 0
        or die "gettimeofday: $!";
    my($seconds, $microseconds) = unpack("LL", $tv);
    return $seconds + ($microseconds / 1_000_000);
}

1;

If you are forced to require an old-style .pl or .ph file, do so from the main package (package main in the preceding code). These old libraries always put their symbols in the current package, and main serves as a reasonable rendezvous point. To use a symbol, use its fully qualified name, as we did with main::SYS_gettimeofday.

The sys/ioctl.ph file, if you can get it to build on your system, is the gateway to your system's idiosyncratic I/O functions through the ioctl function. One such function is the TIOCSTI ioctl, shown in Example 12-1. That abbreviation stands for "terminal I/O control, simulate terminal input." On systems that implement this function, it will push one character into your device stream so that the next time any process reads from that device, it gets the character you put there.

Example 12-1. jam

  #!/usr/bin/perl -w
  # jam - stuff characters down STDIN's throat
  require "sys/ioctl.ph";
  die "no TIOCSTI" unless defined &TIOCSTI;
  sub jam {
      local $SIG{TTOU} = "IGNORE"; # "Stopped for tty output"
      local *TTY;  # make local filehandle
      open(TTY, "+<", "/dev/tty")             or die "no tty: $!";
      for (split(//, $_[0])) {
          ioctl(TTY, &TIOCSTI, $_)            or die "bad TIOCSTI: $!";
      }
      close(TTY);
  }
  jam("@ARGV\n");

Since sys/ioctl.h translation is so dodgy, you'll probably have to run this C program to get your TIOCSTI value:

% cat > tio.c << EOF && cc tio.c && a.out
#include <sys/ioctl.h>
main( ) { printf("%#08x\n", TIOCSTI); }
EOF
0x005412

Another popular use for ioctl is for figuring out your current window size in rows and columns, and maybe even in pixels. This is shown in Example 12-2.

Example 12-2. winsz

  #!/usr/bin/perl
  # winsz - find x and y for chars and pixels
  require "sys/ioctl.ph";
  die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
  open(TTY, "+<", "/dev/tty")                   or die "No tty: $!";
  unless (ioctl(TTY, &TIOCGWINSZ, $winsize="")) {
      die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
  }
  ($row, $col, $xpixel, $ypixel) = unpack("S4", $winsize);
  print "(row,col) = ($row,$col)";
  print "  (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
  print "\n";

As you see, as soon as you start playing with .ph files, unpack ing binary data, and calling syscall and ioctl, you need to know about the C APIs that Perl normally hides. The only other thing that requires this much C knowledge is using the XS interface. Some suggest you should resist the temptation to descend into such unportable convolutions. Others feel that the demands put upon the trenchworkers are such that they must be forgiven these desperate measures.

Fortunately, less fragile mechanisms are increasingly available. CPAN modules for most of these functions now exist, which should theoretically prove more robust than sourcing .ph files.

12.17.4. See Also

h2ph(1); the instructions on running h2ph in the INSTALL file from the Perl source distribution; the syscall and ioctl functions in Chapter 29 of Programming Perl and in perlmod(1); Recipe 12.18

Previous | Home | Next
12.16. Referring to Packages Indirectly | Book Index | 12.18. Using h2xs to Make a Module with C Code
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.18. Using h2xs to Make a Module with C Code

12.18.1. Problem

You'd like to access your system's unique C functions from Perl.

12.18.2. Solution

Use the h2xs tool to generate the necessary template files, fill the files in appropriately, and then type:

% perl Makefile.PL
% make

12.18.3. Discussion

A Perl module need not be written solely in Perl. As with any other module, first pick a module name and use h2xs on it. We'll make a FineTime::time function with the same semantics as in the previous recipe, but this time around, we'll implement it using real C.

First, we run the following command:

% h2xs -cn FineTime

If we had a .h file with function prototype declarations, we could include that, but because we're writing this one from scratch, we'll use the -c switch to omit building code to translate any #define symbols. The -n switch says to create a module directory named FineTime/, which will have the following files:

Manifest | List of files in the distribution
Changes | Change log
Makefile.PL | A meta-makefile
FineTime.pm | The Perl parts
FineTime.xs | The soon-to-be C parts
test.pl | A test driver

Before we can type make, we'll have to generate a Makefile based on our system's configuration using the Makefile.PL template. Here's how to do that:

% perl Makefile.PL

If the XS code calls library code that isn't in the normal set of libraries Perl links from, add one more line to Makefile.PL first. For example, if we wanted to link against the librpm.a library, which lives in the /usr/redhat/lib directory, we'd change the line of Makefile.PL that reads:

"LIBS"      => [""],   # e.g., "-lm"

so that it says:

"LIBS"      => ["-L/usr/redhat/lib -lrpm"],

If the module is to be installed somewhere other than the local site_lib directory, specify that on the command line:

% perl Makefile.PL LIB=~/perllib

Finally, edit the FineTime.pm and FineTime.xs files. In the first case, most of the work has been done for us. We just set up the export list with the function to be exported. This time we put it in @EXPORT_OK so that if the user wants the function, they must ask for it by name. Here's FineTime.pm:

package FineTime;
use strict;
use vars qw($VERSION @ISA @EXPORT_OK);
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
@EXPORT_OK = qw(time);
$VERSION = "0.01";
bootstrap FineTime $VERSION;
1;

The make process automatically translates FineTime.xs into a FineTime.c file and eventually into a shared library, probably called FineTime.so on most platforms. The utility that does this translation is xsubpp, which is described in its own manpage and perlxstut(1). The build will call xsubpp automatically.

Besides a strong C background, you also need to understand the C-to-Perl interface, called XS (external subroutine). The details and nuances of XS are beyond the scope of this book. The automatically generated FineTime.xs had the Perl-specific include files in it, as well as the MODULE declaration. We've added some extra includes and written the code for the new time function. Although this doesn't look entirely like C, it will, once xsubpp is done with it.

Here's the FineTime.xs we used:

#include <unistd.h>
#include <sys/time.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

MODULE = FineTime           PACKAGE = FineTime

double
time( )
    CODE:
        struct timeval tv;
        gettimeofday(&tv,0);
        RETVAL = tv.tv_sec + ((double) tv.tv_usec) / 1000000;
    OUTPUT:
        RETVAL

Defining a function by the same name as one from the standard C library won't cause a problem when it's compiled, because that's not its real name. That's just what Perl calls it. The C linker will see it as XS_FineTime_time, so no conflict exists.

Here's what happened with make install (with some edits):

% make install
mkdir ./blib/lib/auto/FineTime
cp FineTime.pm ./blib/lib/FineTime.pm
/usr/local/bin/perl -I/usr/lib/perl5/i686-linux/5.00403  -I/usr/lib/perl5
/usr/lib/perl5/ExtUtils/xsubpp -typemap
        /usr/lib/perl5/ExtUtils/typemap FineTime.xs
FineTime.tc && mv FineTime.tc FineTime.c && cc -c -Dbool=char -DHAS_BOOL
    -O2-DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fpic
    -I/usr/lib/perl5/i686-linux/5.00403/CORE  FineTime.c
Running Mkbootstrap for FineTime ( )
chmod 644 FineTime.bs
LD_RUN_PATH="" cc -o blib/arch/auto/FineTime/FineTime.so
    -shared -L/usr/local/lib FineTime.o
chmod 755 blib/arch/auto/FineTime/FineTime.so
cp FineTime.bs ./blib/arch/auto/FineTime/FineTime.bs
chmod 644 blib/arch/auto/FineTime/FineTime.bs
Installing /home/tchrist/perllib/i686-linux/./auto/FineTime/FineTime.so
Installing /home/tchrist/perllib/i686-linux/./auto/FineTime/FineTime.bs
Installing /home/tchrist/perllib/./FineTime.pm
Writing /home/tchrist/perllib/i686-linux/auto/FineTime/.packlist
Appending installation info to /home/tchrist/perllib/i686-linux/perllocal.pod

Once this is all done, we'll be able to type something like this into the shell:

% perl -I ~/perllib -MFineTime=time -le "1 while print time( )" | head
888177070.090978
888177070.09132
888177070.091389
888177070.091453
888177070.091515
888177070.091577
888177070.091639
888177070.0917
888177070.091763
888177070.091864

12.18.4. See Also

Chapters 18 through 20 in Advanced Perl Programming; perlxstut(1) and perlxs(1) to learn how to call C from Perl; perlcall(1) and perlguts(1) to understand the internal Perl API, also the "Extending Perl" section of Chapter 21 of Programming Perl; perlembed(1) to learn how to call Perl from C, also the "Embedding Perl" section of Chapter 21 of Programming Perl; the documentation for the standard ExtUtils::MakeMaker module, h2ph(1) and xsubpp(1); http://www.cpan.org/authors/Dean_Roehrich/, which contains Dean's comprehensive XS cookbook that includes directions on interfacing with C++

Previous | Home | Next
12.17. Using h2ph to Translate C #include Files | Book Index | 12.19. Writing Extensions in C with Inline::C
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.19. Writing Extensions in C with Inline::C

12.19.1. Problem

You'd like to write functions in C that you can call from Perl. You may already have tried XS and found it harmful to your mental health.

12.19.2. Solution

Use the Inline::C module available from CPAN:

use Inline C;
$answer = somefunc(20, 4);
print "$answer\n";               # prints 80
_ _END_ _
_ _C_ _
double somefunc(int a, int b) {  /* Inline knows most basic C types */
  double answer = a * b;
  return answer;
}

12.19.3. Discussion

Inline::C was created as an alternative to the XS system for building C extension modules. Rather than jumping through all the hoopla of h2xs and the format of an .xs file, Inline::C lets you embed C code into your Perl program. There are also Inline modules for Python, Ruby, and Java, among other languages.

By default, your C source is in the _ _END_ _ or _ _DATA_ _ section of your program after a _ _C_ _ token. This permits multiple Inlined language blocks in a single file. If you want, use a here document when you load Inline:

use Inline C <<'END_OF_C';
double somefunc(int a, int b) {  /* Inline knows most basic C types */
  double answer = a * b;
  return answer;
}
END_OF_C

Inline::C scans the source code for ANSI-style function definitions. When it finds a function definition it knows how to deal with, it creates a Perl wrapper for the function. Inline can automatically translate the basic C data types (double, int, char *, etc.) by using the typemap that comes with Perl. A typemap shows Perl how to convert between C values and Perl data types, and you can install your own if you need to use more complex data structures than the basic typemap supports.

You can link against external libraries, parse header files as h2xs does, pass and return multiple values, handle objects, and more. See the Inline::C-Cookbook manpage that comes with the Inline::C module for more details.

12.19.4. See Also

The documentation with the Inline::C module from CPAN; the Inline::C-Cookbook manpage

Previous | Home | Next
12.18. Using h2xs to Make a Module with C Code | Book Index | 12.20. Documenting Your Module with Pod
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.20. Documenting Your Module with Pod

12.20.1. Problem

You need to document your module, but don't know what format to use.

12.20.2. Solution

Embed your documentation in the your module file using pod format.

12.20.3. Discussion

Pod stands for plain old documentation. It's documentation embedded in your program using a very simple markup format. Programmers are notorious for writing the code first and the documentation never, so pod was designed to make writing documentation so easy that anyone can and will do so. Sometimes this even works.

When Perl is parsing your source code, a line starting with an equals sign (where a new statement is expected) says to ignore all text until it finds a line beginning with =cut, after which it will start parsing code again. This lets you mix code and documentation throughout your Perl program or module file. Since it's mostly plain text, type in your documentation as literal text, or nearly so. The translators try to be clever and make output-specific decisions so the programmer doesn't have to specifically format variable names, function calls, etc.

Perl ships with several translators that filter generic pod format into specific output styles. These include pod2man to change your pods into troff for use with the man program or for phototypesetting and printing; pod2html for creating web pages (which works even on non-Unix systems); and pod2text for plain ASCII. Other translators, such as pod2ipf, pod2fm, pod2texi, pod2latex, and pod2ps, may also be available or can be found on CPAN.

Many books are written using proprietary word processors with limited scripting capabilities. Not this one! It was written in pod format using common text editors (vi for Tom, emacs for Nat). The final book was produced by converting the pod source files to FrameMaker.

Although formally documented in perlpod(1), pod is probably easiest to learn by reading existing module files. If you started making your module using h2xs, then you already have the sample pods right there. The Makefile knows to convert these into man format and install those manpages so others can read them. Alternatively, the perldoc program can translate pods on the fly using pod2text.

Indented paragraphs will be left verbatim. Other paragraphs will be reformatted to fit the page. Only two kinds of markups are used in pod: paragraphs beginning with an equals sign and one or more words, and interior sequences starting with a single letter followed by text enclosed in angle brackets. Paragraph tags are for headers, list enumeration, and per-translator escapes. Angle bracket sequences are mainly used for font changes, such as selecting bold, italic, or constant-width fonts. Here's an example of an =head2 pod directive and various bracket escapes for font changes:

=head2 Discussion

If we had a I<.h> file with function prototype declarations, we
could include that, but since we're writing this one from scratch,
we'll use the B<-c> flag to omit building code to translate any
#define symbols.  The B<-n> flag says to create a module directory
named I<FineTime/>, which will have the following files.

The =for escape introduces specific code that is only for a particular output filter. This book, for example, written mostly in pod, includes calls to the standard troff tools eqn, tbl, and pic. Here's an example of embedded eqn. Only translators that produce troff will heed this paragraph.

=for troff
.EQ
log sub n (x) = { {log sub e (x)} over {log sub e (n)} }
.EN

Pod can also create multiline comments. In C, the sequence /* .... */ can comment out many lines of text all at once—there's no need to put a marker on each line. Since Perl ignores pod directives, use these for block commenting. The trick is to find a directive that the pod filters ignore. You could specify that a block is "for later" or "for nobody":

=for later
next if 1 .. ?^$?;
s/^(.)/>$1/;
s/(.{73})........*/$1
<SNIP>/;

=cut back to perl

or you could use a =begin and =end pair:

=begin comment

if (!open(FILE, "<", $file)) {
    unless ($opt_q) {
        warn "$me: $file: $!\n";
        $Errors++;
    }
    next FILE;
}

$total = 0;
$matches = 0;

=end comment

12.20.4. See Also

The section on "PODs: Embedded Documentation" in
perlsyn(1), as well as
perlpod(1), pod2man(1),
pod2html(1), and
pod2text(1); Chapter 26 of Programming
Perl

Previous | Home | Next
12.19. Writing Extensions in C with Inline::C | Book Index | 12.21. Building and Installing a CPAN Module
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.21. Building and Installing a CPAN Module

12.21.1. Problem

You want to install a module file that you downloaded from CPAN over the Net or obtained from a CD.

12.21.2. Solution

Type the following commands into your shell. It will build and install Version 4.54 of the Some::Module package.

% gunzip Some-Module-4.54.tar.gz
% tar xf Some-Module-4.54
% cd Some-Module-4.54
% perl Makefile.PL
% make
% make test
% make install

12.21.3. Discussion

Like most programs on the Net, Perl modules are available in source kits stored as tar archives in GNU zip format.[23] If tar warns of "Directory checksum errors", then you downloaded the binary file in text format, mutilating it.

[23]This is not the same as the zip format common on Windows machines, but newer version of Windows winzip will read it. Prior to Perl 5.005, you'll need the standard port of Perl for Win32, not the ActiveState port, to build CPAN modules. Free versions of tar and gnutar are also available for Microsoft systems.

You'll probably have to become a privileged user with adequate permissions to install the module in the system directories. Standard modules are installed in a directory like /usr/lib/perl5, whereas third-party modules are installed in /usr/lib/perl5/site_ perl.

Here's a sample run, showing the installation of the MD5 module:

% gunzip MD5-1.7.tar.gz
% tar xf MD5-1.7.tar
% cd MD5-1.7
% perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for MD5
% make
mkdir ./blib
mkdir ./blib/lib
cp MD5.pm ./blib/lib/MD5.pm
AutoSplitting MD5 (./blib/lib/auto/MD5)
/usr/bin/perl -I/usr/local/lib/perl5/i386 ...
...
cp MD5.bs ./blib/arch/auto/MD5/MD5.bs
chmod 644 ./blib/arch/auto/MD5/MD5.bsmkdir ./blib/man3
Manifying ./blib/man3/MD5.3
% make test
PERL_DL_NONLAZY=1 /usr/bin/perl -I./blib/arch -I./blib/lib
-I/usr/local/lib/perl5/i386-freebsd/5.00404 -I/usr/local/lib/perl5 test.pl
1..14
ok 1
ok 2
...
ok 13
ok 14
% sudo make install
Password:
Installing /usr/local/lib/perl5/site_perl/i386-freebsd/./auto/MD5/
    MD5.so
Installing /usr/local/lib/perl5/site_perl/i386-freebsd/./auto/MD5/
    MD5.bs
Installing /usr/local/lib/perl5/site_perl/./auto/MD5/autosplit.ix
Installing /usr/local/lib/perl5/site_perl/./MD5.pm
Installing /usr/local/lib/perl5/man/man3/./MD5.3
Writing /usr/local/lib/perl5/site_perl/i386-freebsd/auto/MD5/.packlist
Appending installation info to /usr/local/lib/perl5/i386-freebsd/
5.00404/perllocal.pod

If your system manager isn't around or can't be prevailed upon to run the installation, don't worry. When you use Perl to generate the Makefile from template Makefile.PL, you can specify alternate installation directories.

# if you just want the modules installed in your own directory
% perl Makefile.PL LIB=~/lib

# if you have your own complete distribution
% perl Makefile.PL PREFIX=~/perl5-private

An even simpler approach is to use the CPAN module from the command line, because it can search for, download, and install the module you need. Suppose you wanted to find the CPAN module Getopt::Declare. All you'd have to do is type:

% perl -MCPAN -e "install Getopt::Declare"

The first time you use the CPAN module, it will ask you some configuration questions. It saves these away so that when you use it in the future, it won't need to ask you those questions again.

The CPAN module also supports an interactive command shell. This can be used to search for modules whose precise names you're uncertain of, check which CPAN modules have newer versions than you have installed, install bundles of related modules, and various other useful commands.

Here's an example run of the interactive shell.

% perl -MCPAN -e shell

cpan shell -- CPAN exploration and modules installation (v1.70)
ReadLine support enabled

cpan> h

Display Information
 command  argument          description
 a,b,d,m  WORD or /REGEXP/  about authors, bundles, distributions, modules
 i        WORD or /REGEXP/  about anything of above
 r        NONE              reinstall recommendations
 ls       AUTHOR            about files in the author's directory

Download, Test, Make, Install...
 get                        download
 make                       make (implies get)
 test      MODULES,         make test (implies make)
 install   DISTS, BUNDLES   make install (implies test)
 clean                      make clean
 look                       open subshell in these dists' directories
 readme                     display these dists' README files

Other
 h,?           display this menu       ! perl-code   eval a perl command
 o conf [opt]  set and query options   q             quit the cpan shell
 reload cpan   load CPAN.pm again      reload index  load newer indices
 autobundle    Snapshot                force cmd     unconditionally do cmd

cpan> i /inflect/
CPAN: Storable loaded ok
Going to read /home/tchrist/.cpan/Metadata
  Database was generated on Mon, 07 Apr 2003 22:42:33 GMT
Distribution    D/DC/DCONWAY/Lingua-EN-Inflect-1.88.tar.gz
Module          Lingua::EN::Inflect (D/DC/DCONWAY/Lingua-EN-Inflect-1.88.tar.gz)
2 items found

cpan> install Lingua::EN::Inflect
[build and install output deleted]

cpan> quit

The CPAN module is slowly being phased out in favor of CPANPLUS, a module with similar functionality that is built for flexibility as well as power. The CPANPLUS text interface is similar to that of the CPAN module, but it also offers a GUI and programmer interfaces, which can access a lot of functionality that the CPAN module hides.

12.21.4. See Also

The documentation for the standard ExtUtils::MakeMaker module; the INSTALL file in the Perl source distribution for information on building a statically linked perl binary

Previous | Home | Next
12.20. Documenting Your Module with Pod | Book Index | 12.22. Example: Module Template
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.22. Example: Module Template

Following is the skeleton of a module. If you want to write a module of your own, you can copy this and customize it.

package Some::Module;  # must live in Some/Module.pm

use strict;

require Exporter;

# set the version for version checking
our $VERSION     = 0.01;

our @ISA         = qw(Exporter);
our @EXPORT      = qw(&func1 &func2 &func4);
our %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],

# your exported package globals go here,
# as well as any optionally exported functions
our @EXPORT_OK   = qw($Var1 %Hashit &func3);

use vars qw($Var1 %Hashit);
# non-exported package globals go here
our(@more, $stuff);

# initialize package globals, first exported ones
$Var1   = "";
%Hashit = ( );

# then the others (which are still accessible as $Some::Module::stuff)
$stuff  = "";
@more   = ( );

# all file-scoped lexicals must be created before
# the functions below that use them.

# file-private lexicals go here
my $priv_var    = "";
my %secret_hash = ( );

# here's a file-private function as a closure,
# callable as &$priv_func.
my $priv_func = sub {
    # stuff goes here.
};

# make all your functions, whether exported or not;
# remember to put something interesting in the {  } stubs
sub func1      { .... }    # no prototype
sub func2( )    { .... }    # proto'd void
sub func3($$)  { .... }    # proto'd to 2 scalars

# this one isn't auto-exported, but could be called!
sub func4(\%)  { .... }    # proto'd to 1 hash ref

END { }       # module cleanup code here (global destructor)

1;
Previous | Home | Next
12.21. Building and Installing a CPAN Module | Book Index | 12.23. Program: Finding Versions and Descriptions of Installed Modules
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.23. Program: Finding Versions and Descriptions of Installed Modules

Perl comes with many modules included standard. Even more can be found on CPAN. The following program prints out the names, versions, and descriptions of all modules installed on your system. It uses standard modules like File::Find and includes several techniques described in this chapter.

To run it, type:

% pmdesc

It prints a list of modules and their descriptions:

FileHandle (2.00) - supply object methods for filehandles
IO::File (1.06021) - supply object methods for filehandles
IO::Select (1.10) - OO interface to the select system call
IO::Socket (1.1603) - Object interface to socket communications
...

With the -v flag, pmdesc provides the names of the directories the files are in:

% pmdesc -v

<<<Modules from /usr/lib/perl5/i686-linux/5.00404>>>

FileHandle (2.00) - supply object methods for filehandles
    ...

The -w flag warns if a module doesn't come with a pod description, and -s sorts the module list within each directory.

The program is given in Example 12-3.

Example 12-3. pmdesc

  #!/usr/bin/perl -w
  # pmdesc - describe pm files
  # tchrist@perl.com

  use strict;
  use File::Find      qw(find);
  use Getopt::Std     qw(getopts);
  use Carp;

  use vars (
      q!$opt_v!,              # give debug info
      q!$opt_w!,              # warn about missing descs on modules
      q!$opt_a!,              # include relative paths
      q!$opt_s!,              # sort output within each directory
  );

  $| = 1;

  getopts("wvas")             or die "bad usage";

  @ARGV = @INC unless @ARGV;

  # Globals.  wish I didn't really have to do this.
  use vars (
      q!$Start_Dir!,          # The top directory find was called with
      q!%Future!,             # topdirs find will handle later
  );

  my $Module;

  # install an output filter to sort my module list, if wanted.
  if ($opt_s) {
      if (open(ME, "-|")) {
          $/ = "";
          while (<ME>) {
              chomp;
              print join("\n", sort split /\n/), "\n";
          }
          exit;
      }
  }

  MAIN: {
      my %visited;
      my ($dev,$ino);

      @Future{@ARGV} = (1) x @ARGV;

      foreach $Start_Dir (@ARGV) {
          delete $Future{$Start_Dir};

          print "\n << Modules from $Start_Dir>>\n\n"
              if $opt_v;

          next unless ($dev,$ino) = stat($Start_Dir);
          next if $visited{$dev,$ino}++;
          next unless $opt_a || $Start_Dir =~ m!^/!;

          find(\&wanted, $Start_Dir);
      }
      exit;
  }

  # calculate module name from file and directory
  sub modname {
      local $_ = $File::Find::name;

      if (index($_, $Start_Dir . "/") =  = 0) {
          substr($_, 0, 1+length($Start_Dir)) = "";
      }

      s { /              }    {::}gx;
      s { \.p(m|od)$     }    {  }x;

      return $_;
  }

  # decide if this is a module we want
  sub wanted {
      if ( $Future{$File::Find::name} ) {
          warn "\t(Skipping $File::Find::name, qui venit in futuro.)\n"
              if 0 and $opt_v;
          $File::Find::prune = 1;
          return;
      }
      return unless /\.pm$/ && -f;
      $Module = &modname;
      # skip obnoxious modules
      if ($Module =~ /^CPAN(\Z|::)/) {
          warn("$Module -- skipping because it misbehaves\n");
          return;
      }

      my    $file = $_;

      unless (open(POD, "<", $file)) {
          warn "\tcannot open $file: $!";
              # if $opt_w;
          return 0;
      }

      $: = " -:";

      local $/ = "";
      local $_;
      while (<POD>) {
          if (/=head\d\s+NAME/) {
              chomp($_ = <POD>);
              s/^.*?-\s+//s;
              s/\n/ /g;
              #write;
              my $v;
              if (defined ($v = getversion($Module))) {
                  print "$Module ($v) ";
              } else {
                  print "$Module ";
              }
              print "- $_\n";
              return 1;
          }
      }

      warn "\t(MISSING DESC FOR $File::Find::name)\n"
          if $opt_w;

      return 0;
  }

  # run Perl to load the module and print its verson number, redirecting
  # errors to /dev/null
  sub getversion {
      my $mod = shift;

      my $vers = `$^X -m$mod -e 'print \$${mod}::VERSION' 2>/dev/null`;
      $vers =~ s/^\s*(.*?)\s*$/$1/; # remove stray whitespace
      return ($vers || undef);
  }

  format = ^<<<<<<<<<<<<<<<<<~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  $Module,        $_
  .

This can also be accomplished through the backend programmer interface in the CPANPLUS module, if you have it installed. This program displays information on all available modules (the -X option is to silence any warnings about invalid paths or version numbers):

#!/usr/bin/perl -X

use CPANPLUS::Backend;
use Data::Dumper;

$cp = CPANPLUS::Backend->new;
$installed = $cp->installed->rv;          # fetch list of installed mods

foreach my $module (sort keys %$installed) {
  # get the module's information
  $info = $cp->details(modules => [$module])->rv->{$module};
  # display the fields we care about
  printf("%-35.35s %44.44s\n", $module, $info->{Description});
}

When run, it outputs a table like this:

Algorithm::Cluster                  Perl extension for the C clustering library
Algorithm::NaiveBayes                                                None given
AnyDBM_File                            Uses first available *_File module above
Apache                                       Interface to the Apache server API
Apache::AuthDBI                                                      None given
Apache::Connection                           Inteface to Apache conn_rec struct
Previous | Home | Next
12.22. Example: Module Template | Book Index | 13. Classes, Objects, and Ties
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 13. Classes, Objects, and Ties

Contents:

Introduction
Constructing an Object
Destroying an Object
Managing Instance Data
Managing Class Data
Using Classes as Structs
Cloning Constructors
Copy Constructors
Invoking Methods Indirectly
Determining Subclass Membership
Writing an Inheritable Class
Accessing Overridden Methods
Generating Attribute Methods Using AUTOLOAD
Coping with Circular Data Structures Using Objects
Overloading Operators
Creating Magic Variables with tie

William E. Gladstone, Speech at Liverpool, 28 June 1886

All the world over, I will back the masses against the classes.

13.0. Introduction

Although Perl was not initially conceived of as an object-oriented language, within a few years of its initial release, complete support for object-oriented programming had been added. As usual, Perl doesn't try to enforce one true style, but embraces many. This helps more people do their job the way they want to do it.

You don't have to use objects to write programs, unlike Java, where programs are instances of objects. If you want to, though, you can write Perl programs that use nearly every weapon in the object-oriented arsenal. Perl supports classes and objects, single and multiple inheritance, instance methods and class methods, access to overridden methods, constructors and destructors, operator overloading, proxy methods through autoloading, delegation, a rooted hierarchy for all objects, and two levels of garbage collection.

You can use as many or as few object-oriented techniques as you want and need. Ties are the only part of Perl where you must use object orientation. And even then, only the module implementor need be aware of this; the casual user gets to remain blissfully unaware of the internal mechanics. Ties, discussed in Recipe 13.15, let you transparently intercept access to a variable. For example, you can use ties to create hashes that support lookups by key or value instead of just by key.

13.0.1 Under the Hood

If you ask 10 people what object orientation is, you'll get 10 different answers. People bandy about terms like abstraction and encapsulation, trying to isolate the basic units of object-oriented programming languages and give them big names to write papers and books about. Not all object-oriented languages offer the same features, yet they are still deemed object-oriented. This, of course, produces more papers and books.

We follow the nomenclature used in Perl's documentation, the perlobj(1) manpage, and Chapter 12 of Programming Perl. An object is a variable that belongs to a class. Methods are functions associated with a class. In Perl, a class is a package—and usually a module. An object is a reference to something associated with a class.

Once associated with a class, something is said to be blessed into that class. There's nothing ecclesiastical or spooky going on here. Blessing merely associates a referent with a class, and this is done with the bless function, which takes one or two arguments. The first is a reference to the thing you want associated with the class; the second is the package with which to make that association.

$object = {  };                          # hash reference
bless($object, "Data::Encoder");    # bless $object into Data::Encoder class
bless($object);                     # bless $object into current package

The class name is the package name (Data::Encoder in this example). Because classes are modules (usually), the code for the Data::Encoder class resides in the file Data/Encoder.pm. As with traditional modules, the directory structure is purely for convenience; it implies nothing about inheritance, variable sharing, or anything else. Unlike a traditional module, though, an object module seldom if ever uses the Exporter. Access should be through methods only, not imported functions or variables.

Once an object has been blessed, calling the ref function on its reference returns the name of its class instead of the fundamental type of referent:

$obj = [3,5];
print ref($obj), " ", $obj->[1], "\n";
bless($obj, "Human::Cannibal");
print ref($obj), " ", $obj->[1], "\n";

ARRAY 5
Human::Cannibal 5

As you can see, you can still dereference a reference once it has been blessed. Most frequently, objects are implemented as blessed hash references. You can use any kind of reference you want, but hash references are the most flexible because they allow arbitrarily named data fields in an object.

$obj->{Stomach} = "Empty";   # directly accessing an object's contents
$obj->{NAME}    = "Thag";
# uppercase field name to make it stand out (optional)

Although Perl permits it, it's considered poor form for code outside the class to directly access the contents of an object. The point of objects, everyone agrees, is to give you an abstract something with mediated access through designated methods. This lets the maintainer of the class change its implementation without needing to change all application code that uses the class.

13.0.2. Methods

The whole purpose for blessing—that is, associating a package with a referent—is so that Perl can determine the package namespace in which to find functions when you invoke methods against an object. To invoke a method, use ->. Here, we invoke the encode( ) method of $object with the argument "data" and store the return value in $encoded:

$encoded = $object->encode("data");

The lefthand operand of the -> operator is said to be the method's invocant. Think of the invocant as the entity on whose behalf the method was called. Methods always involve invocants. Here we have an object method because we invoke the method on an object. We can also have class methods where the invocant is a string representing the package—meaning, of course, the class.

$encoded = Data::Encoder->encode("data");

Invoking a method calls the function in the corresponding class, implicitly passing its invocant as the initial argument to that function: a reference for object methods, a string for class methods. It isn't always obvious which of the two invocation types you have, because the invocant could be a variable holding a class name instead of one holding a reference that's been blessed.

$class = "Animal::" . ($aquatic ? "Fish" : "Mammal");
$beastie = $class->create( );

That will sometimes invoke the create method from class Animal::Fish and sometimes invoke the create method from class Animal::Mammal. This might even end up being the same underlying function if those two classes share a common ancestral class. Here you don't know the class until runtime. Recipe 13.8 shows how to invoke a method where the method name isn't determined until runtime.

Most classes provide constructor methods, which return new objects. Unlike in some object-oriented languages, constructor methods in Perl are not specially named. In fact, you can name them anything you like. C++ programmers have a penchant for naming their constructors in Perl new. We recommend that you name your constructors whatever makes sense in the context of the problem you're solving. For example, constructors in the Tk extension to Perl are named after the widgets they create. A less common approach is to export a function with the same name as the class; see Recipe 13.14.4 in Recipe 13.14 for an example.

A typical constructor used as a class method looks like this:

sub new {
    my $class = shift;
    my $self  = {  };         # allocate new hash for object
    bless($self, $class);
    return $self;
}

Call the constructor with:

$object = Classname->new( );

If there isn't any inheritance or other monkey business working behind the scenes, this is effectively the same as:

$object = Classname::new("Classname");

The new function's first argument here is the name of the class—hence, the package—to bless the new reference into. A constructor should pass that string as the second argument to bless.

Recipe 13.1 also talks about functions that return blessed references. Constructors don't have to be class methods; it's often useful to have object methods that themselves return new objects, as discussed in Recipe 13.6 and Recipe 13.7.

A destructor is a subroutine that runs when an object's referent is garbage collected, which happens when its internal reference count becomes zero. Because it is invoked implicitly by Perl, unlike a constructor, you have no choice in naming a destructor. You must name your destructor method DESTROY. This method, if it exists, is invoked on an object immediately prior to memory deallocation. Destructors, described in Recipe 13.2, are optional in Perl.

Some languages syntactically allow the compiler to restrict access to a class's methods. Perl does not—it allows code to invoke any method of an object. The author of a class should clearly document the public methods (those that may be used), and the user of a class should avoid undocumented (implicitly private) methods.

Perl doesn't distinguish between methods that can be invoked on a class (class methods) and methods that can be invoked on an object (instance methods). If you want a particular method to be invoked as a class method only, do something like this:

use Carp;
sub class_only_method {
    my $class = shift;
    croak "class method invoked on object" if ref $class;
    # more code here
}

If you want to allow a particular method to be invoked as an instance method only, do something like this:

use Carp;
sub instance_only_method {
    my $self = shift;
    croak "instance method invoked on class" unless ref $self;
    # more code here
}

If your code invokes an undefined method on an object, Perl won't complain at compile time, but this will trigger an exception at runtime. Methods are just function calls whose package is determined at runtime. Like all indirect functions, they can have no prototype checking, because that happens at compile time. Even if methods were aware of prototypes, in Perl the compiler never checks the precise types or ranges of arguments to functions. Perl prototypes are used to coerce a function argument's context, not to check ranges. Recipe 10.11 details Perl's peculiar perspective on prototypes.

You can prevent Perl from triggering an exception for undefined methods by using the AUTOLOAD mechanism to catch calls to nonexistent methods. We show an application of this in Recipe 13.12.

13.0.3. Inheritance

Inheritance defines a hierarchy of classes. Calls to methods not defined in a class search this hierarchy for a method of that name. The first method found is used. Inheritance means allowing one class to piggyback on top of another so you don't have to write the same code again and again. This is a form of software reuse, and therefore related to Laziness, the principal virtue of a programmer.

Some languages provide special syntax for inheritance. In Perl, each class (package) can put its list of superclasses (parents in the hierarchy) into the package variable @ISA. This list is searched at runtime when a method that is not defined in the object's class is invoked. If the first package listed in @ISA doesn't have the method but that package has its own @ISA, Perl looks first in that package's own @ISA, recursively, before going on.

If the inheritance search fails, the same check is run again, this time looking for a method named AUTOLOAD. The lookup sequence for $invocant->meth( ), where $invocant is either a package name or a reference to something blessed into that package, is:

  • P::meth

  • All packages S in @P::ISA, recursively, for any S::meth( )

  • UNIVERSAL::meth

  • The P::AUTOLOAD subroutine

  • All packages S in @P::ISA, recursively, for any S::AUTOLOAD( )

  • The UNIVERSAL::AUTOLOAD subroutine

Most classes have just one item in their @ISA array, a situation called single inheritance. Classes with more than one element in @ISA represent multiple inheritance. The benefits of multiple inheritance are widely contested, but it is supported by Perl.

Recipe 13.10 talks about the basics of inheritance and designing a class so it can be easily subclassed. In Recipe 13.11, we show how a subclass can invoke overridden methods in its superclasses.

Perl doesn't support inheritance of data values. You could say that Perl supports only interface (method) inheritance, not implementation (data) inheritance. A class usually can, but seldom should, touch another's data directly. This violates the envelope and ruins the abstraction. If you follow the advice in Recipe 13.11, this won't be much of an issue.

13.0.4. A Warning on Indirect Object Notation

The indirect notation for method invocations:

$lector = new Human::Cannibal;
feed $lector "Zak";
move $lector "New York";

is an alternative syntax for:

$lector = Human::Cannibal->new( );
$lector->feed("Zak");
$lector->move("New York");

This indirect object notation is appealing to English speakers and familiar to C++ programmers, who use new this way. However, it suffers from several tricky problems. One is that the construct follows the same quirky rules as the filehandle slot in print and printf:

printf STDERR "stuff here\n";

This slot, if filled, is limited to a bare symbol, a block, or a scalar variable name; it can't be just any old scalar expression. This can lead to horribly confusing precedence problems, as in these next two lines:

move $obj->{FIELD};                 # probably wrong
move $ary[$i];                      # probably wrong

Surprisingly, those actually parse as:

$obj->move->{FIELD};                # Surprise!
$ary->move->[$i];                   # Surprise!

rather than as you might have expected:

$obj->{FIELD}->move( );              # Nope, you wish
$ary[$i]->move;                     # Nope, you wish

As with printf, you can fix this by wrapping the expression in braces to make it a block:

move { $obj->{FIELD} };                 # These work
move { $ary[$i] };

Furthermore, just like print or printf with a filehandle in the indirect object slot, parentheses are optional, and the method invocation becomes a list operator syntactically. Therefore, if you write:

move $obj (3 * $position) + 2;
print STDERR (3 * $position) + 2;

that will end up being taken to mean:

$obj->move(3 * $position) + 2;
STDERR->print(3 * $position) + 2;

So you'd need to put in an extra set of parentheses:

move $obj ((3 * $position) + 2);
print STDERR ((3 * $position) + 2);

The other problem is that Perl must guess at compile time whether name and move are functions or methods. If you write:

$obj = new Game;

that could, depending on what's in scope and what the compiler has seen, mean any of the following:

$obj = new("Game");
$obj = new(Game( ));
$obj = "Game"->new( );

of which only the third is the one you want. In fact, even using the infix arrow operator for method invocation has a potential problem. For example:

$obj = Game->new( );

could end up being interpreted as:

$obj = Game( )->new( );

under slightly esoteric circumstances: when there's a function in the current package named Game( ). Usually Perl gets it right, but when it doesn't, you get a function call compiled as a method invocation, or vice versa. This can introduce incredibly subtle bugs that are hard to unravel.

The surest way to disambiguate this is to put a double-colon after the package (class) name.

$obj = new Game::;             # always "Game"->new( )
$obj = Game::->new;            # always "Game"->new( )

Now it doesn't matter whether there is a function named Game or new visible in the current package; you'll always get the method invocation. When you use a package-quoted class like this, the invocant has the double-colon stripped off again when the method is run, as the comments indicate.

To be honest, you can almost always get away using just the bare class name and omitting the ugly trailing double-colon—provided two things are true. First, there must be no subroutine of the same name as the class. (If you follow the convention that subroutine names like new start with a lowercase letter and class names like Game start with an uppercase letter, this is never a problem.) Second, the class needs to have been loaded with one of:

use Game;
require Game;

Either of these declarations ensures that Perl knows Game is a module name. This forces any bare name like new before the class name Game to be interpreted as a method invocation, even if you happen to have declared a new subroutine of your own in the current package. People don't generally get into trouble with indirect objects unless they start cramming multiple classes into the same file, in which case Perl might not know that a particular package name was supposed to be a class name. People who name subroutines with names that look like ModuleNames also come to grief eventually.

For more information about this, see the sections on "Syntactic Snafus with Indirect Objects" and "Package-Quoted Classes" in Chapter 12 of Programming Perl.

13.0.5. Some Notes on Object Terminology

In the object-oriented world, many words describe only a few concepts. If you've programmed in another object-oriented language, you might like to know how familiar terms and concepts map onto Perl.

For example, it's common to refer to objects as instances of a class and those objects' methods instance methods. Data fields peculiar to each object are often called instance data or object attributes, and data fields common to all members of that class are class data, class attributes, or static data members.

Also, base class, generic class, and superclass all describe the same notion (a parent or similar ancestor in the inheritance hierarchy), whereas derived class, specific class, and subclass describe the opposite relationship (a child or descendent in the inheritance hierarchy).

C++ programmers have static methods, virtual methods, and instance methods, but Perl only has class methods and object methods. Actually, Perl only has methods. It accepts any sort of invocant you choose to employ. Whether a method acts as a class or an object method is determined solely by actual usage. You could call a class method (one expecting a string argument) on an object or an object method (one expecting a reference) on a class, but you shouldn't expect reasonable results if you do.

A C++ programmer thinks about global (class) constructors and destructors. These correspond to module initialization code and per-module END{ } blocks, respectively.

From the C++ perspective, all methods in Perl are virtual. This is why their arguments are never checked for function prototypes as the built-in and user-defined functions can be. Prototypes are checked by the compiler at compile time, and you can't determine until runtime the function called by method invocation.

13.0.6. Philosophical Aside

In its OO programming, Perl gives you a lot of freedom: the ability to do things more than one way (you can bless any data type to make an object), to inspect and modify classes you didn't write (adding functions to their packages), and to use these to write tangled pits of misery—if that's really what you want to do.

Less flexible programming languages are usually more restrictive. Many are fanatically devoted to enforced privacy, compile-time type checking, complex function signatures, and a smorgasbord of other features. Perl doesn't provide these things with objects because it doesn't provide them anywhere else, either. Keep this in mind if you find Perl's object-oriented implementation weird. You only think it's weird because you're used to another language's philosophy. Perl's treatment of OO is perfectly sensible—if you think in Perl. For every problem that you can't solve by writing Perl as though it were Java or C++, there is a native Perl solution that works perfectly. The absolutely paranoid programmer can even have complete privacy: the perltoot(1) manpage describes how to bless closures to produce objects that are as private as those in C++ (and more so).

Perl's objects are not wrong; they're differently right.

13.0.7. See Also

The general literature on object-oriented programming rarely refers directly to Perl. The documentation that came with Perl is a good place to begin learning about object-oriented programming, particularly the object tutorials perltoot(1) and perlboot(1). For a reference, read perlobj(1) and Chapter 12 of Programming Perl. You might need it when you read perlbot(1), which is full of object-oriented tricks.

Damian Conway's Object Oriented Perl (Manning) is the best introduction and reference for object-oriented programming in Perl. It's readable, accurate, and comprehensive.

Previous | Home | Next
12.23. Program: Finding Versions and Descriptions of Installed Modules | Book Index | 13.1. Constructing an Object
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.1. Constructing an Object

13.1.1. Problem

You want to create a way for your users to generate new objects.

13.1.2. Solution

Make a constructor. In Perl, the constructor method must not only initialize its object, but must also first allocate memory for it, typically using an anonymous hash. C++ constructors, on the other hand, are called with memory already allocated. Some of the object-oriented world would call C++'s constructors initializers.

Here's the canonical object constructor in Perl:

sub new {
    my $class = shift;
    my $self  = { };
    bless($self, $class);
    return $self;
}

This is the equivalent one-liner:

sub new { bless( { }, shift ) }

13.1.3. Discussion

Any method that allocates and initializes a new object acts as a constructor. The most important thing to remember is that a reference isn't an object until bless has been called on it. The simplest possible constructor, although not particularly useful, is the following:

sub new { bless({  }) }

Let's add some initialization:

sub new {
    my $self = { };  # allocate anonymous hash
    bless($self);
    # init two sample attributes/data members/fields
    $self->{START} = time( );
    $self->{AGE}   = 0;
    return $self;
}

This constructor isn't very useful, because it uses the single-argument form of bless, which always blesses the object into the current package. This means it can't be usefully inherited from; objects it constructs will always be blessed into the class that the new function was compiled into. With inheritance, this is not necessarily the class on whose behalf the method was invoked.

To solve this, have the constructor heed its first argument. For a class method, this is the package name. Pass this class name as the second argument to bless:

sub new {
    my $classname  = shift;           # What class are we constructing?
    my $self       = {  };            # Allocate new memory
    bless($self, $classname);         # Mark it of the right type
    $self->{START}  = time( );       # init data fields
    $self->{AGE}    = 0;
    return $self;                     # And give it back
}

Now the constructor can be correctly inherited by a derived class.

You might also want to separate the memory allocation and blessing step from the instance data initialization step. Simple classes won't need this, but it can sometimes make inheritance easier by separating memory allocation from initialization; see Recipe 13.11.

sub new {
    my $classname  = shift;           # What class are we constructing?
    my $self      = {  };             # Allocate new memory
    bless($self, $classname);         # Mark it of the right type
    $self->_init(@_);                 # Call _init with remaining args
    return $self;
}

# "private" method to initialize fields.  It always sets START to
# the current time, and AGE to 0.  If invoked with arguments, _init
# interprets them as key+value pairs to initialize the object with.
sub _init {
    my $self = shift;
    $self->{START} = time( );
    $self->{AGE}   = 0;
    if (@_) {
        my %extra = @_;
        @$self{keys %extra} = values %extra;
    }
}

13.1.4. See Also

perltoot(1), perlboot(1), and perlobj(1); Chapter 12 of Programming Perl; Recipe 13.6; Recipe 13.10; Recipe 13.11

Previous | Home | Next
13. Classes, Objects, and Ties | Book Index | 13.2. Destroying an Object
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.2. Destroying an Object

13.2.1. Problem

You want to run special code whenever an object is no longer used. This is sometimes needed when the object is an interface to the outside world—or contains circular data structures—and must clean up after itself. You might remove temporary files, break circular links, gracefully disconnect from a socket, or kill a spawned subprocess.

13.2.2. Solution

Create a method named DESTROY. This will be invoked when there are no more references to the object, or else when the program shuts down, whichever comes first. You don't need to do any memory deallocation here, just any finalization code that makes sense for the class.

sub DESTROY {
    my $self = shift;
    printf("$self dying at %s\n", scalar localtime);
}

13.2.3. Discussion

Every story has a beginning and an end. The beginning of the object's story is its constructor, explicitly invoked when the object comes into existence. The end of its story is the destructor, a method implicitly invoked when an object leaves this life. Any per-object clean-up code is placed in the destructor, which must be named DESTROY.

Why can't destructors have arbitrary names? Because although constructors are explicitly called by name, the destructor is not. Destruction happens automatically via Perl's garbage collection (GC) system, which is currently implemented as a quick but lazy reference-based GC system. To know what to call, Perl insists that the destructor be named DESTROY. If more than one object goes out of scope at once, Perl makes no promise about invoking destructors in any particular order.

Why is DESTROY in all caps? Perl on occasion uses purely uppercase function names as a convention to indicate that the function will be automatically called by Perl. Others that are called implicitly include BEGIN, INIT, END, AUTOLOAD, plus all methods used by tied objects (see Recipe 13.15), such as STORE and FETCH.

The user doesn't care when the destructor is invoked. It just happens when it's supposed to. In languages without any form of GC, this is undependable, so the programmer must explicitly invoke the destructor to clean up memory and state, crossing their fingers that it's the right time to do so. This is a terrible state of affairs.

Because of Perl's automatic memory management, an object destructor is rarely needed in Perl. Even when it is, explicit invocation is not only uncalled for, it's downright dangerous. The destructor will be invoked by the run-time system when the object is no longer in use. Most classes don't need a destructor because Perl takes care of simple matters like memory deallocation.

The only situation where Perl's reference-based garbage collection system won't work for you is when there's a circularity in your data structure, such as:

$self->{WHATEVER} = $self;

In that case, you must delete the self-reference manually if you expect your program not to leak memory. While admittedly error-prone, this is the best we can do right now. Recipe 11.5 and Recipe 13.13 provide solutions to this problem using techniques easily generalizable to any data structure. Nonetheless, rest assured that when your program is finished, all objects' destructors are duly invoked. At interpreter shutdown time, a second, more sweeping form of garbage collection is performed. Not even unreachable or circular objects can escape this final destruction. So you are guaranteed that an object eventually gets properly destroyed, unless a program never exits. If you're running Perl embedded in another application, the second GC pass happens more frequently—whenever an interpreter shuts down.

DESTROY is not invoked when a program replaces itself with another via exec.

13.2.4. See Also

perltoot(1), perlboot(1), and perlobj(1); the section "Garbage Collection, Circular References, and Weak References" in Chapter 8 of Programming Perl; Recipe 13.11; Recipe 13.13

Previous | Home | Next
13.1. Constructing an Object | Book Index | 13.3. Managing Instance Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.3. Managing Instance Data

13.3.1. Problem

Each data attribute of an object, sometimes named data members or properties, needs its own method for access. How do you write functions that manipulate the object's instance data?

13.3.2. Solution

Either write pairs of get and set methods that affect the appropriate key in the object hash, like this:

sub get_name {
    my $self = shift;
    return $self->{NAME};
}

sub set_name {
    my $self      = shift;
    $self->{NAME} = shift;
}

or make single methods that do both jobs depending on whether they're passed an argument:

sub name {
    my $self = shift;
    if (@_) { $self->{NAME} = shift }
    return $self->{NAME};
}

When setting a new value, sometimes it may be useful to return not that new value, but the previous one:

# returns previously set value if changing it
sub age {
    my $self = shift;
    my $oldage = $self->{AGE};
    if (@_) { $self->{AGE} = shift }
    return $oldage;
}
$previous_age = $obj->age( $obj->age( ) + $TIME_PASSES );

13.3.3. Discussion

Methods are how you implement the public interface to the object. A proper class doesn't encourage anyone to poke around inside its innards. Each data attribute should have a method to update it, retrieve it, or both. If a user writes code like this:

$him = Person->new( );
$him->{NAME} = "Sylvester";
$him->{AGE}  = 23;

then an argument could justifiably be made that they have violated the interface and so deserve whatever they get.

For nominally private data elements, you may omit methods that access them. However, then if—better make that when—you update the implementation, you'll need to scour the class to find where other methods within the class rely upon the particular representation that you're now changing. To be squeaky clean, you could have the class itself go through a mediated, functional interface to access instance data.

This extraordinary care isn't strictly required by the class of its own methods, but from the perspective of code that simply uses your module, it most certainly is. By mandating a strictly functional interface, you are free to alter your internal representation later without fear of breaking user code. The functional interface allows you to run arbitrary range checks and take care of any data reformatting or conversion.

Here's a fancy version of the name method that demonstrates this:

use Carp;
sub name {
    my $self = shift;
    return $self->{NAME} unless @_;
    local $_ = shift;
    croak "too many arguments" if @_;
    if ($^W) {
        /[^\s\w'-]/         && carp "funny characters in name";
        /\d/                && carp "numbers in name";
        /\S+(\s+\S+)+/      || carp "prefer multiword name";
        /\S/                || carp "name is blank";
    }
    s/(\w+)/\u\L$1/g;       # enforce capitalization
    $self->{NAME} = $_;
}

If users, or even other classes through inheritance, had been accessing the "NAME" field directly, you couldn't add this kind of code later. By insisting on only indirect, functional access to all data attributes, you keep your options open.

If you're used to C++ objects, then you're accustomed to being able to get at an object's data members as simple variables from within a method. The Alias module from CPAN provides for this, as well as a good bit more, such as the possibility of private methods that the object can invoke but folks outside the class cannot.

Here's an example of creating a Person using the Alias module. When you update these magical instance variables, you automatically update value fields in the hash. Convenient, eh?

package Person;

# this is the same as before...
sub new {
     my $that  = shift;
     my $class = ref($that) || $that;
     my $self = {
           NAME  => undef,
           AGE   => undef,
           PEERS => [  ],
    };
    bless($self, $class);
    return $self;
}

use Alias qw(attr);
our ($NAME, $AGE, @PEERS);

sub name {
    my $self = attr shift;
    if (@_) { $NAME = shift; }
    return    $NAME;
};

sub age {
    my $self = attr shift;
    if (@_) { $AGE = shift; }
    return    $AGE;
}

sub peers {
    my $self = attr shift;
    if (@_) { @PEERS = @_; }
    return    @PEERS;
}

sub exclaim {
    my $self = attr shift;
    return sprintf "Hi, I'm %s, age %d, working with %s",
            $NAME, $AGE, join(", ", @PEERS);
}

sub happy_birthday {
    my $self = attr shift;
    return ++$AGE;
}

You need to declare the package variables via our because Alias plays with package globals by the same names as the fields. To use globals while use strict is in effect, you have to predeclare them. These variables are localized to the block enclosing the attr invocation, just as though local were used on them. That means that they're still considered global package variables with temporary values.

13.3.4. See Also

perltoot(1), perlboot(1), perlobj(1), and perlbot(1); the section on "Managing Instance Data" in Chapter 12 of Programming Perl; the documentation for the Alias module from CPAN; Recipe 13.12

Previous | Home | Next
13.2. Destroying an Object | Book Index | 13.4. Managing Class Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.4. Managing Class Data

13.4.1. Problem

You need a method invoked on behalf of the whole class, not just on one object. This might be a procedural request, or it might be a global data attribute shared by all instances of the class.

13.4.2. Solution

Instead of expecting a reference as their first argument as object methods do, class methods expect a string containing the name of the class. Class methods access package data, not object data, as in the population method shown here:

package Person;

$Body_Count = 0;

sub population { return $Body_Count }

sub new {                                   # constructor
    $Body_Count++;
    return bless({  }, shift);
}

sub DESTROY { --$Body_Count }                # destructor

# later, the user can say this:
package main;

for (1..10) { push @people, Person->new }
printf "There are %d people alive.\n", Person->population( );

There are 10 people alive.

13.4.3. Discussion

Normally, each object has its own complete state stored within itself. The value of a data attribute in one object is unrelated to the value that attribute might have in another instance of the same class. For example, setting her gender here does nothing to his gender, because they are different objects with distinct states:

$him = Person->new( );
$him->gender("male");

$her = Person->new( );
$her->gender("female");

Imagine a classwide attribute where changing the attribute for one instance changes it for all of them. Just as some programmers prefer capitalized global variables, some prefer uppercase names when the method affects class data instead of instance data. Here's an example of using a class method named Max_Bounds:

FixedArray->Max_Bounds(100);                # set for whole class
$alpha = FixedArray->new( );
printf "Bound on alpha is %d\n", $alpha->Max_Bounds( );
100
$beta = FixedArray->new( );
$beta->Max_Bounds(50);                      # still sets for whole class
printf "Bound on alpha is %d\n", $alpha->Max_Bounds( );
50

The implementation is simple:

package FixedArray;
$Bounds = 7;  # default
sub new { bless( {  }, shift ) }
sub Max_Bounds {
    my $proto  = shift;
    $Bounds    = shift if @_;          # allow updates
    return $Bounds;
}

To make the value effectively read-only, simply remove the update possibility, as in:

sub Max_Bounds { $Bounds }

If you're deeply paranoid, make $Bounds a lexical variable private to the scope of the file containing the class. Then no one could say $FixedArray::Bounds to discover its values. They'd be forced to go through the method interface instead.

Here's a tip to help build scalable classes: store object data on the object's namespace (in the hash), and store class data in the class namespace (package variables or file-scoped lexicals). Only class methods should directly access classwide attributes. Object methods should access only instance data. If the object method needs access to class data, its constructor should store a reference to that data in the object. Here's an example:

sub new {
    my $class = shift;
    my $self = bless({  }, $class);
    $self->{Max_Bounds_ref} = \$Bounds;
    return $self;
}

13.4.4. See Also

perltoot(1), perlboot(1), perlobj(1), and perlbot(1); the section on "Managing Class Data" in Chapter 12 of Programming Perl; Recipe 13.3; the places method in Recipe 13.14.5 in Recipe 13.14

Previous | Home | Next
13.3. Managing Instance Data | Book Index | 13.5. Using Classes as Structs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.5. Using Classes as Structs

13.5.1. Problem

You're used to structured data types more complex than Perl's arrays and hashes, such as C's structs and Pascal's records. You've heard that Perl's classes are comparable, but you aren't an object-oriented programmer.

13.5.2. Solution

Use the standard Class::Struct module's struct to declare data structures reminiscent of those in the C programming language:

use Class::Struct;          # load struct-building module

struct Person => {          # create a definition for a "Person"
    name   => '$',          #    name field is a scalar
    age    => '$',          #    age field is also a scalar
    peers  => '@',          #    but peers field is an array (reference)
};

my $p = Person->new( );      # allocate an empty Person struct

$p->name("Jason Smythe");                   # set its name field
$p->age(13);                                # set its age field
$p->peers( ["Wilbur", "Ralph", "Fred" ] );  # set its peers field

# or this way:
@{$p->peers} = ("Wilbur", "Ralph", "Fred");

# fetch various values, including the zeroth friend
printf "At age %d, %s's first friend is %s.\n",
    $p->age, $p->name, $p->peers(0);

13.5.3. Discussion

The Class::Struct::struct function builds struct-like classes on the fly. It creates a class of the name given in the first argument, complete with a constructor named new and per-field accessor methods.

In the structure layout definition, the keys are the names of the fields and the values are the data type. This type can be one of the three base types: '$' for scalars, '@' for arrays, and '%' for hashes. Each accessor method can be invoked without arguments to fetch the current value, or with an argument to set the value. For a field whose type is an array or hash, a zero-argument method invocation returns a reference to the entire array or hash, a one-argument invocation retrieves the value at that subscript,[24] and a two-argument invocation sets the value at that subscript.

[24]Unless it's a reference, in which case it uses that as the new aggregate, with type checking.

The type can even be the name of another named structure—or any class, for that matter. Because a class constructor doesn't have to be named new, if a component of your class is another object class, you'll have to invoke that named constructor yourself.

use Class::Struct;

struct Person => {name => '$',      age  => '$'};
struct Family => {head => 'Person', address => '$', members => '@'};

$folks  = Family->new( );

$folks->head($dad = Person->new);
$dad->name("John");
$dad->age(34);

printf("%s's age is %d\n", $folks->head->name, $folks->head->age);

You can pass the constructors created by Class::Struct initializer pairs:

$dad = Person->new(name => "John", age => 34);
$folks->head($dad);

Internally, the class is implemented using a hash, just as most classes are. This makes your code easy to debug and manipulate. Consider the effect of printing out a structure in the debugger, for example. If you use the Perl debugger's x command to dump out the $folks object you've just created, you'll notice something interesting:

DB<2> x $folks
0  Family=HASH(0xcc360)
   'Family::address' => undef
   'Family::head' => Person=HASH(0x3307e4)
      'Person::age' => 34
      'Person::name' => 'John'
   'Family::members' => ARRAY(0xcc078)
        empty array

Each hash key contains more than the just the name of the method: that name is prefixed by the package name and a double-colon. This convention guards against two classes in the same inheritance hierarchy using the same slot in the object hash for different purposes. This is a wise practice to follow for your own classes, too. Always use the package name as part of the hash key, and you won't have to worry about conflicting uses in subclasses.

If you'd like to impose more parameter checking on the fields' values, supply your own version for the accessor method to override the default version. Let's say you wanted to make sure the age value contains only digits, and that it falls within reasonably human age requirements. Here's how that function might be coded:

sub Person::age {
    use Carp;
    my ($self, $age) = @_;
    if    (@_  > 2) {  confess "too many arguments" }
    elsif (@_ =  = 1) {  return $self->{"Person::age"}      }
    elsif (@_ =  = 2) {
        carp "age `$age' isn't numeric"   if $age !~ /^\d+/;
        carp "age `$age' is unreasonable" if $age > 150;
        $self->{'Person::age'} = $age;
    }
}

Using the principles outlined in Recipe 12.15, you can provide warnings only when warnings have been requested using warnings::enabled. Once your module has registered its package as a warnings class with use warnings::register, you can write:

if (warnings::enabled("Person") || warnings::enabled("numeric")) {
    carp "age `$age' isn't numeric"   if $age !~ /^\d+/;
    carp "age `$age' is unreasonable" if $age > 150;
}

You could even complain when warnings are in force, but raise an exception if the user hadn't asked for warnings. (Don't be confused by the pointer arrow; it's an indirect function call, not a method invocation.)

my $gripe = warnings::enabled("Person") ? \&carp : \&croak;
$gripe->("age `$age' isn't numeric")   if $age !~ /^\d+/;
$gripe->("age `$age' is unreasonable") if $age > 150;

The Class::Struct module also supports an array representation. Just specify the fields within square brackets instead of curly ones:

struct Family => [head => 'Person', address => '$', members => '@'];

Empirical evidence suggests that selecting the array representation instead of a hash trims between 10% and 50% off the memory consumption of your objects, and up to 33% of the access time. The cost is less informative debugging information and more mental overhead when writing override functions, such as Person::age shown earlier. Choosing an array representation for the object would make it difficult to use inheritance. That's not an issue here, because C-style structures employ the much more easily understood notion of aggregation instead.

The use fields pragma provides the speed and space of arrays with the expressiveness of hashes, and adds compile-time checking of an object's field names.

If all fields are the same type, rather than writing it out this way:

struct Card => {
    name    => '$',
    color   => '$',
    cost    => '$',
    type    => '$',
    release => '$',
    text    => '$',
};

you could use a map to shorten it:

struct Card => { map { $_ => '$' } qw(name color cost type release text) };

Or, if you're a C programmer who prefers to precede the field name with its type, rather than vice versa, just reverse the order:

struct hostent => { reverse qw{
    $ name
    @ aliases
    $ addrtype
    $ length
    @ addr_list
}};

You can even make aliases, in the (dubious) spirit of #define, that allow the same field to be accessed under multiple aliases. In C, you can say:

#define h_type h_addrtype
#define h_addr h_addr_list[0]

In Perl, you might try this:

# make (hostent object)->type( ) same as (hostent object)->addrtype( )
*hostent::type = \&hostent::addrtype;

# make (hostenv object)->addr( ) same as (hostenv object)->addr_list(0)
sub hostent::addr { shift->addr_list(0,@_) }

As you see, you can add methods to a class—or functions to a package—simply by declaring a subroutine in the right namespace. You don't have to be in the file defining the class, subclass it, or do anything fancy and complicated. It might be better to subclass it, however:

package Extra::hostent;
use Net::hostent;
@ISA = qw(hostent);
sub addr {
shift->addr_list(0,@_) }
1;

That one's already available in the standard Net::hostent class, so you needn't bother. Check out that module's source code as a form of inspirational reading. We can't be held responsible for what it inspires you to do, though.

13.5.4. See Also

perltoot(1), perlboot(1), perlobj(1), and perlbot(1); the documentation for the standard Class::Struct module; the source code for the standard Net::hostent module; the documentation for the use fields pragma; the documentation for the Alias module from CPAN; Recipe 13.3

Previous | Home | Next
13.4. Managing Class Data | Book Index | 13.6. Cloning Constructors
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.6. Cloning Constructors

13.6.1. Problem

You want to write a constructor method that might be invoked on an existing object, and if so, to use that object for default values.

13.6.2. Solution

Start your constructor like this:

my $proto  = shift;
my $class  = ref($proto) || $proto;
my $parent = ref($proto) && $proto;

The $class variable will contain the class to bless into, and the $parent variable will either be false, or else the object you're cloning.

13.6.3. Discussion

Sometimes you need another object of the same type as the current one. You could do this:

$ob1 = SomeClass->new( );
# later on
$ob2 = (ref $ob1)->new( );

but that's not very clear. It's clearer to have a single constructor that behaves correctly, regardless of whether its invocant is a class name or an existing object of that class. As a class method, it should return a new object with the default initialization. As an instance method, it should return a new object initialized from the object it was invoked on:

$ob1 = Widget->new( );
$ob2 = $ob1->new( );

Here's a version of new that takes this into consideration:

sub new {
    my $proto  = shift;
    my $class  = ref($proto) || $proto;
    my $parent = ref($proto) && $proto;

    my $self;
    # check whether we're shadowing a new from @ISA
    if (@ISA && $proto->SUPER::can("new") ) {
        $self = $proto->SUPER::new(@_);
    } else {
        $self = {  };
        bless ($self, $class);
    }

    $self->{PARENT}  = $parent;
    $self->{START}   = time( );   # init data fields
    $self->{AGE}     = 0;

    return $self;
}

Initializing doesn't have to mean simply copying values from the parent. If you're writing a linked list or binary tree class, your constructor can return a new object linked into the list or tree, when invoked as an instance method.

13.6.4. See Also

perlobj(1) and Chapter 12 of Programming Perl; Recipe 13.1; Recipe 13.10; Recipe 13.13

Previous | Home | Next
13.5. Using Classes as Structs | Book Index | 13.7. Copy Constructors
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.7. Copy Constructors

13.7.1. Problem

You would like to provide users of your class with a copy method, or you would like to copy an object for which no copy method has been provided by the class.

13.7.2. Solution

Use the dclone( ) function from the standard Storable module.

use Storable qw(dclone);
use Carp;
sub copy {
     my $self = shift;
     croak "can't copy class $self" unless ref $self;
     my $copy = Storable::dclone($self);
     return $copy;
}

13.7.3. Discussion

As described in Recipe 11.12, the Storable module's dclone function will recursively copy (virtually) any data structure. It works on objects, too, correctly giving you back new objects that are appropriately blessed. This assumes that the underlying types are SCALAR, ARRAY, HASH, or CODE refs. Things like GLOB and IO refs won't serialize.

Some classes already provide methods to copy their objects; others do not, not so much out of intent as out of neglect. Consider this:

sub UNIVERSAL::copy {
    my $self = shift;
    unless (ref $self) {
        require Carp;
        Carp::croak("can't copy class $self");
    }
    require Storable;
    my $copy = Storable::dclone($self);
    return $copy;
}

Now all objects can be copied, providing they're of the supported types. Classes that provide their own copy methods are unaffected, but any class that doesn't provide its own copy method will pick up this definition. We placed the require on Storable within the function call itself so that you load Storable only if you actually plan to use it. Likewise, we placed the one for Carp inside the test that will end up using it. By using require, we delay loading until the module is actually needed.

We also avoid use because it would import things into our current package. This could be antisocial. From the previous code snippet, you cannot determine what package you're even in. Just because we've declared a subroutine named copy to be in package UNIVERSAL doesn't mean that the code within that subroutine is in package UNIVERSAL. Rather, it's in whatever package we are currently compiling into.

Some folks would argue that we're being outrageously cavalier by interjecting a function into somebody else's namespace like that—especially into all possible class namespaces, as it's in UNIVERSAL. Cavalier perhaps, but hardly outrageously so; after all, UNIVERSAL is there to be used. It's no holy namespace, sacrosanct against any change. Whether this ends up being a very stupid thing or a very clever thing is not up to Perl to decide, or prevent.

13.7.4. See Also

Recipe 11.12; Recipe 13.9; the documentation for the standard Storable modules; the section on Inheritance in the introduction to this chapter; the section on "UNIVERSAL: The Ultimate Ancestor Class" in Chapter 12 of Programming Perl

Previous | Home | Next
13.6. Cloning Constructors | Book Index | 13.8. Invoking Methods Indirectly
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.8. Invoking Methods Indirectly

13.8.1. Problem

You want to invoke a method by a name that isn't known until runtime.

13.8.2. Solution

Store the method name as a string in a scalar variable and use it where you would use the real method name to the right of the arrow operator:

$methname = "flicker";
$obj->$methname(10);         # invokes $ob->flicker(10);

# invoke three methods on the object, by name
foreach $m ( qw(start run stop) ) {
    $obj->$m( );
}

13.8.3. Discussion

Sometimes you need to invoke a method whose name you've stored somewhere. You can't take the address of a method, but you can store its name. If you have a scalar variable $meth containing the method name, invoke the method on an object $crystal with $crystal->$meth( ).

@methods = qw(name rank serno);
%his_info = map { $_ => $ob->$_( ) } @methods;

# same as this:

%his_info = (
    'name'  => $ob->name( ),
    'rank'  => $ob->rank( ),
    'serno' => $ob->serno( ),
);

If you're desperate to devise a way to get a method's address, you should try to rethink your algorithm. For example, instead of incorrectly taking \$ob->method( ), which simply applies the backslash to that method's return value or values, do this:

my $fnref = sub { $ob->method(@_) };

Now when it's time to invoke that indirectly, you would use:

$fnref->(10, "fred");

and have the closure in turn correctly use the original value of $ob (provided $ob was a lexical variable) that was around when it was created to call:

$ob->method(10, "fred");

This works even if $ob has gone out of scope. This solution is much cleaner.

When using indirect method invocation, it is permitted to store a subroutine reference in the scalar variable instead of a string representing the method name. No verification that the function represents a valid method.

The code reference returned by the UNIVERSAL can method should probably not be used for indirect method invocation on objects other than the one on which it was called, or at least those of the same class. That's because you have no reason to believe that this will be a valid method when applied to an object of an arbitrary class.

For example, this is highly dubious code:

$coderef = $some_object->can("wither");
$other_object->$coderef( );   # wither( ) it even if we shouldn't

That is reasonable only when the two objects are of the same, or compatible, classes. If they were not, and the second did not have a wither method, no exception would be raised, unlike here:

$some_object->wither( );
$other_object->wither( );

Another interesting possibility is to use the strategy outlined in Recipe 12.5 to implement nominally private methods.

my $secret_meth = sub { ... }
sub reg_meth {
    my $self = shift;
    # ... do whatever you want, then
    $self->$secret_meth(@_);
    #
}

Because the lexical variable $secret_meth is scoped to the class module's file, code from outside the class cannot access it, and therefore cannot invoke the closure. However, code that is in the module file can see that scalar, so it can use the code reference with $secret_meth to make an indirect method invocation.

When you use a code reference to invoke a method indirectly, Perl doesn't consult a package or its @ISA at all; it just makes the function call and passes in the invocant in the initial slot. That means these two lines are the same:

$self->$secret_meth(@_);        # indirect method invocation
$secret_meth->($self, @_)       # indirect function call

So if you hadn't shifted the invocant off, but had left it in @_, then you could just make the equivalent dereferenced function call yourself:

sub reg_meth {
    # ... do whatever you want, then
    $secret_meth->(@_);
}

13.8.4. See Also

perlobj(1); Recipe 11.8

Previous | Home | Next
13.7. Copy Constructors | Book Index | 13.9. Determining Subclass Membership
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.9. Determining Subclass Membership

13.9.1. Problem

You want to know whether an object is an instance of a particular class or that class's subclasses. Perhaps you want to decide whether a particular method should be invoked on an arbitrary object.

13.9.2. Solution

Use methods from the special UNIVERSAL class:

$obj->isa("HTTP::Message");                  # as object method
HTTP::Response->isa("HTTP::Message");        # as class method

if ($obj->can("method_name")) { .... }       # check method validity

13.9.3. Discussion

Wouldn't it be convenient if all objects were rooted at some ultimate base class? That way you could give every object common methods without having to add to each @ISA. Well, you can. You don't see it, but Perl pretends there's an extra element at the end of @ISA—the package named UNIVERSAL.

UNIVERSAL has only a few predefined methods, although you are free to add your own. These are built right into your Perl binary, so they don't take extra time to load. Predefined methods include isa, can, and VERSION. All three may be used for both sorts of invocants: classes and objects.

The isa method reports whether its invocant inherits the class name directly or indirectly from the class name supplied as the argument. This saves having to traverse the hierarchy yourself, and is much better than testing with an exact check against the string returned by the ref built-in. You may even supply a basic type that ref might return as an argument, such as SCALAR, ARRAY, HASH, or GLOB.

$has_io = $fd->isa("IO::Handle") || $fd->isa("GLOB");
$itza_handle = IO::Socket->isa("IO::Handle");

Type checks like this are sometimes frowned upon as being too constraining. If you just want to know if a certain method can be invoked against something, it might be better to just try to invoke the method you're hoping will be there instead of checking for the class.

Another possibility is to use another UNIVERSAL method, can. The can method reports whether its string argument is a valid method for its invocant. In fact, it even returns a function reference for that method:

$his_print_method = $obj->can('as_string');

Finally, the VERSION method checks whether the invocant class has a package global called $VERSION that's high enough, as in:

Some_Module->VERSION(3.0);
$his_vers = $obj->VERSION( );

However, we don't usually invoke VERSION ourselves. Remember, in Perl an all-uppercase function name means that the function will be automatically called by Perl in some way. In this case, it happens when you say:

use Some_Module 3.0;

If you wanted to add version checking to your Person class explained earlier, add this to Person.pm:

our $VERSION = "1.01";

Then, in the user code say use Person 1.01; to make sure that you have at least that version number or higher available. This is not the same as loading in that exact version number; it just has to be at least that high. Lamentably, no mechanism for concurrent installation of multiple versions of a module yet exists.

13.9.4. See Also

The documentation for the standard UNIVERSAL module; the use keyword in perlfunc(1) and in Chapter 11 of Programming Perl

Previous | Home | Next
13.8. Invoking Methods Indirectly | Book Index | 13.10. Writing an Inheritable Class
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.10. Writing an Inheritable Class

13.10.1. Problem

You're not sure whether you've designed your class robustly enough to be inherited.

13.10.2. Solution

Use the "empty subclass test" on your class.

13.10.3. Discussion

Imagine you've implemented a class named Person that supplies a constructor named new, and methods such as age and name. Here's the straightforward implementation:

package Person;
sub new {
    my $class = shift;
    my $self  = { };
    return bless $self, $class;
}
sub name {
    my $self = shift;
    $self->{NAME} = shift if @_;
    return $self->{NAME};
}
sub age {
    my $self = shift;
    $self->{AGE} = shift if @_;
    return $self->{AGE};
}

You might use the class in this way:

use Person;
my $dude = Person->new( );
$dude->name("Jason");
$dude->age(23);
printf "%s is age %d.\n", $dude->name, $dude->age;

Now consider another class, the one named Employee:

package Employee;
use Person;
@ISA = ("Person");
1;

There's not a lot to that one. All it's doing is loading in class Person and stating that Employee will inherit any needed methods from Person. Since Employee has no methods of its own, it will get all of its methods from Person. We rely upon an Employee to behave just like a Person.

Setting up an empty class like this is called the empty base class test; that is, it creates a derived class that does nothing but inherit from a base class. If the original base class has been designed properly, then the new derived class can be used as a drop-in replacement for the old one. This means you should be able to change just the class name and everything will still work:

use Employee;
my $empl = Employee->new( );
$empl->name("Jason");
$empl->age(23);
printf "%s is age %d.\n", $empl->name, $empl->age;

By proper design, we mean using only the two-argument form of bless, avoiding any direct access of class data, and exporting nothing. In the Person::new( ) function defined previously, we were careful to do these things. We use some package data in the constructor, but the reference to this is stored on the object itself. Other methods access package data via that reference, so we should be okay.

Why did we say the Person::new function—is that not actually a method? A method is just a function that expects its first argument to be a class name (package) or object (blessed reference). Person::new is the function that the Person->new method and the Employee->new method both end up calling. (See Table 13-1.) Although method invocation looks a lot like a function call, they aren't the same. If you treat them as the same, very soon you'll be left with nothing but broken programs. First, the actual underlying calling conventions are different: methods get an extra argument. Second, function calls don't do inheritance, but methods do.

Table 13-1. Mapping methods to functions

Method call | Resulting function call
Person->new( ) | Person::new("Person")
Employee->new( ) | Person::new("Employee")

If you got in the habit of calling:

$him = Person::new( );               # WRONG

you'd have a subtle problem, because the function wouldn't get an argument of "Person" as it is expecting, and so it couldn't bless into the passed-in class. Still worse, you'd probably want to try to call Employee::new also. But there is no such function! It's just an inherited method.

So, don't call a function when you mean to invoke a method.

13.10.4. See Also

perltoot(1), perlobj(1), and perlbot(1); Chapter 13 of Programming Perl; Recipe 13.1; Recipe 13.11

Previous | Home | Next
13.9. Determining Subclass Membership | Book Index | 13.11. Accessing Overridden Methods
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.11. Accessing Overridden Methods

13.11.1. Problem

Your class's constructor method overrides the constructor of its parent class. You want your constructor to invoke the parent class's constructor.

13.11.2. Solution

Learn about the special pseudoclass, SUPER.

sub meth {
    my $self = shift;
    $self->SUPER::meth( );
}

13.11.3. Discussion

In languages like C++ where constructors don't actually allocate memory but just initialize the object, all base class constructors are automatically invoked for you. In languages like Java and Perl, you have to invoke them yourself.

To invoke a method in a particular class, the notation $self->SUPER::meth( ) is used. This is an extension of the regular notation that means to begin searching for a method in a particular class. It is valid only from within an overridden method. Here's a comparison of styles:

$self->meth( );                # Call wherever first meth is found
$self->Where::meth( );         # Start looking in package "Where"
$self->SUPER::meth( );         # Call overridden version

Simple users of the class should probably restrict themselves to the first line in the previous example. The second is possible, but not suggested for this situation, because we have the special notation shown in the third line, which only works within the overridden method.

An overriding constructor should invoke its SUPER's constructor to allocate and bless the object, limiting itself to instantiating any data fields needed. It makes sense here to separate the object allocation code from the object initialization code for reasons that will become clear a couple paragraphs from now. We'll name it with a leading underscore, a convention indicating a nominally private method. Think of it as a "Do Not Disturb" sign.

sub new {
    my $classname  = shift;         # What class are we constructing?
    my $self       = $classname->SUPER::new(@_);
    $self->_init(@_);
    return $self;                   # And give it back
}

sub _init {
    my $self = shift;
    $self->{START}   = time( );   # init data fields
    $self->{AGE}     = 0;
    $self->{EXTRA}   = { @_ };   # anything extra
}

Both SUPER::new and _init are invoked with any remaining arguments. That way the user might pass other field initializers in, as in:

$obj = Widget->new( haircolor => red, freckles => 121 );

Whether you store these user parameters in their own extra hash is up to you.

Note that SUPER works only on the first overridden method. If your @ISA array has several classes, there could be several. A manual traversal of @ISA is possible, but seldom worth the hassle.

my $self = bless {  }, $class;
for my $class (@ISA) {
    my $meth = $class . "::_init";
    $self->$meth(@_) if $class->can("_init");
}

This fragile code assumes that all superclasses initialize their objects with _init instead of initializing in the constructor. It also assumes that a hash reference is used for the underlying object.

For a slightly more general approach to accessing all overridden methods, save the return value from the can( ) method, which is the code reference to the subroutine that would be invoked through normal method invocation. Then use that reference for indirect method invocation.

sub some_method {
    my $self = shift;
    my %seen;
    print "some_method($self): checking all ancestors\n";
    for my $parent (our @ISA) {
        if (my $code = $parent->can("some_method")) {
            $self->$code(@_) unless $seen{$code}++;
        }
    }
}

To avoid calling the same subroutine more than once, the %seen hash keeps track of which subroutines have been called. This could happen if several parent classes shared a common ancestor.

Methods that would trigger an AUTOLOAD will not be accurately reported unless that package has declared (but not defined) the subroutines it wishes to have autoloaded.

13.11.4. See Also

The discussion on the SUPER class in perltoot(1) and perlobj(1), and in the section on "Method Invocation" in Chapter 12 of Programming Perl

Previous | Home | Next
13.10. Writing an Inheritable Class | Book Index | 13.12. Generating Attribute Methods Using AUTOLOAD
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.12. Generating Attribute Methods Using AUTOLOAD

13.12.1. Problem

Your object needs accessor methods to set or get its data fields, and you're tired of writing them all out one at a time.

13.12.2. Solution

Carefully use Perl's AUTOLOAD mechanism as something of a proxy method generator so you don't have to create them all yourself each time you want to add a new data field.

13.12.3. Discussion

Perl's AUTOLOAD mechanism intercepts all possible undefined method invocations. To disallow arbitrary data names, we store the list of permitted fields in a hash. The AUTOLOAD method checks for whether the accessed field name is in that hash.

package Person;
use strict;
use Carp;
our(%ok_field);

# Authorize four attribute fields
for my $attr ( qw(name age peers parent) ) { $ok_field{$attr}++; }

sub AUTOLOAD {
    my $self = shift;
    my $attr = our $AUTOLOAD;
    $attr =~ s/.*:://;
    return unless $attr =~ /[^A-Z]/;  # skip DESTROY and all-cap methods
    croak "invalid attribute method: ->$attr( )" unless $ok_field{$attr};
    $self->{uc $attr} = shift if @_;
    return $self->{uc $attr};
}
sub new {
    my $proto  = shift;
    my $class  = ref($proto) || $proto;
    my $parent = ref($proto) && $proto;
    my $self = {  };
    bless($self, $class);
    $self->parent($parent);
    return $self;
}
1;

This class supports a constructor method named new, plus four attribute methods: name, age, peers, and parent. Use the module this way:

use Person;
my ($dad, $kid);
$dad = Person->new;
$dad->name("Jason");
$dad->age(23);
$kid = $dad->new;
$kid->name("Rachel");
$kid->age(2);
printf "Kid's parent is %s\n", $kid->parent->name;
Kid's parent is Jason

This is tricky when producing inheritance trees. Suppose you'd like an Employee class that had every data attribute of the Person class, plus two new ones, like salary and boss. Class Employee can't rely upon an inherited Person::AUTOLOAD to determine what Employee's attribute methods are. So each class would need its own AUTOLOAD function. This would check just that class's known attribute fields, but instead of croaking when incorrectly triggered, it would invoke overridden superclass version.

Here's a version that takes this into consideration:

sub AUTOLOAD {
    my $self = shift;
    my $attr = our $AUTOLOAD;
    $attr =~ s/.*:://;
    return if $attr eq "DESTROY";

    if ($ok_field{$attr}) {
        $self->{uc $attr} = shift if @_;
        return $self->{uc $attr};
    } else {
        my $superior = "SUPER::$attr";
        $self->$superior(@_);
    }
}

If the attribute isn't in our OK list, we'll pass it up to our superior, hoping that it can cope with it. But you can't inherit this AUTOLOAD; each class has to have its own, because it is unwisely accessing class data directly, not through the object. Even worse, if a class A inherits from two classes B and C, both of which define their own AUTOLOAD, an undefined method invoked on A will hit the AUTOLOAD in only one of the two parent classes.

We could try to cope with these limitations, but AUTOLOAD eventually begins to feel like a kludge piled on a hack piled on a workaround. There are better approaches for the more complex situations.

One further proviso: the UNIVERSAL::can method will not normally report as invokable a method that would only trigger a class's AUTOLOAD. If you prefer that it do so, declare the methods without defining them. For example:

sub eat;
sub drink;
sub be_merry;
sub AUTOLOAD  {
    my $self = shift;
    my $funcname = our $AUTOLOAD;
    $funcname =~ s/.*:://;
    ...
}

You don't normally need to declare functions to trigger AUTOLOAD. If you had an object of that class:

$man->be_merry( );

the AUTOLOAD would still trigger, even without the declarations. However, you need the declarations to make the can method notice them:

$man->be_merry( ) if $man->can("be_merry");

13.12.4. See Also

The examples using AUTOLOAD in perltoot(1); Chapter 10 of Programming Perl; Recipe 10.15

Previous | Home | Next
13.11. Accessing Overridden Methods | Book Index | 13.13. Coping with Circular Data Structures Using Objects
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.13. Coping with Circular Data Structures Using Objects

13.13.1. Problem

You have an inherently self-referential data structure, so Perl's reference-based garbage collection system won't notice when it's no longer being used. You want to prevent your program from leaking memory.

13.13.2. Solution

Create a non-circular container object that holds a pointer to the self-referential data structure. Define a DESTROY method for the containing object's class that manually breaks the self-referential circularities.

Or use weak references, as described in Recipe 11.15.

13.13.3. Discussion

Many interesting data structures include references back to themselves. This can occur in code as simple as this:

$node->{NEXT} = $node;

As soon as you do that, you've created a circularity that will hide the data structure from Perl's referenced-based garbage collection system. Destructors will eventually be invoked when your program exits, but sometimes you don't want to wait that long.

A circular linked list is similarly self-referential. Each node contains a front pointer, a back pointer, and the node's value. If you implement it with references in Perl, you get a circular set of references and the data structure won't be automatically garbage collected when there are no external references to its nodes.

Making each node an instance of class Ring doesn't solve the problem. What you want is for Perl to clean up this structure as it would any other structure—which it will do if you implement your object as a structure that contains a reference to the real circle. That reference will be stored in the "DUMMY" field:

package Ring;

# return an empty ring structure
sub new {
    my $class = shift;
    my $node  = { };
    $node->{NEXT} = $node->{PREV} = $node;
    my $self  = { DUMMY => $node, COUNT => 0 };
    bless $self, $class;
    return $self;
}

It's the nodes contained in the ring that are circular, not the returned ring object itself. That means code like the following won't cause a memory leak:

use Ring;

$COUNT = 1000;
for (1 .. 20) {
    my $r = Ring->new( );
    for ($i = 0; $i < $COUNT; $i++) { $r->insert($i) }
}

Even though we create 20 rings of 1,000 nodes each, each ring is thrown away before a new one is created. The user of the class need do no more to free the ring's memory than they would to free a string's memory. That is, this all happens automatically, just as it's supposed to.

However, the implementer of the class does have to have a destructor for the ring, one that will manually delete the nodes:

# when a Ring is destroyed, destroy the ring structure it contains
sub DESTROY {
    my $ring = shift;
    my $node;
    for ( $node  =  $ring->{DUMMY}->{NEXT};
          $node !=  $ring->{DUMMY};
          $node  =  $node->{NEXT} )
    {
             $ring->delete_node($node);
    }
    $node->{PREV} = $node->{NEXT} = undef;
}

# delete a node from the ring structure
sub delete_node {
    my ($ring, $node) = @_;
    $node->{PREV}->{NEXT} = $node->{NEXT};
    $node->{NEXT}->{PREV} = $node->{PREV};
    --$ring->{COUNT};
}

Here are a few other methods you might like in your Ring class. Notice how the real work lies within the circularity hidden inside the object:

# $node = $ring->search( $value ) : find $value in the ring
# structure in $node
sub search {
    my ($ring, $value) = @_;
    my $node = $ring->{DUMMY}->{NEXT};
    while ($node != $ring->{DUMMY} && $node->{VALUE} != $value) {
          $node = $node->{NEXT};
    }
    return $node;
}

# $ring->insert( $value ) : insert $value into the ring structure
sub insert_value {
    my ($ring, $value) = @_;
    my $node = { VALUE => $value };
    $node->{NEXT} = $ring->{DUMMY}->{NEXT};
    $ring->{DUMMY}->{NEXT}->{PREV} = $node;
    $ring->{DUMMY}->{NEXT} = $node;
    $node->{PREV} = $ring->{DUMMY};
    ++$ring->{COUNT};
}

# $ring->delete_value( $value ) : delete a node from the ring
# structure by value
sub delete_value {
    my ($ring, $value) = @_;
    my $node = $ring->search($value);
    return if $node =  = $ring->{DUMMY};
    $ring->delete_node($node);
}

1;

Here's one for your fortune file: Perl's garbage collector abhors a naked circularity.

In Recipe 11.15, we see an alternate implementation for this same code, one that doesn't involve objects at all. Because it uses weak references for the data structure's own references back to itself, Perl's memory management system suffices to clean up the data structure once it's no longer needed. This obviates the need for a destructor, and therefore even allows the data structure to be constructed using simple reference without recourse to classes or objects.

13.13.4. See Also

The algorithms in both this recipe and Recipe 11.15 derive in part from Introduction to Algorithms, by Cormen, Leiserson, and Rivest (MIT Press/McGraw-Hill); the section on "Garbage Collection, Circular References, and Weak References" in Chapter 8 of Programming Perl; the documentation for the standard Devel::Peek and Scalar::Util modules

Previous | Home | Next
13.12. Generating Attribute Methods Using AUTOLOAD | Book Index | 13.14. Overloading Operators
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.14. Overloading Operators

13.14.1. Problem

You want to use familiar operators like = = or + on objects from a class you've written, or you want to define the print interpolation value for objects.

13.14.2. Solution

Use the use overload pragma. Here are two of the more commonly overloaded operators:

use overload
  '<=>' => \&threeway_compare;

sub threeway_compare {
    my ($s1, $s2) = @_;
    return uc($s1->{NAME}) cmp uc($s2->{NAME});
}

use overload
    '""'  => \&stringify;

sub stringify {
    my $self = shift;
    return sprintf "%s (%05d)",
            ucfirst(lc($self->{NAME})),
            $self->{IDNUM};
}

13.14.3. Discussion

When you use built-in types, certain operators apply, like + for addition or . for string concatenation. With the use overload pragma, you can customize these operators so they do something special on your own objects.

This pragma takes a list of operator/function call pairs, such as:

package TimeNumber;
use overload         '+' => \&my_plus,
                     '-' => \&my_minus,
                     '*' => \&my_star,
                     '/' => \&my_slash;

Those four operators can now be used with objects of class TimeNumber, and the listed functions will be called as method invocations. These functions can do anything you'd like.

Here's a simple example of an overload of + for use with an object that holds hours, minutes, and seconds. It assumes that both operands are of a class that has a new method that can be invoked as an object method, and that the structure names are as shown:

sub my_plus {
    my($left, $right) = @_;
    my $answer = $left->new( );
    $answer->{SECONDS} = $left->{SECONDS} + $right->{SECONDS};
    $answer->{MINUTES} = $left->{MINUTES} + $right->{MINUTES};
    $answer->{HOURS}   = $left->{HOURS}   + $right->{HOURS};

    if ($answer->{SECONDS} >= 60) {
        $answer->{SECONDS} %= 60;
        $answer->{MINUTES} ++;
    }

    if ($answer->{MINUTES} >= 60) {
        $answer->{MINUTES} %= 60;
        $answer->{HOURS}   ++;
    }

    return $answer;

}

It's probably best to overload numeric operators only when the objects themselves are mirroring some sort of inherently numeric construct, such as complex or infinite precision numbers, vectors, or matrices. Otherwise, the code becomes hard to understand and might lead users to invalid assumptions. Imagine a class that modeled a country. If you can add one country to another, couldn't you subtract one country from another? Applying overloaded mathematical operators for non-mathematical objects rapidly becomes ridiculous.

You may compare objects (and, in fact, any reference) using either = = or eq, but this only tells you whether the addresses are the same. (Using = = is about 10 times faster than eq though.) Because an object is a higher-level notion than a raw machine address, you often want to define your own notion of what it takes for two of them to be considered equal.

Two operators frequently overloaded even for a non-numeric class are the comparison and string interpolation operators. Both the <=> and the cmp operators can be overloaded, although the former is more prevalent. Once the spaceship operator <=> is defined for an object, you can use = =, !=, <, <=, >, and >= as well. This lets objects be collated. If ordering is not desired, overload only = =. Similarly, an overloaded cmp is used for lt, gt, and other string comparisons if they aren't explicitly overloaded.

The string interpolation operator goes by the unlikely name of "", that is, two double quotes. This operator is triggered whenever a conversion to a string is called for, such as within double or back quotes or when passed to the print function.

Read the documentation on the overload pragma that comes with Perl or Chapter 13 of Programming Perl. Perl's operator overloading has some elaborate features, such as string, numeric, and Boolean conversion methods, autogeneration of missing methods, and reversing operands if needed, as in 5 + $a where $a is an object.

13.14.4. Example: Overloaded StrNum Class

Here's a StrNum class that lets you use strings with numeric operators. Yes, we're about to do something we advised against—that is, use numeric operators on non-numeric entities—but programmers from other backgrounds are always expecting + and = = to work on strings. This is a simple way to demonstrate operator overloading. We almost certainly wouldn't use this in a time-critical production program due to performance concerns. It's also an interesting illustration of using a constructor of the same name as the class, something that C++ and Python programmers may take some small comfort in.

#!/usr/bin/perl
# show_strnum - demo operator overloading
use StrNum;

$x = StrNum("Red"); $y = StrNum("Black");
$z = $x + $y; $r = $z * 3;
print "values are $x, $y, $z, and $r\n";
print "$x is ", $x < $y ? "LT" : "GE", " $y\n";

values are Red, Black, RedBlack, and RedBlackRedBlackRedBlack
Red is GE Black

The class is shown in Example 13-1.

Example 13-1. StrNum

  package StrNum;
  use Exporter ( );
  @ISA = "Exporter";
  @EXPORT = qw(StrNum);  # unusual
  use overload        (
          '<=>'   => \&spaceship,
          "cmp"   => \&spaceship,
          '""'    => \&stringify,
          "bool"  => \&boolify,
          '0+'    => \&nummify,
          '+'     => \&concat,
          '*'     => \&repeat,
  );
  # constructor
  sub StrNum {
      my ($value) = @_;
      return bless \$value;
  }
  sub stringify { ${ $_[0] } }
  sub nummify    { ${ $_[0] } }
  sub boolify   { ${ $_[0] } }
  # providing <=> gives us <, =  =, etc. for free.
  sub spaceship {
      my ($s1, $s2, $inverted) = @_;
      return $inverted ? $$s2 cmp $$s1 : $$s1 cmp $$s2;
  }
  # this uses stringify
  sub concat {
      my ($s1, $s2, $inverted) = @_;
      return StrNum($inverted ? ($s2 . $s1) : ($s1 . $s2));
  }
  # this uses stringify
  sub repeat {
      my ($s1, $s2, $inverted) = @_;
      return StrNum($inverted ? ($s2 x $s1) : ($s1 x $s2));
  }
  1;

13.14.5. Example: Overloaded FixNum Class

This class uses operator overloading to control the number of decimal places in output. It still uses full precision for its operations. A places method can be used on the class or a particular object to set the number of places of output to the right of the decimal point.

#!/usr/bin/perl
# demo_fixnum - show operator overloading
use FixNum;

FixNum->places(5);

$x = FixNum->new(40);
$y = FixNum->new(12);

print "sum of $x and $y is ", $x + $y, "\n";
print "product of $x and $y is ", $x * $y, "\n";

$z = $x / $y;
printf "$z has %d places\n", $z->places;
$z->places(2) unless $z->places;
print "div of $x by $y is $z\n";
print "square of that is ", $z * $z, "\n";

sum of STRFixNum: 40 and STRFixNum: 12 is STRFixNum: 52
product of STRFixNum: 40 and STRFixNum: 12 is STRFixNum: 480
STRFixNum: 3 has 0 places
div of STRFixNum: 40 by STRFixNum: 12 is STRFixNum: 3.33
square of that is STRFixNum: 11.11

The class itself is shown in Example 13-2. It overloads only the addition, multiplication, and division operations for math operators. Other overloaded operators are the spaceship operator (which handles all comparisons), the string-interpolation operator, and the numeric conversion operator. The string interpolation operator is given a distinctive look for debugging purposes.

Example 13-2. FixNum

  package FixNum;
  use strict;
  my $PLACES = 0;
  sub new {
      my $proto   = shift;
      my $class   = ref($proto) || $proto;
      my $parent  = ref($proto) && $proto;
      my $v = shift;
      my $self = {
          VALUE  => $v,
          PLACES => undef,
      };
      if ($parent && defined $parent->{PLACES}) {
          $self->{PLACES} = $parent->{PLACES};
      } elsif ($v =~ /(\.\d*)/) {
          $self->{PLACES} = length($1) - 1;
      }  else {
          $self->{PLACES} = 0;
      }
      return bless $self, $class;
  }
  sub places {
      my $proto = shift;
      my $self  = ref($proto) && $proto;
      my $type  = ref($proto) || $proto;
      if (@_) {
          my $places = shift;
          ($self ? $self->{PLACES} : $PLACES) = $places;
      }
      return $self ? $self->{PLACES} : $PLACES;
  }
  sub _max { $_[0] > $_[1] ? $_[0] : $_[1] }
  use overload '+'    => \&add,
               '*'    => \&multiply,
               '/'    => \&divide,
               '<=>'  => \&spaceship,
               '""'   => \&as_string,
               '0+'   => \&as_number;
  sub add {
      my ($this, $that, $flipped) = @_;
      my $result = $this->new( $this->{VALUE} + $that->{VALUE} );
      $result->places( _max($this->{PLACES}, $that->{PLACES} ));
      return $result;
  }
  sub multiply {
      my ($this, $that, $flipped) = @_;
      my $result = $this->new( $this->{VALUE} * $that->{VALUE} );
      $result->places( _max($this->{PLACES}, $that->{PLACES} ));
      return $result;
  }
  sub divide {
      my ($this, $that, $flipped) = @_;
      my $result = $this->new( $this->{VALUE} / $that->{VALUE} );
      $result->places( _max($this->{PLACES}, $that->{PLACES} ));
      return $result;
  }
  sub as_string {
      my $self = shift;
      return sprintf("STR%s: %.*f", ref($self),
          defined($self->{PLACES}) ? $self->{PLACES} : $PLACES,
  }
  sub as_number {
      my $self = shift;
      return $self->{VALUE};
  }
  sub spaceship {
      my ($this, $that, $flipped) = @_;
      $this->{VALUE} <=> $that->{VALUE};
  }
  1;

13.14.6. See Also

The documentation for the standard overload, bigint, and bigrat pragmata and the standard Math::BigInt, Math::BigFloat, and Math::Complex modules; also Chapters 13, 31, and 32 of Programming Perl

Previous | Home | Next
13.13. Coping with Circular Data Structures Using Objects | Book Index | 13.15. Creating Magic Variables with tie
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.15. Creating Magic Variables with tie

13.15.1. Problem

You want to add special processing to a variable or handle.

13.15.2. Solution

Use the tie function to give your ordinary variables object hooks.

13.15.3. Discussion

Anyone who's ever used a DBM file under Perl has already used tied objects. Perhaps the most excellent way of using objects is such that the user need never notice them. With tie, you can bind a variable or handle to a class, after which all access to the tied variable or handle is transparently intercepted by specially named object methods (see Table 13-2).

The most important tie methods are FETCH to intercept read access, STORE to intercept write access, and the constructor, which is one of TIESCALAR, TIEARRAY, TIEHASH, or TIEHANDLE.

Table 13-2. How tied variables are interpreted

User code | Executed code
tie $s, "SomeClass" | SomeClass->TIESCALAR( )
$p = $s | $p = $obj->FETCH( )
$s = 10 | $obj->STORE(10)

Where did that $obj come from? The tie triggers an invocation of the class's TIESCALAR constructor method. Perl squirrels away the object returned and surreptitiously uses it for later access.

Here's a simple example of a tie class that implements a value ring. Every time the variable is read from, the next value on the ring is displayed. When it's written to, a new value is pushed on the ring. Here's an example:

#!/usr/bin/perl
# demo_valuering - show tie class
use ValueRing;
tie $color, "ValueRing", qw(red blue);
print "$color $color $color $color $color $color\n";
red blue red blue red blue

$color = "green";
print "$color $color $color $color $color $color\n";
green red blue green red blue

The simple implementation is shown in Example 13-3.

Example 13-3. ValueRing

  package ValueRing;
  # this is the constructor for scalar ties
  sub TIESCALAR {
      my ($class, @values) = @_;
      bless  \@values, $class;
      return \@values;
  }
  # this intercepts read accesses
  sub FETCH {
      my $self = shift;
      push(@$self, shift(@$self));
      return $self->[-1];
  }
  # this intercepts write accesses
  sub STORE {
      my ($self, $value) = @_;
      unshift @$self, $value;
      return $value;
  }
  1;

This example might not be compelling, but it illustrates how easy it is to write ties of arbitrary complexity. To the user, $color is just a plain old variable, not an object. All the magic is hidden beneath the tie. You don't have to use a scalar reference just because you're tying a scalar. Here we've used an array reference, but you can use anything you'd like. Usually a hash reference will be used no matter what's being tied because hashes provide the most flexible object representation.

For arrays and hashes, more elaborate operations are possible. Because so many object methods are needed to fully support tied variables (except perhaps for scalars), most users choose to inherit from standard modules that provide base class definitions of customary methods for operations on that variable type. They then selectively override only those whose behaviors they wish to alter.

These four modules are Tie::Scalar, Tie::Array, Tie::Hash, and Tie::Handle. Each module provides two different classes: a bare-bones class by the name of the module itself, as well as a more fleshed out class named Tie::StdTYPE, where TYPE is one of the four types.

Following are numerous examples of interesting uses of ties.

13.15.4. Tie Example: Outlaw $_

This curious tie class is used to outlaw unlocalized uses of the implicit variable, $_. Instead of pulling it in with use, which implicitly invokes the class's import( ) method, this one should be loaded with no to call invoke the seldom-used unimport( ) method. The user says:

no UnderScore;

Then, all uses of the unlocalized global $_ will raise an exception.

Here's a little test suite for the module:

#!/usr/bin/perl
#nounder_demo - show how to ban $_ from your program
no UnderScore;
@tests = (
    "Assignment"  => sub { $_ = "Bad" },
    "Reading"     => sub { print },
    "Matching"    => sub { $x = /badness/ },
    "Chop"        => sub { chop },
    "Filetest"    => sub { -x },
    "Nesting"     => sub { for (1..3) { print } },
);

while ( ($name, $code) = splice(@tests, 0, 2) ) {
    print "Testing $name: ";
    eval { &$code };
    print $@ ? "detected" : "missed!";
    print "\n";
}

The result is the following:

Testing Assignment: detected
Testing Reading: detected
Testing Matching: detected
Testing Chop: detected
Testing Filetest: detected
Testing Nesting: 123missed!

The reason the last one was missed is that it was properly localized by the for loop, so it was considered safe.

The UnderScore module itself is shown in Example 13-4. Notice how small it is. The module itself does the tie in its initialization code.

Example 13-4. UnderScore

  package UnderScore;
  use Carp;
  sub TIESCALAR {
      my $class = shift;
      my $dummy;
      return bless \$dummy => $class;
  }
  sub FETCH { croak "Read access to \$_ forbidden"  }
  sub STORE { croak "Write access to \$_ forbidden" }
  sub unimport { tie($_, _ _PACKAGE_ _) }
  sub import { untie $_ }
  tie($_, _ _PACKAGE_ _) unless tied $_;
  1;

You can't usefully mix calls to use and no for this class in your program, because they all happen at compile time, not runtime. To renege and let yourself use $_ again, local ize it.

13.15.5. Tie Example: Make a Hash That Always Appends

The class shown here produces a hash whose keys accumulate in an array.

#!/usr/bin/perl
#appendhash_demo - show magic hash that autoappends
use Tie::AppendHash;
tie %tab, "Tie::AppendHash";

$tab{beer} = "guinness";
$tab{food} = "potatoes";
$tab{food} = "peas";

while (my($k, $v) = each %tab) {
    print "$k => [@$v]\n";
}

Here is the result:

food => [potatoes peas]
beer => [guinness]

To make this class easy, we use the boilerplate hash tying module from the standard distribution, shown in Example 13-5. To do this, we load the Tie::Hash module and then inherit from the Tie::StdHash class. (Yes, those are different names. The file Tie/Hash.pm provides both the Tie::Hash and Tie::StdHash classes, which are slightly different.)

Example 13-5. Tie::AppendHash

  package Tie::AppendHash;
  use strict;
  use Tie::Hash;
  use Carp;
  our @ISA = qw(Tie::StdHash);
  sub STORE {
      my ($self, $key, $value) = @_;
      push @{$self->{$key}}, $value;
  }
  1;

13.15.6. Tie Example: Case-Insensitive Hash

Here's a fancier hash tie called Tie::Folded. It provides a hash with case-insensitive keys.

#!/usr/bin/perl
#folded_demo - demo hash that magically folds case
use Tie::Folded;
tie %tab, "Tie::Folded";

$tab{VILLAIN}  = "big ";
$tab{herOine}  = "red riding hood";
$tab{villain} .= "bad wolf";

while ( my($k, $v) = each %tab ) {
    print "$k is $v\n";
}

The following is the output of this demo program:

heroine is red riding hood
villain is big bad wolf

Because we have to trap more accesses, the class in Example 13-6 is slightly more complicated than the one in Example 13-5.

Example 13-6. Tie::Folded

  package Tie::Folded;
  use strict;
  use Tie::Hash;
  our @ISA = qw(Tie::StdHash);
  sub STORE {
      my ($self, $key, $value) = @_;
      return $self->{lc $key} = $value;
      }
  sub FETCH {
      my ($self, $key) = @_;
      return $self->{lc $key};
  }
  sub EXISTS {
      my ($self, $key) = @_;
      return exists $self->{lc $key};
  }
  sub DEFINED {
      my ($self, $key) = @_;
      return defined $self->{lc $key};
  }
  1;

13.15.7. Tie Example: Hash That Allows Lookups by Key or Value

Here is a hash that lets you look up members by key or by value. It does this by having a store method that uses not only the key to store the value, but also uses the value to store the key.

Normally there could be a problem if the value being stored were a reference, since you can't normally use a reference as a key. The standard distribution comes with the Tie::RefHash class that avoids this problem. We'll inherit from it so that we can also avoid this difficulty.

#!/usr/bin/perl -w
#revhash_demo - show hash that permits key *or* value lookups
use strict;
use Tie::RevHash;
my %tab;
tie %tab, "Tie::RevHash";
%tab = qw{
    Red         Rojo
    Blue        Azul
    Green       Verde
};
$tab{EVIL} = [ "No way!", "Way!!" ];

while ( my($k, $v) = each %tab ) {
    print ref($k) ? "[@$k]" : $k, " => ",
        ref($v) ? "[@$v]" : $v, "\n";
}

When run, revhash_demo produces this:

[No way! Way!!] => EVIL
EVIL => [No way! Way!!]
Blue => Azul
Green => Verde
Rojo => Red
Red => Rojo
Azul => Blue
Verde => Green

The module is shown in Example 13-7. Notice how small it is!

Example 13-7. Tie::RevHash

  package Tie::RevHash;
  use Tie::RefHash;
  our @ISA = qw(Tie::RefHash);
  sub STORE {
      my ($self, $key, $value) = @_;
      $self->SUPER::STORE($key, $value);
      $self->SUPER::STORE($value, $key);
  }
  sub DELETE {
      my ($self, $key) = @_;
      my $value = $self->SUPER::FETCH($key);
      $self->SUPER::DELETE($key);
      $self->SUPER::DELETE($value);
  }
  1;

13.15.8. Tie Example: Handle That Counts Access

Here's an example of tying a filehandle:

use Counter;
tie *CH, "Counter";
while (<CH>) {
    print "Got $_\n";
}

When run, that program keeps printing Got 1, Got 2, and so on until the universe collapses, you hit an interrupt, or your computer reboots, whichever comes first. Its simple implementation is shown in Example 13-8.

Example 13-8. Counter

  package Counter;
  sub TIEHANDLE {
      my $class = shift;
      my $start = shift;
      return bless \$start => $class;
  }
  sub READLINE {
      my $self = shift;
      return ++$$self;
  }
  1;

13.15.9. Tie Example: Multiple Sink Filehandles

Finally, here's an example of a tied handle that implements a tee-like functionality by twinning standard out and standard error:

use Tie::Tee;
tie *TEE, "Tie::Tee", *STDOUT, *STDERR;
print TEE "This line goes both places.\n";

Or, more elaborately:

#!/usr/bin/perl
# demo_tietee
use Tie::Tee;
use Symbol;

@handles = (*STDOUT);
for $i ( 1 .. 10 ) {
    push(@handles, $handle = gensym( ));
    open($handle, ">/tmp/teetest.$i");
}

tie *TEE, "Tie::Tee", @handles;
print TEE "This lines goes many places.\n";

The Tie/Tee.pm file is shown in Example 13-9.

Example 13-9. Tie::Tee

  package Tie::Tee;
  sub TIEHANDLE {
      my $class   = shift;
      my $handles = [@_];
      bless $handles, $class;
      return $handles;
  }
  sub PRINT {
      my $href = shift;
      my $handle;
      my $success = 0;
      foreach $handle (@$href) {
          $success += print $handle @_;
      }
      return $success =  = @$href;
  }
  1;

13.15.10. See Also

The tie function in perlfunc(1); perltie(1); Chapter 14 of Programming Perl

Previous | Home | Next
13.14. Overloading Operators | Book Index | 14. Database Access
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 14. Database Access

Contents:

Introduction
Making and Using a DBM File
Emptying a DBM File
Converting Between DBM Files
Merging DBM Files
Sorting Large DBM Files
Storing Complex Data in a DBM File
Persistent Data
Saving Query Results to Excel or CSV
Executing an SQL Command Using DBI
Escaping Quotes
Dealing with Database Errors
Repeating Queries Efficiently
Building Queries Programmatically
Finding the Number of Rows Returned by a Query
Using Transactions
Viewing Data One Page at a Time
Querying a CSV File with SQL
Using SQL Without a Database Server
Program: ggh—Grep Netscape Global History

Charles Dickens, David Copperfield

I only ask for information.

14.0. Introduction

Everywhere you find data, you find databases. At the simplest level, every file can be considered a database. At the most complex level, expensive and complex relational database systems handle thousands of transactions per second. In between are countless improvised schemes for fast access to loosely structured data. Perl can work with all of them.

Early in the history of computers, people noticed that flat file databases don't scale to large data sets. Flat files were tamed using fixed-length records or auxiliary indices, but updating became expensive, and previously simple applications bogged down with I/O overhead.

After some head-scratching, clever programmers devised a better solution. As hashes in memory provide more flexible access to data than do arrays, hashes on disk offer more convenient kinds of access than array-like text files. These benefits in access time cost you space, but disk space is cheap these days (or so the reasoning goes).

The DBM library gives Perl programmers a simple, easy-to-use database. You use the same standard operations on hashes bound to DBM files as you do on hashes in memory. In fact, that's how you use DBM databases from Perl. You use tie to associate a hash with a class and a file. Then whenever you access the hash, the class consults or changes the DBM database on disk. The old dbmopen function also did this, but only let you use one DBM implementation in your program, so you couldn't copy from one format to another.

Recipe 14.1 shows how to create a DBM database and gives tips on using it efficiently. Although you can do with DBM files the same things you do with regular hashes, their disk-based nature leads to performance concerns that don't exist with in-memory hashes. Because DBM files are disk-based and can be shared between processors, use a sentinel lock file (see Recipe 7.24) to regulate concurrent access to them.Recipes Recipe 14.2 and Recipe 14.4 explain these concerns and show how to work around them. DBM files also make possible operations that aren't available using regular hashes. Recipe 14.5 explains two of these things.

Various DBM implementations offer varying features. Table 14-1 shows several possible DBM libraries you can choose from.

Table 14-1. DBM libraries and their features

Feature | NDBM | SDBM | GDBM | DB
Linkage comes with Perl | yes | yes | yes | yes
Source bundled with Perl | no | yes | no | no
Source redistributable | no | yes | gpl[25] | yes
FTPable | no | yes | yes | yes
Easy to build | N/A | yes | yes | ok[26]
Often comes with Unix | yes[27] | no | no[28] | no[28]
Builds okay on Unix | N/A | yes | yes | yes[29]
Builds okay on Windows | N/A | yes | yes | yes[30]
Code size | [31] | small | big | big[32]
Disk usage | [31] | small | big | ok
Speed | [31] | slow | ok | fast
Block size limits | 4k | 1k[33] | none | none
Byte-order independent | no | no | no | yes
User-defined sort order | no | no | no | yes
Partial key lookups | no | no | no | yes

[25]Using GPLed code in your program places restrictions upon you. See http://www.gnu.org for more details.

[26]See the DB_File library method. Requires symbolic links.

[27]On mixed-universe machines, this may be in the BSD compatibility library, which is often shunned.

[28]Except for free Unix ports such as Linux, FreeBSD, versions of Perl on Windows systems were widely available, including the standard port build from the normal Perl distribution and several proprietary ports. Like most CPAN modules, DB builds only on the standard port.

[31]Depends on how much your vendor has tweaked it.

[32]Can be reduced if you compile for one access of compatibility with older files).

NDBM comes with most BSD-derived machines. GDBM is a GNU DBM implementation. SDBM is part of the X11 distribution and also the standard Perl source distribution. DB refers to the Berkeley DB library. While the others are essentially reimplementations of the original DB library, the Berkeley DB code gives you three different types of database on disk and attempts to solve many of the disk, speed, and size limitations that hinder the other implementations.

Code size refers to the size of the compiled libraries. Disk usage refers to the size of the database files it creates. Block size limits refer to the database's maximum key or value size. Byte-order independence refers to whether the database system relies on hardware byte order or whether it instead creates portable files. A user-defined sort order lets you tell the library in what order to return lists of keys. Partial key lookups let you make approximate searches on the database.

Most Perl programmers prefer the Berkeley DB implementations. Many systems already have this library installed, and Perl can use it. For others, you are advised to fetch and install it from CPAN. It will make your life much easier.

DBM files provide key/value pairs. In relational database terms, you get a database with one table that has only two columns. Recipe 14.6 shows you how to use the MLDBM module from CPAN to store arbitrarily complex data structures in a DBM file.

As good as MLDBM is, it doesn't get around the limitation that you only retrieve rows based on one single column, the hash key. If you need complex queries, the difficulties can be overwhelming. In these cases, consider a separate database management system (DBMS). The DBI project provides modules to work with Oracle, Sybase, mSQL, MySQL, Ingres, and others.

An interesting medium between a full relational database server and a DBM file is the DBD::SQLite module. This provides an SQL interface to a relational database, but without a server process—the module reads and writes the single file that contains all your tables. This gives you the power of SQL and multiple tables without the inconvenience of RDBMS administration. A benefit of manipulating tables from the one process is a considerable gain in speed.

See http://dbi.perl.org/doc/index.html and http://search.cpan.org/modlist/Database_Interfaces. DBI supports most major and minor databases, including Oracle, ODBC, Sybase, Informix, MySQL, PostgreSQL, and XBase. There are also DBD interfaces to data sources such as SQLite, Excel files, and CSV files.

Previous | Home | Next
13.15. Creating Magic Variables with tie | Book Index | 14.1. Making and Using a DBM File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.1. Making and Using a DBM File

14.1.1. Problem

You want to create, populate, inspect, or delete values in a DBM database.

14.1.2. Solution

Use tie to open the database and make it accessible through a hash. Then use the hash as you normally would. When you're done, call untie:

use DB_File;             # load database module

tie %HASH, "DB_File", $FILENAME                # open database to be accessed
    or die "Can't open $FILENAME:$!\n";        # through %HASH

$V = $HASH{$KEY};                              # retrieve from database
$HASH{$KEY} = $VALUE;                          # put value into database
if (exists $HASH{$KEY}) {                      # check whether in database
    # ...
}
delete $HASH{$KEY};                            # delete from database
untie %HASH;                                   # close the database

14.1.3. Discussion

Accessing a database as a hash is powerful but easy, giving you a persistent hash that sticks around after the program using it has finished running. It's also much faster than loading in a new hash every time; even if the hash has a million entries, your program starts up virtually instantaneously.

The program in Example 14-1 treats the database as though it were a normal hash. You can even call keys or each on it. Likewise, exists and defined are implemented for tied DBM hashes. Unlike a normal hash, a DBM hash does not distinguish between those two functions.

Example 14-1. userstats

  #!/usr/bin/perl -w
  # userstats - generates statistics on who is logged in.
  # call with an argument to display totals

  use DB_File;

  $db = "/tmp/userstats.db";       # where data is kept between runs

  tie(%db, 'DB_File', $db)         or die "Can't open DB_File $db : $!\n";

  if (@ARGV) {
      if ("@ARGV" eq "ALL") {
          @ARGV = sort keys %db;
      }
      foreach $user (@ARGV) {
              print "$user\t$db{$user}\n";
      }
  } else {
      @who = `who`;                                   # run who(1)
      if ($?) {
          die "Couldn't run who: $?\n";               # exited abnormally
      }
      # extract username (first thing on the line) and update
      foreach $line (@who) {
          $line =~ /^(\S+)/;
          die "Bad line from who: $line\n" unless $1;
          $db{$1}++;
      }
  }

  untie %db;

We use who to get a list of users logged in. This typically produces output like:

gnat     ttyp1   May 29 15:39   (coprolith.frii.com)

If the userstats program is called without any arguments, it checks who's logged on and updates the database appropriately.

If the program is called with arguments, these are treated as usernames whose information will be presented. The special argument "ALL" sets @ARGV to a sorted list of DBM keys. For large hashes with many keys, this is prohibitively expensive—a better solution would be to use the BTREE bindings of DB_File described in Recipe 14.5.

The old dbmopen function still works. Here's the solution rewritten to use dbmopen and dbmclose:

use DB_File;                                   # optional; overrides default
dbmopen %HASH, $FILENAME, 0666                 # open database, accessed through %HASH
    or die "Can't open $FILENAME:$!\n";

$V = $HASH{$KEY};                              # retrieve from database
$HASH{$KEY} = $VALUE;                          # put value into database
if (exists $HASH{$KEY}) {                      # check whether in database
    # ...
}
delete $HASH{$KEY};                            # remove from database
dbmclose %HASH;                                # close the database

14.1.4. See Also

The documentation for the standard modules GDBM_File, NDBM_File, SDBM_File, and DB_File, some of which are in Chapter 32 of Programming Perl; perltie(1); Chapter 14 of Programming Perl; the discussion on the effect of your umask on file creation in Recipe 7.1; Recipe 13.15

Previous | Home | Next
14. Database Access | Book Index | 14.2. Emptying a DBM File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.2. Emptying a DBM File

14.2.1. Problem

You want to clear out a DBM file.

14.2.2. Solution

Open the database and assign ( ) to it. Use tie:

use DB_File;

tie(%HASH, "DB_File", $FILENAME)        or die "Can't open FILENAME: $!\n";
%HASH = ( );
untie %HASH;

Alternatively, delete the file and reopen:

unlink $FILENAME
    or die "Couldn't unlink $FILENAME to empty the database: $!\n";
tie(%HASH => "DB_File", $FILENAME)
    or die "Couldn't create $FILENAME database: $!\n";

14.2.3. Discussion

It may be quicker to delete the file and create a new one than to reset it, but doing so opens you up to a race condition that trips up a careless program or makes it vulnerable to an attacker. The attacker could make a link pointing to the file /etc/precious with the same name as your file between the time when you deleted the file and when you recreated it. When the DBM library opens the file, it clobbers /etc/precious.

If you delete a DB_File database and recreate it, you'll lose any customizable settings like page size, fill-factor, and so on. This is another good reason to assign the empty list to the tied hash.

14.2.4. See Also

The documentation for the standard DB_File module, also in Chapter 32 of Programming Perl; the unlink function in perlfunc(1); Recipe 14.1

Previous | Home | Next
14.1. Making and Using a DBM File | Book Index | 14.3. Converting Between DBM Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.3. Converting Between DBM Files

14.3.1. Problem

You have a file in one DBM format, but another program expects input in a different DBM format.

14.3.2. Solution

Read the keys and values from the initial DBM file and write them to a new file in the different DBM format as in Example 14-2.

Example 14-2. db2gdbm

  #!/usr/bin/perl -w
  # db2gdbm: converts DB to GDBM

  use strict;

  use DB_File;
  use GDBM_File;

  unless (@ARGV =  = 2) {
      die "usage: db2gdbm infile outfile\n";
  }

  my ($infile, $outfile) = @ARGV;
  my (%db_in, %db_out);

  # open the files
  tie(%db_in, 'DB_File', $infile)
      or die "Can't tie $infile: $!";
  tie(%db_out, 'GDBM_File', $outfile, GDBM_WRCREAT, 0666)
      or die "Can't tie $outfile: $!";

  # copy (don't use %db_out = %db_in because it's slow on big databases)
  while (my($k, $v) = each %db_in) {
      $db_out{$k} = $v;
  }

  # these unties happen automatically at program exit
  untie %db_in;
  untie %db_out;

Call the program as:

% db2gdbm /tmp/users.db /tmp/users.gdbm

14.3.3. Discussion

When multiple types of DBM file are used in the same program, you have to use tie, not the dbmopen interface. That's because with dbmopen you can use only one database format, which is why its use is deprecated.

Copying hashes by simple assignment, as in %new = %old, works on DBM files. However, it loads everything into memory first as a list, which doesn't matter with small hashes, but can be prohibitively expensive in the case of DBM files. For database hashes, use each to iterate through them instead.

14.3.4. See Also

The documentation for the standard modules GDBM_File, NDBM_File, SDBM_File, DB_File, some of which are in Chapter 32 of Programming Perl; Recipe 14.1

Previous | Home | Next
14.2. Emptying a DBM File | Book Index | 14.4. Merging DBM Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.4. Merging DBM Files

14.4.1. Problem

You want to combine two DBM files into a single DBM file with original key-value pairs.

14.4.2. Solution

Either merge the databases by treating their hashes as lists:

%OUTPUT = (%INPUT1, %INPUT2);

or, more wisely, by iterating over each key-value pair:

%OUTPUT = ( );
foreach $href ( \%INPUT1, \%INPUT2 ) {
    while (my($key, $value) = each(%$href)) {
        if (exists $OUTPUT{$key}) {
            # decide which value to use and set $OUTPUT{$key} if necessary
        } else {
            $OUTPUT{$key} = $value;
        }
    }
}

14.4.3. Discussion

This straightforward application of Recipe 5.11 comes with the same caveats. Merging hashes by treating them as lists requires that the hashes be preloaded into memory, creating a potentially humongous temporary list. If you're dealing with large hashes, have little virtual memory, or both, then you want to iterate over the keys with each to save memory.

Another difference between these merging techniques is what to do if the same key exists in both input databases. The blind assignment merely overwrites the first value with the second value. The iterative merging technique lets you decide what to do. Possibilities include issuing a warning or error, choosing the first over the second, choosing the second over the first, or concatenating the new value to the old one. If you're using the MLDBM module, you can even store them both, using an array reference to the two values.

14.4.4. See Also

Recipe 5.11; Recipe 14.6

Previous | Home | Next
14.3. Converting Between DBM Files | Book Index | 14.5. Sorting Large DBM Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.5. Sorting Large DBM Files

14.5.1. Problem

You want to process a large dataset you'd like to commit to a DBM file in a particular order.

14.5.2. Solution

Use the DB_File's B-tree bindings and supply a comparison function of your own devising:

use DB_File;

# specify the Perl sub to do key comparison using the
# exported $DB_BTREE hash reference
$DB_BTREE->{'compare'} = sub {
    my ($key1, $key2) = @_ ;
    "\L$key1" cmp "\L$key2" ;
};

tie(%hash, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE)
    or die "can't tie $filename: $!";

14.5.3. Description

An annoyance of hashes, whether in memory or as DBM files, is that they do not maintain proper ordering. The CPAN module Tie::IxHash can make a regular hash in memory maintain its insertion order, but that doesn't help for DBM databases or arbitrary sorting criteria.

The DB_File module supports a nice solution to this using a B-tree implementation. One advantage of a B-tree over a regular DBM hash is its ordering. When the user defines a comparison function, all calls to keys, values, and each are automatically ordered. For example, Example 14-3 is a program that maintains a hash whose keys will always be sorted case-insensitively.

Example 14-3. sortdemo

  #!/usr/bin/perl
  #
  sortdemo - show auto dbm sorting
  use strict;
  use DB_File;

  $DB_BTREE->{'compare'} = sub {
      my ($key1, $key2) = @_ ;
      "\L$key1" cmp "\L$key2" ;
  };

  my %hash;
  my $filename = '/tmp/sorthash.db';
  tie(%hash, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE)
      or die "can't tie $filename: $!";

  my $i = 0;
  for my $word (qw(Can't you go camp down by Gibraltar)) {
      $hash{$word} = ++$i;
  }

  while (my($word, $number) = each %hash) {
      printf "%-12s %d\n", $word, $number;
  }

By default, the entries in a B-tree DB_File database are stored alphabetically. Here, though, we provide a case-insensitive comparison function, so using each to fetch all the keys would show:

by           6
camp         4
Can't        1
down         5
Gibraltar    7
go           3
you          2

This sorting property on hashes is so convenient that it's worth using even without a permanent database. If you pass undef where the filename is expected on the tie, DB_File will create a file in /tmp and then immediately unlink it, giving an anonymous database:

tie(%hash, "DB_File", undef, O_RDWR|O_CREAT, 0666, $DB_BTREE)
        or die "can't tie: $!";

Remember these two things if you supply a comparison for your BTREE database. One, the new compare function must be specified when you create the database. Two, you cannot change the ordering once the database has been created; you must use the same compare function every time you access the database.

Using BTREE databases under DB_File also permits duplicate or partial keys. See its documentation for examples.

14.5.4. See Also

Recipe 5.7

Previous | Home | Next
14.4. Merging DBM Files | Book Index | 14.6. Storing Complex Data in a DBM File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.6. Storing Complex Data in a DBM File

14.6.1. Problem

You want values in a DBM file to be something other than scalars. For instance, you use a hash of hashes in your program and want to store them in a DBM file for other programs to access, or you want them to persist across process runs.

14.6.2. Solution

Use the CPAN module MLDBM to store more complex values than strings and numbers.

use MLDBM 'DB_File';
tie(%HASH, 'MLDBM', [... other DBM arguments]) or die $!;

Specify a particular serializing module with:

use MLDBM qw(DB_File Storable);

14.6.3. Discussion

MLDBM uses a serializing module like Storable, Data::Dumper, or FreezeThaw (see Recipe 11.4) to convert data structures to and from strings so that they can be stored in a DBM file. It doesn't store references; instead, it stores the data those references refer to:

# %hash is a tied hash
$hash{"Tom Christiansen"} = [ "book author", 'tchrist@perl.com' ];
$hash{"Tom Boutell"} = [ "shareware author", 'boutell@boutell.com' ];

# names to compare
$name1 = "Tom Christiansen";
$name2 = "Tom Boutell";

$tom1 = $hash{$name1};      # snag local pointer
$tom2 = $hash{$name2};      # and another

print "Two Toming: $tom1 $tom2\n";

Tom Toming: ARRAY(0x73048) ARRAY(0x73e4c)

Each time MLDBM retrieves a data structure from the DBM file, it generates a new copy of that data. To compare data that you retrieve from a MLDBM database, you need to compare the values within the structure:

if ($tom1->[0] eq $tom2->[0] &&
    $tom1->[1] eq $tom2->[1]) {
    print "You're having runtime fun with one Tom made two.\n";
} else {
    print "No two Toms are ever alike.\n";
}

This is more efficient than:

if ($hash{$name1}->[0] eq $hash{$name2}->[0] &&     # INEFFICIENT
    $hash{$name1}->[1] eq $hash{$name2}->[1]) {
    print "You're having runtime fun with one Tom made two.\n";
 } else {
    print "No two Toms are ever alike.\n";
}

Each time we say $hash{...}, the DBM file is consulted. The inefficient code accesses the database four times, whereas the code using the temporary variables $tom1 and $tom2 only accesses the database twice.

Current limitations of Perl's tie mechanism prevent you from storing or modifying parts of a MLDBM value directly:

$hash{"Tom Boutell"}->[0] = "Poet Programmer";      # WRONG

Always get, change, and set pieces of the stored structure through a temporary variable:

$entry = $hash{"Tom Boutell"};                      # RIGHT
$entry->[0] = "Poet Programmer";
$hash{"Tom Boutell"} = $entry;

If MLDBM uses a database with size limits on values, like SDBM, you'll quickly hit those limits. To get around this, use GDBM_File or DB_File, which don't limit the size of keys or values. DB_File is the better choice because it is byte-order neutral, which lets the database be shared between both big- and little-endian architectures.

14.6.4. See Also

The documentation for the standard Data::Dumper and Storable modules; the documentation for the FreezeThaw and MLDBM modules from CPAN; Recipe 11.13; Recipe 14.7

Previous | Home | Next
14.5. Sorting Large DBM Files | Book Index | 14.7. Persistent Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.7. Persistent Data

14.7.1. Problem

You want your variables to retain their values between calls to your program.

14.7.2. Solution

Use a MLDBM to store the values between calls to your program:

use MLDBM "DB_File";

my ($VARIABLE1,$VARIABLE2);
my $Persistent_Store = "/projects/foo/data";
BEGIN {
    my %data;
    tie(%data, "MLDBM", $Persistent_Store)
        or die "Can't tie to $Persistent_Store : $!";
    $VARIABLE1 = $data{VARIABLE1};
    $VARIABLE2 = $data{VARIABLE2};
    # ...
    untie %data;
}
END {
    my %data;
    tie (%data, "MLDBM", $Persistent_Store)
        or die "Can't tie to $Persistent_Store : $!";
    $data{VARIABLE1} = $VARIABLE1;
    $data{VARIABLE2} = $VARIABLE2;
    # ...
    untie %data;
}

14.7.3. Discussion

An important limitation of MLDBM is that you can't add to or alter the structure in the reference without assignment to a temporary variable. We do this in the sample program in Example 14-4, assigning to $array_ref before we push. You can't simply do this:

push(@{$db{$user}}, $duration);

For a start, MLDBM doesn't allow it. Also, $db{$user} might not be in the database (the array reference isn't automatically created as it would be if %db weren't tied to a DBM file). This is why we test exists $db{$user} when we give $array_ref its initial value. We're creating the empty array for the case where it doesn't already exist.

Example 14-4. mldbm-demo

  #!/usr/bin/perl -w
  # mldbm_demo - show how to use MLDBM with DB_File

  use MLDBM "DB_File";

  $db = "/tmp/mldbm-array";

  tie %db, "MLDBM", $db
    or die "Can't open $db : $!";

  while(<DATA>) {
      chomp;
      ($user, $duration) = split(/\s+/, $_);
      $array_ref = exists $db{$user} ? $db{$user} : [  ];
      push(@$array_ref, $duration);
      $db{$user} = $array_ref;
  }

  foreach $user (sort keys %db) {
      print "$user: ";
      $total = 0;
      foreach $duration (@{ $db{$user} }) {
          print "$duration ";
          $total += $duration;
      }
          print "($total)\n";
      }

  _ _END_ _
  gnat        15.3
  tchrist     2.5
  jules       22.1
  tchrist     15.9
  gnat        8.7

Newer versions of MLDBM allow you to select not just the database module (we recommend DB_File), but also the serialization module (we recommend Storable). Early versions limited you to Data::Dumper for serializing, which is slower than Storable. Here's how you use DB_File with Storable:

use MLDBM qw(DB_File Storable);

14.7.4. See Also

The documentation for the standard Data::Dumper and Storable modules; the documentation for the FreezeThaw and MLDBM modules from CPAN; Recipe 11.13; Recipe 14.6

Previous | Home | Next
14.6. Storing Complex Data in a DBM File | Book Index | 14.8. Saving Query Results to Excel or CSV
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.8. Saving Query Results to Excel or CSV

14.8.1. Problem

You want to query a relational database and create a file of the results so that another program or person can use them. The two common formats people want to get data in are CSV and Excel.

14.8.2. Solution

Use the CPAN module DBIx::Dump to dump the statement handle after the query:

use DBIx::Dump;
use DBI;

# ... connect to your database as normal
$sth = $dbh->prepare("SELECT ...");  # your query here
$sth->execute( );

$out = DBIx::Dump->new('format' => $FORMAT,   # excel or csv
                       'output' => $FILENAME, # file to save as
                       'sth'    => $sth);
$out->dump( );

14.8.3. Discussion

The CPAN module DBIx::Dump supports Excel and CSV file formats. It uses the CPAN module Spreadsheet::WriteExcel to write Excel files, and the CPAN module Text::CSV_XS to write CSV files.

The first row in the output files holds the column names. For example:

ID,NAME
1,Nat
2,Tom
4,Larry
5,Damian
6,Jon
7,Dan

14.8.4. See Also

The documentation for the CPAN modules DBIx::Dump, Spreadsheet::WriteExcel, and Text::CSV_XS; Recipe 14.17

Previous | Home | Next
14.7. Persistent Data | Book Index | 14.9. Executing an SQL Command Using DBI
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.9. Executing an SQL Command Using DBI

14.9.1. Problem

You want to send SQL queries to a database system such as Oracle, Sybase, mSQL, or MySQL, and process the results.

14.9.2. Solution

Use the DBI (DataBase Interface) and DBD (DataBase Driver) modules available from CPAN:

use DBI;

$dbh = DBI->connect('dbi:driver:database', 'username', 'auth',
            { RaiseError => 1, AutoCommit => 1});

$dbh->do($NON_SELECT_SQL_STATEMENT);

$results = $dbh->selectall_arrayref($SELECT_SQL_STATEMENT);

$sth = $dbh->prepare($SQL_SELECT_STATEMENT);
$sth->execute( );
while (@row = $sth->fetchrow_array) {
    # ...
}

$dbh->disconnect( );

14.9.3. Discussion

The DBI module abstracts away the different database APIs, offering you a single set of functions for accessing every database. The actual work of connecting to a database, issuing queries, parsing results, etc. is done by a DBD module specific to that database (e.g., DBD::mysql, DBD::Oracle, etc.).

All work with databases via the DBI is done through handles. A handle is simply an object, created by calling DBI->connect. This is attached to a specific database and driver using the DBI->connect call.

The first argument to DBI->connect is a single string with three colon-separated fields. This DSN (Data Source Name) identifies the database you're connecting to. The first field is always dbi (though this is case-insensitive, so DBI will do just as well), and the second is the name of the driver you're going to use (Oracle, mysql, etc.). The rest of the string is passed by the DBI module to the requested driver module (DBD::mysql, for example) where it identifies the database.

The second and third arguments authenticate the user.

The fourth argument is an optional hash reference defining attributes of the connection. PrintError controls whether DBI warns when a DBI method fails (the default is true; setting it to a false value keeps DBI quiet). Setting RaiseError is like PrintError except that die is used instead of warn. AutoCommit controls transactions, and setting it to true says that you don't want to deal with them (see Recipe 14.11).

At the time of this writing, there were DBD modules for all common databases (MySQL, Oracle, PostgreSQL, Informix, DB2, SQLServer), many fringe ones (XBase, SQLite), and several non-databases. For a list, see http://search.cpan.org/modlist/Database_Interfaces/DBD.

Here are some sample DSNs:

dbi:Oracle:tnsname
dbi:Oracle:host=foo.bar.com;sid=ORCL
dbi:Oracle:host=foo.bar.com;sid=ORCL;port=1521
dbi:mysql:database=foo;host=foo.bar.com;port=3306;mysql_compression=1
dbi:Pg:dbname=foo;host=foo.bar.com;options=-F

You can execute simple SQL statements (those that don't return rows of data) with a database handle's do method. This returns Boolean true or false. The quickest way to perform a query that returns rows of data is with the selectall_arrayref and selectall_hashref methods:

$rows = $dbh->selectall_arrayref("SELECT isbn,title,author FROM books");
print $row[0][1];            # prints title from first row

$rows = $dbh->selectall_hashref("SELECT isbn,title,author FROM books", "isbn");
print $rows->{596000278}[2]; # prints "Programming Perl"

The database system uses the second and third arguments, the username and password, to authenticate the user.

Sometimes your query will generate many rows of results, but you're only interested in one column. The selectcol_arrayref method is designed for just such a case: it turns a series of one-column rows into a reference to a simple Perl array of values:

$books = $dbh->selectcol_arrayref("SELECT title FROM books");
print $books[3]; # prints the title of the fourth book

If you don't want to read all results into memory at once, or you want to efficiently reuse queries, use the database handle's prepare method to create a statement handle. Then call the execute method on the statement handle to perform the query, and retrieve rows with a fetch method like fetchrow_array or fetchrow_hashref (which returns a reference to a hash, mapping column name to value). This is used in Recipe 14.12.

If you know your result will return only a single row, use the selectrow_* methods:

@row = $dbh->selectrow_array("SELECT title,author FROM books WHERE
isbn='596000278'");
print $row[1];              # prints author of first book returned

$row = $dbh->selectrow_arrayref("SELECT title,author FROM books WHERE
isbn='596000278'");
print $row->[1];            # prints author of first book returned

$row = $dbh->selectrow_hashref("SELECT title,author FROM books WHERE
isbn='596000278'", "title");
print $row->{author};       # prints author of first book returned

Statement handles and database handles often correspond to underlying connections to the database, so some care must be taken with them. A connection is automatically cleaned up when its handle goes out of scope. If a database handle goes out of scope while there are active statement handles for that database, though, you will get a warning like this:

disconnect(DBI::db=HASH(0x9df84)) invalidates 1 active cursor(s)
        at -e line 1.

This indicates that you have not fetched all of the data returned by a SELECT statement. In the few rare cases where this does not indicate a problem, and you don't want to use one of the selectrow_* methods, then the finish method can be used to discard the unfetched data and mark the statement handle as inactive.

The DBI module comes with a FAQ (the DBI::FAQ(3) manpage, kept up to date at http://dbi.perl.org) and regular documentation (perldoc DBI). The driver for your DBMS also has documentation (DBD::mysql(3), for instance). The DBI API is larger than the simple subset we've shown here: it provides diverse ways of fetching results, and it hooks into DBMS-specific features like stored procedures. Consult the driver module's documentation to learn about these.

The program in Example 14-5 creates, populates, and searches a MySQL table of users. It uses the RaiseError attribute so it doesn't have to check the return status of every method call.

Example 14-5. dbusers

  #!/usr/bin/perl -w
  # dbusers - manage MySQL user table
  use DBI;
  use User::pwent;

  $dbh = DBI->connect('dbi:mysql:dbname:mysqlserver.domain.com:3306',
                      'user', 'password',
                      { RaiseError => 1, AutoCommit => 1 })

  $dbh->do("CREATE TABLE users (uid INT, login CHAR(8))");

  $sql_fmt = "INSERT INTO users VALUES( %d, %s )";
  while ($user = getpwent) {
      $sql = sprintf($sql_fmt, $user->uid, $dbh->quote($user->name));
      $dbh->do($sql);
  }
  $rows = $dbh->selectall_arrayref("SELECT uid,login FROM users WHERE uid < 50");
  foreach $row (@$rows) {
      print join(", ", map {defined $_ ? $_ : "(null)"} @$row), "\n";
  }

  $dbh->do("DROP TABLE users");

  $dbh->disconnect;

14.9.4. See Also

The documentation for the DBI and relevant DBD modules from CPAN; http://dbi.perl.org/ and http://search.cpan.org/modlist/Database_Interfaces; Programming the Perl DBI, by Alligator Descartes and Tim Bunce (O'Reilly)

Previous | Home | Next
14.8. Saving Query Results to Excel or CSV | Book Index | 14.10. Escaping Quotes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.10. Escaping Quotes

14.10.1. Problem

You want to put Perl values into queries as literal strings, but you're not sure how your database wants strings to be quoted.

14.10.2. Solution

Use the database handle's quote method:

$quoted = $dbh->quote($unquoted);

This $quoted value is now suitable for interpolation into queries:

$sth->prepare("SELECT id,login FROM People WHERE name = $quoted");

Or simply use placeholders in your query and DBI automatically quotes strings for you:

$sth->prepare("SELECT id,login FROM People WHERE name = ?");
$sth->execute($unquoted);

14.10.3. Discussion

Each database has its own quoting idiosyncrasies, so leave the quoting to the quote method or placeholders rather than trying to roll your own quoting function. Not only is hardcoding quotes into your SQL non-portable, it doesn't take into account the possibility that the strings you're interpolating might have quotes in them. For example, take this:

$sth = $dbh->prepare(qq{SELECT id,login FROM People WHERE name="$name"});

If $name is Jon "maddog" Orwant, then you are effectively preparing this query, which is invalid SQL:

SELECT id,login FROM People WHERE name="Jon "maddog" Orwant"

The only strange quoting behavior from quote is this: because the DBI represents NULL values as undef, if you pass undef to quote, it returns NULL without quotes.

14.10.4. See Also

The documentation with the DBI module from CPAN; http://dbi.perl.org; Programming the Perl DBI

Previous | Home | Next
14.9. Executing an SQL Command Using DBI | Book Index | 14.11. Dealing with Database Errors
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.11. Dealing with Database Errors

14.11.1. Problem

You want your program to catch and handle database errors, possibly displaying informative error messages.

14.11.2. Solution

The best solution is to enable RaiseError when you connect to the database, then wrap database calls in eval:

$dbh = DBI->connect($DSN, $user, $password,
                    { RaiseError > 1 });
eval {
  $dbh->do($SQL);
  $sth = $dbh->prepare($SQL2);
  $sth->execute( );
  while (@row = $sth->fetchrow_array) {
    # ...
  }
};
if ($@) {
  # recover here using $DBI::lasth->errstr to get
  # the error message
}

14.11.3. Discussion

The logic here is simple: first tell DBI to die if there's a problem with your SQL (otherwise, the database can't do what you wanted it to). Then, wrap the code that might die in eval to catch fatal errors. Next, check $@ (either the error message you would have die d with or empty if there was no error) to see whether something went wrong. If it did, somehow deal with the error.

DBI supplies the $DBI::lasth variable, containing the last handle acted on. If something went wrong, that's the handle that caused it. You could use the $@ error message, but that also has the "died at file ... line ..." text from die that you might not want. To discover the SQL statement that died, use $DBI::lasth->{Statement}. If you are using only the one handle, you can call the methods directly on your handle instead of on $DBI::lasth:

$msg = $dbh->errstr;
$sql = $dbh->{Statement};

An alternative approach is to disable RaiseError and check the return value for each database call. Methods such as do and execute return a true value if successful, so you can say:

$dbh->do($SQL) or die $dbh->errstr;
$sth->execute( ) or die $sth->errstr;

The do method returns the number of rows affected, but in such a way that it always returns a true value if successful. (If you're curious how to do this, see the Introduction to Chapter 1 for the gory details of how Perl decides what's true and what's false.)

If you're debugging error catching and error handling, you might want to add the PrintError attribute to your database connection:

$dbh = DBI->connect($DSN, $user, $password,
                    { RaiseError => 1, PrintError => 1 });

When problems occur on the handle, PrintError issues a warning before RaiseError calls die. So even if you catch the error with eval and it doesn't necessarily kill your program, you still get to see the text of the error message.

14.11.4. See Also

The documentation with the DBI module from CPAN; http://dbi.perl.org; Programming the Perl DBI; Recipe 14.12

Previous | Home | Next
14.10. Escaping Quotes | Book Index | 14.12. Repeating Queries Efficiently
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.12. Repeating Queries Efficiently

14.12.1. Problem

You have a query that you want to execute repeatedly, and you'd like to do it as efficiently as possible. Sometimes you have several queries that are similar, but not quite identical, that you'd like to execute efficiently (for example, you have a loop through an array of names and want to SELECT ... WHERE name=$name).

14.12.2. Solution

Take advantage of the fact that you can repeatedly execute a query that you need prepare only once.

$sth = $dbh->prepare($SQL);
# execute query ten times
for ($i=0; $i < 10; $i++) {
  $sth->execute( );
  while (@row = $sth->fetchrow_array) {
    # ...
  }
}

If you have changing parameters, use the DBI's binding features:

$sth = $dbh->prepare('SELECT uid,login FROM People WHERE name = ?');
foreach $person (@names) {
  $sth->execute($person);
  while (@row = $sth->fetchrow_array) {
    # ...
  }
}

14.12.3. Discussion

"Prepare once, execute often" is one secret to DBI success. By separating preparation from execution, the database server can parse and optimize queries once and then execute them many times. Most databases can do this even when the queries contain placeholders for values to be filled when the query is executed.

The process of replacing placeholders with actual values is known as binding. The simplest way is to bind when you execute:

$sth = $dbh->prepare('SELECT id,login FROM People WHERE middle_initial = ?');
$sth->execute('J');

If you have multiple parameters to bind, pass more values to execute:

$sth = $dbh->prepare('SELECT * FROM Addresses WHERE House = ?
                      AND Street LIKE ?');
$sth->execute('221b', 'Baker%');

You don't have to do the binding and the execution in one step. The bind_param function binds without executing:

$sth = $dbh->prepare('SELECT id,login FROM People WHERE middle_initial = ?');
$sth->bind_param(1, 'J');
$sth->execute( );

The first argument to bind_param is the placeholder number (starting from 1) in the statement:

$sth = $dbh->prepare('SELECT * FROM Addresses WHERE House = ?
                      AND Street LIKE ?');
$sth->bind_param(1, '221b');
$sth->bind_param(2, 'Baker');

You can give an optional third argument to bind_param that identifies the data type of the value and thus whether to quote it:

$sth->bind_param(1, 'J', SQL_CHAR);

If you want to use this type argument, you must import the types explicitly or import all of them:

use DBI qw(SQL_CHAR SQL_INTEGER);
use DBI qw(:sql_types);

List all types with:

foreach (@{ $dbi::EXPORT_TAGS{sql_types} }) {
  printf "%s=%d\n", $_, &{"DBI::$_"};
}

You do not need to quote the values you pass to bind or to a binding execute. DBI automatically quotes them if they are to be used as strings.

The major limitation to binding is that you often can't use placeholders for table or column names. That is, you can't prepare this query:

SELECT ?,? FROM ? WHERE ? = ?

Remember, the goal of separate prepare and execute is to let the database server optimize the query. There's precious little information to do any optimization on in that query!

A smaller limitation is that each placeholder can represent only a single scalar value. Consider this query:

SELECT id,login FROM People WHERE name IN (?)

You can prepare this query without a problem, but you can't bind more than one value to the placeholder.

14.12.4. See Also

The documentation with the DBI module from CPAN; http://dbi.perl.org; Programming the Perl DBI

Previous | Home | Next
14.11. Dealing with Database Errors | Book Index | 14.13. Building Queries Programmatically
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.13. Building Queries Programmatically

14.13.1. Problem

You want to create searches at runtime. For example, you want users of your program to be able to specify combinations of columns and allowable ranges of values.

14.13.2. Solution

Build a list of clauses and join them together to form the SQL WHERE clause:

if ($year_min)     { push @clauses, "Year >= $year_min" }
if ($year_max)     { push @clauses, "Year <= $year_max" }
if ($bedrooms_min) { push @clauses, "Beds >= $bedrooms_min" }
if ($bedrooms_max) { push @clauses, "Beds <= $bedrooms_max" }
# ...
$clause = join(" AND ", @clauses);
$sth = $dbh->prepare("SELECT beds,baths FROM Houses WHERE $clause");

14.13.3. Discussion

Don't try to build up a string in a loop:

$where = '';
foreach $possible (@names) {
  $where .= ' OR Name=' . $dbh->quote($possible);
}

That code will end up creating a WHERE clause like:

OR Name="Tom" OR Name="Nat" OR Name="Larry" OR Name="Tim"

Then you end up having to lop off the leading " OR ". It's much cleaner to use map and never have the extra text at the start:

$where = join(" OR ", map { "Name=".$dbh->quote($_) } @names);

The map produces a list of strings like:

Name="Nat"
Name="Tom"
Name="Larry"
Name="Tim"

and then they're joined together with " OR " to create a well-formed clause:

Name="Nat" OR Name="Tom" OR Name="Larry" OR Name="Tim"

Unfortunately, you cannot use placeholders here:

$sth = $dbh->prepare("SELECT id,login FROM People WHERE ?");   # BAD
$sth->bind_param(1, $where);

As explained in Recipe 14.12, placeholders can only be used for simple scalar values and not entire clauses. However, there is an elegant solution: construct the clause and the values to be bound in parallel:

if ($year_min)     { push @clauses, "Year >= ?"; push @bind, $year_min }
if ($year_max)     { push @clauses, "Year <= ?"; push @bind, $year_max }
if ($bedrooms_min) { push @clauses, "Beds >= ?"; push @bind, $bedrooms_min }
if ($bedrooms_max) { push @clauses, "Beds <= ?"; push @bind, $bedrooms_max }
$clause = join(" AND ", @clauses);
$sth = $dbh->prepare("SELECT id,price FROM Houses WHERE $clause");
$sth->execute(@bind);

14.13.4. See Also

The documentation with the DBI module from CPAN; http://dbi.perl.org; Programming the Perl DBI; Recipe 14.12

Previous | Home | Next
14.12. Repeating Queries Efficiently | Book Index | 14.14. Finding the Number of Rows Returned by a Query
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.14. Finding the Number of Rows Returned by a Query

14.14.1. Problem

You want to find out how many rows were returned by a query.

14.14.2. Solution

For operations that aren't queries (such as INSERTs, UPDATEs, and DELETEs), the do method returns the number of rows affected, -1 when it can't determine the right value, or else undef in case of failure.

$rows = $dbh->do("DELETE FROM Conference WHERE Language='REBOL'");
if (! defined $rows) {
  # failed, but this is not needed if RaiseError is active
} else {
  print "Deleted $rows rows\n";
}

You can't reliably get row counts from queries without either fetching all of the results and then counting them, or writing another query.

14.14.3. Discussion

The easiest way to find out how many rows a query will return is to use the COUNT function in SQL. For example, take this query:

SELECT id,name FROM People WHERE Age > 30

To find out how many rows it will return, simply issue this query:

SELECT COUNT(*) FROM People WHERE Age > 30

If the database is so volatile that you're afraid the number of rows will change between the COUNT query and the data-fetching query, your best option is to fetch the data and then count rows yourself.

With some DBD modules, execute returns the number of rows affected. This isn't portable and may change in the future.

14.14.4. See Also

The documentation with the DBI module from CPAN; http://dbi.perl.org; Programming the Perl DBI

Previous | Home | Next
14.13. Building Queries Programmatically | Book Index | 14.15. Using Transactions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.15. Using Transactions

14.15.1. Problem

A single change to the database requires several INSERT, UPDATE, or DELETE commands in SQL. For example, you might have to add a person to the People table, add an address to the Address table, and add a link between them to the LivesAt table. The database is in a logically inconsistent state from the first insert until the last completes. If another client queries the database, it will get inconsistent data (e.g., there'll be a Person with no address).

You want to perform the update in such a way that another client never sees an inconsistent database—either all of the changes or none of them should be visible in the database during and after the changes, regardless of any client or server failures during processing.

14.15.2. Solution

Use transactions. The DBI supports these via the commit and rollback methods on a database handle. Use them thus:

$dbh->{AutoCommit} = 0; # enable transactions
$dbh->{RaiseError} = 1; # die( ) if a query has problems

eval {
  # do inserts, updates, deletes, queries here
  $dbh->commit( );
};

if ($@) {
  warn "Transaction aborted: $@";
  eval { $dbh->rollback( ) };   # in case rollback( ) fails
  # do your application cleanup here
}

14.15.3. Discussion

The AutoCommit option controls whether the database commits each change as soon as you issue the command. When AutoCommit is disabled, the database won't update until you call the commit method. If midway through the series of updates you change your mind or an error occurs, the rollback method undoes all pending changes.

You don't have to explicitly set the AutoCommit and RaiseError attributes before each transaction. For convenience, set those attributes in the connect call:

$dbh = DBI->connect($dsn, $username, $password,
                    { AutoCommit => 0, RaiseError => 1 });

Because RaiseError causes DBI to call die whenever a database operation fails, you break out of the eval if any database operation fails while the eval is in effect (even if from within the eval you call a function that accesses the database).

Always explicitly call commit or rollback to end a transaction. Different databases react differently if you disconnect with an unfinished transaction. Some (for example, Oracle and Ingres) commit the transaction, while some (MySQL, Informix) rollback.

When a database handle commits or rolls back a transaction, many database drivers invalidate any active statement handles from that database handle. For example:

$sth = $dbh->prepare(...);
$sth->execute( );
eval {
  $dbh->do(...);
  $dbh->commit;
};
if ($@) { eval { $dbh->rollback } }
while (@row = $sth->fetchrow_array) { ... }  # may not work

The last line is not guaranteed to work across database handles, as the acts of committing and rolling back may invalidate the statement handle in $sth. The standard solution to this is to create two database handles for the database (by calling connect twice) and use one handle for all SELECT statements.

14.15.4. See Also

The documentation with the DBI module from CPAN; http://dbi.perl.org; Programming the Perl DBI

Previous | Home | Next
14.14. Finding the Number of Rows Returned by a Query | Book Index | 14.16. Viewing Data One Page at a Time
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.16. Viewing Data One Page at a Time

14.16.1. Problem

You want to display the contents of a table or the results of a query one page at a time.

14.16.2. Solution

Keep track of which record you're starting with, then use that value to decide how many records to skip before you display a page worth. If your database supports a LIMIT clause that takes a range, use this to avoid transferring unnecessary rows into your program.

14.16.3. Discussion

The example code in this recipe pages through the contents of a table. To page through the results of a query, select the data into a temporary table and page through that.

In desktop applications (e.g., Tk), you can keep track of the current page number yourself. With web applications, the easiest thing to do is to use query parameters in the URL to indicate where you are. For example:

/users-report/view?start=1

Begin by finding out how many records there are in total:

$row = $Dbh->selectrow_arrayref("SELECT COUNT(*) FROM Users");
$count = $row->[0];

Find the first record to display by looking at the start parameter, then calculate the last record from that. You need to know the number of records per page, which here we assume is in the $Page_Size variable:

$first = param('start') || 1;
$last  = $first + $Page_Size - 1;
$last = $count if $last > $count;   # don't go past the end

Now fetch the data into an array and display the records you're interested in:

$results = $Dbh->selectall_arrayref('SELECT id,lastname,firstname FROM Users
                                     ORDER BY lastname,firstname,id');

for (my $i=$first; $i <= $last; $i++) {
  my $user = $results->[$i-1];        # result 1 is in row 0
  printf("%d.  %s, %s.<br>\n", $i, $user->[1], $user->[2]);
}

That will produce output like:

1.  Brocard, Leon.<br>
2.  Cawley, Piers.<br>
3.  Christiansen, Tom.<br>

The last step is adding next and previous links to move to the next and previous pages (if available):

$prev_rec = $first - $Page_Size;
$prev_rec = 1 if $prev_rec < 1;
$prev_link = sprintf('%s/%d', url(-full => 1), $prev_rec);
$next_rec = $last + 1;
$next_link = sprintf('%s/%d', url(-full => 1), $next_rec);

if ($first =  = 1) {
  print 'Previous';
} else {
  printf('<a href="%s">Previous</a>', $prev_link);
}
print " | ";   # separate "Previous" and "Next"
if ($next_rec < $count) {
  printf('<a href="%s">Next</a>', $next_link);
} else {
  print 'Next';
}

This becomes easier if your database lets you specify an offset as part of the LIMIT clause (MySQL and PostgreSQL both do). Instead of transferring all records in the database back to your program, you need transfer only the records you're interested in:

$results = $dbh->selectall_arrayref("SELECT id,lastname,firstname FROM Users
                                     ORDER BY lastname,firstname,id
                                     LIMIT " . ($first-1) . ", $Page_Size");

for ($i=0; $i < @$results; $i++) {
  my $user = $results->[$i];
  printf("%d.  %s, %s.<br>", $i+$first, $user->[1], $user->[2]);
}

MySQL's LIMIT m,n is written LIMIT n OFFSET m in PostgreSQL.

14.16.4. See Also

The documentation with the DBI and DBIx::Pager modules from CPAN; http://dbi.perl.org and http://www.mysql.com; Programming the Perl DBI; MySQL Reference Manual, by Michael "Monty" Widenius, David Axmark, and MySQL AB (O'Reilly)

Previous | Home | Next
14.15. Using Transactions | Book Index | 14.17. Querying a CSV File with SQL
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.17. Querying a CSV File with SQL

14.17.1. Problem

You want to use SQL to insert, delete, or retrieve data from a comma-separated values (CSV) file.

14.17.2. Solution

Use the DBD::CSV module from CPAN:

use DBI;

$dbh = DBI->connect("dbi:CSV:f_dir=/home/gnat/payroll", "", "",
                    { AutoCommit => 1, RaiseError => 1 });

$dbh->do("UPDATE salaries SET salary = salary * 2 WHERE name = 'Nat'");

$sth = $dbh->prepare("SELECT name,salary FROM salaries WHERE name = 'Nat'");
$sth->execute( );
while (@row = $sth->fetchrow_array) {
  # ...
}
$sth->finish( );

$dbh->disconnect( );

14.17.3. Discussion

A "table" in CSV terms is a file (the table name becomes the filename). The tables are kept in the directory specified by the f_dir parameter in the connect method call. The DBD::CSV module supports CREATE and DROP to make and destroy tables:

$dbh->do("CREATE TABLE salaries (salary FLOAT, name CHAR(20))");

Valid column types are: TINYINT, BIGINT, LONGVARBINARY, VARBINARY, BINARY, LONGVARCHAR, CHAR, NUMERIC, DECIMAL, INTEGER, SMALLINT, FLOAT, REAL, and DOUBLE.

When you access a table, the DBD::CSV module locks the corresponding file with the flock(2) syscall. If flock(2) isn't supported on the filesystem containing the CSV file, two processes will be able to access the file at the same time, possibly leading to incorrect results or lost data.

If you're reading or writing an Excel CSV file, you need to tell the DBD::CSV module that the value separator is actually a semicolon:

$dbh = DBI->connect('dbi:CSV:f_dir=/home/gnat/payroll;csv_sep_char=\;');

We need to quote the semicolon to prevent connect from thinking it's separating csv_sep_char= from another connection attribute. We use single quotes rather than double quotes to avoid having to backslash the backslash:

$dbh = DBI->connect("dbi:CSV:f_dir=/home/gnat/payroll;csv_sep_char=\\;");

14.17.4. See Also

The documentation for the CPAN module DBD::CSV; Recipe 1.20; Recipe 14.8

Previous | Home | Next
14.16. Viewing Data One Page at a Time | Book Index | 14.18. Using SQL Without a Database Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.18. Using SQL Without a Database Server

14.18.1. Problem

You want to make complex SQL queries but don't want to maintain a relational database server.

14.18.2. Solution

Use the DBD::SQLite module from CPAN:

use DBI;

$dbh = DBI->connect("dbi:SQLite:dbname=/Users/gnat/salaries.sqlt", "", "",
                    { RaiseError => 1, AutoCommit => 1 });

$dbh->do("UPDATE salaries SET salary = 2 * salary WHERE name = 'Nat'");

$sth = $dbh->prepare("SELECT id,deductions FROM salaries WHERE name = 'Nat'");
# ...

14.18.3. Discussion

An SQLite database lives in a single file, specified with the dbname parameter in the DBI constructor. Unlike most relational databases, there's no database server here—DBD::SQLite interacts directly with the file. Multiple processes can read from the same database file at the same time (with SELECTs), but only one process can make changes (and other processes are prevented from reading while those changes are being made).

SQLite supports transactions. That is, you can make a number of changes to different tables, but the updates won't be written to the file until you commit them:

use DBI;
$dbh = DBI->connect("dbi:SQLite:dbname=/Users/gnat/salaries.sqlt", "", "",
                    { RaiseError => 1, AutoCommit => 0 });
eval {
  $dbh->do("INSERT INTO people VALUES (29, 'Nat', 1973)");
  $dbh->do("INSERT INTO people VALUES (30, 'William', 1999)");
  $dbh->do("INSERT INTO father_of VALUES (29, 30)");
  $dbh->commit( );
};
if ($@) {
      eval { $dbh->rollback( ) };
      die "Couldn't roll back transaction" if $@;
}

SQLite is a typeless database system. Regardless of the types specified when you created a table, you can put any type (strings, numbers, dates, blobs) into any field. Indeed, you can even create a table without specifying any types:

CREATE TABLE people (id, name, birth_year);

The only time that data typing comes into play is when comparisons occur, either through WHERE clauses or when the database has to sort values. The database ignores the type of the column and looks only at the type of the specific value being compared. Like Perl, SQLite recognizes only strings and numbers. Two numbers are compared as floating-point values, two strings are compared as strings, and a number is always less than a string when values of two different types are compared.

There is only one case when SQLite looks at the type you declare for a column. To get an automatically incrementing column, such as unique identifiers, specify a field of type "INTEGER PRIMARY KEY":

CREATE TABLE people (id INTEGER PRIMARY KEY, name, birth_year);

Example 14-6 shows how this is done.

Example 14-6. ipk

  #!/usr/bin/perl -w
  # ipk - demonstrate integer primary keys
  use DBI;
  use strict;
  my $dbh = DBI->connect("dbi:SQLite:ipk.dat", "", "",
  {RaiseError => 1, AutoCommit => 1});
  # quietly drop the table if it already existed
  eval {
    local $dbh->{PrintError} = 0;
    $dbh->do("DROP TABLE names");
  };
  # (re)create it
  $dbh->do("CREATE TABLE names (id INTEGER PRIMARY KEY, name)");
  # insert values
  foreach my $person (qw(Nat Tom Guido Larry Damian Jon)) {
    $dbh->do("INSERT INTO names VALUES (NULL, '$person')");
  }
  # remove a middle value
  $dbh->do("DELETE FROM names WHERE name='Guido'");
  # add a new value
  $dbh->do("INSERT INTO names VALUES (NULL, 'Dan')");
  # display contents of the table
  my $all = $dbh->selectall_arrayref("SELECT id,name FROM names");
  foreach my $row (@$all) {
    my ($id, $word) = @$row;
    print "$word has id $id\n";
  }

SQLite can hold 8-bit text data, but can't hold an ASCII NUL character (\0). The only workaround is to do your own encoding (for example, URL encoding or Base64) before you store and after you retrieve the data. This is true even of columns declared as BLOBs.

14.18.4. See Also

Recipe 14.9; the documentation for the CPAN module DBD::SQLite; the SQLite home page at http://www.hwaci.com/sw/sqlite/

Previous | Home | Next
14.17. Querying a CSV File with SQL | Book Index | 14.19. Program: ggh—Grep Netscape Global History
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.19. Program: ggh—Grep Netscape Global History

This program divulges the contents of Netscape's history.db file. It can be called with full URLs or with a (single) pattern. If called without arguments, it displays every entry in the history file. The ~/.netscape/history.db file is used unless the -database option is given.

Each output line shows the URL and its access time. The time is converted into localtime representation with -localtime (the default) or gmtime representation with -gmtime—or left in raw form with -epochtime, which is useful for sorting by date.

To specify a pattern to match against, give one single argument without a ://.

To look up one or more URLs, supply them as arguments:

% ggh http://www.perl.com/index.html

To find out a link you don't quite recall, use a regular expression (a single argument without a :// is a pattern):

% ggh perl

To find out everyone you've mailed:

% ggh mailto:

To find out the FAQ sites you've visited, use a snazzy Perl pattern with an embedded /i modifier:

% ggh -regexp '(?i)\bfaq\b'

If you don't want the internal date converted to localtime, use -epoch:

% ggh -epoch http://www.perl.com/perl/

If you prefer gmtime to localtime, use -gmtime:

% ggh -gmtime http://www.perl.com/perl/

To look at the whole file, give no arguments (but perhaps redirect to a pager):

% ggh | less

If you want the output sorted by date, use the -epoch flag:

% ggh -epoch | sort -rn | less

If you want it sorted by date into your local time zone format, use a more sophisticated pipeline:

% ggh -epoch | sort -rn | perl -pe 's/\d+/localtime $&/e' | less

The Netscape release notes claim that they're using NDBM format. This is misleading: they're actually using Berkeley DB format, which is why we require DB_File (not supplied standard with all systems Perl runs on) instead of NDBM_File (which is). The program is shown in Example 14-7.

Example 14-7. ggh

  #!/usr/bin/perl -w
  # ggh -- grovel global history in netscape logs
  $USAGE = << EO_COMPLAINT;
  usage: $0 [-database dbfilename] [-help]
             [-epochtime | -localtime | -gmtime]
             [ [-regexp] pattern] | href ... ]
  EO_COMPLAINT

  use Getopt::Long;

  ($opt_database, $opt_epochtime, $opt_localtime,
   $opt_gmtime,   $opt_regexp,    $opt_help,
   $pattern,                                  )      = (0) x 7;

  usage( ) unless GetOptions qw{ database=s
                                regexp=s
                                epochtime localtime gmtime
                                help
                              };

  if ($opt_help) { print $USAGE; exit; }

  usage("only one of localtime, gmtime, and epochtime allowed")
      if $opt_localtime + $opt_gmtime + $opt_epochtime > 1;

  if ( $opt_regexp ) {
      $pattern = $opt_regexp;
  } elsif (@ARGV && $ARGV[0] !~ m(://)) {
      $pattern = shift;
  }

  usage("can't mix URLs and explicit patterns")
      if $pattern && @ARGV;

  if ($pattern && !eval { '' =~ /$pattern/; 1 } ) {
      $@ =~ s/ at \w+ line \d+\.//;
      die "$0: bad pattern $@";
  }

  require DB_File; DB_File->import( );  # delay loading until runtime
  $| = 1;                              # feed the hungry PAGERs

  $dotdir  = $ENV{HOME}    || $ENV{LOGNAME};
  $HISTORY = $opt_database || "$dotdir/.netscape/history.db";

  die "no netscape history dbase in $HISTORY: $!" unless -e $HISTORY;
  die "can't dbmopen $HISTORY: $!" unless dbmopen %hist_db, $HISTORY, 0666;

  # the next line is a hack because the C programmers who did this
  # didn't understand strlen vs strlen+1.  jwz told me so. :-)
  $add_nulls   = (ord(substr(each %hist_db, -1)) =  = 0);

  # XXX: should now do scalar keys to reset but don't
  #      want cost of full traverse, required on tied hashes.
  #   better to close and reopen?

  $nulled_href = "";
  $byte_order  = "V";         # PC people don't grok "N" (network order)

  if (@ARGV) {
      foreach $href (@ARGV) {
          $nulled_href = $href . ($add_nulls && "\0");
          unless ($binary_time = $hist_db{$nulled_href}) {
              warn "$0: No history entry for HREF $href\n";
              next;
          }
          $epoch_secs = unpack($byte_order, $binary_time);
          $stardate   = $opt_epochtime ? $epoch_secs
                                       : $opt_gmtime ? gmtime    $epoch_secs
                                                     : localtime $epoch_secs;
          print "$stardate $href\n";
      }
  } else {
      while ( ($href, $binary_time) = each %hist_db ) {
          chop $href if $add_nulls;
          next unless defined $href && defined $binary_time;
          # gnat reports some binary times are missing
          $binary_time = pack($byte_order, 0) unless $binary_time;
          $epoch_secs = unpack($byte_order, $binary_time);
          $stardate   = $opt_epochtime ? $epoch_secs
                                       : $opt_gmtime ? gmtime    $epoch_secs
                                                     : localtime $epoch_secs;
          print "$stardate $href\n" unless $pattern && $href !~ /$pattern/o;
      }
  }

  sub usage {
      print STDERR "@_\n" if @_;
      die $USAGE;
  }

14.19.1. See Also

The Introduction to this chapter; Recipe 6.18

Previous | Home | Next
14.18. Using SQL Without a Database Server | Book Index | 15. Interactivity
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 15. Interactivity

Contents:

Introduction
Parsing Program Arguments
Testing Whether a Program Is Running Interactively
Clearing the Screen
Determining Terminal or Window Size
Changing Text Color
Reading Single Characters from the Keyboard
Ringing the Terminal Bell
Using POSIX termios
Checking for Waiting Input
Reading Passwords
Editing Input
Managing the Screen
Controlling Another Program with Expect
Creating Menus with Tk
Creating Dialog Boxes with Tk
Responding to Tk Resize Events
Removing the DOS Shell Window with Windows Perl/Tk
Graphing Data
Thumbnailing Images
Adding Text to an Image
Program: Small termcap Program
Program: tkshufflepod
Program: graphbox

Emily Dickinson, "I heard a Fly buzz—when I died"

And then the Windows failed—and then I could not see to see

15.0. Introduction

Everything we use has a user interface: VCRs, computers, telephones, even books. Our programs have user interfaces: do we have to supply arguments on the command line? Can we drag and drop files into the program? Do we have to press Enter after every response we make, or can the program read a single keystroke at a time?

This chapter won't discuss designing user interfaces: entire bookshelves are filled with books written on the subject. Instead, we focus on implementing user interfaces—parsing command-line arguments, reading a character at a time, writing anywhere on the screen, and writing a graphical user interface.

The simplest user interface is what we are called line mode interfaces. Line mode programs normally read entire lines and write characters or entire lines. Filters like grep and utilities like mail exemplify this type of interface. We don't really talk much about this type of interface in this chapter, because so much of the rest of the book does.

A more complex interface is what is called full-screen mode. Programs such as vi, elm, and lynx have full-screen interfaces. They read single characters at a time and can write to any character position on the screen. We address this type of interface in Recipe 15.4, Recipe 15.6, Recipe 15.9, Recipe 15.10, and Recipe 15.11.

Still more complex are the graphical user interfaces (GUIs). Programs with GUIs can address individual pixels, not just characters. GUIs often follow a windowing metaphor, in which a program creates windows that appear on the user's display device. The windows are filled with widgets, which include things like scrollbars to drag or buttons to click. Netscape Navigator provides a full graphical user interface, as does your window manager. Perl can use many GUI toolkits, but here we'll cover the Tk toolkit, since it's the most well-known and portable. See Recipe 15.14, Recipe 15.15, and Recipe 15.22.

The final class of UIs is one we won't address here—web user interfaces. Increasingly, people are eschewing the complicated programming of a fully responsive GUI whose every pixel is addressable, preferring relatively clunky and plain-looking HTML pages. After all, everyone has a web browser, but not everyone can figure out how to install Perl/Tk. We cover the Web in Chapter 19, Chapter 20, and Chapter 21.

A program's user interface is different from the environment you run it in. Your environment determines the type of program you can run. If you're logged in through a terminal capable of full-screen I/O, you can run line mode applications but not GUI programs. Let's look briefly at the environments.

Some environments only handle programs that have a bare line mode interface. This includes executing programs with backticks, over rsh or ssh, or from cron. Their simple interface allows them to be combined creatively and powerfully as reusable components in larger scripts. Line mode programs are wonderful for automation, because they don't rely on a keyboard or screen. They rely on STDIN and STDOUT only—if that. These are often the most portable programs because they use nothing but the basic I/O supported by virtually all systems.

The typical login session, where you use a terminal with a screen and keyboard, permits both line mode and full-screen interfaces. Here the program with the full-screen interface talks to the terminal driver and has intimate knowledge of how to make the terminal write to various positions on the screen. To automate such a program, you need to create a pseudo-terminal for the program to talk to, as shown in Recipe 15.13.

Finally, some window systems let you run line mode and full-screen programs as well as programs that use a GUI. For instance, you can run grep (line-mode programs) from within vi (a full-screen program) from an xterm window (a GUI program running in a window system environment). GUI programs are difficult to automate unless they provide an alternative interface through remote procedure calls.

Toolkits exist for programming in full-screen and GUI environments. These toolkits (curses for full-screen programs; Tk for GUI programs) increase the portability of your programs by abstracting out system-specific details. A curses program can run on virtually any kind of terminal without the user worrying about which particular escape sequences they need to use. Tk programs will run unmodified on Unix and Windows systems—providing you don't use operating-system specific functions.

There are other ways to interact with a user, most notably through the Web. We cover the Web in Chapter 19, Chapter 20, and Chapter 21, so we make no further mention of it here.

GUIs, web pages, and printed documents are all enhanced by graphics. We give here a few recipes for working with image files and creating graphs of data. Once again, the environment you're in doesn't preclude creating or manipulating images. You don't need a GUI to create a graph of data (though you'll need one to view it, unless you print the graph out).

Previous | Home | Next
14.19. Program: ggh—Grep Netscape Global History | Book Index | 15.1. Parsing Program Arguments
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.1. Parsing Program Arguments

15.1.1. Problem

You want to let users change your program's behavior by giving options on the command line. For instance, you want to allow the user to control the level of output that your program produces with a -v (verbose) option.

15.1.2. Solution

Use the standard Getopt::Std module to permit single-character options:

use Getopt::Std;

# -v ARG, -D ARG, -o ARG, sets $opt_v, $opt_D, $opt_o
getopt("vDo");
# -v ARG, -D ARG, -o ARG, sets $args{v}, $args{D}, $args{o}
getopt("vDo", \%args);

getopts("vDo:");         # -v, -D, -o ARG, sets $opt_v, $opt_D, $opt_o
getopts("vDo:", \%args); # -v, -D, -o ARG, sets $args{v}, $args{D}, $args{o}

Or, use the standard Getopt::Long module to permit named arguments:

use Getopt::Long;

GetOptions( "verbose"  => \$verbose,     # --verbose
            "Debug"    => \$debug,       # --Debug
            "output=s" => \$output );    # --output=string or --output string

15.1.3. Discussion

Most traditional programs like ls and rm take single-character options (also known as flags or switches), such as -l and -r. In the case of ls -l and rm -r, the argument is Boolean: either it is present or it isn't. Contrast this with gcc -o compiledfile source.c, where compiledfile is a value associated with the option -o. We can combine Boolean options into a single option in any order. For example:

% rm -r -f /tmp/testdir

Another way of saying this is:

% rm -rf /tmp/testdir

The Getopt::Std module, part of the standard Perl distribution, parses these types of traditional options. Its getopt function takes a single string of characters (each corresponding to an option that takes a value), parses the command-line arguments stored in @ARGV, and sets a global variable for each option. For example, the value for the -D option will be stored in $opt_D. All options parsed though getopt are value options, not Boolean options.

Getopt::Std also provides the getopts function, which lets you specify whether each option is Boolean or takes a value. Arguments that take a value, such as the -o option to gcc, are indicated by a ":", as in this code:

use Getopt::Std;
getopts("o:");
if ($opt_o) {
    print "Writing output to $opt_o";
}

Both getopt and getopts can take a second argument, a reference to a hash. If present, option values are stored in $hash{X} instead of $opt_X:

use Getopt::Std;

%option = ( );
getopts("Do:", \%option);

if ($option{D}) {
    print "Debugging mode enabled.\n";
}

 # if not set, set output to "-".  opening "-" for writing
 # means STDOUT
 $option{o} = "-" unless defined $option{o};

print "Writing output to file $option{o}\n" unless $option{o} eq "-";
open(STDOUT, "> $option{o}")
     or die "Can't open $option{o} for output: $!\n";

Some programs' options you specify using full words instead of single characters. These options are (usually) indicated with two dashes instead of one:

% gnutar --extract --file latest.tar

The value for the - -file option could also be given with an equals sign:

% gnutar --extract --file=latest.tar

The Getopt::Long module's GetOptions function parses this style of options. It takes a hash whose keys are options and values are references to scalar variables:

use Getopt::Long;

GetOptions( "extract" => \$extract,
            "file=s"  => \$file );

if ($extract) {
    print "I'm extracting.\n";
}

die "I wish I had a file" unless defined $file;
print "Working on the file $file\n";

If a key in the hash is just an option name, it's a Boolean option. The corresponding variable will be set to false if the option wasn't given, or to 1 if it was. Getopt::Long provides fancier options than just the Boolean and value of Getopt::Std. Here's what the option specifier can look like:

Specifier | Value? | Comment
option | No | Given as - -option or not at all
option! | No | May be given as - -option or - -nooption
option=s | Yes | Mandatory string parameter: - -option=somestring
option:s | Yes | Optional string parameter: - -option or - -option=somestring
option=i | Yes | Mandatory integer parameter: - -option=35
option:i | Yes | Optional integer parameter: - -option or - -option=35
option=f | Yes | Mandatory floating point parameter: - -option=3.141
option:f | Yes | Optional floating point parameter: - -option or - -option=3.141

15.1.4. See Also

The documentation for the standard Getopt::Long and Getopt::Std modules; the Getopt::Declare module from CPAN; examples of argument parsing by hand can be found in Recipe 1.6, Recipe 1.23, Recipe 6.21, Recipe 7.14, Recipe 8.25, and Recipe 15.12

Previous | Home | Next
15. Interactivity | Book Index | 15.2. Testing Whether a Program Is Running Interactively
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.2. Testing Whether a Program Is Running Interactively

15.2.1. Problem

You want to know whether your program is being called interactively or not. For instance, a user running your program from a shell is interactive, whereas the program being called from cron is not.

15.2.2. Solution

Use -t to test STDIN and STDOUT:

sub I_am_interactive {
    return -t STDIN && -t STDOUT;
}

If you're on a POSIX system, test process groups:

use POSIX qw/getpgrp tcgetpgrp/;

sub I_am_interactive {
    my $tty;
    open($tty, "<", "/dev/tty")    or die "can't open /dev/tty: $!";
    my $tpgrp = tcgetpgrp(fileno($tty));
    my $pgrp  = getpgrp( );
    close $tty;
    return ($tpgrp =  = $pgrp);
}

15.2.3. Discussion

The -t file test operator tells whether the filehandle or file is a tty device. Such devices are signs of interactive use. This only tells you whether your program has been redirected. Running your program from the shell and redirecting STDIN and STDOUT makes the -t version of I_am_interactive return false. Called from cron, I_am_interactive also returns false.

The POSIX test tells you whether your program has exclusive control over its tty. A program whose input and output has been redirected still can control its tty if it wants to, so the POSIX version of I_am_interactive returns true. A program run from cron has no tty, so I_am_interactive returns false.

Whichever I_am_interactive you choose to use, here's how you'd call it:

while (1) {
    if (I_am_interactive( )) {
        print "Prompt: ";
    }
    $line = <STDIN>;
    last unless defined $line;
    # do something with the line
}

Or, more clearly:

sub prompt { print "Prompt: " if I_am_interactive( ) }
for (prompt( ); $line = <STDIN>; prompt( )) {
    # do something with the line
}

15.2.4. See Also

The documentation for the standard POSIX module, also in Chapter 32 of Programming Perl; the -t file test operator in Chapter 3 of Programming Perl and in perlop(1)

Previous | Home | Next
15.1. Parsing Program Arguments | Book Index | 15.3. Clearing the Screen
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.3. Clearing the Screen

15.3.1. Problem

You want to clear the screen.

15.3.2. Solution

Use the Term::Cap module to send the appropriate character sequence. Use POSIX:: Termios to get the output speed of the terminal (or guess 9600 bps). Use eval to trap any exceptions that arise using POSIX::Termios.

use Term::Cap;

$OSPEED = 9600;
eval {
    require POSIX;
    my $termios = POSIX::Termios->new( );
    $termios->getattr;
    $OSPEED = $termios->getospeed;
};

$terminal = Term::Cap->Tgetent({OSPEED=>$OSPEED});
$terminal->Tputs('cl', 1, STDOUT);

Or, just run the clear command:

system("clear");

15.3.3. Discussion

If you clear the screen a lot, cache the return value from the termcap or clear command:

$clear = $terminal->Tputs('cl');
$clear = `clear`;

Then you can clear the screen a hundred times without running clear a hundred times:

print $clear;

15.3.4. See Also

Your system's clear(1) and termcap(5) manpages (if you have them); the documentation for the standard module Term::Cap module, also in Chapter 32 of Programming Perl; the documentation for the Term::Lib module from CPAN

Previous | Home | Next
15.2. Testing Whether a Program Is Running Interactively | Book Index | 15.4. Determining Terminal or Window Size
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.4. Determining Terminal or Window Size

15.4.1. Problem

You need to know the size of the terminal or window. For instance, you want to format text so that it doesn't pass the righthand boundary of the screen.

15.4.2. Solution

Either use the ioctl described in Recipe 12.17, or else use the CPAN module Term::ReadKey:

use Term::ReadKey;

($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize( );

15.4.3. Discussion

GetTerminalSize returns four elements: the width and height in characters and the width and height in pixels. If the operation is unsupported for the output device (for instance, if output has been redirected to a file), it returns an empty list.

Here's how you'd graph the contents of @values, assuming no value is less than 0:

use Term::ReadKey;

($width) = GetTerminalSize( );
die "You must have at least 10 characters" unless $width >= 10;

$max = 0;
foreach (@values) {
    $max = $_ if $max < $_;
}

$ratio = ($width-10)/$max;          # chars per unit
foreach (@values) {
    printf("%8.1f %s\n", $_, "*" x ($ratio*$_));
}

15.4.4. See Also

The documentation for the Term::ReadKey module from CPAN; Recipe 12.17

Previous | Home | Next
15.3. Clearing the Screen | Book Index | 15.5. Changing Text Color
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.5. Changing Text Color

15.5.1. Problem

You want text to appear in different colors on the screen. For instance, you want to emphasize a mode line or highlight an error message.

15.5.2. Solution

Use the CPAN module Term::ANSIColor to send the ANSI color-change sequences to the user's terminal:

use Term::ANSIColor;

print color("red"), "Danger, Will Robinson!\n", color("reset");
print "This is just normal text.\n";
print colored("<BLINK>Do you hurt yet?</BLINK>", "blink");

Or, you can use convenience functions from Term::ANSIColor:

use Term::ANSIColor qw(:constants);

print RED, "Danger, Will Robinson!\n", RESET;

15.5.3. Discussion

Term::ANSIColor prepares escape sequences that some (but far from all) terminals will recognize. For example, if you normally launch a color-xterm, this recipe will work. If you normally use the normal xterm program, or have a vt100 in your kitchen, it won't.

There are two ways of using the module: either by calling the exported functions color($attribute) and colored($text, $attribute), or by using convenience functions like BOLD, BLUE, and RESET.

Attributes can be a combination of colors and controls. The colors are black, red, green, yellow, blue, magenta, on_black, on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, and on_white. (Apparently orange and purple don't matter.) The controls are clear, reset, bold, underline, underscore, blink, reverse, and concealed. clear and reset are synonyms, as are underline and underscore. reset restores the colors to the way they were when the program started, and concealed makes foreground and background colors the same.

You can combine attributes:

# rhyme for the deadly coral snake
print color("red on_black"),  "venom lack\n";
print color("red on_yellow"), "kill that fellow\n";

print color("green on_cyan blink"), "garish!\n";
print color("reset");

We could have written this as:

print colored("venom lack\n", "red", on_black");
print colored("kill that fellow\n", "red", "on_yellow");

print colored("garish!\n", "green", "on_cyan", "blink");

or as:

use Term::ANSIColor qw(:constants);

print BLACK, ON_WHITE, "black on white\n";
print WHITE, ON_BLACK, "white on black\n";
print GREEN, ON_CYAN, BLINK, "garish!\n";
print RESET;

Here, BLACK is a function exported from Term::ANSIColor.

It's important to print RESET or color("reset") at the end of your program if you're not calling colored for everything. Failure to reset your terminal will leave it displaying odd colors. You may want to use:

END { print color("reset") }

to ensure the colors will be reset when your program finishes.

Attributes that span lines of text can confuse some programs or devices. If this becomes a problem, either manually set the attributes at the start of each line, or use colored after setting the variable $Term::ANSIColor::EACHLINE to the line terminator:

$Term::ANSIColor::EACHLINE = $/;
print colored(<< EOF, RED, ON_WHITE, BOLD, BLINK);
This way
each line
has its own
attribute set.
EOF

15.5.4. See Also

The documentation for the Term::AnsiColor module from CPAN

Previous | Home | Next
15.4. Determining Terminal or Window Size | Book Index | 15.6. Reading Single Characters from the Keyboard
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.6. Reading Single Characters from the Keyboard

15.6.1. Problem

You want to read a single character from the keyboard. For instance, you've displayed a menu of one-character options, and you don't want to require users to press the Enter key to make their selection.

15.6.2. Solution

Use the CPAN module Term::ReadKey to put the terminal into cbreak mode, read characters from STDIN, and then put the terminal back into its normal mode:

use Term::ReadKey;

ReadMode 'cbreak';
$key = ReadKey(0);
ReadMode 'normal';

15.6.3. Discussion

Term::ReadKey can put the terminal into many modes—cbreak is just one of them. cbreak mode makes each character available to your program as it is typed (see Example 15-1). It also echoes the characters to the screen; see Recipe 15.10 for an example of a mode that does not echo.

Example 15-1. sascii

  #!/usr/bin/perl -w
  # sascii - Show ASCII values for keypresses

  use Term::ReadKey;
  ReadMode('cbreak');
  print "Press keys to see their ASCII values.  Use Ctrl-C to quit.\n";

  while (1) {
      $char = ReadKey(0);
      last unless defined $char;
      printf(" Decimal: %d\tHex: %x\n", ord($char), ord($char));
  }

  ReadMode('normal');

Using cbreak mode doesn't prevent the terminal's device driver from interpreting end-of-file and flow-control characters. If you want to be able to read a real Ctrl-C (which normally sends a SIGINT to your process) or a Ctrl-D (which indicates end-of-file under Unix), you want to use raw mode.

An argument of 0 to ReadKey indicates that we want a normal read using getc. If no input is available, the program will pause until there is some. We can also pass -1 to indicate a non-blocking read, or a number greater than 0 to indicate the number of seconds to wait for input to become available; fractional seconds are allowed. Non-blocking reads and timed-out reads return either undef when no input is available or a zero-length string on end-of-file.

Recent versions of Term::ReadKey also include limited support for non-Unix systems.

15.6.4. See Also

The getc and sysread functions in Chapter 29 of Programming Perl, and in perlfunc(1); the documentation for the Term::ReadKey module from CPAN; Recipe 15.8; Recipe 15.9

Previous | Home | Next
15.5. Changing Text Color | Book Index | 15.7. Ringing the Terminal Bell
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.7. Ringing the Terminal Bell

15.7.1. Problem

You want to sound an alarm on the user's terminal.

15.7.2. Solution

Print the "\a" character to sound a bell:

print "\aWake up!\n";

Or use the "vb" terminal capability to show a visual bell:

use Term::Cap;

$OSPEED = 9600;
eval {
    require POSIX;
    my $termios = POSIX::Termios->new( );
    $termios->getattr;
    $OSPEED = $termios->getospeed;
};

$terminal = Term::Cap->Tgetent({OSPEED=>$OSPEED});
$vb = "";
eval {
    $terminal->Trequire("vb");
    $vb = $terminal->Tputs('vb', 1);
};

print $vb;                                  # ring visual bell

15.7.3. Discussion

The "\a" escape is the same as "\cG", "\007", and "\x07". They all correspond to the ASCII BEL character and cause an irritating ding. In a crowded terminal room at the end of the semester, this beeping caused by dozens of vi novices all trying to get out of insert mode at once can be maddening. The visual bell is a workaround to avoid irritation. Based upon the polite principle that terminals should be seen and not heard (at least, not in crowded rooms), some terminals let you briefly reverse the foreground and background colors to give a flash of light instead of an audible ring.

Not every terminal supports the visual bell, which is why we eval the code that finds it. If the terminal doesn't support it, Trequire will die without having changed the value of $vb from "". If the terminal does support it, the value of $vb will be set to the character sequence to flash the bell.

There's a better approach to the bell issue in graphical terminal systems like xterm. Many of these let you enable the visual bell from the enclosing application itself, allowing all programs that blindly output a chr(7) to become less noisy.

15.7.4. See Also

The section on "String Literals" in Chapter 2 of Programming Perl or the section on "Quote and Quote-like Operators" in perlop(1); the documentation for the standard Term::Cap module

Previous | Home | Next
15.6. Reading Single Characters from the Keyboard | Book Index | 15.8. Using POSIX termios
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.8. Using POSIX termios

15.8.1. Problem

You'd like to manipulate your terminal characteristics directly.

15.8.2. Solution

Use the POSIX termios interface.

15.8.3. Description

Think of everything you can do with the stty command—you can set everything from special characters to flow control and carriage-return mapping. The standard POSIX module provides direct access to the low-level terminal interface to implement stty-like capabilities in your program.

Example 15-2 finds what your tty's erase and kill characters are (probably backspace and Ctrl-U). Then it sets them back to their original values out of antiquity, # and @, and has you type something. It restores them when done.

Example 15-2. demo POSIX termios

  #!/usr/bin/perl -w
  # demo POSIX termios

  use POSIX qw(:termios_h);

  $term = POSIX::Termios->new;
  $term->getattr(fileno(STDIN));

  $erase = $term->getcc(VERASE);
  $kill = $term->getcc(VKILL);
  printf "Erase is character %d, %s\n", $erase, uncontrol(chr($erase));
  printf "Kill is character %d, %s\n", $kill, uncontrol(chr($kill));

  $term->setcc(VERASE, ord('#'));
  $term->setcc(VKILL, ord('@'));
  $term->setattr(1, TCSANOW);

  print("erase is #, kill is @; type something: ");
  $line = <STDIN>;
  print "You typed: $line";

  $term->setcc(VERASE, $erase);
  $term->setcc(VKILL, $kill);
  $term->setattr(1, TCSANOW);

  sub uncontrol {

      local $_ = shift;
      s/([\200-\377])/sprintf("M-%c",ord($1) & 0177)/eg;
      s/([\0-\37\177])/sprintf("^%c",ord($1) ^ 0100)/eg;
      return $_;
  }

Here's a module called HotKey that implements a readkey function in pure Perl. It doesn't provide any benefit over Term::ReadKey, but it shows POSIX termios in action:

# HotKey.pm
package HotKey;

@ISA = qw(Exporter);
@EXPORT = qw(cbreak cooked readkey);

use strict;
use POSIX qw(:termios_h);
my ($term, $oterm, $echo, $noecho, $fd_stdin);

$fd_stdin = fileno(STDIN);
$term     = POSIX::Termios->new( );
$term->getattr($fd_stdin);
$oterm    = $term->getlflag( );

$echo     = ECHO | ECHOK | ICANON;
$noecho   = $oterm & ~$echo;

sub cbreak {
    $term->setlflag($noecho);  # ok, so i don't want echo either
    $term->setcc(VTIME, 1);
    $term->setattr($fd_stdin, TCSANOW);
}

sub cooked {
    $term->setlflag($oterm);
    $term->setcc(VTIME, 0);
    $term->setattr($fd_stdin, TCSANOW);
}

sub readkey {
    my $key = '';
    cbreak( );
    sysread(STDIN, $key, 1);
    cooked( );
    return $key;
}

END { cooked( ) }

1;

15.8.4. See Also

POSIX Programmer's Guide, by Donald Lewine; the documentation for the standard POSIX module, also in Chapter 32 of Programming Perl; Recipe 15.6; Recipe 15.9

Previous | Home | Next
15.7. Ringing the Terminal Bell | Book Index | 15.9. Checking for Waiting Input
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.9. Checking for Waiting Input

15.9.1. Problem

You want to know whether keyboard input is waiting without actually reading it.

15.9.2. Solution

Use the CPAN module Term::ReadKey, and try to read a key in non-blocking mode by passing it an argument of -1:

use Term::ReadKey;

ReadMode ('cbreak');

if (defined ($char = ReadKey(-1)) ) {
    # input was waiting and it was $char
} else {
    # no input was waiting
}

ReadMode ('normal');                  # restore normal tty settings

15.9.3. Discussion

The -1 parameter to ReadKey indicates a non-blocking read of a character. If no character is available, ReadKey returns undef.

15.9.4. See Also

The documentation for the Term::ReadKey module from CPAN; Recipe 15.6

Previous | Home | Next
15.8. Using POSIX termios | Book Index | 15.10. Reading Passwords
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.10. Reading Passwords

15.10.1. Problem

You want to read input from the keyboard without the keystrokes being echoed on the screen. For instance, you want to read passwords as passwd does, i.e., without displaying the user's password.

15.10.2. Solution

Use the CPAN module Term::ReadKey, set the input mode to noecho, and then use ReadLine:

use Term::ReadKey;

ReadMode('noecho');
$password = ReadLine(0);

15.10.3. Discussion

Example 15-3 shows how to verify a user's password. If your system uses shadow passwords, only the superuser can get the encrypted form of the password with getpwuid. Everyone else just gets * as the password field of the database, which is useless for verifying passwords.

Example 15-3. checkuser

  #!/usr/bin/perl -w
  # checkuser - demonstrates reading and checking a user's password

  use Term::ReadKey;

  print "Enter your password: ";
  ReadMode 'noecho';
  $password = ReadLine 0;
  chomp $password;
  ReadMode 'normal';

  print "\n";

  ($username, $encrypted) = ( getpwuid $<)[0,1];

  if (crypt($password, $encrypted) ne $encrypted) {
      die "You are not $username\n";
  } else {
      print "Welcome, $username\n";
  }

15.10.4. See Also

The documentation for the Term::ReadKey module from CPAN; the crypt and getpwuid functions in Chapter 29 of Programming Perl and in perlfunc(1), which demonstrate using the stty(1) command; your system's crypt(3) and passwd(5) manpages (if you have them)

Previous | Home | Next
15.9. Checking for Waiting Input | Book Index | 15.11. Editing Input
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.11. Editing Input

15.11.1. Problem

You want a user to be able to edit a line before sending it to you for reading.

15.11.2. Solution

Use the standard Term::ReadLine library along with the Term::ReadLine::Gnu module from CPAN:

use Term::ReadLine;

$term = Term::ReadLine->new("APP DESCRIPTION");
$OUT = $term->OUT || *STDOUT;

$term->addhistory($fake_line);
$line = $term->readline($prompt);

print $OUT "Any program output\n";

15.11.3. Discussion

The program in Example 15-4 acts as a crude shell. It reads a line and passes it to the shell to execute. The readline method reads a line from the terminal, with editing and history recall. It automatically adds the user's line to the history.

Example 15-4. vbsh

  #!/usr/bin/perl -w
  # vbsh -  very bad shell
  use strict;

  use Term::ReadLine;
  use POSIX qw(:sys_wait_h);

  my $term = Term::ReadLine->new("Simple Shell");
  my $OUT = $term->OUT( ) || *STDOUT;
  my $cmd;

  while (defined ($cmd = $term->readline('$ ') )) {
      my @output = `$cmd`;
      my $exit_value  = $? >> 8;
      my $signal_num  = $? & 127;
      my $dumped_core = $? & 128;
      printf $OUT "Program terminated with status %d from signal %d%s\n",
             $exit_value, $signal_num,
             $dumped_core ? " (core dumped)" : "";
      print @output;
      $term->addhistory($cmd);
  }

If you want to seed the history with your own functions, use the addhistory method:

$term->addhistory($seed_line);

You can't seed with more than one line at a time. To remove a line from the history, use the remove_history method, which takes an index into the history list. 0 is the first (least recent) entry, 1 the second, and so on up to the most recent history lines.

$term->remove_history($line_number);

To get a list of history lines, use the GetHistory method, which returns a list of the lines:

@history = $term->GetHistory;

15.11.4. See Also

The documentation for the standard Term::ReadLine module and the Term::ReadLine::Gnu from CPAN

Previous | Home | Next
15.10. Reading Passwords | Book Index | 15.12. Managing the Screen
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.12. Managing the Screen

15.12.1. Problem

You want to control the screen layout or highlighting, detect when special keys are pressed, or present full-screen menus, but you don't want to think about what kind of display device the user has.

15.12.2. Solution

Use the Curses module from CPAN, which makes use of your native curses(3) library.

15.12.3. Description

The curses library provides easy access to the full-screen display in an efficient and device-independent fashion. (By display, we mean any cursor-addressable monitor.) With Curses, you write high-level code to put data on the logical display, building it up character by character or string by string. When you want output to show up, call the refresh function. The library generates output consisting only of the changes on the virtual display since the last call to refresh. This is particularly appreciated on a slow connection.

The example program in Example 15-5, called rep, demonstrates this. Call it with arguments of the program to run, like any of these:

% rep ps aux
% rep netstat
% rep -2.5 lpq

The rep script will repeatedly call the listed command, printing its output to the screen, updating only what changed since the previous run. This is most effective when the changes between runs are small. It maintains the current date in reverse video at the bottom-right corner of your screen.

By default, rep waits 10 seconds before rerunning the command. You can change this delay period by calling it an optional number of seconds (which can be a decimal number) as shown in the previous example when calling lpq. You may also hit any key during the pause for it to run the command right then.

Example 15-5. rep

  #!/usr/bin/perl -w
  # rep - screen repeat command
  use strict;
  use Curses;

  my $timeout = 10;
  if (@ARGV && $ARGV[0] =~ /^-(\d+\.?\d*)$/) {
      $timeout = $1;
      shift;
  }

  die "usage: $0 [ -timeout ] cmd args\n" unless @ARGV;

  initscr( );          # start screen
  noecho( );
  cbreak( );
  nodelay(1);         # so getch( ) is non-blocking

  $SIG{INT} = sub { done("Ouch!") };
  sub done { endwin( ); print "@_\n"; exit; }

  while (1) {
      while ((my $key = getch( )) ne ERR) {    # maybe multiple keys
          done("See ya") if $key eq 'q'
      }
      my @data = `(@ARGV) 2>&1`;              # gather output+errors
      for (my $i = 0; $i < $LINES; $i++) {
          addstr($i, 0, $data[$i] || ' ' x $COLS);
      }

      standout( );
      addstr($LINES-1, $COLS - 24, scalar localtime);
      standend( );

      move(0,0);
      refresh( );                              # flush new output to display

      my ($in, $out) = ('', '');
      vec($in,fileno(STDIN),1) = 1;           # look for key on stdin
      select($out = $in,undef,undef,$timeout);# wait up to this long
  }

Curses lets you tell whether the user typed one of the arrow keys or those other funny keys, like HOME or INSERT. This is normally difficult, because those keys send multiple bytes. With Curses, it's easy:

keypad(1);                  # enable keypad mode
$key = getch( );
if ($key eq 'k'     ||      # vi mode
    $key eq "\cP"   ||      # emacs mode
    $key eq KEY_UP)         # arrow mode
{
    # do something
}

Other Curses functions let you read the text at particular screen coordinates, control highlighting and standout mode, and even manage multiple windows.

The perlmenu module, also from CPAN, is built on top of the lower-level Curses module. It provides high-level access to menus and fill-out forms. Here's a sample form from the perlmenu distribution:

                   Template Entry Demonstration

  Address Data Example                                      Record # ___

  Name: [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]
  Addr: [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __]
  City: [__ __ __ __ __ __ __ __ __]          State: [__]       Zip: [\\\\\]

  Phone: (\\\) \\\-\\\\                            Password: [^^^^^^^^]

  Enter all information available.
  Edit fields with left/right arrow keys or "delete".
  Switch fields with "Tab" or up/down arrow keys.
  Indicate completion by pressing "Return".
  Refresh screen with "Control-L".
  Abort this demo here with "Control-X".

The user types in the areas indicated, with regular text indicated by underline fields, numeric data by backslashed fields, and starred-out data with circumflexed fields. This is reminiscent of Perl's formats, except that forms are used for output, not input.

15.12.4. See Also

Your system's curses(3) manpage (if you have it); the documentation for the Curses and the perlmenu modules from CPAN; Chapter 7 of Programming Perl, or perlform(1); Recipe 3.10

Previous | Home | Next
15.11. Editing Input | Book Index | 15.13. Controlling Another Program with Expect
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.13. Controlling Another Program with Expect

15.13.1. Problem

You want to automate interaction with a full-screen program that expects to have a terminal behind STDIN and STDOUT.

15.13.2. Solution

Use the Expect module from CPAN:

use Expect;

$command = Expect->spawn("program to run")
    or die "Couldn't start program: $!\n";

# prevent the program's output from being shown on our STDOUT
$command->log_stdout(0);

# wait 10 seconds for "Password:" to appear
unless ($command->expect(10, "Password")) {
    # timed out
}

# wait 20 seconds for something that matches /[lL]ogin: ?/
unless ($command->expect(20, -re => '[lL]ogin: ?')) {
    # timed out
}

# wait forever for "invalid" to appear
unless ($command->expect(undef, "invalid")) {
    # error occurred; the program probably went away
}

# send "Hello, world" and a carriage return to the program
print $command "Hello, world\r";

# if the program will terminate by itself, finish up with
$command->soft_close( );

# if the program must be explicitly killed, finish up with
$command->hard_close( );

15.13.3. Discussion

This module requires two other modules from CPAN: IO::Pty and IO::Stty. It sets up a pseudo-terminal to interact with programs that insist on talking to the terminal device driver. People often use this for talking to passwd to change passwords. telnet (Net::Telnet, described in Recipe 18.6, is probably more suitable and portable) and ftp are also programs that expect a real tty.

Start the program you want to run with Expect->spawn, passing a program name and arguments either in a single string or as a list. Expect starts the program and returns an object representing that program, or undef if the program couldn't be started.

To wait for the program to emit a particular string, use the expect method. Its first argument is the number of seconds to wait for the string, or undef to wait forever. To wait for a string, give that string as the second argument to expect. To wait for a regular expression, give "-re" as the second argument and a string containing the pattern as the third argument. You can give further strings or patterns to wait for:

$which = $command->expect(30, "invalid", "success", "error", "boom");
if ($which) {
    # found one of those strings
}

In scalar context, expect returns the number of arguments it matched. In the previous example, expect would return 1 if the program emitted "invalid", 2 if it emitted "success", and so on. If none of the patterns or strings matches, expect returns false.

In list context, expect returns a five-element list. The first element is the number of the pattern or string that matched, which is the same as its return value in scalar context. The second argument is a string indicating why expect returned. If there were no error, the second argument would be undef. Possible errors are "1:TIMEOUT", "2:EOF", "3:spawn id(...)died", and "4:...". (See the Expect(3) manpage for the precise meaning of these messages.) The third argument of expect's return list is the string matched. The fourth argument is text before the match, and the fifth argument is text after the match.

Sending input to the program you're controlling with Expect is as simple as using print. The only catch is that terminals, devices, and sockets all vary in what they send and expect as the line terminator—we've left the sanctuary of the C standard I/O library, so the behind-the-scenes conversion to "\n" isn't taking place. We recommend trying "\r" at first. If that doesn't work, try "\n" and "\r\n".

When you're finished with the spawned program, you have three options. One, you can continue with your main program, and the spawned program will be forcibly killed when the main program ends. This will accumulate processes, though. Two, if you know the spawned program will terminate normally either when it has finished sending you output or because you told it to stop—for example, telnet after you exit the remote shell—call the soft_close method. If the spawned program could continue forever, like tail -f, then use the hard_close method; this kills the spawned program.

15.13.4. See Also

The documentation for the Expect, IO::Pty, and IO::Stty modules from CPAN; Exploring Expect, by Don Libes (O'Reilly)

Previous | Home | Next
15.12. Managing the Screen | Book Index | 15.14. Creating Menus with Tk
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.14. Creating Menus with Tk

15.14.1. Problem

You want to create a window that has a menu bar at the top.

15.14.2. Solution

Use the Tk Menubutton and Frame widgets:

use Tk;

$main = MainWindow->new( );

# Create a horizontal space at the top of the window for the
# menu to live in.
$menubar = $main->Frame(-relief              => "raised",
                        -borderwidth         => 2)
                ->pack (-anchor              => "nw",
                        -fill                => "x");

# Create a button labeled "File" that brings up a menu
$file_menu = $menubar->Menubutton(-text      => "File",
                                  -underline => 1)
                     ->pack      (-side      => "left" );
# Create entries in the "File" menu
$file_menu->command(-label   => "Print",
                    -command => \&Print);

This is considerably easier if you use the -menuitems shortcut:

$file_menu = $menubar->Menubutton(-text             => "File",
                                 -underline         => 1,
                                 -menuitems         => [
              [ Button => "Print",-command          => \&Print ],
               [ Button => "Save",-command          => \&Save  ] ])
                           ->pack(-side             => "left");

15.14.3. Discussion

Menus in applications can be viewed as four separate components working together: Frames, Menubuttons, Menus, and Menu Entries. The Frame is the horizontal bar at the top of the window that the menu resides in (the menubar). Inside the Frame are a set of Menubuttons, corresponding to Menus: File, Edit, Format, Buffers, and so on. When the user clicks on a Menubutton, the Menubutton brings up the corresponding Menu, a vertically arranged list of Menu Entries.

Options on a Menu are labels (Open, for example) or separators (horizontal lines dividing one set of entries from another in a single menu).

The command entry, like Print in the File menu shown earlier, has code associated with it. When the entry is selected, the command is run by invoking the callback. These are the most common:

$file_menu->command(-label   => "Quit Immediately",
                    -command => sub { exit } );

Separators don't have any action associated with them:

$file_menu->separator( );

A checkbutton menu entry has an on value, an off value, and a variable associated with it. If the variable has the on value, the checkbutton menu entry has a check beside its label. If the variable has the off value, it does not. Selecting the entry on the menu toggles the state of the variable.

$options_menu->checkbutton(-label    => "Create Debugging File",
                           -variable => \$debug,
                           -onvalue  => 1,
                           -offvalue => 0);

A group of radiobuttons is associated with a single variable. Only one radiobutton associated with that variable can be on at any time. Selecting a radiobutton gives the variable the value associated with it:

$debug_menu->radiobutton(-label    => "Level 1",
                         -variable => \$log_level,
                         -value    => 1);

$debug_menu->radiobutton(-label    => "Level 2",
                         -variable => \$log_level,
                         -value    => 2);

$debug_menu->radiobutton(-label    => "Level 3",
                         -variable => \$log_level,
                         -value    => 3);

Create nested menus with the cascade menu entry. For instance, under Netscape Navigator, the File menu button at the left has a cascade menu entry New that brings up a selection of new windows. Creating a cascading menu entry is trickier than creating the other menu entries. You must create a cascade menu entry, fetch the new menu associated with that menu entry, and create entries on that new menu.

# step 1: create the cascading menu entry
$format_menu->cascade          (-label    => "Font");

# step 2: get the new Menu we just made
$font_menu = $format_menu->cget("-menu");

# step 3: populate that Menu
$font_menu->radiobutton        (-label    => "Courier",
                                -variable => \$font_name,
                                -value    => "courier");
$font_menu->radiobutton        (-label    => "Times Roman",
                                -variable => \$font_name,
                                -value    => "times");

A tear-off menu entry lets the user move the menu that it is on. By default, all Menubuttons and cascade menu entries make Menus that have a tear-off entry at the top of them. To create Menus without that default, use the -tearoff option:

$format_menu = $menubar->Menubutton(-text      => "Format",
                                    -underline => 1
                                    -tearoff   => 0)
                       ->pack;

$font_menu  = $format_menu->cascade(-label     => "Font",
                                    -tearoff   => 0);

The -menuitems option to Menubutton is a shorthand for creating these menubuttons. Pass it an array reference representing the options on the Menubutton. Each option is itself an anonymous array. The first two elements of the option array are the button type ("command", "radiobutton", "checkbutton", "cascade", or "tearoff") and the menu name.

Here's how to use menuitems to make an Edit menu:

my $f = $menubar->Menubutton(-text => "Edit", -underline => 0,
                              -menuitems =>
    [
     [Button => 'Copy',        -command => \&edit_copy ],
     [Button => 'Cut',         -command => \&edit_cut ],
     [Button => 'Paste',       -command => \&edit_paste  ],
     [Button => 'Delete',      -command => \&edit_delete ],
     [Separator => ''],
     [Cascade => 'Object ...', -tearoff => 0,
                               -menuitems => [
        [ Button => "Circle",  -command => \&edit_circle ],
        [ Button => "Square",  -command => \&edit_square ],
        [ Button => "Point",   -command => \&edit_point ] ] ],
    ])->grid(-row => 0, -column => 0, -sticky => 'w');

15.14.4. See Also

The documentation for the Tk module from CPAN; Mastering Perl/Tk, by Stephen Lidie and Nancy Walsh

Previous | Home | Next
15.13. Controlling Another Program with Expect | Book Index | 15.15. Creating Dialog Boxes with Tk
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.15. Creating Dialog Boxes with Tk

15.15.1. Problem

You want to create a dialog box, i.e., a new top-level window with buttons to make the window go away. The dialog box might also have other items, such as labels and text entry widgets for creating a fill-out form. You could use such a dialog box to collect registration information, and you want it to go away when registration is sent or if the user chooses not to register.

15.15.2. Solution

For simple jobs, use the Tk::DialogBox widget:

use Tk::DialogBox;

$dialog = $main->DialogBox( -title   => "Register This Program",
                            -buttons => [ "Register", "Cancel" ] );

# add widgets to the dialog box with $dialog->Add( )

# later, when you need to display the dialog box
$button = $dialog->Show( );
if ($button eq "Register") {
    # ...
} elsif ($button eq "Cancel") {
    # ...
} else {
    # this shouldn't happen
}

15.15.3. Discussion

A DialogBox has two parts: the bottom is a set of buttons, and the top has the widgets of your choosing. Show ing a DialogBox pops it up and returns the button the user selected.

Example 15-6 contains a complete program demonstrating the DialogBox.

Example 15-6. tksample3

  #!/usr/bin/perl -w
  # tksample3 - demonstrate dialog boxes

  use Tk;
  use Tk::DialogBox;

  $main = MainWindow->new( );

  $dialog = $main->DialogBox( -title   => "Register",
                              -buttons => [ "Register", "Cancel" ],
                             );

  # the top part of the dialog box will let people enter their names,
  # with a Label as a prompt

  $dialog->add("Label", -text => "Name")->pack( );
  $entry = $dialog->add("Entry", -width => 35)->pack( );

  # we bring up the dialog box with a button
  $main->Button( -text    => "Click Here For Registration Form",
                 -command => \&register)    ->pack(-side => "left");
  $main->Button( -text    => "Quit",
                 -command => sub { exit } ) ->pack(-side => "left");

  MainLoop;

  #
  # register
  #
  # Called to pop up the registration dialog box
  #

  sub register {
      my $button;
      my $done = 0;

      do {
          # show the dialog
          $button = $dialog->Show;

          # act based on what button they pushed
          if ($button eq "Register") {
              my $name = $entry->get;

              if (defined($name) && length($name)) {
                  print "Welcome to the fold, $name\n";
                  $done = 1;
              } else {
                  print "You didn't give me your name!\n";
              }
          } else {
              print "Sorry you decided not to register.\n";
              $done = 1;
          }
      } until $done;
  }

The top part of this DialogBox has two widgets: a label and a text entry. To collect more information from the user, we'd have more labels and text entries.

A common use of dialog boxes is to display error messages or warnings. The program in Example 15-7 demonstrates how to display Perl's warn function in a DialogBox.

Example 15-7. tksample4

  #!/usr/bin/perl -w
  # tksample4 - popup dialog boxes for warnings

  use Tk;
  use Tk::DialogBox;

  my $main;

  # set up a warning handler that displays the warning in a Tk dialog box

  BEGIN {
      $SIG{_ _WARN_ _} = sub {
          if (defined $main) {
              my $dialog = $main->DialogBox( -title   => "Warning",
                                             -buttons => [ "Acknowledge" ]);
              $dialog->add("Label", -text => $_[0])->pack;
              $dialog->Show;
          } else {
              print STDOUT join("\n", @_), "n";
          }
      };
  }

  # your program goes here

  $main = MainWindow->new( );

  $main->Button( -text   => "Make A Warning",
                 -command => \&make_warning) ->pack(-side => "left");
  $main->Button( -text   => "Quit",
                 -command => sub { exit } )  ->pack(-side => "left");

  MainLoop;

  # dummy subroutine to generate a warning

  sub make_warning {
      my $a;
      my $b = 2 * $a;
  }

15.15.4. See Also

The Tk::DialogBox manpage in the documentation for the Tk module from CPAN; the menu(n) manpage (if you have it); Mastering Perl/Tk

Previous | Home | Next
15.14. Creating Menus with Tk | Book Index | 15.16. Responding to Tk Resize Events
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.16. Responding to Tk Resize Events

15.16.1. Problem

You've written a Tk program, but your widget layout goes awry when the user resizes their window.

15.16.2. Solution

You can prevent the user from resizing the window by intercepting the Configure event:

use Tk;

$main = MainWindow->new( );

$main->bind('<Configure>' => sub {
    $xe = $main->XEvent;
    $main->maxsize($xe->w, $xe->h);
    $main->minsize($xe->w, $xe->h);
});

Or you can use pack to control how each widget resizes and expands when the user resizes its container:

$widget->pack( -fill => "both", -expand => 1 );
$widget->pack( -fill => "x",    -expand => 1 );

15.16.3. Discussion

By default, packed widgets resize if their container changes size—they don't scale themselves or their contents to the new size. This can lead to empty space between widgets, or cropped or cramped widgets if the user resizes the window.

One solution is to prevent resizing. We bind to the Configure event, which is sent when a widget's size or position changes, registering a callback to reset the window's size. This is how you'd ensure a pop-up error-message box couldn't be resized.

You often want to let the user resize the application's windows. You must then define how each widget will react. Do this through the arguments to the pack method: -fill controls the dimensions the widget will resize in, and -expand controls whether the widget's size will change to match available space. The -expand option takes a Boolean value, true or false. The -fill option takes a string indicating the dimensions the widget can claim space in: "x", "y", "both", or "none".

The solution requires both options. Without -fill, -expand won't claim space to grow into. Without -expand, -fill will claim empty space but won't expand in it.

Different parts of your application will behave differently. The main area of a web browser, for example, should probably change size in both dimensions when the window is resized. You'd pack the widget like this:

$mainarea->pack( -fill => "both", -expand => 1 );

The menubar above the main area, though, should expand horizontally but not vertically. You'd pack the widget thus:

$menubar->pack( -fill => "x", -expand => 1 );

Associated with resizing is the need to anchor a widget to part of its container. Here's how you'd anchor the menubar to the top-left corner of its container when you call pack:

$menubar->pack (-fill     => "x",
                -expand   => 1,
                -anchor   => "nw" );

Now when you resize it, the menubar stays at the top of the window where it belongs, instead of being centered in wide open space.

15.16.4. See Also

The pack(n), XEvent(3), and XConfigureEvent(3) manpages (if you have them); Tcl and the Tk Toolkit, by John Ousterhout (Addison-Wesley); Mastering Perl/Tk

Previous | Home | Next
15.15. Creating Dialog Boxes with Tk | Book Index | 15.17. Removing the DOS Shell Window with Windows Perl/Tk
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.17. Removing the DOS Shell Window with Windows Perl/Tk

15.17.1. Problem

You have written a Perl program for the Windows port of Perl and Tk, but you get a DOS shell window every time you start your program.

15.17.2. Solution

Add this to the start of your program:

BEGIN {
  if ($^O eq 'MSWin32') {
    require Win32::Console;
    Win32::Console::Free( );
  }
}

15.17.3. Description

The Win32::Console module lets you control the terminal window that launched your program. All you need to do is close that window (or Free it in, in the peculiar parlance of the Windows API) and voilà—no pesky DOS shell window.

15.17.4. See Also

The documentation for the Win32::Console module, which is included with distributions of Perl destined for Microsoft systems

Previous | Home | Next
15.16. Responding to Tk Resize Events | Book Index | 15.18. Graphing Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.18. Graphing Data

15.18.1. Problem

You have numerical data that you want to represent as a bar, pie, or line chart.

15.18.2. Solution

Use the GD::Graph::* modules from CPAN:

use GD::Graph::lines;                      # bars, lines, points, pie
$chart = GD::Graph::lines->new(480,320);
$chart->set(x_label => $X_AXIS_LABEL,      # no axes for pie chart
            y_label => $Y_AXIS_LABEL,
            title   => $GRAPH_TITLE,
            # ... more options possible
           );
$plot = $chart->plot($DATA_REF) or die $chart->error;
# do something with $plot->png which is the image in PNG form

Here is a sample data structure (every row must have the same number of values):

$DATA_REF = [
              [ 1990, 1992, 1993, 1995, 2002 ],      # X values
              [ 10,   15,   18,   20,   25   ],      # first dataset
              [ 9,    undef,17,   undef,12   ],      # second dataset
              # ...
            ];

15.18.3. Discussion

The GD::Graph module requires you to have the GD module installed, which itself depends on a C library available from http://www.boutell.com/gd/. Early versions of this library created GIF images, but since the owners of the GIF patent are cracking down, the library now emits PNG and JPEG images:

$png_data = $plot->png;
$jpg_data = $plot->jpeg;

The documentation for GD::Graph lists a large number of options you can fine-tune (colors, fonts, placement), but the most important ones are labels and the image title. There are no axes to label in pie charts, so the x_label and y_label options are not available. By default, pie charts are drawn with a pseudo-3D look, which you can disable by setting the 3d option to a false value.

Recipe 15.23 contains a program that (crudely) extracts the day of the week on which each mail message in a mailbox was sent, and then graphs that data.

15.18.4. See Also

Documentation for the GD and GD::Graph modules; Perl Graphics Programming, by Shawn Wallace (O'Reilly)

Previous | Home | Next
15.17. Removing the DOS Shell Window with Windows Perl/Tk | Book Index | 15.19. Thumbnailing Images
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.19. Thumbnailing Images

15.19.1. Problem

You have a large image and you want to create a smaller version of that image, the thumbnail. For example, on a web site you might use a thumbnail as a preview to let readers see the basic image before they decide whether to download the larger original.

15.19.2. Solution

Use the Image::Magick module from CPAN:

use Image::Magick;

$image = Image::Magick->new( );
$image->Read($ORIGINAL_FILENAME);
$image->Resize(geometry => '120x90');
$image->Write($THUMBNAIL_FILENAME);

15.19.3. Discussion

The Image::Magick module is a frontend to the ImageMagick suite, available from http://imagemagick.sourceforge.net. It handles many complex and powerful image manipulations, but here we're only concerned with the very simple resizing.

The Resize method's geometry parameter indicates the new geometry (width xheight). You can also specify percentages: '75%' to resize each axis proportionally to 3/4 of its original size, or '10%x30%' to resize the X axis to 10% of its original value and the Y axis to 30%.

You can also specify a filter to use and how much to blur or sharpen the image with that filter:

$image->Resize(geometry => '120x90',
               filter   => 'Gaussian',
               blur     => 2);

A blur value greater than 1 indicates blurring; a value less than 1 indicates sharpening. The valid filters are Point, Box, Triangle, Hermite, Hanning, Hamming, Blackman, Gaussian, Quadratic, Cubic, Catrom, Mitchell, Lanczos, Bessel, and Sinc.

15.19.4. See Also

The documentation for the Image::Magick modules; Perl Graphics Programming

Previous | Home | Next
15.18. Graphing Data | Book Index | 15.20. Adding Text to an Image
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.20. Adding Text to an Image

15.20.1. Problem

You want to write text onto an existing image. For example, you want to add a small copyright message to all photos on your web site.

15.20.2. Solution

Use the GD module from CPAN:

use GD;
$image = GD::Image->new($FILENAME);
$blue = $image->colorAllocate(0,0,255);
$image->string(gdTinyFont, 10, 10, "Copyright Me, 2037", $blue);
# write $image->png( ) to file

15.20.3. Discussion

The GD module can load only certain file formats; precisely which depends on the C libraries available when the underlying C library of GD was built. At the time of this writing, GD could read and write PNG, JPEG, XBM, XPM, and WBMP (Windows Bitmap), as well as its own GD2 and GD formats.

The arguments to the string method are: the font to use, the x and y coordinates to draw at, the string to draw, and the color to draw the text in.

GD comes with five fonts: gdTinyFont, gdSmallFont, gdMediumBoldFont, gdLargeFont, and gdGiantFont. If your GD was compiled to handle TrueType fonts, you can write with a TrueType font using:

$image->stringFT($color, $font, $point_size, $angle, $x, $y, $string);

Here, $font is the absolute pathname of the .ttf file containing the TrueType font. The $point_size and $angle parameters indicate the size (in points; fractions are acceptable) and rotation from horizontal (in radians). For example:

$image->stringFT($blue, '/Users/gnat/fonts/arial.ttf', 8, 0,
                 10, 20, 'Copyright Me Me Me');

15.20.4. See Also

The documentation for the GD module; Perl Graphics Programming

Previous | Home | Next
15.19. Thumbnailing Images | Book Index | 15.21. Program: Small termcap Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.21. Program: Small termcap Program

15.21.1. Description

This program clears your screen and scribbles all over it until you interrupt it. It shows how to use Term::Cap to clear the screen, move the cursor, and write anywhere on the screen. It also uses Recipe 16.6.

The program text is shown in Example 15-8.

Example 15-8. tcapdemo

  #!/usr/bin/perl -w
  # tcapdemo - show off direct cursor placement

  use POSIX;
  use Term::Cap;

  init( );                     # Initialize Term::Cap.
  zip( );                      # Bounce lines around the screen.
  finish( );                   # Clean up afterward.
  exit( );

  # Two convenience functions.  clear_screen is obvious, and
  # clear_end clears to the end of the screen.
  sub clear_screen { $tcap->Tputs('cl', 1, *STDOUT) }
  sub clear_end    { $tcap->Tputs('cd', 1, *STDOUT) }

  # Move the cursor to a particular location.
  sub gotoxy {
      my($x, $y) = @_;
      $tcap->Tgoto('cm', $x, $y, *STDOUT);
  }

  # Get the terminal speed through the POSIX module and use that
  # to initialize Term::Cap.
  sub init {
      $| = 1;
      $delay = (shift( ) || 0) * 0.005;
      my $termios = POSIX::Termios->new( );
      $termios->getattr;
      my $ospeed = $termios->getospeed;
      $tcap = Term::Cap->Tgetent ({ TERM => undef, OSPEED => $ospeed });
      $tcap->Trequire(qw(cl cm cd));
  }

  # Bounce lines around the screen until the user interrupts with
  # Ctrl-C.
  sub zip {
      clear_screen( );
      ($maxrow, $maxcol) = ($tcap->{_li} - 1, $tcap->{_co} - 1);

      @chars = qw(* - / | \ _ );
      sub circle { push(@chars, shift @chars); }

      $interrupted = 0;
      $SIG{INT} = sub { ++$interrupted };

      $col = $row = 0;
      ($row_sign, $col_sign) = (1,1);

      do {
          gotoxy($col, $row);
          print $chars[0];
          select(undef, undef, undef, $delay);

          $row += $row_sign;
          $col += $col_sign;

          if    ($row =  = $maxrow) { $row_sign = -1; circle; }
          elsif ($row =  = 0 )      { $row_sign = +1; circle; }

          if    ($col =  = $maxcol) { $col_sign = -1; circle; }
          elsif ($col =  = 0 )      { $col_sign = +1; circle; }

      } until $interrupted;

  }

  # Clean up the screen.
  sub finish {
      gotoxy(0, $maxrow);
      clear_end( );
  }

This is what it looks like in mid-run:

*     _                       /     |                       \     -
 *   _ \                     - /   | /                     | \   - *
  * _   \                   -   / |   /                   |   \ -   *
   *     \                 -     |     /                 |     -     *
  _ *     \               -     | /     /               |     - \     *
 _   *     \             -     |   /     /             |     -   \     *
*     *     \           -     |     /     /           |     -     \     *
 *     *     \         -     |       /     /         |     -       \     *
  *     *     \       -     |         /     /       |     -         \     *
   *     *     \     -     |           /     /     |     -           \     *
    *     *     \   -     |             /     /   |     -             \     *
     *     *     \ -     |               /     / |     -               \
      *     -     \     |                 /     /     -                 \
       *   - *   - \   |                   /   | /   -                   \
        * -   * -   \ |                     / |   / -                     \ _
         -     -     \                       |     /                       _

15.21.2. See Also

termcap(5) (if you have it); the documentation for the standard Term::Cap module

Previous | Home | Next
15.20. Adding Text to an Image | Book Index | 15.22. Program: tkshufflepod
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.22. Program: tkshufflepod

This short program uses Tk to list the =head1 sections in the file using the Listbox widget, and it lets you drag the sections around to reorder them. When you're done, press "s" or "q" to save or quit. You can even double-click a section to view it with the Pod widget. It writes the section text to a temporary file in /tmp and removes the file when the Pod widget is destroyed.

Call it with the name of the Pod file to view:

% tkshufflepod chap15.pod

We used this a lot when we wrote this book.

The program text is shown in Example 15-9.

Example 15-9. tkshufflepod

  #!/usr/bin/perl -w
  # tkshufflepod - reorder =head1 sections in a pod file

  use Tk;
  use Tk::Pod;
  use strict;

  # declare variables

  my $podfile;     # name of the file to open
  my $m;             # main window
  my $l;             # listbox
  my ($up, $down);   # positions to move
  my @sections;      # list of pod sections
  my $all_pod;       # text of pod file (used when reading)

  # read the pod file into memory, and split it into sections.

  $podfile = shift || "-";

  undef $/;
  open(F, " < $podfile")
    or die "Can't open $podfile : $!\n";
  $all_pod = <F>;
  close(F);
  @sections = split(/(?=  =head1)/, $all_pod);

  # turn @sections into an array of anonymous arrays.  The first element
  # in each of these arrays is the original text of the message, while
  # the second element is the text following =head1 (the section title).

  foreach (@sections) {
      /(.*)/;
      $_ = [ $_, $1 ];
  }

  # fire up Tk and display the list of sections.

  $m = MainWindow->new( );
  $l = $m->Listbox('-width' => 60)->pack('-expand' => 1, '-fill' => 'both');

  foreach my $section (@sections) {
      $l->insert("end", $section->[1]);
  }

  # permit dragging by binding to the Listbox widget.
  $l->bind( '<Any-Button>'     => \&down );
  $l->bind( '<Any-ButtonRelease>' => \&up );

  # permit viewing by binding double-click
  $l->bind( '<Double-Button>'     => \&view );

  # 'q' quits and 's' saves
  $m->bind( '<q>'             => sub { exit } );
  $m->bind( '<s>'            => \&save );

  MainLoop;

  # down(widget): called when the user clicks on an item in the Listbox.

  sub down {
      my $self = shift;
      $down = $self->curselection;;
  }

  # up(widget): called when the user releases the mouse button in the
  # Listbox.

  sub up {
      my $self = shift;
      my $elt;

      $up = $self->curselection;;

      return if $down =  = $up;

      # change selection list
      $elt = $sections[$down];
      splice(@sections, $down, 1);
      splice(@sections, $up, 0, $elt);

      $self->delete($down);
      $self->insert($up, $sections[$up]->[1]);
  }

  # save(widget): called to save the list of sections.

  sub save {
      my $self = shift;

      open(F, "> $podfile")
        or die "Can't open $podfile for writing: $!";
      print F map { $_->[0] } @sections;
      close F;

      exit;
  }

  # view(widget): called to display the widget.  Uses the Pod widget.

  sub view {
      my $self = shift;
      my $temporary = "/tmp/$$-section.pod";
      my $popup;

      open(F, "> $temporary")
        or warn ("Can't open $temporary : $!\n"), return;
      print F $sections[$down]->[0];
      close(F);
      $popup = $m->Pod('-file' => $temporary);

      $popup->bind('<Destroy>' => sub { unlink $temporary } );

  }
Previous | Home | Next
15.21. Program: Small termcap Program | Book Index | 15.23. Program: graphbox
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.23. Program: graphbox

The graphbox program shown in Example 15-10 generates a bar graph of how many email messages were sent on each day of the week, using the GD::Graph::Bars module (see Recipe 15.18). It extracts the day of the week from the Date: headers and then plots the results.

Example 15-10. graphbox

#!/usr/bin/perl -w
# graphbox - graph number of messages by day of week they were sent

use GD::Graph::bars;
use Getopt::Std;
use strict;

my %count;  # running total of messages for each day of the week
my $chart;  # the GD::Graph::bars object
my $plot;   # the GD object containing the actual graph

my @DAYS = qw(Mon Tue Wed Thu Fri Sat Sun);
my $day_re = join("|", @DAYS);
$day_re = qr/$day_re/;

# process options

my %Opt;
getopts('ho:', \%Opt);
if ($Opt{h} or !$Opt{o}) {
  die "Usage:\n\t$0 -o outfile.png < mailbox\n";
}

# extract dates from Date headers (guessing!)

while (<>) {
  if (/^Date: .*($day_re)/) {
    $count{$1}++;
  }
}

# build graph

$chart = GD::Graph::bars->new(480,320);
$chart->set(x_label => "Day",
            y_label => "Messages",
            title   => "Mail Activity");
$plot = $chart->plot([ [ @DAYS ],
                       [ @count{@DAYS} ],
                     ]);

# save it

open(F, "> $Opt{o}")
  or die "Can't open $Opt{o} for writing: $!\n";
print F $plot->png;
close F;

Previous | Home | Next
15.22. Program: tkshufflepod | Book Index | 16. Process Management and Communication
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 16. Process Management and Communication

Contents:

Introduction
Gathering Output from a Program
Running Another Program
Replacing the Current Program with a Different One
Reading or Writing to Another Program
Filtering Your Own Output
Preprocessing Input
Reading STDERR from a Program
Controlling Input and Output of Another Program
Controlling the Input, Output, and Error of Another Program
Communicating Between Related Processes
Making a Process Look Like a File with Named Pipes
Sharing Variables in Different Processes
Listing Available Signals
Sending a Signal
Installing a Signal Handler
Temporarily Overriding a Signal Handler
Writing a Signal Handler
Catching Ctrl-C
Avoiding Zombie Processes
Blocking Signals
Timing Out an Operation
Turning Signals into Fatal Errors
Program: sigrand

Sherlock Holmes, The Red-Headed League

It is quite a three-pipe problem, and I beg that you won't speak to me for fifty minutes.

16.0. Introduction

Perl may be many things to many people, but to most of us it is the glue that connects diverse components. This chapter is about launching commands and connecting separate processes together. It's about managing their creation, communication, and ultimate demise. It's about systems programming.

When it comes to systems programming, Perl, as usual, makes easy things easy and hard things possible. If you want to use it as you would the shell, Perl is happy to assist you. If you want to roll up your sleeves for low-level hacking like a hardcore C programmer, you can do that, too.

Because Perl lets you get so close to the system, portability issues can sneak in. This chapter is the most Unix-centric chapter of the book. It will be tremendously useful to those on Unix systems, but of limited use to others. (If you're not on Unix, consult the perlport(3) manpage that came with Perl to see which of the techniques we describe are available on other operating systems or emulated by Perl.) We deal with features that aren't as universal as strings and numbers and basic arithmetic. Most basic operations work more or less the same everywhere. But if you're not using some kind of Unix or other POSIX conformant system, most of the interesting features in this chapter may work differently for you—or not at all. Check the documentation that came with your Perl port if you aren't sure.

You might even be pleasantly surprised. Windows users, for example, are often astonished to learn that Perl's fork function, long unique to Unix, is supported on their platform. See perlfork(1).

16.0.1 Process Creation

In this chapter, we cover the proper care and feeding of your own child processes. Sometimes this means launching a standalone command and letting it have its own way with the world (using system). Other times it means keeping a tight rein on your child, feeding it carefully filtered input or taking hold of its output stream (backticks and piped open s). Without even starting a new process, you can use exec to replace your current program with a completely different program.

We first show how to use the most portable and commonly used operations for managing processes: backticks, system, open, and the manipulation of the %SIG hash. Those are the easy things, but we don't stop there. We also show what to do when the simple approach isn't good enough.

For example, you might want to interrupt your program while it's running a different program. Maybe you need to process a child program's standard error separately from its standard output. Perhaps you need to control both the input and output of a program simultaneously. When you tire of having just one thread of control and begin to take advantage of multitasking, you'll want to learn how to split your current program into several, simultaneously running processes that all talk to each other.

For tasks like these, you have to drop back to the underlying syscalls: pipe, fork, and exec. The pipe function creates two connected filehandles, a reader and writer, whereby anything written to the writer can be read from the reader. The fork function is the basis of multitasking, but unfortunately it has not been supported on all non-Unix systems. It clones off a duplicate process identical in virtually every aspect to its parent, including variable settings and open files. The most noticeable changes are the process ID and parent process ID. New programs are started by forking, then using exec to replace the program in the child process with a new one. You don't always both fork and exec together, so having them as separate primitives is more expressive and powerful than if all you could do is run system. In practice, you're more apt to use fork by itself than exec by itself.

When a child process dies, its memory is returned to the operating system, but its entry in the process table isn't freed. This lets a parent check the exit status of its child processes. Processes that have died but haven't been removed from the process table are called zombies, and you should clean them up lest they fill the whole process table. Backticks and the system and close functions automatically take care of this, and will work on most non-Unix systems. You have more to worry about when you go beyond these simple portable functions and use low-level primitives to launch programs. One thing to worry about is signals.

16.0.2 Signals

Your process is notified of the death of a child it created with a signal. Signals are a kind of notification delivered by the operating system. They are used for errors (when the kernel says, "Hey, you can't touch that area of memory!") and for events (death of a child, expiration of a per-process timer, interrupt with Ctrl-C). If you're launching processes manually, you normally arrange for a subroutine of your choosing to be called whenever one of your children exits.

Each process has a default disposition for each possible signal. You may install your own handler or otherwise change the disposition of most signals. Only SIGKILL and SIGSTOP cannot be changed. The rest you can ignore, trap, or block.

Briefly, here's a rundown of the more important signals:

SIGINT
Normally triggered by Ctrl-C. This requests that a process interrupt what it's doing. Simple programs like filters usually just die, but more important ones like shells, editors, or FTP programs usually use SIGINT to stop long-running operations so you can tell them to do something else.

SIGQUIT
Also normally generated by a terminal, usually Ctrl-\. Its default behavior is to generate a core dump.

SIGTERM
Sent by the kill shell command when no signal name is explicitly given. Think of it as a polite request for a process to die.

SIGUSR1 and SIGUSR2
Never caused by system events, so user applications can safely use them for their own purposes.

SIGPIPE
Sent by the kernel when your process tries to write to a pipe or socket when the process on the other end has closed its connection, usually because it no longer exists.

SIGALRM
Sent when the timer set by the alarm function expires, as described in Recipe 16.21.

SIGHUP
Sent to a process when its controlling terminal gets a hang-up (e.g., the modem lost its carrier), but it also often indicates that a program should restart or reread its configuration.

SIGCHLD
Probably the most important signal when it comes to low-level systems programming. The system sends your process a SIGCHLD when one of its child processes stops running—or, more likely, when that child exits. See Recipe 16.19 for more on SIGCHLD.

Signal names are a convenience for humans. Each signal has an associated number that the operating system uses instead of names. Although we talk about SIGCHLD, your operating system knows it only as a number, like 20 (these numbers vary across operating systems). Perl translates between signal names and numbers for you, so you can think in terms of signal names.

Recipe 16.15, Recipe 16.17, Recipe 16.21, Recipe 16.18, and Recipe 16.20 run the full gamut of signal handling.

Previous | Home | Next
15.23. Program: graphbox | Book Index | 16.1. Gathering Output from a Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.1. Gathering Output from a Program

16.1.1. Problem

You want to run a program and collect its output into a variable.

16.1.2. Solution

Either use backticks:

$output = `program args`;   # collect output into one multiline string
@output = `program args`;   # collect output into array, one line per element

or use Recipe 16.4:

open(my $fh, "-|", "program", @args)
    or die "Can't run program: $!\n";
while (<$fh>) {
    $output .= $_;
}
close $fh;

16.1.3. Discussion

The backticks are a convenient way to run other programs and gather their output. The backticks do not return until the called program exits. Perl goes to some trouble behind the scenes to collect the output, so it is inefficient to use the backticks and ignore their return value:

`fsck -y /dev/rsd1a`;       # BAD AND SCARY

The backtick operator calls the shell to run the command. This makes it unsafe when used in a program with special privileges, but lets you use shell wildcards in the command:

@files = `ls -1 /music/*.mp3`;

If you want to read the output of a wildcarded command line as it's generated (and don't mind the potential security problems), use this form of open:

open(README, "ls -l /music/*.mp3 |") or die "Can't run program: $!\n";
while(<README>) {
    # the latest line is in $_
}
close(README);

In versions of Perl before 5.8, this two-argument form of open was the only one available to you. In those versions of Perl, you wrote the solution as:

open(FH, "program @args |")
  or die "Can't run program: $!\n";

Here's a low-level workaround, using pipe (to create two connected filehandles), fork (to split off a new process), and exec (to replace the new process with the program to read from):

use POSIX qw(:sys_wait_h);

my  ($readme, $writeme);
pipe $readme, $writeme;
if ($pid = fork) {
    # parent
    $SIG{CHLD} = sub { 1 while ( waitpid(-1, WNOHANG)) > 0 };
    close $writeme;
} else {
    die "cannot fork: $!" unless defined $pid;
    # child
    open(STDOUT, ">&=", $writeme)   or die "Couldn't redirect STDOUT: $!";
    close $readme;
    exec($program, $arg1, $arg2)    or die "Couldn't run $program : $!\n";
}

while (<$readme>) {
    $string .= $_;
    # or  push(@strings, $_);
}
close($readme);

There's no reason to prefer this over the open "-|" code in the Solution, except that the low-level workaround lets you change signal disposition before you launch the new program. For example, you could disable the INT signal in the child so that only the parent process receives it.

16.1.4. See Also

The section on The section on "Talking to Yourself" in Chapter 16 of Programming Perl or perlsec(1); Recipe 16.2; Recipe 16.4; Recipe 16.10; Recipe 16.19; Recipe 19.5

Previous | Home | Next
16. Process Management and Communication | Book Index | 16.2. Running Another Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.2. Running Another Program

16.2.1. Problem

From one program you want to run another, pause until it is done, and then continue with the original program. The other program should have the same STDIN and STDOUT as you have.

16.2.2. Solution

Call system with a string to have the shell interpret the string as a command line:

$status = system("vi $myfile");

If you don't want the shell involved, pass system a list:

$status = system("vi", $myfile);

16.2.3. Discussion

The system function is the simplest and most generic way to run another program in Perl. It doesn't gather the program's STDOUT like backticks or open. Instead, its return value is (essentially) that program's exit status. While the new program is running, your main program is suspended, so the new program can read from your STDIN and write to your STDOUT so users can interact with it.

Like open, exec, and backticks, system uses the shell to start the program whenever it's called with one argument. This is convenient when you want to do redirection or other tricks:

system("cmd1 args | cmd2 | cmd3 >outfile");
system("cmd args < infile >outfile 2>errfile");

To avoid the shell, call system with a list of arguments:

$status = system($program, $arg1, $arg);
die "$program exited funny: $?" unless $status =  = 0;

The returned status value is not just the exit value: it includes the signal number (if any) that the process died from. This is the same value that wait sets $? to. See Recipe 16.19 to learn how to decode this value.

The system function ignores SIGINT and SIGQUIT while child processes are running. That way those signals will kill only the child process. If you want your main program to die as well, check the return value of system or the value of the $? variable.

if (($signo = system(@arglist)) &= 127) {
    die "program killed by signal $signo\n";
}

To get the effect of a system that ignores SIGINT, install your own signal handler and then manually fork and exec:

if ($pid = fork) {
    # parent catches INT and berates user
    local $SIG{INT} = sub { print "Tsk tsk, no process interruptus\n" };
    waitpid($pid, 0);
} else {
    die "cannot fork: $!" unless defined $pid;
    # child ignores INT and does its thing
    $SIG{INT} = "IGNORE";
    exec("summarize", "/etc/logfiles")             or die "Can't exec: $!\n";
}

A few programs examine their own program name. Shells look to see whether they were called with a leading minus to indicate interactivity. The expn program at the end of Chapter 18 behaves differently if called as vrfy, which can happen if you've installed the file under two different links as suggested. This is why you shouldn't trust that $0 is really the pathname to the invoked program—you could have been lied to in a number of ways.

If you want to fib to the program you're executing about its own name, specify the real path as the "indirect object" in front of the list passed to system. (This also works with exec.) The indirect object has no comma following it, just like using printf with a filehandle or making object methods without the pointer arrow.

$shell = '/bin/tcsh';
system $shell '-csh';           # pretend it's a login shell

Or, more directly:

system {'/bin/tcsh'} '-csh';    # pretend it's a login shell

In the next example, the program's real pathname is supplied in the indirect object slot as {'/home/tchrist/scripts/expn'}. The fictitious name 'vrfy' is given as the first real function argument, which the program will see stored in $0.

# call expn as vrfy
system {'/home/tchrist/scripts/expn'} 'vrfy', @ADDRESSES;

Using an indirect object with system is also more secure. This usage forces interpretation of the arguments as a multivalued list, even if the list had just one argument. That way you're safe from the shell expanding wildcards or splitting up words with whitespace in them.

@args = ( "echo surprise" );

system @args;# subject to shell escapes if @args =  = 1
system { $args[0] } @args;  # safe even with one-arg list

The first version, the one without the indirect object, ran the echo program, passing it "surprise" as an argument. The second version didn't—it tried to run a program literally called "echo surprise", didn't find it, and set $? to a non-zero value indicating failure.

16.2.4. See Also

The section on "Talking to Yourself" in Chapter 16 of Programming Perl or perlsec(1); the waitpid, fork, exec, system, and open functions in Chapter 29 of Programming Perl, or perlfunc(1); Recipe 16.1; Recipe 16.4; Recipe 16.19; Recipe 19.5; Advanced Programming in the UNIX Environment, by Richard W. Stevens (Addison-Wesley)

Previous | Home | Next
16.1. Gathering Output from a Program | Book Index | 16.3. Replacing the Current Program with a Different One
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.3. Replacing the Current Program with a Different One

16.3.1. Problem

You want to replace the running program with another, as when checking parameters and setting up the initial environment before running another program.

16.3.2. Solution

Use the built-in exec function. If exec is called with a single argument containing metacharacters, the shell will be used to run the program:

exec("archive *.data")
    or die "Couldn't replace myself with archive: $!\n";

If you pass exec more than one argument, the shell will not be used:

exec("archive", "accounting.data")
    or die "Couldn't replace myself with archive: $!\n";

If called with a single argument containing no shell metacharacters, the argument will be split on whitespace and then interpreted as though the resulting list had been passed to exec:

exec("archive accounting.data")
    or die "Couldn't replace myself with archive: $!\n";

16.3.3. Discussion

The exec function in Perl is a direct interface to the execlp(2) syscall, which replaces the current program with another, leaving the process intact. The program that calls exec gets wiped clean, and its place in the operating system's process table is taken by the program specified in the arguments to exec. As a result, the new program has the same process ID ($$) as the original program. If the specified program couldn't be run, exec returns a false value and the original program continues. Be sure to check for this.

As with system (see Recipe 16.2), an indirect object identifies the program to be run:

exec { '/usr/local/bin/lwp-request' } 'HEAD', $url;

The first real argument ('HEAD' here) is what the new program will be told it is. Some programs use this to control their behavior, and others use it for logging. The main use of this, however, is that exec called with an indirect object will never use the shell to run the program.

If you exec yourself into a different program, neither your END blocks nor any object destructors will be automatically run as they would if your process actually exited.

16.3.4. See Also

The exec function in Chapter 29 of Programming Perl, and in perlfunc(1); your system's execlp(2) manpage (if you have it); Recipe 16.2

Previous | Home | Next
16.2. Running Another Program | Book Index | 16.4. Reading or Writing to Another Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.4. Reading or Writing to Another Program

16.4.1. Problem

You want to run another program and either read its output or supply the program with input.

16.4.2. Solution

Use open with a pipe symbol at the beginning or end. To read from a program, put the pipe symbol at the end:

$pid = open $readme, "-|", "program", "arguments"
                                            or die "Couldn't fork: $!\n";
while (<$readme>) {
    # ...
}
close $readme                               or die "Couldn't close: $!\n";

To write to the program, put the pipe at the beginning:

$pid = open $writeme, "|-", "program", "arguments"
                                            or die "Couldn't fork: $!\n";
print $writeme "data\n";
close $writeme                              or die "Couldn't close: $!\n";

16.4.3. Discussion

In the case of reading, this is similar to using backticks, except you have a process ID and a filehandle, and the shell is never involved. If you want Perl to use the shell when it sees shell-special characters in its argument—for example, to let the shell do filename wildcard expansion and I/O redirection—then you must use the two-argument form of open:

open($writeme, "| program args");
open($readme, "program args |");

However, sometimes this isn't desirable. Piped open s that include unchecked user data would be unsafe while running in taint mode or in untrustworthy situations.

Notice how we specifically call close on the filehandle. When you use open to connect a filehandle to a child process, Perl remembers this and automatically waits for the child when you close the filehandle. If the child hasn't exited by then, Perl waits until it does. This can be a very, very long wait if your child doesn't exit:

$pid = open $f, "-|", "sleep", "100000";  # child goes to sleep
close $f;                                 # and the parent goes to lala land

To avoid this, you can save the PID returned by open to kill your child, or use a manual pipe-fork-exec sequence as described in Recipe 16.10.

If you attempt to write to a process that has gone away, your process will receive a SIGPIPE. The default disposition for this signal is to kill your process, so the truly paranoid install a SIGPIPE handler just in case.

If you want to run another program and be able to supply its STDIN yourself, a similar construct is used:

$pid = open $writeme, "|-", "program", "args";
print $writeme "hello\n";            # program will get hello\n on STDIN
close $writeme;                      # program will get EOF on STDIN

The second argument to open ("|-") tells Perl to start another process instead. It connects the open ed filehandle to the process's STDIN. Anything you write to the filehandle can be read by the program through its STDIN. When you close the filehandle, the open ed process will get EOF when it next tries to read from STDIN.

You can also use this technique to change your program's normal output path. For example, to automatically run everything through a pager, use something like:

$pager = $ENV{PAGER} || '/usr/bin/less';  # XXX: might not exist
open(STDOUT, "|-", $pager);

Now, without changing the rest of your program, anything you print to standard output will go through the pager automatically.

As before, the parent should also be wary of close. If the parent closes the filehandle connecting it to the child, the parent will block while waiting for the child to finish. If the child doesn't finish, neither will the close. The workaround as before is to either kill your child process prematurely, or else use the low-level pipe-fork-exec scenario.

When using piped opens, always check return values of both open and close, not just of open. That's because the return value from open does not indicate whether the command was successfully launched. With a piped open, you fork a child to execute the command. Assuming the system hasn't run out of processes, the fork immediately returns the PID of the child it just created.

By the time the child process tries to exec the command, it's a separately scheduled process. So if the command can't be found, there's effectively no way to communicate this back to the open function, because that function is in a different process!

Check the return value from close to see whether the command was successful. If the child process exits with non-zero status—which it will do if the command isn't found—the close returns false and $? is set to the wait status of that process. You can interpret its contents as described in Recipe 16.19.

In the case of a pipe opened for writing, you should also install a SIGPIPE handler, since writing to a child that isn't there will trigger a SIGPIPE.

16.4.4. See Also

The open function in Chapter 29 of Programming Perl, and in perlfunc(1); Recipe 16.10; Recipe 16.15; Recipe 16.19; Recipe 19.5

Previous | Home | Next
16.3. Replacing the Current Program with a Different One | Book Index | 16.5. Filtering Your Own Output
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.5. Filtering Your Own Output

16.5.1. Problem

You want to postprocess your program's output without writing a separate program to do so.

16.5.2. Solution

Use the forking form of open to attach a filter to yourself. For example, this will restrict your program to a hundred lines of output:

head(100);
while (<>) {
    print;
}

sub head {
    my $lines = shift || 20;
    return if $pid = open STDOUT, "|-";
    die "cannot fork: $!" unless defined $pid;
    while (<STDIN>) {
        print;
        last unless --$lines;
    }
    exit;
}

16.5.3. Discussion

It's easy to add an output filter. Just use the forking open on your own STDOUT, and let the child filter STDIN to STDOUT, performing whatever alterations you care about. Notice that we install the output filter before we generate the output. This makes sense—you can't filter your output if it has already left your program. Any such filters should be applied in LIFO order—the last one inserted is the first one run.

Here's an example that uses two output filters. One numbers lines; the other quotes the lines like a mail reply. When run on /etc/motd, you get something like:

1:  > Welcome to Linux, version 2.0.33 on a i686
2:  >
3:  >    "The software required `Windows 95 or better',
4:  >     so I installed Linux."

If you reversed the order of the two filters, you'd get:

> 1: Welcome to Linux, Kernel version 2.0.33 on a i686
> 2:
> 3:     "The software required `Windows 95 or better',
> 4:      so I installed Linux."

The program is in Example 16-1.

Example 16-1. qnumcat

  #!/usr/bin/perl
  # qnumcat - demo additive output filters

  number( );                   # push number filter on STDOUT
  quote( );                    # push quote filter on STDOUT

  while (<>) {                # act like /bin/cat
      print;
  }
  close STDOUT;               # tell kids we're done--politely
  exit;

  sub number {
      my $pid;
      return if $pid = open STDOUT, "|-";
      die "cannot fork: $!" unless defined $pid;
      while (<STDIN>) { printf "%d: %s", $., $_ }
      exit;
  }

  sub quote {
      my $pid;
      return if $pid = open STDOUT, "|-";
      die "cannot fork: $!" unless defined $pid;
      while (<STDIN>) { print "> $_" }
      exit;
  }

As with all process forks, doing this a zillion times has some cost, but it's fine for a couple of processes, or even a couple dozen. If the system was actually designed to be multitasking right from the start, as Unix was, this is far cheaper than you might imagine. Virtual memory and copy-on-write makes this efficient. Forking is an elegant and inexpensive solution to many, if not most, multitasking needs.

16.5.4. See Also

The open function in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 16.4

Previous | Home | Next
16.4. Reading or Writing to Another Program | Book Index | 16.6. Preprocessing Input
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.6. Preprocessing Input

16.6.1. Problem

You'd like your programs to work on files with funny formats, such as compressed files or remote web documents specified with a URL, but your program only knows how to access regular text in local files.

16.6.2. Solution

Take advantage of Perl's easy pipe handling by changing your input files' names to pipes before opening them.

To autoprocess gzipped or compressed files by decompressing them with gzip, use:

@ARGV = map { /\.(gz|Z)$/ ? "gzip -dc $_ |" : $_  } @ARGV;
while (<>) {
    # .......
}

To fetch URLs before processing them, use the GET program from LWP (see Chapter 20):

@ARGV = map { m#^\w+://# ? "GET $_ |" : $_ } @ARGV;
while (<>) {
    # .......
}

You might prefer to fetch just the text, of course, not the HTML. That just means using a different command, perhaps lynx -dump.

16.6.3. Discussion

As shown in Recipe 16.1, Perl's built-in open function is magical: you don't have to do anything special to get Perl to open a pipe instead of a file. (That's why it's sometimes called magic open and, when applied to implicit ARGV processing, magic ARGV.) If it looks like a pipe, Perl will open it like a pipe. We take advantage of this by rewriting certain filenames to include a decompression or other preprocessing stage. For example, the file "09tails.gz" becomes "gzcat -dc 09tails.gz|".

This technique has further applications. Suppose you wanted to read /etc/passwd if the machine isn't using NIS, and the output of ypcat passwd if it is. You'd use the output of the domainname program to decide if you're running NIS, and then set the filename to open to be either "</etc/passwd" or "ypcat passwd|":

$pwdinfo = `domainname` =~ /^(\(none\))?$/
                ? '</etc/passwd'
                : 'ypcat  passwd |';

open(PWD, $pwdinfo)                 or die "can't open $pwdinfo: $!";

The wonderful thing is that even if you didn't think to build such processing into your program, Perl already did it for you. Imagine a snippet of code like this:

print "File, please? ";
chomp($file = <>);
open (FH, $file)                    or die "can't open $file: $!";

The user can enter a regular filename—or something like "webget http://www.perl.com |" instead—and your program would suddenly be reading from the output of some webget program. They could even enter -, a lone minus sign, which, when opened for reading, interpolates standard input instead.

This also comes in handy with the automatic ARGV processing we saw in Recipe 7.14.

16.6.4. See Also

Recipe 7.14; Recipe 16.4

Previous | Home | Next
16.5. Filtering Your Own Output | Book Index | 16.7. Reading STDERR from a Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.7. Reading STDERR from a Program

16.7.1. Problem

You want to run a program as you would with system, backticks, or open, but you don't want its STDERR to be sent to your STDERR. You would like to be able to either ignore or read the STDERR.

16.7.2. Solution

Use the shell's numeric redirection and duplication syntax for file descriptors. (We don't check the return value from open here in order to make the examples easier to read, but you should always check it in your programs!)

To capture a command's STDERR and STDOUT together:

$output = `cmd 2>&1`;                          # with backticks
# or
$pid = open(PH, "cmd 2>&1 |");                 # with an open pipe
while (<PH>) { }                               # plus a read

To capture a command's STDOUT and discard its STDERR:

$output = `cmd 2>/dev/null`;                   # with backticks
# or
$pid = open(PH, "cmd 2>/dev/null |");          # with an open pipe
while (<PH>) { }                               # plus a read

To capture a command's STDERR and discard its STDOUT:

$output = `cmd 2>&1 1>/dev/null`;              # with backticks
# or
$pid = open(PH, "cmd 2>&1 1>/dev/null |");     # with an open pipe
while (<PH>) { }                               # plus a read

To exchange a command's STDOUT and STDERR, i.e., capture the STDERR but have its STDOUT come out on our old STDERR:

$output = `cmd 3>&1 1>&2 2>&3 3>&-`;           # with backticks
# or
$pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");   # with an open pipe
while (<PH>) { }                               # plus a read

To read both a command's STDOUT and its STDERR separately, it's easiest and safest to redirect them separately to files, and then read from those files when the program is done:

system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");

16.7.3. Discussion

When you launch a command with backticks, a piped open, or system on a single string, Perl checks for characters special to the shell. These allow you to redirect the new program's file descriptors. STDIN is file descriptor number 0, STDOUT number 1, and STDERR number 2. You can then use 2>file to redirect STDERR to a file. The special notation &N where N is a file descriptor number is used to redirect to a file descriptor. Therefore, 2>&1 points STDERR at STDOUT.

Table 16-1 lists some interesting shell file descriptor redirections.

Table 16-1. Redirections and their meanings

Redirection | Meaning
0</dev/null | Make STDIN give immediate EOF
1>/dev/null | Discard STDOUT
2>/dev/null | Discard STDERR
2>&1 | Send STDERR to STDOUT instead
2>&- | Close STDERR (not recommended)
3<>/dev/tty | Open fd 3 to /dev/tty in read-write mode

Using this, let's examine the most complicated of the redirection sequences from the Solution:

$output = `cmd 3>&1 1>&2 2>&3 3>&-`;

There are four steps here:

Step A: 3>&1
Make a new file descriptor, number 3, be a copy of number 1. This saves the destination of STDOUT in the new file descriptor we've just opened.

Step B: 1>&2
Make STDOUT go wherever STDERR had been going. We still have the saved destination squirreled away in descriptor 3.

Step C: 2>&3
Make file descriptor 2 a copy of number 3. That means that STDERR is now going out where STDOUT originally had been going.

Step D: 3>&-
Since we're done moving streams around, keep everything nice and tidy and close our temporary file descriptor. This avoids file descriptor leaks.

If that's confusing, it might help to think in terms of regular variables and a sequence of assignment statements, with $fd1 representing STDOUT and $fd2 representing STDERR. If you wanted to exchange the two variables, you'd use a temporary file to hold one value. That's all we're doing here.

$fd3 = $fd1;
$fd1 = $fd2;
$fd2 = $fd3;
$fd3 = undef;

When all's said and done, the string returned from the backticks is the command's STDERR, and its STDOUT has been diverted to the original STDERR.

Ordering is important in all of these examples because the shell processes file descriptor redirections in strictly left to right order.

system("prog args 1>tmpfile 2>&1");
system("prog args 2>&1 1>tmpfile");

The first command sends both standard out and standard error to the temporary file. The second command sends only the old standard output there, and the old standard error shows up on the old standard out. If that's confusing, think in terms of assignments to variables representing file descriptors. For example:

# system ("prog args 1>tmpfile 2>&1");
$fd1 = "tmpfile";        # change stdout destination first
$fd2 = $fd1;             # now point stderr there, too

is very different from:

# system("prog args 2>&1 1>tmpfile");
$fd2 = $fd1;             # stderr same destination as stdout
$fd1 = "tmpfile";        # but change stdout destination

16.7.4. See Also

Your system's sh(1) manpage (if you have one) for details about file descriptor redirection; the system function in Chapter 29 of Programming Perl and in perlfunc(1)

Previous | Home | Next
16.6. Preprocessing Input | Book Index | 16.8. Controlling Input and Output of Another Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.8. Controlling Input and Output of Another Program

16.8.1. Problem

You want to both write to and read from another program. The open function lets you do one or the other, but not both.

16.8.2. Solution

Use the standard IPC::Open2 module:

use IPC::Open2;

$pid = open2(*README, *WRITEME, $program);
print WRITEME "here's your input\n";
$output = <README>;
close(WRITEME);
close(README);
waitpid($pid, 0);

16.8.3. Discussion

Wanting simultaneous read and write access to another program is very common, but surprisingly perilous. That's one reason the built-in open doesn't permit:

open(my $double_handle, "| program args |")     # WRONG

The big problem here is buffering. Because you can't force the other program to unbuffer its output, you can't guarantee that your reads won't block. If you block trying to read at the same time the other process blocks waiting for you to send something, you've achieved the unholy state of deadlock. There you'll both stay, wedged, until someone kills your process or the machine reboots.

If you control the other process's buffering because you wrote the other program and know how it works, then IPC::Open2 may be the module for you. If you pass undefined scalar values as the first two arguments, open2 creates new filehandles:

use IPC::Open2;

$pid = open2(my $reader, my $writer, $program);

Alternatively, you can pass in arguments that look like "<&OTHERFILEHANDLE" or ">&OTHERFILEHANDLE", which specify existing filehandles for the child process to read from or write to. These filehandles don't have to be controlled by your program—they may be connected to other programs, files, or sockets.

You can specify the program either as a list (where the first element is the program name and the remaining elements are arguments to the program) or as a single string (which is passed to the shell as a command to start the program). If you also want control over the process's standard error, use the IPC::Open3 module and see the next recipe.

If an error occurs, open2 and open3 do not return. Instead, they die with an error message that begins with "open2" or "open3". To test for failure, use the eval BLOCK construct:

eval {
    $pid = open2($readme, $writeme, @program_and_arguments);
};
if ($@) {
    if ($@ =~ /^open2/) {
        warn "open2 failed: $!\n$@\n";
        return;
    }
    die;            # reraise unforeseen exception
}

You must call waitpid, as we do in the Solution, because IPC::Open2 doesn't reap the child process after it exits. See Recipe 16.19 for details.

16.8.4. See Also

The documentation for the IPC::Open2 and IPC::Open3 modules; Recipe 10.12; the eval function in Chapter 29 of Programming Perl and in perlfunc(1); the $@ variable in the section on "Special Variables in Alphabetical Order" in Chapter 28 of Programming Perl and in perlvar(1)

Previous | Home | Next
16.7. Reading STDERR from a Program | Book Index | 16.9. Controlling the Input, Output, and Error of Another Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.9. Controlling the Input, Output, and Error of Another Program

16.9.1. Problem

You want full control over a command's input, output, and error streams.

16.9.2. Solution

Carefully use the standard IPC::Open3 module, possibly in conjunction with the standard IO::Select module.

16.9.3. Discussion

If you're interested in only one of the program's STDIN, STDOUT, or STDERR, the task is simple. When you want to manage two or more of these, however, it abruptly stops being simple. Multiplexing multiple I/O streams is never a pretty picture. Here's an easy workaround:

@all = `($cmd | sed -e 's/^/stdout: /' ) 2>&1`;
for (@all) { push @{ s/stdout: // ? \@outlines : \@errlines }, $_ }
print "STDOUT:\n", @outlines, "\n";
print "STDERR:\n", @errlines, "\n";

If you don't have sed on your system, you'll find that for simple cases like this, perl -pe works just as well as sed -e.

However, that's not really simultaneous processing. All we're doing is marking STDOUT lines with "stdout:" and then stripping them back out once we've read all the STDOUT and STDERR the program produced.

You can use the standard IPC::Open3 module for this. Mysteriously, the argument order is different for IPC::Open3 than for IPC::Open2.

open3($write_me, $read_me, $errors, "program to run");

Using this has even more potential for chaos than using open2. If you're reading the program's STDERR as it is trying to write more than one buffer's worth to its STDOUT, the program will block on the write because its buffers are full, and you will block on the read because there's nothing available.

You can avoid this deadlock by mimicking open3 with fork, open, and exec; making all filehandles unbuffered; and using sysread, syswrite, and select to decide which readable filehandle to read a byte from. This makes your program slower and bulkier, though, and it doesn't solve the classic open2 deadlock where each program is expecting the other to say something.

use IPC::Open3;
$pid = open3($child_in, $child_out, $child_err, $cmd);
close $child_in;  # give end-of-file to kid
@outlines = <$child_out>;              # read till EOF
@errlines = <$child_err>;              # XXX: block potential if massive
print "STDOUT:\n", @outlines, "\n";
print "STDERR:\n", @errlines, "\n";

As if deadlock weren't bad enough, this approach is subtly error-prone. There are at least three worrisome situations: both the child and the parent trying to read at the same time, causing deadlock; full buffers causing the child to block as it tries to write to STDERR while the parent is blocked trying to read from the child's STDOUT; and full buffers causing the parent to block writing to the child's STDIN while the child is blocked writing to either its STDOUT or STDERR. The first problem is generally unsolvable, although you can work around it by setting timers with alarm and preventing blocking operations from restarting if a SIGALRM is received.

We use the IO::Select module (you could also do this with the built-in function select) to learn which filehandles (if any) can be read from. This solves the second problem, but not the third. To solve the third, you also need alarm and non-restarting SIGALRM.

If you want to send input to the program, read its output, and either read or ignore its error, you need to work much harder. (See Example 16-2.)

Example 16-2. cmd3sel

  #!/usr/bin/perl
  # cmd3sel - control all three of kids in, out, and error.
  use IPC::Open3;
  use IO::Select;

  $cmd = "grep vt33 /none/such - /etc/termcap";
  $pid = open3($cmd_in, $cmd_out, $cmd_err, $cmd);

  $SIG{CHLD} = sub {
      print "REAPER: status $? on $pid\n" if waitpid($pid, 0) > 0
  };

  print $cmd_in "This line has a vt33 lurking in it\n";
  close $cmd_in;

  $selector = IO::Select->new( );
  $selector->add($cmd_err, $cmd_out);

  while (@ready = $selector->can_read) {
      foreach $fh (@ready) {
          if (fileno($fh) =  = fileno($cmd_err)) {print "STDERR: ", scalar <$cmd_err>}
          else                                 {print "STDOUT: ", scalar <$cmd_out>}
          $selector->remove($fh) if eof($fh);
      }
  }
  close $cmd_out;
  close $cmd_err;

We sent only a short line as input, then closed the handle. This avoids the deadlock situation of two processes each waiting for the other to write something.

16.9.4. See Also

The documentation for the standard IO::Select, IPC::Open2, and IPC::Open3 modules; the alarm function in Chapter 29 of Programming Perl or perlfunc(1); Recipe 16.8; Recipe 16.15; Recipe 16.16

Previous | Home | Next
16.8. Controlling Input and Output of Another Program | Book Index | 16.10. Communicating Between Related Processes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.10. Communicating Between Related Processes

16.10.1. Problem

You have two related processes that need to communicate, and you need better control than you can get from open, system, and backticks.

16.10.2. Solution

Use pipe and then fork:

my ($reader, $writer);
pipe $reader, $writer;
if (fork) {
    # run parent code, either reading or writing, not both
} else {
    # run child code, either reading or writing, not both
}

Or use a special forking form of open:

if ($pid = (open $child, "|-")) {
        # run parent code, writing to child
} else {
    die "cannot fork: $!" unless defined $pid;
    # otherwise run child code here, reading from parent
}

Or, going the other way:

if ($pid = open ($child, "-|")) {
    # run parent code, reading from child
} else {
    die "cannot fork: $!" unless defined $pid;
    # otherwise run child code here, writing to parent
}

16.10.3. Discussion

Pipes are simply two connected filehandles, where data written to one filehandle can be read by the other. The pipe function creates two filehandles linked in this way, one writable and one readable. Even though you can't take two already existing filehandles and link them, pipe can be used for communication between processes. One process creates a pair of filehandles with the pipe functions, then forks off a child, resulting in two distinct processes both running in the same program, each with a copy of the connected filehandles. As with open, if pipe is passed undefined scalars instead of filehandles, it creates filehandles in those scalars.

It doesn't matter which process is the reader and which is the writer, so long as one of them takes one role and its peer process takes the other. You can only have one-way communication. (But read on.)

We'll pull in the IO::Handle module so we can call its autoflush method. (You could instead play the select games described in Chapter 7, if you prefer a lightweight solution.) If we didn't, our single line of output would get lodged in the pipe and not make it through to the other side until we closed that handle.

The version of the parent writing to the child is shown in Example 16-3.

Example 16-3. pipe1

  #!/usr/bin/perl -w
  # pipe1 - use pipe and fork so parent can send to child

  use IO::Handle;
  my ($reader, $writer);
  pipe $reader, $writer;
  $writer->autoflush(1);

  if ($pid = fork) {
      close $reader;
      print $writer "Parent Pid $$ is sending this\n";
      close $writer;
      waitpid($pid,0);
  } else {
      die "cannot fork: $!" unless defined $pid;
      close $writer;
      chomp($line = <$reader>);
      print "Child Pid $$ just read this: `$line'\n";
      close $reader;  # this will happen anyway
      exit;
  }

In the examples in this recipe, most error checking has been left as an exercise for the reader. This is so you can more clearly see how the functions interact. In real life, test the return values of all syscalls.

The version of the child writing to the parent is shown in Example 16-4.

Example 16-4. pipe2

  #!/usr/bin/perl -w
  # pipe2 - use pipe and fork so child can send to parent

  use IO::Handle;
  my ($reader, $writer);
  pipe($reader, $writer);
  $writer->autoflush(1);

  if ($pid = fork) {
      close $writer;
      chomp($line = <$reader>);
      print "Parent Pid $$ just read this: `$line'\n";
      close $reader;
      waitpid($pid,0);
  } else {
      die "cannot fork: $!" unless defined $pid;
      close $reader;
      print $writer "Child Pid $$ is sending this\n";
      close $writer;  # this will happen anyway
      exit;
  }

In most code, both halves would go into loops, with the reader continuing to read until end-of-file. This happens when the writer closes or exits.

Because piped filehandles are not bidirectional, each process uses just one of the pair and closes the filehandle it doesn't use. The reason is subtle; picture the situation where the reader does not close the writable filehandle. If the writer then exits while the reader is trying to read something, the reader will hang forever. This is because the system won't tell the reader that there's no more data to be read until all copies of the writable filehandle are closed.

The open function, when passed as its second argument either "-|" or "|-", will implicitly pipe and fork. This makes the piping code shown earlier slightly easier. The child talks to the parent over STDIN or STDOUT, depending on whether "-|" or "|-" was used.

Using open this way, if the parent wants to write to the child, it does something like what's shown in Example 16-5.

Example 16-5. pipe3

  #!/usr/bin/perl -w
  # pipe3 - use forking open so parent can send to child

  use IO::Handle;
  if ($pid = open ($child, "|-")) {
      $child->autoflush(1);
      print $child "Parent Pid $$ is sending this\n";
      close $child;
  } else {
      die "cannot fork: $!" unless defined $pid;
      chomp($line = <STDIN>);
      print "Child Pid $$ just read this: `$line'\n";
      exit;
  }

Since the child already has STDIN set to the parent, the child could exec some other program that expects to read from standard input, such as lpr. In fact, this is useful and commonly done.

If the child wants to write to the parent, it does something like what's shown in Example 16-6.

Example 16-6. pipe4

  #!/usr/bin/perl -w
  # pipe4 - use forking open so child can send to parent

  use IO::Handle;
  if ($pid = open $child, "-|") {
      chomp($line = <$child>);
      print "Parent Pid $$ just read this: `$line'\n";
      close $child;
  } else {
      die "cannot fork: $!" unless defined $pid;
      STDOUT->autoflush(1);
      print STDOUT "Child Pid $$ is sending this\n";
      exit;
  }

Again, since the child already has its STDOUT connected to the parent, this child could exec some other program to produce something interesting on its standard output. That output would be available to the parent as input from <CHILD>.

When using open this way, we don't have to manually call waitpid since we didn't do a manual fork. We do have to call close, though. In both cases, the $? variable will have the child's wait status in it (see Recipe 16.19 to see how to interpret this status value).

The preceding examples were unidirectional. What if you want both processes talking to each other? Just make two calls to pipe before forking. You must be careful about who tells whom what and when, though, or you're apt to deadlock. (See Example 16-7.)

Example 16-7. pipe5

  #!/usr/bin/perl -w
  # pipe5 - bidirectional communication using two pipe pairs
  #         designed for the socketpair-challenged
  use IO::Handle;
  my ($parent_rdr, $child_wtr, $child_rdr, $parent_wtr);
  pipe $parent_rdr, $child_wtr;
  pipe $child_rdr,  $parent_wtr;
  $child_wtr->autoflush(1);
  $parent_wtr->autoflush(1);

  if ($pid = fork) {
      close $parent_rdr; close $parent_wtr;
      print $child_wtr "Parent Pid $$ is sending this\n";
      chomp($line = <$child_rdr>);
      print "Parent Pid $$ just read this: `$line'\n";
      close $child_rdr; close $child_wtr;
      waitpid($pid,0);
  } else {
      die "cannot fork: $!" unless defined $pid;
      close $child_rdr; close $child_wtr;
      chomp($line = <$parent_rdr>);
      print "Child Pid $$ just read this: `$line'\n";
      print $parent_wtr "Child Pid $$ is sending this\n";
      close $parent_rdr; close $parent_wtr;
      exit;
  }

That's getting complicated. It just so happens that there's a special syscall, shown in Example 16-8, that makes the last example simpler. It's called socketpair, and it works like pipe, except that both handles can be used for reading and for writing.

Example 16-8. pipe6

  #!/usr/bin/perl -w
  # pipe6 - bidirectional communication using socketpair
  #   "the best ones always go both ways"

  use Socket;
  use IO::Handle;
  # We say AF_UNIX because although *_LOCAL is the
  # POSIX 1003.1g form of the constant, many machines
  # still don't have it.
  socketpair($child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
      or  die "socketpair: $!";

  $child->autoflush(1);
  $parent->autoflush(1);

  if ($pid = fork) {
      close $parent;
      print $child "Parent Pid $$ is sending this\n";
      chomp($line = <$child>);
      print "Parent Pid $$ just read this: `$line'\n";
      close $child;
      waitpid($pid,0);
  } else {
      die "cannot fork: $!" unless defined $pid;
      close $child;
      chomp($line = <$parent>);
      print "Child Pid $$ just read this: `$line'\n";
      print $parent "Child Pid $$ is sending this\n";
      close $parent;
      exit;
  }

In fact, some systems have historically implemented pipes as two half-closed ends of a socketpair. They essentially define pipe($reader, $writer) this way:

socketpair($reader, $writer, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
shutdown($reader, 1);        # no more writing for reader
shutdown($writer, 0);        # no more reading for writer

16.10.4. See Also

Chapter 29 of Programming Perl or perlfunc(1) for all functions used here; the documentation for the standard IPC::Open2 module; Advanced Programming in the UNIX Environment; Recipe 16.8; Recipe 19.5

Previous | Home | Next
16.9. Controlling the Input, Output, and Error of Another Program | Book Index | 16.11. Making a Process Look Like a File with Named Pipes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.11. Making a Process Look Like a File with Named Pipes

16.11.1. Problem

You want a process to intercept all access to a file. For instance, you want to make your ~/.plan file a program that returns a random quote.

16.11.2. Solution

Use named pipes. First create one, probably from your shell:

% mkfifo /path/to/named.pipe

Here's a reader for it:

open($fifo, "<", "/path/to/named.pipe")      or die $!;
while (<$fifo>) {
    print "Got: $_";
}
close $fifo;

Here's a writer for it:

open($fifo, ">", "/path/to/named.pipe")      or die $!;
print $fifo "Smoke this.\n";
close $fifo;

16.11.3. Discussion

A named pipe, or FIFO as they are also known, is a special file that acts as a buffer to connect processes on the same machine. Ordinary pipes also allow processes to communicate, but those processes must have inherited the filehandles from their parents. To use a named pipe, a process need know only the named pipe's filename. In most cases, processes don't even need to be aware that they're reading from a FIFO.

Named pipes can be read from and written to just as though they were ordinary files (unlike Unix-domain sockets as discussed in Chapter 17). Data written into the FIFO is buffered up by the operating system, then read back in the order it was written in. Because a FIFO acts as a buffer to connect processes, opening one for reading will block until another process opens it for writing, and vice versa. If you open for read and write using the +< mode to open, you won't block (on most systems), because your process could be both reader and writer.

Let's examine how to use a named pipe so people will get a different file each time they finger you. To create a named pipe, use mkfifo or mknod to create a named pipe called .plan in your home directory:

% mkfifo ~/.plan                    # isn't this everywhere yet?
% mknod  ~/.plan p                  # in case you don't have mkfifo

On some systems, you must use mknod(8). The location and names of these programs aren't uniform or necessarily obvious, so consult your system documentation to find out where these programs are.

The next step is to create a program to feed data to the programs that read from your ~/.plan file. We'll just print the date and time, as shown in Example 16-9.

Example 16-9. dateplan

  #!/usr/bin/perl -w
  # dateplan - place current date and time in .plan file
  while (1) {
      open($fifo, "> $ENV{HOME}/.plan")
          or die "Couldn't open $ENV{HOME}/.plan for writing: $!\n";
      print $fifo "The current time is ", scalar(localtime), "\n";
      close $fifo;
      sleep 1;
  }

Unfortunately, this won't always work, because some finger programs and their attendant daemons check the size of the .plan file before trying to read it. Because named pipes appear as special files of zero size on the filesystem, such clients and servers will not try to open or read from our named pipe, and the trick will fail.

In our .plan example, the writer was a daemon. It's not uncommon for readers to be daemons as well. Take, for instance, the use of a named pipe to centralize logging from many processes. The log server reads log messages from the named pipe and can send them to a database or file. Clients write their messages to the named pipe. This removes the distribution logic from the clients, making changes to message distribution easy to implement.

Example 16-10 is a simple program to read two-line messages where the first line is the name of the service and the second line is the message being logged. All messages from httpd are ignored, while all messages from login are saved to /var/log/login.

Example 16-10. fifolog

  #!/usr/bin/perl -w
  # fifolog - read and record log msgs from fifo

  $SIG{ALRM} = sub { close(FIFO) };   # move on to the next queued process

  while (1) {
      alarm(0);                       # turn off alarm for blocking open
      open($fifo, "</tmp/log")        or die "Can't open /tmp/log : $!\n";
      alarm(1);                       # you have 1 second to log

      $service = <$fifo>;
      next unless defined $service;   # interrupted or nothing logged
      chomp $service;

      $message = <$fifo>;
      next unless defined $message;   # interrupted or nothing logged
      chomp $message;

      alarm(0);                       # turn off alarms for message processing

      if ($service eq "http") {
          # ignoring
      } elsif ($service eq "login") {
          # log to /var/log/login
          if ( open($log, ">> /tmp/login") ) {
              print $log scalar(localtime), " $service $message\n";
              close $log;
          } else {
              warn "Couldn't log $service $message to /var/log/login : $!\n";
          }
      }
  }

This program is more complicated than the .plan program for several reasons. First and foremost, we don't want our logging server to block would-be writers for long. It's easy to imagine a situation where an attacker or misbehaving writer opens the named pipe for writing, but doesn't send a complete message. To prevent this, we use alarm and SIGALRM to signal us if we get stuck reading.

Only two exceptional conditions can happen when using named pipes: a writer can have its reader disappear, or vice versa. If a process is reading from a named pipe and the writer closes its end, the reading process will get an end-of-file (<> returns undef). If the reader closes the connection, though, the writer will get a SIGPIPE when it next tries to write there. If you disregard broken pipe signals with $SIG{PIPE} = 'IGNORE', your print will return a false value and $! will be set to EPIPE:

use POSIX qw(:errno_h);

$SIG{PIPE} = 'IGNORE';
# ...
$status = print $fifo "Are you there?\n";
if (!$status && $! =  = EPIPE) {
    warn "My reader has forsaken me!\n";
    next;
}

You may be asking "If I have 100 processes all trying simultaneously to write to this server, how can I be sure that I'll get 100 separate entries and not a jumbled mishmash with characters or lines from different processes?" That's a good question. The POSIX standard says that writes of less than PIPE_BUF bytes in size will be delivered atomically, i.e., not jumbled. You can get the PIPE_BUF constant from POSIX:

use POSIX;
print PIPE_BUF, "\n";

Fortunately, the POSIX standard also requires PIPE_BUF to be at least 512 bytes. This means that all we have to do is ensure that our clients don't try to log more than 512 bytes at a time.

What if you want to log more than 512 bytes at a time? Then you split each large message into several smaller (fewer than 512 bytes) messages, preface each with the unique client identifier (process ID, say), and have the server reassemble them. This is similar to the processing involved in TCP/IP message fragmentation and reassembly.

Because a single named pipe doesn't allow bidirectional access between writer and reader, authentication and similar ways of preventing forged messages are hard to do (if not impossible). Rather than struggle to force such things on top of a model that doesn't accommodate them, you are better off using the filesystem's access control to restrict access to the file through the owner and group permissions on the named pipe.

16.11.4. See Also

mkfifo(8) or mknod(8) (if you have them); Recipe 17.6

Previous | Home | Next
16.10. Communicating Between Related Processes | Book Index | 16.12. Sharing Variables in Different Processes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.12. Sharing Variables in Different Processes

16.12.1. Problem

You want to share variables across forks or between unrelated processes.

16.12.2. Solution

Use SysV IPC if your operating system supports it.

16.12.3. Discussion

While SysV IPC (shared memory, semaphores, etc.) isn't as widely used as pipes, named pipes, and sockets for interprocess communication, it still has some interesting properties. Normally, however, you can't expect to use shared memory via shmget or the mmap(2) syscall to share a variable among several processes. That's because Perl would reallocate your string when you weren't wanting it to.

The CPAN module IPC::Shareable takes care of that. Using a clever tie module, SysV shared memory, and the Storable module from CPAN allows data structures of arbitrary complexity to be shared among cooperating processes on the same machine. These processes don't even have to be related to each other.

Example 16-11 is a simple demonstration of the module.

Example 16-11. sharetest

  #!/usr/bin/perl
  # sharetest - test shared variables across forks
  use IPC::Shareable;

  $handle = tie $buffer, 'IPC::Shareable', undef, { destroy => 1 };
  $SIG{INT} = sub { die "$$ dying\n" };

  for (1 .. 10) {
      unless ($child = fork) {        # i'm the child
          die "cannot fork: $!" unless defined $child;
          squabble( );
          exit;
      }
      push @kids, $child;  # in case we care about their pids
  }

  while (1) {
      print "Buffer is $buffer\n";
      sleep 1;
  }
  die "Not reached";

  sub squabble {
      my $i = 0;
      while (1) {
          next if $buffer =~ /^$$\b/o;
          $handle->shlock( );
          $i++;
          $buffer = "$$ $i";
          $handle->shunlock( );
      }
  }

The starting process creates the shared variable, forks off 10 children, and then sits back and prints out the value of the buffer every second or so, forever, or until you hit Ctrl-C.

Because the SIGINT handler was set before any forking, it got inherited by the squabbling children as well, so they'll also bite the dust when the process group is interrupted. Keyboard interrupts send signals to the whole process group, not just one process.

What do the kids squabble over? They're bickering over who gets to update that shared variable. Each one looks to see whether someone else was here or not. So long as the buffer starts with their own signature (their PID), they leave it alone. As soon as someone else has changed it, they lock the shared variable using a special method call on the handle returned from the tie, update it, and release the lock.

The program runs much faster by commenting out the line that starts with next where each process is checking that they were the last one to touch the buffer.

The /^$$\b/o may look suspicious, since /o tells Perl to compile the pattern once only, but then went and changed the variable's value by forking. Fortunately, the value isn't locked at program compile time, but only the first time the pattern is itself compiled in each process, during whose own lifetime $$ does not alter.

The IPC::Sharable module also supports sharing variables among unrelated processes on the same machine. See its documentation for details.

16.12.4. See Also

The semctl, semget, semop, shmctl, shmget, shmread, and shmwrite functions in Chapter 29 of Programming Perl, and in perlfunc(1); the documentation for the IPC::Shareable module from CPAN

Previous | Home | Next
16.11. Making a Process Look Like a File with Named Pipes | Book Index | 16.13. Listing Available Signals
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.13. Listing Available Signals

16.13.1. Problem

You want to know the signals your operating system provides.

16.13.2. Solution

If your shell has a built-in kill -l command, use it:

% kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE
ALRM TERM CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM
PROF WINCH POLL PWR

Or using just Perl, print the keys in %SIG if you have release 5.004 or later:

% perl -e 'print join(" ", keys %SIG), "\n"'
XCPU ILL QUIT STOP EMT ABRT BUS USR1 XFSZ TSTP INT IOT USR2 INFO TTOU
ALRM KILL HUP URG PIPE CONT SEGV VTALRM PROF TRAP IO TERM WINCH CHLD
FPE TTIN SYS

Before Version 5.004, you had to use the Config module:

% perl -MConfig -e 'print $Config{sig_name}'
ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM
TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH
INFO USR1 USR2 IOT

16.13.3. Discussion

If your version of Perl is before 5.004, you have to use signame and signo in Config to find the list of available signals, since keys %SIG wasn't implemented then.

The following code retrieves by name and number the available signals from Perl's standard Config.pm module. Use @signame indexed by number to get the signal name, and %signo indexed by name to get the signal number.

use Config;
defined $Config{sig_name} or die "No sigs?";
$i = 0;                     # Config prepends fake 0 signal called "ZERO".
foreach $name (split(' ', $Config{sig_name})) {
    $signo{$name} = $i;
    $signame[$i] = $name;
    $i++;
}

16.13.4. See Also

The documentation for the standard Config module, also in Chapter 32 of Programming Perl; the "Signals" sections in Chapter 16 of Programming Perl and in perlipc(1)

Previous | Home | Next
16.12. Sharing Variables in Different Processes | Book Index | 16.14. Sending a Signal
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.14. Sending a Signal

16.14.1. Problem

You want to send a signal to a process. This could be sent to your own process or to another on the same system. For instance, you caught SIGINT and want to pass it on to your children.

16.14.2. Solution

Use kill to send a signal by name or number to the process IDs listed in the remaining arguments:

kill  9     => $pid;                    # send $pid a signal 9
kill -1     => $pgrp;                   # send whole job a signal 1
kill  USR1  => $$;                      # send myself a SIGUSR1
kill  HUP   => @pids;                   # send a SIGHUP to processes in @pids

16.14.3. Discussion

Perl's kill function is an interface to the syscall of the same name. The first argument is the signal to send, identified by number or by name; subsequent arguments are process IDs to send the signal to. It returns the count of processes successfully signaled. You can only send signals to processes running under the same real or saved UID as your real or effective UID—unless you're the superuser.

If the signal number is negative, Perl interprets remaining arguments as process group IDs and sends that signal to all those groups' processes using the killpg(2) syscall.

A process group is essentially a job. It's how the operating system ties related processes together. For example, when you use your shell to pipe one command into another, you've started two processes, but only one job. When you use Ctrl-C to interrupt the current job or Ctrl-Z to suspend it, this sends the appropriate signals to the entire job, which may be more than one process.

kill can also check whether a process is alive. Sending the special pseudo-signal number 0 checks whether it's legal for you to send a signal to the process—without actually sending one. If it returns true, the process is still alive. If it returns false, the process either has changed its effective UID (in which case $! will be set to EPERM) or no longer exists (and $! is ESRCH). Zombie processes (as described in Recipe 16.19) also report back as ESRCH.

use POSIX qw(:errno_h);

if (kill 0 => $minion) {
    print "$minion is alive!\n";
} elsif ($! =  = EPERM) {             # changed uid
    print "$minion has escaped my control!\n";
} elsif ($! =  = ESRCH) {
    print "$minion is deceased.\n";  # or zombied
} else {
    warn "Odd; I couldn't check on the status of $minion: $!\n";
}

16.14.4. See Also

The "Signals" sections in Chapter 16 of Programming Perl and in perlipc(1); your system's sigaction(2), signal(3), and kill(2) manpages (if you have them); the kill function in Chapter 29 of Programming Perl and perlfunc(1)

Previous | Home | Next
16.13. Listing Available Signals | Book Index | 16.15. Installing a Signal Handler
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.15. Installing a Signal Handler

16.15.1. Problem

You want to control how your program responds to signals. You need to do this if you want to catch Ctrl-C, avoid accumulating finished subprocesses, or prevent your process from dying when it writes to a child that has gone away.

16.15.2. Solution

Use the %SIG hash to install your own handler by name or by code reference:

$SIG{QUIT} = \&got_sig_quit;     # call &got_sig_quit for every SIGQUIT
$SIG{PIPE} = 'got_sig_pipe';     # call main::got_sig_pipe for every SIGPIPE
$SIG{INT}  = sub { $ouch++ };    # increment $ouch for every SIGINT

%SIG also lets you ignore a signal:

$SIG{INT} = 'IGNORE';            # ignore the signal INT

It also restores handling for that signal to the default:

$SIG{STOP} = 'DEFAULT';          # restore default STOP signal handling

16.15.3. Discussion

Perl uses the %SIG hash to control what happens when signals are received. Each key in %SIG corresponds to a signal. Each value is the action to take when Perl receives the corresponding signal. Perl provides two special behaviors: "IGNORE" to take no action when a particular signal is received, and "DEFAULT" to perform the default Unix action for that signal.

Although a C programmer might think of a signal as SIGINT, Perl uses just INT. Perl figures you only use signal names in functions that deal with signals, so the SIG prefix is redundant. This means that you'll assign to $SIG{CHLD} to change what your process does when it gets a SIGCHLD.

If you want to run your own code when a given signal is received, you have two choices of what to put in the hash: either a code reference or a subroutine name. (This means you can't name a signal handler IGNORE or DEFAULT if you store the string, but they'd be mighty strange names for signal handlers anyway.) If you use a subroutine name that isn't qualified by a package, Perl will interpret this name to be a function in the main:: package, not one in the package in which the handler was installed. A code reference refers to a subroutine in a particular package, so it is a better choice.

Perl calls your handler code with a single argument: the name of the signal that triggered it, such as "INT" or "USR1". Returning from a signal handler takes you back to whatever you were doing when the signal hit.

Perl defines two special signals, _ _DIE_ _ and _ _WARN_ _, whose handlers are called whenever a Perl program emits warnings through warn or dies through die. This lets you catch such warnings, and selectively trap or propagate them. The die and warn handlers are disabled while they run, so you can safely die from a _ _DIE_ _ handler or warn from a _ _WARN_ _ handler without fear of recursion.

16.15.4. See Also

The "Signals" sections in Chapter 16 of Programming
Perl and in perlipc(1); your
system's sigaction(2),
signal(3), and kill(2)
manpages (if you have them)

Previous | Home | Next
16.14. Sending a Signal | Book Index | 16.16. Temporarily Overriding a Signal Handler
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.16. Temporarily Overriding a Signal Handler

16.16.1. Problem

You want to install a signal handler only for a particular subroutine. For instance, your subroutine catches SIGINT, and you don't want to disturb SIGINT handling outside the subroutine.

16.16.2. Solution

Use local to temporarily override a signal's behavior:

# the signal handler
sub ding {
    $SIG{INT} = \&ding;
    warn "\aEnter your name!\n";
}

# prompt for name, overriding SIGINT
sub get_name {
    local $SIG{INT} = \&ding;
    my $name;

    print "Kindly Stranger, please enter your name: ";
    chomp( $name = <> );
    return $name;
}

16.16.3. Discussion

You must use local rather than my to save away one value out of %SIG. The change remains in effect throughout the execution of that block, including in anything called from it. In this case, that's the get_name subroutine. If the signal is delivered while another function that your function calls is running, your signal handler is triggered—unless the called subroutine installs its own signal handler. The previous value of the hash is automatically restored when the block exits. This is one of the (few) places where dynamic scoping is more convenient than confusing.

16.16.4. See Also

Recipe 10.13; Recipe 16.15; Recipe 16.18

Previous | Home | Next
16.15. Installing a Signal Handler | Book Index | 16.17. Writing a Signal Handler
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.17. Writing a Signal Handler

16.17.1. Problem

You want to write a subroutine that will be called whenever your program receives a signal.

16.17.2. Solution

A signal handler is just a subroutine. With some risk, you can do anything in a signal handler you'd do in any Perl subroutine, but the more you do, the riskier it gets.

Some systems require you to reinstall your signal handler after each signal:

$SIG{INT} = \&got_int;
sub got_int {
    $SIG{INT} = \&got_int;          # but not for SIGCHLD!
    # ...
}

Some systems restart blocking operations, such as reading data. In such cases, you must call die within the handler and trap it with eval:

my $interrupted = 0;

sub got_int {
    $interrupted = 1;
    $SIG{INT} = 'DEFAULT';          # or 'IGNORE'
    die;
}

eval {
    $SIG{INT} = \&got_int;
    # ... long-running code that you don't want to restart
};

if ($interrupted) {
    # deal with the signal
}

16.17.3. Discussion

At the C level, signals can interrupt just about anything. Unfortunately, this means that signals could interrupt Perl while Perl is changing its own internal data structures, leaving those data structures inconsistent and leading to a core dump. As of Perl 5.8, Perl tries very hard to ensure that this doesn't happen—when you install a signal handler, Perl installs a C-level signal handler that says "Perl received this signal." When Perl's data structures are consistent (after each operation it performs), the Perl interpreter checks to see whether a signal was received. If one was, your signal handler is called.

This prevents core dumps, but at the cost of slightly delaying signals in cases where one of Perl's built-in operations takes a long time to finish. For example, building a long list like this:

@a = 1..5_000_000;

might take 10 seconds on a heavily loaded system, but you won't be able to interrupt it because Perl will not check whether a signal was received while the list is being built. There are two operations in this statement, list generation and assignment, and Perl checks for signals only after each operation completes.

Signals have been implemented in many different operating systems, often in slightly different flavors. The two situations where signal implementations vary the most are when a signal occurs while its signal handler is active (reliability), and when a signal interrupts a blocking syscall such as read or accept (restarting).

The initial Unix implementation of signals was unreliable, meaning that while a handler was running, further occurrences of the same signal would cause the default action, likely aborting the program. Later systems addressed this (each in their own subtly different way, of course) by providing a way to block the delivery of further signals of that number until the handler has finished. If Perl detects that your system can use reliable signals, it generates the proper syscalls needed for this saner, safer behavior. You can use POSIX signals to block signal delivery at other times, as described in Recipe 16.20.

For truly portable code, the paranoid programmer will assume the worst case (unreliable signals) and reinstall the signal handler manually, usually as the first statement in a function:

$SIG{INT} = \&catcher;
sub catcher {
    $SIG{INT} = \&catcher;
    # ...
}

In the special case of catching SIGCHLD, see Recipe 16.19. System V has bizarre behavior that can trip you up.

Use the Config module to find out whether you have reliable signals:

use Config;
print "Hurrah!\n" if $Config{d_sigaction};

Just because you have reliable signals doesn't mean you automatically get reliable programs. But without them, you certainly won't.

The first implementation of signals interrupted slow syscalls, functions that require the cooperation of other processes or device drivers. If a signal comes in while those syscalls are still running, they (and their Perl counterparts) return an error value and set the error to EINTR, "Interrupted system call". Checking for this condition made programs so complicated that most didn't check, and therefore misbehaved or died if a signal interrupted a slow syscall. Most modern versions of Unix allow you to change this behavior. Perl will always make syscalls restartable if it is on a system that supports it. If you have a POSIX system, you can control restarting using the POSIX module (see Recipe 16.20).

To determine whether your interrupted syscalls will automatically restart, look at your system's C signal.h include file:

% egrep 'S[AV]_(RESTART|INTERRUPT)' /usr/include/*/signal.h

Two signals are untrappable and unignorable: SIGKILL and SIGSTOP. Full details of the signals available on your system and what they mean can be found in the signal(3) manpage.

Finally, if you have a hostile operating system, you can still have signal problems. In particular, some operating systems have library calls that themselves intercept signals. For example, gethostbyname(3) on some systems uses SIGALRM signals to manage timeouts and restarts. There can be only one timer running, and so you can't say "stop looking up this hostname after five seconds," because your five-second timer is replaced by gethostbyname's timer as soon as Perl calls the library routine. This means you can't interrupt a wedged hostname lookup on such systems, because the signals don't get through. Fortunately, such situations are rare.

16.17.4. See Also

The "Signals" sections in Chapter 16 of Programming Perl and in perlipc(1); your system's sigaction(2), signal(3), and kill(2) manpages (if you have them); Advanced Programming in the UNIX Environment

Previous | Home | Next
16.16. Temporarily Overriding a Signal Handler | Book Index | 16.18. Catching Ctrl-C
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.18. Catching Ctrl-C

16.18.1. Problem

You want to intercept Ctrl-C, which would otherwise kill your whole program. You'd like to ignore it or run your own function when the signal is received.

16.18.2. Solution

Set a handler for SIGINT. Set it to "IGNORE" to make Ctrl-C have no effect:

$SIG{INT} = 'IGNORE';

Or set it to a subroutine of your own devising to respond to Ctrl-C:

$SIG{INT} = \&tsktsk;

sub tsktsk {
    $SIG{INT} = \&tsktsk;           # See ``Writing A Signal Handler''
    warn "\aThe long habit of living indisposeth us for dying.\n";
}

16.18.3. Discussion

Ctrl-C isn't directly affecting your program. The terminal driver processing your keystrokes recognizes the Ctrl-C combination (or whatever you've set your terminal to recognize as the interrupt character), and sends a SIGINT to every process in the foreground process group (foreground job) for that terminal. The foreground job normally comprises all programs started from the shell on a single command line, plus any other programs run by those programs. See Signals in the Introduction to this chapter for details.

The interrupt character isn't the only special character interpreted by your terminal driver. Type stty -a to find out your current settings:

% stty -a
speed 9600 baud; 38 rows; 80 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
       -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
       -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk
        brkint -inpck -ignpar -parmrk
oflags: opost onlcr oxtabs
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
        -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef;>
        eol2 = <undef; erase = ^H; intr = ^C; kill = ^U; lnext = ^V;>
        min = 1; quit = ^\; reprint = ^R; start = ^Q; status = <undef;>
        stop = ^S; susp = ^Z; time = 0; werase = ^W;

The last section, cchars:, is the list of special characters. Recipe 15.8 shows you how to change these from your script without calling the stty program.

16.18.4. See Also

Your system's stty(1) manpage (if you have one); Recipe 15.8; Recipe 16.17

Previous | Home | Next
16.17. Writing a Signal Handler | Book Index | 16.19. Avoiding Zombie Processes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.19. Avoiding Zombie Processes

16.19.1. Problem

Your program forks children, but the dead children accumulate, fill up your process table, and aggravate your system administrator.

16.19.2. Solution

If you don't need to record the children that have terminated, use:

$SIG{CHLD} = 'IGNORE';

To keep better track of deceased children, install a SIGCHLD handler to call waitpid:

use POSIX ":sys_wait_h";

$SIG{CHLD} = \&REAPER;
sub REAPER {
    my $stiff;
    while (($stiff = waitpid(-1, WNOHANG)) > 0) {
        # do something with $stiff if you want
    }
    $SIG{CHLD} = \&REAPER;                  # install *after* calling waitpid
}

16.19.3. Discussion

When a process exits, the system keeps it in the process table so the parent can check its status—whether it terminated normally or abnormally. Fetching a child's status (thereby freeing it to drop from the system altogether) is rather grimly called reaping dead children. (This entire recipe is full of ways to harvest your dead children. If this makes you queasy, we understand.) It involves a call to wait or waitpid. Some Perl functions (piped open s, system, and backticks) will automatically reap the children they make, but you must explicitly wait when you use fork to manually start another process.

To avoid accumulating dead children, simply tell the system that you're not interested in them by setting $SIG{CHLD} to "IGNORE". If you want to know which children die and when, you'll need to use waitpid.

The waitpid function reaps a single process. Its first argument is the process to wait for—use -1 to mean any process—and its second argument is a set of flags. We use the WNOHANG flag to make waitpid immediately return 0 if there are no dead children. A flag value of 0 is supported everywhere, indicating a blocking wait. Call waitpid from a SIGCHLD handler, as we do in the Solution, to reap the children as soon as they die.

The wait function also reaps children, but it does not have a non-blocking option. If you inadvertently call it when there are running child processes but none have exited, your program will pause until there is a dead child.

Because the kernel keeps track of undelivered signals using a bit vector, one bit per signal, if two children die before your process is scheduled, you will get only a single SIGCHLD. You must always loop when you reap in a SIGCHLD handler, and so you can't use wait.

Both wait and waitpid return the process ID that they just reaped and set $? to the wait status of the defunct process. This status is actually two 8-bit values in one 16-bit number. The high byte is the exit value of the process. The low 7 bits represent the number of the signal that killed the process, with the 8th bit indicating whether a core dump occurred. Here's one way to isolate those values:

$exit_value  = $? >> 8;
$signal_num  = $? & 127;
$dumped_core = $? & 128;

The standard POSIX module has macros to interrogate status values: WIFEXITED, WEXITSTATUS, WIFSIGNALLED, and WTERMSIG. Oddly enough, POSIX doesn't have a macro to test whether the process core dumped.

Beware of two things when using SIGCHLD. First, the operating system doesn't send a SIGCHLD just when a child exits; it also sends one when the child stops. A process can stop for many reasons—waiting to be foregrounded so it can do terminal I/O, being sent a SIGSTOP (it will wait for the SIGCONT before continuing), or being suspended from its terminal. You need to check the status with the WIFEXITED [34] function from the POSIX module to make sure you're dealing with a process that really died, and isn't just suspended.

[34]Not SPOUSEXITED, even on a PC.

use POSIX qw(:signal_h :errno_h :sys_wait_h);

$SIG{CHLD} = \&REAPER;
sub REAPER {
    my $pid;

    $pid = waitpid(-1, &WNOHANG);

    if ($pid =  = -1) {
        # no child waiting.  Ignore it.
    } elsif (WIFEXITED($?)) {
        print "Process $pid exited.\n";
    } else {
        print "False alarm on $pid.\n";
    }
    $SIG{CHLD} = \&REAPER;          # in case of unreliable signals
}

The second trap with SIGCHLD is related to Perl, not the operating system. Because system, open, and backticks all fork subprocesses and the operating system sends your process a SIGCHLD whenever any of its subprocesses exit, you could get called for something you weren't expecting. The built-in operations all wait for the child themselves, so sometimes the SIGCHLD will arrive before the close on the filehandle blocks to reap it. If the signal handler gets to it first, the zombie won't be there for the normal close. This makes close return false and set $! to "No child processes". Then, if the close gets to the dead child first, waitpid will return 0.

Most systems support a non-blocking waitpid. Use Perl's standard Config.pm module to find out:

use Config;
$has_nonblocking = $Config{d_waitpid} eq "define" ||
                   $Config{d_wait4}   eq "define";

System V defines SIGCLD, which has the same signal number as SIGCHLD but subtly different semantics. Use SIGCHLD to avoid confusion.

16.19.4. See Also

The "Signals" sections in Chapter 16 of Programming Perl and in perlipc(1); the wait and waitpid functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard POSIX module in Chapter 32 of Programming Perl; your system's sigaction(2), signal(3), and kill(2) manpages (if you have them); Recipe 16.17

Previous | Home | Next
16.18. Catching Ctrl-C | Book Index | 16.20. Blocking Signals
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.20. Blocking Signals

16.20.1. Problem

You'd like to delay the reception of a signal, possibly to prevent unpredictable behavior from signals that can interrupt your program at any point.

16.20.2. Solution

Use the POSIX module's interface to the sigprocmask(2) syscall. This is available only if your system is POSIX conformant.

To block a signal around an operation:

use POSIX qw(:signal_h);

$sigset = POSIX::SigSet->new(SIGINT);    # define the signals to block
$old_sigset = POSIX::SigSet->new;        # where the old sigmask will be kept

sigprocmask(SIG_BLOCK, $sigset, $old_sigset)
    or die "Could not block SIGINT\n";

To unblock:

defined sigprocmask(SIG_UNBLOCK, $old_sigset)
    or die "Could not unblock SIGINT\n";

16.20.3. Discussion

The POSIX standard introduced sigaction and sigprocmask to give you better control over how signals are delivered. The sigprocmask function controls delayed delivery of signals, and sigaction installs handlers. If available, Perl uses sigaction when you change %SIG.

To use sigprocmask, first build a signal set using POSIX::SigSet->new. This takes a list of signal numbers. The POSIX module exports functions named after the signals, which return their signal numbers.

use POSIX qw(:signal_h);

$sigset = POSIX::SigSet->new( SIGINT, SIGKILL );

Pass the POSIX::SigSet object to sigprocmask with the SIG_BLOCK flag to delay signal delivery, SIG_UNBLOCK to restore delivery of the signals, or SIG_SETMASK to block only signals in the POSIX::SigSet. The most paranoid of programmers block signals for a fork to prevent a signal handler in the child process being called before Perl can update the child's $$ variable, its process id. If the signal handler were called immediately and reported $$ in that handler, it could possibly report its parent's $$, not its own. This issue does not arise often.

16.20.4. See Also

Your system's sigprocmask(2) manpage (if you have one); the documentation for the standard POSIX module in Chapter 32 of Programming Perl

Previous | Home | Next
16.19. Avoiding Zombie Processes | Book Index | 16.21. Timing Out an Operation
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.21. Timing Out an Operation

16.21.1. Problem

You want to make sure an operation doesn't take more than a certain amount of time. For instance, you're running filesystem backups and want to abort if it takes longer than an hour. Or, you want to give the user a limited amount of time to respond to a query.

16.21.2. Solution

To interrupt a long-running operation, set a SIGALRM handler to call die, in effect transforming the signal into an exception. Set an alarm with alarm, then eval your code:

eval {
    local $SIG{ALRM} = sub { die "alarm clock restart" };
    alarm 10;                   # schedule alarm in 10 seconds
    eval {
          ########
          # long-running operation goes here
          ########
    };
    alarm 0;                    # cancel the alarm
};
alarm 0;                        # race condition protection
die if $@ && $@ !~ /alarm clock restart/; # reraise

16.21.3. Discussion

The alarm function takes one argument: the integer number of seconds before the kernel sends your process a SIGALRM, that is, an alarm signal. It may be delivered after that time in busy time-sharing systems. The default action for SIGALRM is to terminate your program, so you should install your own signal handler.

Because this example should work no matter what operation is being timed out, we take some special precautions in case your long-running operation contains a slow syscall. Slow syscalls are those that don't return immediately, but await some external event, such as for I/O to happen or some sort of timer to go off. These external events include read (including readline, the <FH> operator), write, and open on certain devices, fifos, and sockets, as well as accept, connect, send, recv, flock, wait, waitpid, and of course, sleep. If the alarm hits while you're in a slow syscall and you simply catch the signal and return, you'll go right back into that syscall. That's because Perl automatically restarts syscalls where it's able to. The only way out of them is to raise an exception through die and then let eval catch it. (This works because the exception winds up calling the C library's longjmp(3) function, which is what really gets you out of the restarting syscall.)

The nested exception trap is because you cannot be sure that arbitrary code in your long-running operation isn't going to raise some exception of its own. If it did, then that would pop you out of the inner eval with the alarm still pending. You need to make sure to clear the alarm anyway. The second alarm 0 is in case the signal comes in after running the long-running operation, but before getting to the first alarm 0. If you don't do that, you would risk a tiny race condition—but size doesn't matter in race conditions; they either exist or they don't. And we prefer that they don't.

You cannot (usefully) give the alarm function a fractional number of seconds; if you try, it will be truncated to an integer. For precise timers, see Recipe 3.9.

16.21.4. See Also

The "Signals" sections in Chapter 16 of Programming Perl and in perlipc(1); the section on "Handling Race Conditions" in Chapter 23 of Programming Perl; the alarm function in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 3.9

Previous | Home | Next
16.20. Blocking Signals | Book Index | 16.22. Turning Signals into Fatal Errors
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.22. Turning Signals into Fatal Errors

16.22.1. Problem

END blocks aren't run when your program dies from an uncaught signal. Your program gets such signals, and you'd like your END blocks to have a chance to clean up.

16.22.2. Solution

Use the sigtrap pragma:

use sigtrap qw(die untrapped normal-signals);

16.22.3. Discussion

Untrapped signals cause your program to die without running END blocks. Although you could manually install signal handlers that call die, this becomes tedious for a lot of signals:

$SIG{INT} = $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = sub { die };

The sigtrap pragma provides a convenient shorthand for installing such handlers:

use sigtrap qw(die untrapped normal-signals);

The die import tells sigtrap to call die (you can also import stack-trace to install handlers that trigger stack traces). The untrapped import tells sigtrap to install handlers only for signals that don't already have them, so if you handle SIGPIPE yourself, sigtrap won't replace your handler.

normal-signals is one of several imports that specify predefined lists of useful signals to trap. The signal lists are given in Table 16-2.

Table 16-2. Signal lists

List | Signals
normal-signals | HUP, INT, PIPE, TERM
error-signals | ABRT, BUS, EMT, FPE, ILL, QUIT, SEGV, SYS, TRAP
old-interface-signals | ABRT, BUS, EMT, FPE, ILL, PIPE, QUIT, SEGV, SYS, TERM, TRAP

You can combine signal lists:

use sigtrap qw(die untrapped normal-signals error-signals);

You can even combine different handler types in one import list. Here we use untrapped to specify only the normal signals for which there is not already a handler installed, then use any to revert to sigtrap's default behavior of installing handlers for all signals in the named list:

use sigtrap qw(
    die           untrapped    normal-signals
    stack-trace   any          error-signals
);

16.22.4. See Also

Recipe 12.7; the documentation for the standard module sigtrap; Recipe 16.15

Previous | Home | Next
16.21. Timing Out an Operation | Book Index | 16.23. Program: sigrand
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


16.23. Program: sigrand

The following program gives you random signatures by using named pipes. It expects the signatures file to have records in the format of the fortune program—that is, each possible multiline record is terminated with "%%\n". Here's an example:

Make is like Pascal: everybody likes it, so they go in and change it.
                                            --Dennis Ritchie
%%
I eschew embedded capital letters in names; to my prose-oriented eyes,
they are too awkward to read comfortably. They jangle like bad typography.
                                            --Rob Pike
%%
God made the integers; all else is the work of Man.
                                            --Kronecker
%%
I'd rather have :rofix than const.          --Dennis Ritchie
%%
If you want to program in C, program in C.  It's a nice language.
I use it occasionally...   :-)              --Larry Wall
%%
Twisted cleverness is my only skill as a programmer.
                                            --Elizabeth Zwicky
%%
Basically, avoid comments. If your code needs a comment to be understood,
it would be better to rewrite it so it's easier to understand.
                                            --Rob Pike
%%
Comments on data are usually much more helpful than on algorithms.
                                            --Rob Pike
%%
Programs that write programs are the happiest programs in the world.
                                            --Andrew Hume
%%

We check whether we're already running by using a file with our PID in it. If sending a signal number 0 indicates that PID still exists (or, rarely, that something else has reused it), we just exit. We also look at the current Usenet posting to decide whether to look for a per-newsgroup signature file. That way, you can have different signatures for each newsgroup you post to. For variety, a global signature file is still on occasion used even if a per-newsgroup file exists.

You can even use sigrand on systems without named pipes if you remove the code to create a named pipe and extend the sleep interval before file updates. Then .signature would just be a regular file. Another portability concern is that the program forks itself in the background, which is almost like becoming a daemon. If you have no fork call, just comment it out.

The full program is shown in Example 16-12.

Example 16-12. sigrand

  #!/usr/bin/perl -w
  # sigrand - supply random fortunes for .signature file

  use strict;

  # config section variables
  use vars qw( $NG_IS_DIR $MKNOD $FULLNAME $FIFO $ART $NEWS $SIGS $SEMA
                      $GLOBRAND $NAME );

  # globals
  use vars qw( $Home $Fortune_Path @Pwd );

  ################################################################
  # begin configuration section
  # should really read from ~/.sigrandrc

  gethome( );

  # for rec/humor/funny instead of rec.humor.funny
  $NG_IS_DIR      = 1;

  $MKNOD          = "/bin/mknod";
  $FULLNAME       = "$Home/.fullname";
  $FIFO           = "$Home/.signature";
  $ART            = "$Home/.article";
  $NEWS           = "$Home/News";
  $SIGS           = "$NEWS/SIGNATURES";
  $SEMA           = "$Home/.sigrandpid";
  $GLOBRAND       = 1/4;  # chance to use global sigs anyway

  # $NAME should be (1) left undef to have program guess
  # read address for signature maybe looking in ~/.fullname,
  # (2) set to an exact address, or (3) set to empty string
  # to be omitted entirely.

  $NAME           = '';           # means no name used
  ## $NAME        = "me\@home.org\n";

  # end configuration section -- HOME and FORTUNE get autoconf'd
  ################################################################

  setup( );                # pull in inits
  justme( );               # make sure program not already running
  fork && exit;           # background ourself and go away

  open(SEMA, "> $SEMA")              or die "can't write $SEMA: $!";
  print SEMA "$$\n";
  close SEMA                         or die "can't close $SEMA: $!";

  # now loop forever, writing a signature into the
  # fifo file.  if you don't have real fifos, change
  # sleep time at bottom of loop to like 10 to update
  # only every 10 seconds.
  for (;;) {
      open(FIFO, "> $FIFO")                or die "can't write $FIFO: $!";
      my $sig = pick_quote( );
      for ($sig) {
          s/^((:?[^\n]*\n){4}).*$/$1/s;   # trunc to 4 lines
          s/^(.{1,80}).*? *$/$1/gm;       # trunc long lines
      }
      # print sig, with name if present, padded to four lines
      if ($NAME) {
          print FIFO $NAME, "\n" x (3 - ($sig =~ tr/\n//)), $sig;
      } else {
          print FIFO $sig;
      }
      close FIFO;

      # Without a microsleep, the reading process doesn't finish before
      # the writer tries to open it again, which since the reader exists,
      # succeeds.  They end up with multiple signatures.  Sleep a tiny bit
      # between opens to give readers a chance to finish reading and close
      # our pipe so we can block when opening it the next time.

      select(undef, undef, undef, 0.2);   # sleep 1/5 second
  }
  die "XXX: NOT REACHED";         # you can't get here from anywhere

  ################################################################

  # Ignore SIGPIPE in case someone opens us up and then closes the fifo
  # without reading it; look in a .fullname file for their login name.
  # Try to determine the fully qualified hostname.  Look our for silly
  # ampersands in passwd entries.  Make sure we have signatures or fortunes.
  # Build a fifo if we need to.

  sub setup {
      $SIG{PIPE} = 'IGNORE';

      unless (defined $NAME) {            # if $NAME undef in config
          if (-e $FULLNAME) {
                      $NAME = `cat $FULLNAME`;
                      die "$FULLNAME should contain only 1 line, aborting"
                          if $NAME =~ tr/\n// > 1;
          } else {
                      my($user, $host);
                      chop($host = `hostname`);
                      ($host) = gethostbyname($host) unless $host =~ /\./;
                      $user = $ENV{USER} || $ENV{LOGNAME} || $Pwd[0]
                          or die "intruder alert";
                      ($NAME = $Pwd[6]) =~ s/,.*//;
                      $NAME =~ s/&/\u\L$user/g; # can't believe some folks still do this
                      $NAME = "\t$NAME\t$user\@$host\n";
          }
      }

      check_fortunes( ) if !-e $SIGS;

      unless (-p $FIFO) {         # -p checks whether it's a named pipe
          if (!-e _) {
                       system($MKNOD, $FIFO, "p") && die "can't mknod $FIFO";
                       warn "created $FIFO as a named pipe\n";
          } else {
                       die "$0: won't overwrite file .signature\n";
          }
      } else {
          warn "$0: using existing named pipe $FIFO\n";
      }

      # get a good random number seed.  not needed if 5.004 or better.
      srand(time( ) ^ ($$ + ($$ << 15)));
  }

  # choose a random signature
  sub pick_quote {
      my $sigfile = signame( );
      if (!-e $sigfile) {
          return fortune( );
      }
      open(SIGS, "< $sigfile")                or die "can't open $sigfile";
      local $/  = "%%\n";
      local $_;
      my $quip;
      rand($.) < 1 && ($quip = $_) while <SIGS>;
      close SIGS;
      chomp $quip;
      return $quip || "ENOSIG: This signature file is empty.\n";
  }

  # See whether ~/.article contains a Newsgroups line.  if so, see the first
  # group posted to and find out whether it has a dedicated set of fortunes.
  # otherwise return the global one.  also, return the global one randomly
  # now and then to spice up the sigs.
  sub signame {
       (rand(1.0) > ($GLOBRAND) && open ART) || return $SIGS;
       local $/  = '';
       local $_  = <ART>;
       my($ng)   = /Newsgroups:\s*([^,\s]*)/;
       $ng =~ s!\.!/!g if $NG_IS_DIR;     # if rn -/,  or SAVEDIR=%p/%c
       $ng = "$NEWS/$ng/SIGNATURES";
       return -f $ng ? $ng : $SIGS;
  }

  # Call the fortune program with -s for short flag until
  # we get a small enough fortune or ask too much.
  sub fortune {
     local $_;
     my $tries = 0;
     do {
         $_ = `$Fortune_Path -s`;
     } until tr/\n// < 5 || $tries++ > 20;
     s/^/ /mg;
     $_ || " SIGRAND: deliver random signals to all processes.\n";
  }

  # Make sure there's a fortune program.  Search
  # for its full path and set global to that.
  sub check_fortunes {
      return if $Fortune_Path;    # already set
      for my $dir (split(/:/, $ENV{PATH}), '/usr/games') {
          return if -x ($Fortune_Path = "$dir/fortune");
      }
      die "Need either $SIGS or a fortune program, bailing out";
  }

  # figure out our directory
  sub gethome {
      @Pwd = getpwuid($<);
      $Home = $ENV{HOME} || $ENV{LOGDIR} || $Pwd[7]
                         or die "no home directory for user $<";
  }

  # "There can be only one."  --the Highlander
  sub justme {
      if (open SEMA) {
          my $pid;
          chop($pid = <SEMA>);
          kill(0, $pid)              and die "$0 already running (pid $pid), bailing out";
          close SEMA;
      }

  }
Previous | Home | Next
16.22. Turning Signals into Fatal Errors | Book Index | 17. Sockets
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 17. Sockets

Contents:

Introduction
Writing a TCP Client
Writing a TCP Server
Communicating over TCP
Setting Up a UDP Client
Setting Up a UDP Server
Using Unix Domain Sockets
Identifying the Other End of a Socket
Finding Your Own Name and Address
Closing a Socket After Forking
Writing Bidirectional Clients
Forking Servers
Pre-Forking Servers
Non-Forking Servers
Multitasking Server with Threads
Writing a Multitasking Server with POE
Writing a Multihomed Server
Making a Daemon Server
Restarting a Server on Demand
Managing Multiple Streams of Input
Program: backsniff
Program: fwdport

Shakespeare, Henry IV, part I, Act III scene 1

Glendower: I can call spirits from the vasty deep.Hotspur: Why so can I, or so can any man, But will they come when you do call for them?

17.0. Introduction

Sockets are endpoints for communication. Some types of sockets provide reliable communications. Others offer few guarantees, but consume low system overhead. Socket communication can be used to let processes talk on just one machine or over the Internet.

In this chapter we consider the two most commonly used types of sockets: streams and datagrams. Streams provide a bidirectional, sequenced, and reliable channel of communication—similar to pipes. Datagram sockets do not guarantee sequenced, reliable delivery, but they do guarantee that message boundaries will be preserved when read. Your system may support other types of sockets as well; consult your socket(2) manpage or equivalent documentation for details.

We also consider both the Internet and Unix domains. The Internet domain gives sockets two-part names: a host (an IP address in a particular format) and a port number. In the Unix domain, sockets are named using files (e.g., /tmp/mysock).

In addition to domains and types, sockets also have a protocol associated with them. Protocols are not very important to the casual programmer, as there is rarely more than one protocol for a given domain and type of socket.

Domains and types are normally identified by numeric constants (available through functions exported by the Socket and IO::Socket modules). Stream sockets have the type SOCK_STREAM, and datagram sockets have the type SOCK_DGRAM. The Internet domain is PF_INET, and the Unix domain PF_UNIX. (POSIX uses PF_LOCAL instead of PF_UNIX, but PF_UNIX will almost always be an acceptable constant simply because of the preponderance of existing software that uses it.) You should use these symbolic names instead of numbers because the numbers may change (and historically, have).

Protocols have names such as tcp and udp, which correspond to numbers that the operating system uses. The getprotobyname function (built into Perl) returns the number when given a protocol name. Pass protocol number 0 to socket functions to have the system select an appropriate default.

Perl has built-in functions to create and manipulate sockets; these functions largely mimic their C counterparts. While this is good for providing low-level, direct access to every part of the system, most of us prefer something more convenient. That's what the IO::Socket::INET and IO::Socket::UNIX classes are for—they provide a high-level interface to otherwise intricate system calls.

Let's look at the built-in functions first. They all return undef and set $! if an error occurs. The socket function makes a socket, bind gives a socket a local name, connect connects a local socket to a (possibly remote) one, listen readies a socket for connections from other sockets, and accept receives the connections one by one. You can communicate over a stream socket with print and <> as well as with syswrite and sysread, or over a datagram socket with send and recv. (Perl does not currently support sendmsg(2).)

A typical server calls socket, bind, and listen, then loops in a blocking accept call that waits for incoming connections (see Recipe 17.2 and Recipe 17.5). A typical client calls socket and connect (see Recipes Recipe 17.1 and Recipe 17.4). Datagram clients are special. They don't have to connect to send data, because they can specify the destination as an argument to send.

When you bind, connect, or send to a specific destination, you must supply a socket name. An Internet domain socket name is a host (an IP address packed with inet_aton) and a port (a number), packed into a C-style structure with sockaddr_in:

use Socket;

$packed_ip   = inet_aton("208.201.239.37");
$socket_name = sockaddr_in($port, $packed_ip);

A Unix domain socket name is a filename packed into a C structure with sockaddr_un:

use Socket;

$socket_name = sockaddr_un("/tmp/mysock");

To take a packed socket name and turn it back into a filename or host and port, call sockaddr_un or sockaddr_in in list context:

($port, $packed_ip) = sockaddr_in($socket_name);    # for PF_INET sockets
($filename)         = sockaddr_un($socket_name);    # for PF_UNIX sockets

Use inet_ntoa to turn a packed IP address back into an ASCII string. It stands for "numbers to ASCII," and inet_aton stands for "ASCII to numbers."

$ip_address = inet_ntoa($packed_ip);
$packed_ip  = inet_aton("208.201.239.37");
$packed_ip  = inet_aton("www.oreilly.com");

Most recipes use Internet domain sockets in their examples, but nearly everything that applies to the Internet domain also applies to the Unix domain. Recipe 17.6 explains the differences and pitfalls.

Sockets are the basis of network services. We provide three ways to write servers: one where a child process is created for each incoming connection (Recipe 17.11), one where the server forks in advance (Recipe 17.12), and one where the server process doesn't fork at all (Recipe 17.13).

Some servers need to listen to many IP addresses at once, which we demonstrate in Recipe 17.16. Well-behaved servers clean up and restart when they get a HUP signal; Recipe 17.18 shows how to implement that behavior in Perl. We also show how to put a name to both ends of a connection; see Recipe 17.7 and Recipe 17.8.

UNIX Network Programming (Prentice Hall) and the three-volume TCP/IP Illustrated (Addison-Wesley) by W. Richard Stevens are indispensable for the serious socket programmer. If you want to learn the basics about sockets, it's hard to beat the original and classic reference, An Advanced 4.4BSD Interprocess Communication Tutorial. It's written for C, but almost everything is directly applicable to Perl. It's available in /usr/share/doc on most BSD-derived Unix systems. We also recommend you look at The Unix Programming Frequently Asked Questions List (Gierth and Horgan), and Programming UNIX Sockets in C—Frequently Asked Questions (Metcalf and Gierth), both of which are posted periodically to the comp.unix.answers newsgroup.

Previous | Home | Next
16.23. Program: sigrand | Book Index | 17.1. Writing a TCP Client
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.1. Writing a TCP Client

17.1.1. Problem

You want to connect to a socket on a remote machine.

17.1.2. Solution

This solution assumes you're using the Internet to communicate. For TCP-like communication within a single machine, see Recipe 17.6.

Either use the standard IO::Socket::INET class:

use IO::Socket;

$socket = IO::Socket::INET->new(PeerAddr => $remote_host,
                                PeerPort => $remote_port,
                                Proto    => "tcp",
                                Type     => SOCK_STREAM)
    or die "Couldn't connect to $remote_host:$remote_port : $@\n";

# ... do something with the socket
print $socket "Why don't you call me anymore?\n";

$answer = <$socket>;

# and terminate the connection when we're done
close($socket);

or create a socket by hand for better control:

use Socket;

# create a socket
socket(TO_SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

# build the address of the remote machine
$internet_addr = inet_aton($remote_host)
    or die "Couldn't convert $remote_host into an Internet address: $!\n";
$paddr = sockaddr_in($remote_port, $internet_addr);

# connect
connect(TO_SERVER, $paddr)
    or die "Couldn't connect to $remote_host:$remote_port : $!\n";

# ... do something with the socket
print TO_SERVER "Why don't you call me anymore?\n";

# and terminate the connection when we're done
close(TO_SERVER);

17.1.3. Discussion

While coding this by hand requires a lot of steps, the IO::Socket::INET class wraps them all in a convenient constructor. The important things to know are where you're going (the PeerAddr and PeerPort parameters) and how you're getting there (the Type parameter). IO::Socket::INET tries to determine these things from what you've given it. It deduces Proto from the Type and Port if possible, and assumes tcp otherwise.

PeerAddr is a string containing either a hostname ("www.oreilly.com") or an IP address ("208.201.239.36"). PeerPort is an integer, representing the port number to connect to. You can embed the port number in the address by giving an address like "www.oreilly.com:80". Type is the kind of socket to create: SOCK_DGRAM for datagrams or SOCK_STREAM for streams.

If you want a SOCK_STREAM connection to a port on a particular machine with no other options, pass a single string to IO::Socket::INET->new consisting of the hostname and port separated by a colon:

$client = IO::Socket::INET->new("www.yahoo.com:80")
    or die $@;

If an error occurs, IO::Socket::INET will return undef and $@ (not $!) will be set to the error message.

$s = IO::Socket::INET->new(PeerAddr => "Does not Exist",
                           Peerport => 80,
                           Type     => SOCK_STREAM )
    or die $@;

If your packets are disappearing into a network void, it can take a while for your inability to connect to a port to be recognized. You can decrease this time by specifying a Timeout parameter to IO::Socket::INET->new( ):

$s = IO::Socket::INET->new(PeerAddr => "bad.host.com",
                           PeerPort => 80,
                           Type     => SOCK_STREAM,
                           Timeout  => 5 )
    or die $@;

If you do this, though, there's no way to tell from $! or $@ whether you couldn't connect or whether you timed out. Sometimes it's better to set it up by hand instead of using a module.

If you have several network interfaces, the kernel decides which one to use based on your current routes. If you wish to override this default, add a Local parameter to your call to IO::Socket::INET->new. If coding by hand, do this:

$inet_addr = inet_aton("208.201.239.37");
$paddr     = sockaddr_in($port, $inet_addr);
bind(SOCKET, $paddr)         or die "bind: $!";

If you know only the name, do this:

$inet_addr = gethostbyname("www.yahoo.com")
                            or die "Can't resolve www.yahoo.com: $!";
$paddr     = sockaddr_in($port, $inet_addr);
bind(SOCKET, $paddr)        or die "bind: $!";

17.1.4. See Also

The socket, bind, connect, and gethostbyname functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Socket, IO::Socket, and Net::hostent modules; the section on "Networking Clients" in Chapter 16 of Programming Perl and in perlipc(1); UNIX Network Programming; Recipe 17.2; Recipe 17.3

Previous | Home | Next
17. Sockets | Book Index | 17.2. Writing a TCP Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.2. Writing a TCP Server

17.2.1. Problem

You want to write a server that waits for clients to connect over the network to a particular port.

17.2.2. Solution

This recipe assumes you're using the Internet to communicate. For TCP-like communication within a single Unix machine, see Recipe 17.6.

Use the standard IO::Socket::INET class:

use IO::Socket;

$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM,
                                Reuse     => 1,
                                Listen    => 10 )   # or SOMAXCONN
    or die "Couldn't be a tcp server on port $server_port : $@\n";

while ($client = $server->accept( )) {
    # $client is the new connection
}

close($server);

Or craft it by hand for better control:

use Socket;

# make the socket
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

# so we can restart our server quickly
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);

# build up my socket address
$my_addr = sockaddr_in($server_port, INADDR_ANY);
bind(SERVER, $my_addr)
    or die "Couldn't bind to port $server_port : $!\n";

# establish a queue for incoming connections
listen(SERVER, SOMAXCONN)
    or die "Couldn't listen on port $server_port : $!\n";

# accept and process connections
while (accept(CLIENT, SERVER)) {
    # do something with CLIENT
}

close(SERVER);

17.2.3. Discussion

Setting up a server is more complicated than being a client. The optional listen function tells the operating system how many pending, unanswered connections can queue up while waiting for your server. The setsockopt function used in the Solution allows you to avoid waiting two minutes after killing your server before you restart it again (valuable in testing). The bind call registers your server with the kernel so others can find you. Finally, accept takes the incoming connections one by one.

The numeric argument to listen is the number of unaccept ed connections that the operating system should queue before clients start getting "connection refused" errors. Historically, the maximum listen value was 5, and even today, many operating systems silently limit this queue size to around 20. With busy web servers becoming commonplace, many vendors have increased this value. Your documented system maximum can be found in the SOMAXCONN constant from the Socket module.

The accept function takes two arguments: the filehandle to connect to the remote client and the server filehandle. It returns the client's port and IP address, as packed by inet_ntoa:

use Socket;

while ($client_address = accept(CLIENT, SERVER)) {
    ($port, $packed_ip) = sockaddr_in($client_address);
    $dotted_quad = inet_ntoa($packed_ip);
    # do as thou wilt
}

With the IO::Socket classes, accept is a method of the server filehandle:

while ($client = $server->accept( )) {
    # ...
}

If you call the accept method in list context, it returns the client socket and its address:

while (($client,$client_address) = $server->accept( )) {
    # ...
}

If no connection is waiting, your program blocks in the accept until a connection comes in. If you want to ensure that your accept won't block, use non-blocking sockets:

use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);

$flags = fcntl(SERVER, F_GETFL, 0)
            or die "Can't get flags for the socket: $!\n";

$flags = fcntl(SERVER, F_SETFL, $flags | O_NONBLOCK)
            or die "Can't set flags for the socket: $!\n";

Now when you accept and nothing is waiting for you, accept will return undef and set $! to EWOULDBLOCK.

You might fear that when the return flags from F_GETFL are 0, this would trigger the die just as a failure from undef would. Not so—as with ioctl, a non-error return from fcntl is mapped by Perl to the special value "0 but true". This special string is even exempt from non-numeric warnings, so feel free to use it in your functions when you want to return a value that's numerically zero yet still true. It probably should have been "0 and sneaky" instead.

17.2.4. See Also

The socket, bind, listen, accept, fcntl, and setsockopt functions in Chapter 29 of Programming Perl and in perlfunc(1); your system's fcntl(2), socket(2), and setsockopt(2) manpages (if you have them); the documentation for the standard Socket, IO::Socket, and Net::hostent modules; the section on "Networking Servers" in Chapter 16 of Programming Perl and in perlipc(1); UNIX Network Programming; Beej's Guide to Network Programming at http://www.ecst.csuchico.edu/~beej/guide/net; Recipe 7.22; Recipe 7.20; Recipe 17.1; Recipe 17.3; Recipe 17.7

Previous | Home | Next
17.1. Writing a TCP Client | Book Index | 17.3. Communicating over TCP
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.3. Communicating over TCP

17.3.1. Problem

You want to read or write data over a TCP connection.

17.3.2. Solution

This recipe assumes you're using the Internet to communicate. For TCP-like communication within a single machine, see Recipe 17.6.

Use print or <> :

print SERVER "What is your name?\n";
chomp ($response = <SERVER>);

Or use send and recv :

defined (send(SERVER, $data_to_send, $flags))
    or die "Can't send : $!\n";

recv(SERVER, $data_read, $maxlen, $flags)
    or die "Can't receive: $!\n";

Or use the corresponding methods on an IO::Socket object:

use IO::Socket;

$server->send($data_to_send, $flags)
    or die "Can't send: $!\n";

$server->recv($data_read, $maxlen, $flags)
    or die "Can't recv: $!\n";

To find out whether data can be read or written, use the select function, which is nicely wrapped by the standard IO::Socket class:

use IO::Select;

$select = IO::Select->new( );
$select->add(*FROM_SERVER);
$select->add($to_client);

@read_from = $select->can_read($timeout);
foreach $socket (@read_from) {
    # read the pending data from $socket
}

17.3.3. Discussion

Sockets handle two completely different types of I/O, each with attendant pitfalls and benefits. The normal Perl I/O functions used on files (except for seek and sysseek) work for stream sockets, but datagram sockets require the system calls send and recv, which work on complete records.

Awareness of buffering issues is particularly important in socket programming. That's because buffering, while designed to enhance performance, can interfere with the interactive feel that some programs require. Gathering input with <> may try to read more data from the socket than is yet available as it looks for a record separator. Both print and <> use stdio buffers, so unless you've changed autoflushing (see the Introduction to Chapter 7) on the socket handle, your data won't be sent to the other end as soon as you print it. Instead, it will wait until a buffer fills up.

For line-based clients and servers, this is probably okay, so long as you turn on autoflushing for output. Newer versions of IO::Socket do this automatically on the anonymous filehandles returned by IO::Socket->new.

But stdio isn't the only source of buffering. Output (print, printf, or syswrite—or send on a TCP socket) is further subject to buffering at the operating system level under a strategy called the Nagle Algorithm. When a packet of data has been sent but not acknowledged, further to-be-sent data is queued and is sent as soon as another complete packet's worth is collected or the outstanding acknowledgment is received. In some situations (mouse events being sent to a windowing system, keystrokes to a real-time application) this buffering is inconvenient or downright wrong. You can disable the Nagle Algorithm with the TCP_NODELAY socket option:

use Socket;
require "sys/socket.ph";    # for &TCP_NODELAY

setsockopt(SERVER, SOL_SOCKET, &TCP_NODELAY, 1)
    or die "Couldn't disable Nagle's algorithm: $!\n";

Re-enable it with:

setsockopt(SERVER, SOL_SOCKET, &TCP_NODELAY, 0)
    or die "Couldn't enable Nagle's algorithm: $!\n";

In most cases, TCP_NODELAY isn't something you need. TCP buffering is there for a reason, so don't disable it unless your application is one of the few real-time packet-intensive situations that need to.

Load in TCP_NODELAY from sys/socket.ph, a file that isn't automatically installed with Perl, but can be easily built. See Recipe 12.17 for details.

Because buffering is such an issue, you have the select function to determine which filehandles have unread input, which can be written to, and which have "exceptional conditions" pending. The select function takes three strings interpreted as binary data, each bit corresponding to a filehandle. A typical call to select looks like this:

$rin = '';                          # initialize bitmask
vec($rin, fileno(SOCKET), 1) = 1;   # mark SOCKET in $rin
# repeat calls to vec( ) for each socket to check

$timeout = 10;                      # wait ten seconds

$nfound = select($rout = $rin, undef, undef, $timeout);
if (vec($rout, fileno(SOCKET),1)){
    # data to be read on SOCKET
}

The four arguments to select are: a bitmask indicating which filehandles to check for unread data; a bitmask indicating which filehandles to check for safety to write without blocking; a bitmask indicating which filehandles to check for exceptional conditions; and a time in seconds indicating the maximum time to wait (this can be a floating-point number).

The function changes the bitmask arguments passed to it, so that when it returns, the only bits set correspond to filehandles ready for I/O. This leads to the common strategy of assigning an input mask ($rin in the previous example) to an output one ($rout in the example), so that select can only affect $rout, leaving $rin alone.

You can specify a timeout of 0 to poll (check without blocking). Some beginning programmers think that blocking is bad, so they write programs that "busy-wait"—they poll and poll and poll and poll. When a program blocks, the operating system recognizes that the process is pending on input and gives CPU time to other programs until input is available. When a program busy-waits, the system can't let it sleep, because it's always doing something—checking for input! Occasionally, polling is the right thing to do, but far more often it's not. A timeout of undef to select means "no timeout," and your program will patiently block until input becomes available.

Because select uses bitmasks, which are tiresome to create and difficult to interpret, we use the standard IO::Select module in the Solution. It bypasses bitmasks and is generally the easier route.

A full explanation of the exceptional data that is tested for with the third bitmask in select is beyond the scope of this book. Consult Stevens's UNIX Network Programming for a discussion of out-of-band and urgent data.

Other send and recv flags are listed in the manpages for those system calls.

17.3.4. See Also

The send, recv, fileno, vec, setsockopt, and select functions in Chapter 29 of Programming Perl and in perlfunc(1); the sections on "I/O Operators" and on "Bitwise String Operators" in perlop(1); your system's setsockopt(2) manpage (if you have one); the documentation for the standard Socket and IO::Socket modules; the section on "Sockets" in Chapter 16 of Programming Perl and in perlipc(1); UNIX Network Programming; Recipe 17.1; Recipe 17.2

Previous | Home | Next
17.2. Writing a TCP Server | Book Index | 17.4. Setting Up a UDP Client
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.4. Setting Up a UDP Client

17.4.1. Problem

You want to exchange messages with another process using UDP (datagrams).

17.4.2. Solution

To set up a UDP socket handle, use either the low-level Socket module on your own filehandle:

use Socket;
socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
    or die "socket: $!";

or else IO::Socket, which returns an anonymous one:

use IO::Socket;
$handle = IO::Socket::INET->new(Proto => 'udp')
    or die "socket: $@";     # yes, it uses $@ here

Then to send a message to a machine named $HOSTNAME on port number $PORTNO, use:

$ipaddr   = inet_aton($HOSTNAME);
$portaddr = sockaddr_in($PORTNO, $ipaddr);
send(SOCKET, $MSG, 0, $portaddr) =  = length($MSG)
        or die "cannot send to $HOSTNAME($PORTNO): $!";

To receive a message of length no greater than $MAXLEN, use:

$portaddr = recv(SOCKET, $MSG, $MAXLEN, 0)      or die "recv: $!";
($portno, $ipaddr) = sockaddr_in($portaddr);
$host = gethostbyaddr($ipaddr, AF_INET);
print "$host($portno) said $MSG\n";

17.4.3. Discussion

Datagram sockets are unlike stream sockets. Streams provide sessions, giving the illusion of a stable connection. You might think of them as working like a telephone call—expensive to set up, but once established, reliable and easy to use. Datagrams, though, are more like the postal system—it's cheaper and easier to send a letter to your friend on the other side of the world than to call them on the phone. Datagrams are easier on the system than streams. You send a small amount of information one message at a time. But your messages' delivery isn't guaranteed, and they might arrive in the wrong order. Like a small post box, the receiver's queue might fill up and cause further messages to be dropped.

Why then, if datagrams are unreliable, do we have them? Because some applications are most sensibly implemented in terms of datagrams. For instance, in streaming audio, it's more important that the stream as a whole be preserved than that every packet get through, especially if packets are being dropped because there's not enough bandwidth for them all. Another use for datagrams is broadcasting, which corresponds to mass mailing of advertisements in the postal model, and is equally popular in most circles. One use for broadcast packets is to send out a message to your local subnet saying, "Hey, is there anybody around here who wants to be my server?"

Because datagrams don't provide the illusion of a lasting connection, you get a little more freedom in how you use them. You don't have to connect your socket to the remote end that you're sending data. Instead, address each datagram individually when you send. Assuming $remote_addr is the result of a call to sockaddr_in, do this:

send(MYSOCKET, $msg_buffer, $flags, $remote_addr)
    or die "Can't send: $!\n";

The only flag argument used much is MSG_OOB, which lets you send and receive out-of-band data in advanced applications.

The remote address should be a port and Internet address combination returned by the Socket module's sockaddr_in function. If you want, call connect on that address instead. Then you can omit the last argument to your send s, after which they'll all go to that recipient. Unlike streams, you are free to reconnect to another machine with the same datagram socket.

Example 17-1 is a small example of a UDP program. It contacts the UDP time port of the machine whose name is given on the command line, or of the local machine by default. This doesn't work on all machines, but those with a server will send you back a 4-byte integer packed in network byte order representing the time that machine thinks it is. The time returned, however, is in the number of seconds since 1900. You have to subtract the number of seconds between 1900 and 1970 to feed that time to the localtime or gmtime conversion functions.

Example 17-1. clockdrift

  #!/usr/bin/perl
  # clockdrift - compare another system's clock with this one
  use strict;
  use Socket;

  my ($host, $him, $src, $port, $ipaddr, $ptime, $delta);
  my $SECS_of_70_YEARS      = 2_208_988_800;

  socket(MsgBox, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
      or die "socket: $!";
  $him = sockaddr_in(scalar(getservbyname("time", "udp")),
  defined(send(MsgBox, 0, 0, $him))
      or die "send: $!";
  defined($src = recv(MsgBox, $ptime, 4, 0))
      or die "recv: $!";
  ($port, $ipaddr) = sockaddr_in($src);
  $host = gethostbyaddr($ipaddr, AF_INET);
  my $delta = (unpack("N", $ptime) - $SECS_of_70_YEARS) - time( );
  print "Clock on $host is $delta seconds ahead of this one.\n";

If the machine you're trying to contact isn't alive or if its response is lost, you'll only know because your program will get stuck in the recv waiting for an answer that will never come.

17.4.4. See Also

The send, recv, gethostbyaddr, and unpack functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Socket and IO::Socket modules; the section on "Message Passing" in Chapter 16 of Programming Perl and in perlipc(1); UNIX Network Programming; Recipe 17.5

Previous | Home | Next
17.3. Communicating over TCP | Book Index | 17.5. Setting Up a UDP Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.5. Setting Up a UDP Server

17.5.1. Problem

You want to write a UDP server.

17.5.2. Solution

First bind to the port on which the server is to be contacted. With IO::Socket, this is easily accomplished:

use IO::Socket;
$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Proto     => "udp")
    or die "Couldn't be a udp server on port $server_port : $@\n";

Then, go into a loop receiving messages:

while ($him = $server->recv($datagram, $MAX_TO_READ, $flags)) {
    # do something
}

17.5.3. Discussion

Life with UDP is much simpler than life with TCP. Instead of accepting client connections one at a time and committing yourself to a long-term relationship, take messages from clients as they come in. The recv function returns the address of the sender, which you must then decode.

Example 17-2 is a small UDP-based server that just sits around waiting for messages. Every time a message comes in, we find out who sent it, send that person a message based on the previous message, and then save the new message.

Example 17-2. udpqotd

  #!/usr/bin/perl -w
  # udpqotd - UDP message server
  use strict;
  use IO::Socket;
  my ($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO);
  $MAXLEN = 1024;
  $PORTNO = 5151;
  $sock = IO::Socket::INET->new(LocalPort => $PORTNO, Proto => 'udp')
      or die "socket: $@";
  print "Awaiting UDP messages on port $PORTNO\n";
  $oldmsg = "This is the starting message.";
  while ($sock->recv($newmsg, $MAXLEN)) {
      my($port, $ipaddr) = sockaddr_in($sock->peername);
      $hishost = gethostbyaddr($ipaddr, AF_INET);
      print "Client $hishost said ``$newmsg''\n";
      $sock->send($oldmsg);
      $oldmsg = "[$hishost] $newmsg";
  }
  die "recv: $!";

This program is easier using IO::Socket than the raw Socket module. We don't have to say where to send the message, because the library keeps track of who sent the last message and stores that information away on the $sock object. The peername method retrieves it for decoding.

You can't use the telnet program to talk to this server. You have to use a dedicated client. One is shown in Example 17-3.

Example 17-3. udpmsg

  #!/usr/bin/perl -w
  # udpmsg - send a message to the udpquotd server
  use IO::Socket;
  use strict;
  my($sock, $server_host, $msg, $port, $ipaddr, $hishost,
     $MAXLEN, $PORTNO, $TIMEOUT);
  $MAXLEN  = 1024;
  $PORTNO  = 5151;
  $TIMEOUT = 5;
  $server_host = shift;
  $msg         = "@ARGV";
  $sock = IO::Socket::INET->new(Proto     => 'udp',
                                PeerPort  => $PORTNO,
                                PeerAddr  => $server_host)
      or die "Creating socket: $!\n";
  $sock->send($msg) or die "send: $!";
  eval {
      local $SIG{ALRM} = sub { die "alarm time out" };
      alarm $TIMEOUT;
      $sock->recv($msg, $MAXLEN)      or die "recv: $!";
      alarm 0;
      1;  # return value from eval on normalcy
  } or die "recv from $server_host timed out after $TIMEOUT seconds.\n";
  ($port, $ipaddr) = sockaddr_in($sock->peername);
  $hishost = gethostbyaddr($ipaddr, AF_INET);
  print "Server $hishost responded ``$msg''\n";

This time when we create the socket, we supply a peer host and port at the start, allowing us to omit that information in the send.

We've added an alarm timeout in case the server isn't responsive, or maybe not even alive. Because recv is a blocking system call that may not return, we wrap it in the standard eval block construct for timing out a blocking operation.

17.5.4. See Also

The send, recv, and alarm functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Socket and IO::Socket modules; the section on "Message Passing" in Chapter 16 of Programming Perl and in perlipc(1); UNIX Network Programming; Recipe 16.21; Recipe 17.4

Previous | Home | Next
17.4. Setting Up a UDP Client | Book Index | 17.6. Using Unix Domain Sockets
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.6. Using Unix Domain Sockets

17.6.1. Problem

You want to communicate with other processes on only the local machine.

17.6.2. Solution

Use domain sockets. You can use the code and techniques from the preceding Internet domain recipes, with the following changes:

  • Because the naming system is different, use sockaddr_un instead of sockaddr_in.

  • Use IO::Socket::UNIX instead of IO::Socket::INET, and use Peer and Local instead of PeerAddr/PeerPort and LocalAddr/LocalPort.

  • Use PF_UNIX instead of PF_INET, and give PF_UNSPEC as the last argument to socket.

  • SOCK_STREAM clients don't have to bind to a local address before they connect.

17.6.3. Discussion

Unix domain sockets have names like files on the filesystem. In fact, most systems implement them as special files; that's what Perl's -S filetest operator looks for—whether the file is a Unix domain socket.

Supply the filename as the Peer argument to IO::Socket::UNIX->new, or encode it with sockaddr_un and pass it to connect. Here's how to make server and client Unix domain stream sockets with IO::Socket::UNIX:

use IO::Socket;

unlink "/tmp/mysock";
$server = IO::Socket::UNIX->new(LocalAddr => "/tmp/mysock",
                                Type      => SOCK_STREAM,
                                Listen    => 5 )
    or die $@;

$client = IO::Socket::UNIX->new(PeerAddr  => "/tmp/mysock",
                                Type      => SOCK_STREAM,
                                Timeout   => 10 )
    or die $@;

Here's how to use the traditional functions to make stream sockets:

use Socket;

socket(SERVER, PF_UNIX, SOCK_STREAM, 0);
unlink "/tmp/mysock";
bind(SERVER, sockaddr_un("/tmp/mysock"))
    or die "Can't create server: $!";

socket(CLIENT, PF_UNIX, SOCK_STREAM, 0);
connect(CLIENT, sockaddr_un("/tmp/mysock"))
    or die "Can't connect to /tmp/mysock: $!";

Unless you know what you're doing, set the protocol (the Proto argument to IO::Socket::UNIX->new and the last argument to socket) to 0 for PF_UNIX sockets. You can use both SOCK_DGRAM and SOCK_STREAM types of communication in the Unix domain, with the same semantics as we saw for Internet sockets. Changing the domain doesn't change the characteristics of the socket type.

Because many systems actually create a special file in the filesystem, you should delete the file before you try to bind the socket. Even though there is a race condition (somebody could create a file with the name of your socket between your calls to unlink and bind), this isn't a security problem, because bind won't overwrite an existing file.

17.6.4. See Also

Recipe 17.1 through Recipe 17.5

Previous | Home | Next
17.5. Setting Up a UDP Server | Book Index | 17.7. Identifying the Other End of a Socket
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.7. Identifying the Other End of a Socket

17.7.1. Problem

You have a socket and want to identify the machine at the other end.

17.7.2. Solution

If you're only interested in the IP address of the remote machine, use:

use Socket;

$other_end         = getpeername(SOCKET)
    or die "Couldn't identify other end: $!\n";
($port, $iaddr)    = unpack_sockaddr_in($other_end);
$ip_address        = inet_ntoa($iaddr);

If you want its actual hostname, use:

use Socket;

$other_end        = getpeername(SOCKET)
    or die "Couldn't identify other end: $!\n";
($port, $iaddr)   = unpack_sockaddr_in($other_end);
$actual_ip        = inet_ntoa($iaddr);
$claimed_hostname = gethostbyaddr($iaddr, AF_INET);
@name_lookup      = gethostbyname($claimed_hostname)
    or die "Could not look up $claimed_hostname : $!\n";
@resolved_ips     = map { inet_ntoa($_) }
    @name_lookup[ 4 .. $#name_lookup ];

17.7.3. Discussion

For a long time, figuring out who connected to you was considered more straightforward than it really is. The getpeername function returns the IP address of the remote machine in a packed binary structure (or undef if an error occurred). To unpack it, use inet_ntoa. If you want the name of the remote end, call gethostbyaddr to look up the name of the machine in the DNS tables, right?

Not really. That's only half the solution. Because a name lookup goes to the name's owner's DNS server and a lookup of an IP address goes to the address's owner's DNS server, you have to contend with the possibility that the machine that connected to you is giving incorrect names. For instance, the machine evil.crackers.org could belong to malevolent cyberpirates who tell their DNS server that its IP address (1.2.3.4) should be identified as trusted.dod.gov. If your program trusts trusted.dod.gov, a connection from evil.crackers.org will cause getpeername to return the right IP address (1.2.3.4), but gethostbyaddr will return the duplicitous name.

To avoid this problem, we take the (possibly deceitful) name returned by gethostbyaddr and look it up again with gethostbyname. In the case of evil.crackers.org, the lookup of trusted.dod.gov will be done through dod.gov's DNS servers, and will return the real IP address(es) for trusted.dod.gov. Because many machines have more than one IP address (multihomed web servers are the obvious example), we can't use the simplified form of gethostbyname:

$packed_ip  = gethostbyname($name) or die "Couldn't look up $name : $!\n";
$ip_address = inet_ntoa($packed_ip);

So far we've assumed we're dealing with an Internet domain application. You can also call getpeername on a Unix domain socket. If the other end called bind, you'll get the filename they bound to. If the other end didn't call bind, however, getpeername may return an empty string (unpacked), a packed string with oddball garbage in it, or undef to indicate an error, or your computer may reboot. (These possibilities are listed in descending order of probability and desirability.) This is what we in the computer business call "undefined behavior."

Even this level of paranoia and mistrust isn't enough. It's still possible for people to fake out DNS servers they don't directly control, so don't use hostnames for identification or authentication. True paranoiacs and misanthropes use cryptographically secure methods.

17.7.4. See Also

The gethostbyaddr, gethostbyname, and getpeername functions in Chapter 29 of Programming Perl and in perlfunc(1); the inet_ntoa function in the standard Socket module; the documentation for the standard IO::Socket and Net::hostnet modules

Previous | Home | Next
17.6. Using Unix Domain Sockets | Book Index | 17.8. Finding Your Own Name and Address
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.8. Finding Your Own Name and Address

17.8.1. Problem

You want to find your (fully qualified) hostname.

17.8.2. Solution

First, get your (possibly qualified) hostname. Try either the standard Sys::Hostname module:

use Sys::Hostname;

$hostname = hostname( );

or POSIX's uname function:

use POSIX qw(uname);
($kernel, $hostname, $release, $version, $hardware) = uname( );

$hostname = (uname)[1];             # or just one

Then turn it into an IP address and convert to its canonical name:

use Socket;                         # for AF_INET
$address  = gethostbyname($hostname)
    or die "Couldn't resolve $hostname : $!";
$hostname = gethostbyaddr($address, AF_INET)
    or die "Couldn't re-resolve $hostname : $!";

17.8.3. Discussion

Sys::Hostname tries to be portable by using knowledge about your system to decide how best to find the hostname. It tries many different ways of getting the hostname, but several involve running other programs. This can lead to tainted data (see Recipe 19.1).

POSIX::uname, on the other hand, works only on POSIX systems and isn't guaranteed to provide anything useful in the nodename field that we are examining. That said, the value is useful on many machines and doesn't suffer from the tainted data problem that Sys::Hostname does.

Once you have the name, though, you must consider that it might be missing a domain name. For instance, Sys::Hostname may return you guanaco instead of guanaco.camelids.org. To fix this, convert the name back into an IP address with gethostbyname and then back into a name again with gethostbyaddr. By involving the domain name system, you are guaranteed of getting a full name.

17.8.4. See Also

The gethostbyname and gethostbyaddr functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Net::hostent and Sys::Hostname modules

Previous | Home | Next
17.7. Identifying the Other End of a Socket | Book Index | 17.9. Closing a Socket After Forking
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.9. Closing a Socket After Forking

17.9.1. Problem

Your program has forked and you want to tell the other end that you're done sending data. You've tried close on the socket, but the remote end never gets an EOF or SIGPIPE.

17.9.2. Solution

Use shutdown:

shutdown(SOCKET, 0);                # I/we have stopped reading data
shutdown(SOCKET, 1);                # I/we have stopped writing data
shutdown(SOCKET, 2);                # I/we have stopped using this socket

On an IO::Socket object, you could also write:

$socket->shutdown(0);               # I/we have stopped reading data

17.9.3. Discussion

When a process forks, the child has copies of the parent's open filehandles, including sockets. When you close a file or socket, you close only the current process's copy. If another process (parent or child) still has the socket open, the operating system doesn't consider their file or socket closed.

Take the case of a socket that data is being sent to. If two processes have this socket open, one can close it but, because the other still has it open, the socket isn't considered closed by the operating system. Until the other process closes the socket, the process reading from the socket won't get an end-of-file. This can lead to confusion and deadlock.

To avoid this, either close unused filehandles after a fork or use shutdown. The shutdown function is a more insistent form of close—it tells the operating system that even though other processes have copies of this filehandle, it should be marked as closed, and the other end should get an end-of-file if the processes read from it or a SIGPIPE if they write to it.

The numeric argument to shutdown lets you specify which sides of the connection are closed. An argument of 0 says that we're done reading data, so the other end of the socket will get a SIGPIPE if they try writing. 1 says that we're done writing data, so the other end of the socket will get an end-of-file if they try reading. 2 says we're done reading and writing.

Imagine a server that wants to read its client's request until end-of-file, and then send an answer. If the client calls close, that socket is now invalid for I/O, so no answer would ever come back. Instead, the client should use shutdown to half-close the connection.

print SERVER "my request\n";        # send some data
shutdown(SERVER, 1);                # send eof; no more writing
$answer = <SERVER>;                 # but you can still read

17.9.4. See Also

The close and shutdown functions in Chapter 29 of Programming Perl and in perlfunc(1); your system's shutdown(2) manpage (if you have it)

Previous | Home | Next
17.8. Finding Your Own Name and Address | Book Index | 17.10. Writing Bidirectional Clients
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.10. Writing Bidirectional Clients

17.10.1. Problem

You want set up a fully interactive client so you can type a line, get the answer, type a line, get the answer, etc., somewhat like telnet.

17.10.2. Solution

Once you've connected, fork off a duplicate process. One twin reads only your input and passes it on to the server, and the other reads only the server's output and sends it to your own output.

17.10.3. Discussion

In a client-server relationship, it is difficult to know whose turn it is to talk. Single-threaded solutions involving the four-argument version of select are hard to write and maintain. But there's no reason to ignore multitasking solutions. The fork function dramatically simplifies this problem.

Once you've connected to the service you'd like to chat with, call fork to clone a twin. Each of these two (nearly) identical processes has a simple job. The parent copies everything from the socket to standard output, and the child simultaneously copies everything from standard input to the socket.

The code is in Example 17-4.

Example 17-4. biclient

  #!/usr/bin/perl -w
  # biclient - bidirectional forking client
  use strict;
  use IO::Socket;
  my ($host, $port, $kidpid, $handle, $line);

  unless (@ARGV =  = 2) { die "usage: $0 host port" }
  ($host, $port) = @ARGV;

  # create a tcp connection to the specified host and port
  $handle = IO::Socket::INET->new(Proto     => "tcp",
                                  PeerAddr  => $host,
                                  PeerPort  => $port)
         or die "can't connect to port $port on $host: $!";

  $handle->autoflush(1);              # so output gets there right away
  print STDERR "[Connected to $host:$port]\n";

  # split the program into two processes, identical twins
  die "can't fork: $!" unless defined($kidpid = fork( ));

  if ($kidpid) {
      # parent copies the socket to standard output
      while (defined ($line = <$handle>)) {
          print STDOUT $line;
      }
      kill("TERM" => $kidpid);        # send SIGTERM to child
  }
  else {
      # child copies standard input to the socket
      while (defined ($line = <STDIN>)) {
          print $handle $line;
      }
  }
  exit;

To accomplish the same thing using just one process is remarkably more difficult. It's easier to code two processes, each doing a single task, than it is to code one process to do two different tasks. Take advantage of multitasking by splitting your program into multiple threads of control, and some of your bewildering problems will become much easier.

The kill function in the parent's if block is there to send a signal to the child (currently running in the else block) as soon as the remote server has closed its end of the connection. The kill at the end of the parent's block is there to eliminate the child process as soon as the server on the other end goes away.

If the remote server sends data a byte at time and you need that data immediately without waiting for a newline (which may never arrive), you may wish to replace the while loop in the parent with the following:

my $byte;
while (sysread($handle, $byte, 1) =  = 1) {
    print STDOUT $byte;
}

Making a system call for each byte you want to read is not very efficient (to put it mildly), but it is the simplest to explain and works reasonably well.

17.10.4. See Also

The sysread and fork functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard IO::Socket module; Recipe 16.5; Recipe 16.10; Recipe 17.11

Previous | Home | Next
17.9. Closing a Socket After Forking | Book Index | 17.11. Forking Servers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.11. Forking Servers

17.11.1. Problem

You want to write a server that forks a subprocess to handle each new client.

17.11.2. Solution

Fork in the accept loop, and use a $SIG{CHLD} handler to reap the children.

# set up the socket SERVER, bind and listen ...
use POSIX qw(:sys_wait_h);

sub REAPER {
    1 until (-1 =  = waitpid(-1, WNOHANG));
    $SIG{CHLD} = \&REAPER;                 # unless $]>= 5.002
}

$SIG{CHLD} = \&REAPER;

while ($hisaddr = accept(CLIENT, SERVER)) {
    next if $pid = fork;                    # parent
    die "fork: $!" unless defined $pid;     # failure
    # otherwise child
    close(SERVER);                          # no use to child
    # ... do something
    exit;                                   # child leaves
} continue {
    close(CLIENT);                          # no use to parent
}

17.11.3. Discussion

This approach is very common for SOCK_STREAM servers in the Internet and Unix domains. Each incoming connection gets a cloned server of its own. The model is:

  1. Accept a stream connection.

  2. Fork off a duplicate to communicate over that stream.

  3. Return to 1.

This technique isn't used with SOCK_DGRAM sockets, because their method of communication is different. The time it takes to fork makes the forking model impractical for UDP-style servers. Instead of working with a series of stateful, long-running connections, SOCK_DGRAM servers work with a bunch of sporadic datagrams, usually statelessly. With them, the model must become:

  1. Read a datagram.

  2. Handle the datagram.

  3. Return to 1.

The child process deals with the new connection. Because it will never use the SERVER socket, we immediately close it. This is partly to keep a tidy house, but mainly so that the server socket is closed when the parent (server) process exits. If the children do not close the SERVER socket, the operating system considers the socket still open even when the parent dies. For more on this, see Recipe 17.9.

%SIG ensures that we clean up after our children when they exit. See Chapter 16 for details.

17.11.4. See Also

The fork and accept functions in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 16.15; Recipe 16.19; Recipe 17.12; Recipe 17.13

Previous | Home | Next
17.10. Writing Bidirectional Clients | Book Index | 17.12. Pre-Forking Servers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.12. Pre-Forking Servers

17.12.1. Problem

You want to write a server that concurrently processes several clients (as in Recipe 17.11), but connections are coming in so fast that forking slows the server too much.

17.12.2. Solution

Have a master server maintain a pool of pre-forked children, as shown in Example 17-5.

Example 17-5. preforker

  #!/usr/bin/perl
  # preforker - server who forks first
  use IO::Socket;
  use Symbol;
  use POSIX;

  # establish SERVER socket, bind and listen.
  $server = IO::Socket::INET->new(LocalPort => 6969,
                                  Type      => SOCK_STREAM,
                                  Proto     => 'tcp',
                                  Reuse     => 1,
                                  Listen    => 10 )
    or die "making socket: $@\n";

  # global variables
  $PREFORK                = 5;        # number of children to maintain
  $MAX_CLIENTS_PER_CHILD  = 5;        # number of clients each child should process
  %children               = ( );       # keys are current child process IDs
  $children               = 0;        # current number of children

  sub REAPER {                        # takes care of dead children
      $SIG{CHLD} = \&REAPER;
      my $pid = wait;
      $children --;
      delete $children{$pid};
  }

  sub HUNTSMAN {                      # signal handler for SIGINT
      local($SIG{CHLD}) = 'IGNORE';   # we're going to kill our children
      kill 'INT' => keys %children;
      exit;                           # clean up with dignity
  }

  # Fork off our children.
  for (1 .. $PREFORK) {
      make_new_child( );
  }

  # Install signal handlers.
  $SIG{CHLD} = \&REAPER;
  $SIG{INT}  = \&HUNTSMAN;

  # And maintain the population.
  while (1) {
      sleep;                          # wait for a signal (i.e., child's death)
      for ($i = $children; $i < $PREFORK; $i++) {
          make_new_child( );           # top up the child pool
      }
  }

  sub make_new_child {
      my $pid;
      my $sigset;

      # block signal for fork
      $sigset = POSIX::SigSet->new(SIGINT);
      sigprocmask(SIG_BLOCK, $sigset)
          or die "Can't block SIGINT for fork: $!\n";

      die "fork: $!" unless defined ($pid = fork);

      if ($pid) {
          # Parent records the child's birth and returns.
          sigprocmask(SIG_UNBLOCK, $sigset)
              or die "Can't unblock SIGINT for fork: $!\n";
          $children{$pid} = 1;
          $children++;
          return;
      } else {
          # Child can *not* return from this subroutine.
          $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before

          # unblock signals
          sigprocmask(SIG_UNBLOCK, $sigset)
              or die "Can't unblock SIGINT for fork: $!\n";

          # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
          for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
              $client = $server->accept( )     or last;
              # do something with the connection
          }

          # tidy up gracefully and finish

          # this exit is VERY important, otherwise the child will become
          # a producer of more and more children, forking yourself into
          # process death.
          exit;
      }
  }

17.12.3. Discussion

Whew. Although this is a lot of code, the logic is simple: the parent process never deals with clients but instead forks $PREFORK children to do that. The parent keeps track of how many children it has and forks more to replace dead children. Children exit after having handled $MAX_CLIENTS_PER_CHILD clients.

The code is a reasonably direct implementation of this logic. The only trick comes with signal handlers: we want the parent to catch SIGINT and kill its children, so we install our signal handler &HUNTSMAN to do this. But we then have to be careful that the child doesn't have the same handler after we fork. We use POSIX signals to block the signal for the duration of the fork (see Recipe 16.20).

When you use this code in your programs, be sure that make_new_child never returns. If it does, the child will return, become a parent, and spawn off its own children. Your system will fill up with processes, your system administrator will storm down the hallway to find you, and you may end up tied to four horses wondering why you hadn't paid more attention to this paragraph.

On some operating systems, notably Solaris, you cannot have multiple children doing an accept on the same socket. You have to use file locking to ensure that only one child can call accept at any particular moment. Implementing this is left as an exercise for the reader.

17.12.4. See Also

The select function in Chapter 29 of Programming Perl or perlfunc(1); your system's fcntl(2) manpage (if you have one); the documentation for the standard Fcntl, Socket, IO::Select, IO::Socket, and Tie::RefHash modules; Recipe 17.11; Recipe 17.12

Previous | Home | Next
17.11. Forking Servers | Book Index | 17.13. Non-Forking Servers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.13. Non-Forking Servers

17.13.1. Problem

You want a server to deal with several simultaneous connections, but you don't want to fork a process to deal with each connection.

17.13.2. Solution

Keep an array of open clients, use select to read information when it becomes available, and deal with a client only when you have read a full request from it, as shown in Example 17-6.

Example 17-6. nonforker

  #!/usr/bin/perl -w
  # nonforker - server who multiplexes without forking
  use POSIX;
  use IO::Socket;
  use IO::Select;
  use Socket;
  use Fcntl;
  use Tie::RefHash;

  $port = 1685;               # change this at will

  # Listen to port.
  $server = IO::Socket::INET->new(LocalPort => $port,
                                  Listen    => 10 )
    or die "Can't make server socket: $@\n";

  # begin with empty buffers
  %inbuffer  = ( );
  %outbuffer = ( );
  %ready     = ( );

  tie %ready, 'Tie::RefHash';

  nonblock($server);
  $select = IO::Select->new($server);

  # Main loop: check reads/accepts, check writes, check ready to process
  while (1) {
      my $client;
      my $rv;
      my $data;

      # check for new information on the connections we have

      # anything to read or accept?
      foreach $client ($select->can_read(1)) {

          if ($client =  = $server) {
              # accept a new connection

              $client = $server->accept( );
              $select->add($client);
              nonblock($client);
          } else {
              # read data
              $data = '';
              $rv   = $client->recv($data, POSIX::BUFSIZ, 0);

              unless (defined($rv) && length $data) {
                  # This would be the end of file, so close the client
                  delete $inbuffer{$client};
                  delete $outbuffer{$client};
                  delete $ready{$client};

                  $select->remove($client);
                  close $client;
                  next;
              }

              $inbuffer{$client} .= $data;

              # test whether the data in the buffer or the data we
              # just read means there is a complete request waiting
              # to be fulfilled.  If there is, set $ready{$client}
              # to the requests waiting to be fulfilled.
              while ($inbuffer{$client} =~ s/(.*\n)//) {
                  push( @{$ready{$client}}, $1 );
              }
          }
      }

      # Any complete requests to process?
      foreach $client (keys %ready) {
          handle($client);
      }

      # Buffers to flush?
      foreach $client ($select->can_write(1)) {
          # Skip this client if we have nothing to say
          next unless exists $outbuffer{$client};

          $rv = $client->send($outbuffer{$client}, 0);
          unless (defined $rv) {
              # Whine, but move on.
              warn "I was told I could write, but I can't.\n";
              next;
          }
          if ($rv =  = length $outbuffer{$client} ||
              $!  =  = POSIX::EWOULDBLOCK )
          {
              substr($outbuffer{$client}, 0, $rv) = '';
              delete $outbuffer{$client} unless length $outbuffer{$client};
          } else {
              # Couldn't write all the data, and it wasn't because
              # it would have blocked.  Shutdown and move on.
              delete $inbuffer{$client};
              delete $outbuffer{$client};
              delete $ready{$client};

              $select->remove($client);
              close($client);
              next;
          }
      }

      # Out of band data?
      foreach $client ($select->has_exception(0)) {  # arg is timeout
          # Deal with out-of-band data here, if you want to.
      }
  }

  # handle($socket) deals with all pending requests for $client
  sub handle {
      # requests are in $ready{$client}
      # send output to $outbuffer{$client}
      my $client = shift;
      my $request;

      foreach $request (@{$ready{$client}}) {
          # $request is the text of the request
          # put text of reply into $outbuffer{$client}
      }
      delete $ready{$client};
  }

  # nonblock($socket) puts socket into nonblocking mode
  sub nonblock {
      my $socket = shift;
      my $flags;

      $flags = fcntl($socket, F_GETFL, 0)
              or die "Can't get flags for socket: $!\n";
      fcntl($socket, F_SETFL, $flags | O_NONBLOCK)
              or die "Can't make socket nonblocking: $!\n";
  }

17.13.3. Discussion

As you see, handling multiple simultaneous clients within one process is more complicated than forking dedicated clones. You end up having to do a lot of operating system-like work to split your time between different connections and to ensure you don't block while reading.

The select function tells which connections have data waiting to be read, which can have data written to them, and which have unread out-of-band data. We could use the select function built into Perl, but it would take more work to find out which filehandles are available. So we use the standard IO::Select module.

We use fcntl to turn on the non-blocking option for the server socket. Without it, a single client whose socket buffers filled up would cause the server to pause until the buffers emptied. Using non-blocking I/O, however, means that we have to deal with the case of partial reads and writes—we can't simply use <> to block until an entire record can be read, or use print to send an entire record with print. %inbuffer holds the incomplete command read from clients, %outbuffer holds data not yet sent, and %ready holds arrays of unhandled messages.

To use this code in your program, do three things. First, change the IO::Socket::INET call to specify your service's port. Second, change the code that moves records from the inbuffer to the ready queue. Currently it treats each line (text ending in \n) as a request. If your requests are not lines, you'll want to change this.

while ($inbuffer{$client} =~ s/(.*\n)//) {
    push( @{$ready{$client}}, $1 );
}

Finally, change the middle of the loop in handler to actually create a response to the request. A simple echoing program would say:

$outbuffer{$client} .= $request;

Error handling is left as an exercise to the reader. At the moment, we assume any read or write that caused an error is reason to end that client's connection. This is probably too harsh, because "errors" like EINTR and EAGAIN don't warrant termination (although you should never get an EAGAIN when using select( )).

17.13.4. See Also

The select function in Chapter 29 of Programming Perl or perlfunc(1); your system's fcntl(2) manpage (if you have one); the documentation for the standard Fcntl, Socket, IO::Select, IO::Socket, and Tie::RefHash modules; Recipe 17.11; Recipe 17.12

Previous | Home | Next
17.12. Pre-Forking Servers | Book Index | 17.14. Multitasking Server with Threads
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.14. Multitasking Server with Threads

17.14.1. Problem

You want to write a server that handles multiple clients from within the one process using your operating system's threads.

17.14.2. Solution

Use Perl v5.8.1 or later and threads.pm:

use threads;
use IO::Socket;
my $listen = IO::Socket::INET->new(
                                   LocalPort => $SERVER_PORT,
                                   ReuseAddr => 1,
                                   Listen => 10,
                                   );
sub handle_connection {
    my $socket = shift;
    my $output = shift || $socket;
    my $exit = 0;
    while (<$socket>) {
        # work with $_,
        # print to $output
        # set $exit to true when connection is done
        last if $exit;
    }
}
while (my $socket = $listen->accept) {
    async(\&handle_connection, $socket)->detach;
}

17.14.3. Discussion

Threading in Perl is still evolving, but it became functional as of v5.8.1. The code in the Solution will not work in earlier versions of Perl. In particular, earlier versions of Perl implemented an entirely different threading model than the current "interpreter threads" system that threads.pm assumes.

The hard work of handling the connection to the client is done in the handle_connection subroutine. It is given the client socket as a parameter, and can call blocking routines like <$socket> because it runs in its own thread. If one thread blocks while reading, other threads can still run.

The master thread in the program creates the socket and accepts connections on it. When a new client connects, the master thread spawns a new thread (with the async call) to handle the connection. The thread runs until the subroutine it is called with (handle_connection in this case) returns.

We detach the newly created thread to ensure that its variables are garbage collected (closing the socket to the client) when the thread ends. If we didn't call detach, our process would accumulate dead threads until we could no longer spawn new threads.

17.14.4. See Also

The documentation for the standard module threads.pm; Recipe 17.15

Previous | Home | Next
17.13. Non-Forking Servers | Book Index | 17.15. Writing a Multitasking Server with POE
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.15. Writing a Multitasking Server with POE

17.15.1. Problem

You want to write a server that handles multiple clients from within the one process, without using Perl 5.8's threads or the complexity of non-blocking I/O.

17.15.2. Solution

Use the cooperative multitasking framework POE (available from CPAN) and the accompanying POE::Component::Server::TCP module to create the server for you:

#!/usr/bin/perl

use warnings;
use strict;

use POE qw(Component::Server::TCP);

# Start a TCP server.  Client input will be logged to the console and
# echoed back to the client, one line at a time.

POE::Component::Server::TCP->new
  ( Port => $PORT_NUMBER,           # port to listen on
    ClientInput => \&handle_input,  # method to call with input
  );

# Start the server.

$poe_kernel->run( );
exit 0;

sub handle_input {
  my ( $session, $heap, $input ) = @_[ SESSION, HEAP, ARG0 ];
  # $session is a POE::Session object unique to this connection,
  # $heap is this connection's between-callback storage.
  # New data from client is in $input.  Newlines are removed.
  # To echo input back to the client, simply say:
  $heap->{client}->put($input);
  # and log it to the console
  print "client ", $session->ID, ": $input\n";
}

17.15.3. Solution

POE is a cooperatively multitasking framework for Perl built entirely out of software components. POE doesn't require you to recompile the Perl interpreter to support threads, but it does require you to design your program around the ideas of events and callbacks. Documentation for this framework is available at http://poe.perl.org/.

It helps to think of POE as an operating system: there's the kernel (an object responsible for deciding which piece of code is run next) and your processes (called sessions, implemented as objects). POE stores the kernel object in the variable $poe_kernel, which is automatically imported into your namespace. Each process in your operating system has a heap, memory where the variables for that process are stored. Sessions have heaps as well. In an operating system, I/O libraries handle buffered I/O. In POE, a wheel handles accepting data from a writer and sending it on to a reader.

There are dozens of prebuilt sessions (called components) for servers, clients, parsers, queues, databases, and many other common tasks. These components do the hard work of understanding the protocols and data formats, leaving you to write only the interesting code—what to do with the data or what data to serve.

When you use POE::Component::Server::TCP, the component handles creating the server, listening, accepting connections, and receiving data from the client. For each bit of data it receives, the component calls back to your code. Your code is responsible for parsing the request and generating a response.

In the call to POE::Component::Server::TCP's constructor, specify the port to listen on with Port, and your code to handle input with ClientInput. There are many other options and callbacks available, including Address to specify a particular interface address to listen on and ClientFilter to change its default line parser.

Your client input subroutine is called with several parameters, but we use only three: the POE session object representing this connection, the heap for this session, and the latest chunk of input from the client. The first two are standard parameters supplied by POE to all session calls, and the last is supplied by the server component.

The strange assignment line at the start of handle_input merely takes a slice of @_, using constants to identify the position in the method arguments of the session, heap, and first real argument. It's a POE idiom that lets the POE kernel change the actual method parameters and their order, without messing up code that was written before such a change.

my ( $session, $heap, $input ) = @_[ SESSION, HEAP, ARG0 ];

The session's heap contains a client shell that you use for communicating with the client: $heap->{client}. The put method on that object sends data back to the client. The client's IP address is accessible through $heap->{remote_ip}.

If the action you want to perform in the callback is time-consuming and would slow down communication with other clients that are connected to your server, you may want to use POE sessions. A session is an event-driven machine: you break the time-consuming task into smaller (presumably quicker) chunks, each of which is implemented as a callback. Each callback has one or more events that trigger it.

It's the responsibility of each callback to tell the kernel to queue more events, which in turn pass execution to the next callback (e.g., in the "connect to the database" function, you'd tell the kernel to call the "fetch data from the database" function when you're done). If the action cannot be broken up, it can still be executed asynchronously in another process with POE::Wheel::Run or POE::Component::Child.

POE includes non-blocking timers, I/O watchers, and other resources that you can use to trigger callbacks on external conditions. Wheels and Components are ultimately built from these basic resources.

Information on POE programming is given at http://poe.perl.org, including pointers to tutorials given at various conferences. It can take a bit of mental adjustment to get used to the POE framework, but for programs that deal with asynchronous events (such as GUIs and network servers) it's hard to beat POE for portability and functionality.

17.15.4. See Also

The documentation for the CPAN modules POE, POE::Session, POE::Wheel, and POE::Component::Server::TCP; http://poe.perl.org/; Recipe 17.14

Previous | Home | Next
17.14. Multitasking Server with Threads | Book Index | 17.16. Writing a Multihomed Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.16. Writing a Multihomed Server

17.16.1. Problem

You want to write a server that knows that the machine it runs on has multiple IP addresses, and that it should possibly do different things for each address.

17.16.2. Solution

Don't bind your server to a particular address. Instead, bind to INADDR_ANY. Then once you've accept ed a connection, use getsockname on the client socket to find out which address the client connected to:

use Socket;

socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
bind(SERVER, sockaddr_in($server_port, INADDR_ANY))
    or die "Binding: $!\n";

# accept loop
while (accept(CLIENT, SERVER)) {
    $my_socket_address = getsockname(CLIENT);
    ($port, $myaddr)   = sockaddr_in($my_socket_address);
}

17.16.3. Discussion

Whereas getpeername (as discussed in Recipe 17.7) returns the address of the remote end of the socket, getsockname returns the address of the local end. When we've bound to INADDR_ANY, thus accepting connections on any address the machine has, we need to use getsockname to identify which address the client connected to.

If you're using IO::Socket::INET, your code will look like this:

$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM,
                                Proto     => 'tcp',
                                Listen    => 10)
    or die "Can't create server socket: $@\n";

while ($client = $server->accept( )) {
    $my_socket_address = $client->sockname( );
    ($port, $myaddr)   = sockaddr_in($my_socket_address);
    # ...
}

If you don't specify a local port to IO::Socket::INET->new, your socket will be bound to INADDR_ANY.

If you want your server to listen only for a particular virtual host, don't use INADDR_ANY. Instead, bind to a specific host address:

use Socket;

$port = 4269;                       # port to bind to
$host = "specific.host.com";        # virtual host to listen on

socket(Server, PF_INET, SOCK_STREAM, getprotobyname("tcp"))
    or die "socket: $!";
bind(Server, sockaddr_in($port, inet_aton($host)))
    or die "bind: $!";
while ($client_address = accept(Client, Server)) {
    # ...
}

17.16.4. See Also

The getsockname function in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the standard Socket and IO::Socket modules; the section on "Sockets" in Chapter 16 of Programming Perl or perlipc(1)

Previous | Home | Next
17.15. Writing a Multitasking Server with POE | Book Index | 17.17. Making a Daemon Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.17. Making a Daemon Server

17.17.1. Problem

You want your program to run as a daemon.

17.17.2. Solution

If you are paranoid and running as root, chroot to a safe directory:

chroot("/var/daemon")
    or die "Couldn't chroot to /var/daemon: $!";

Fork once, and let the parent exit:

$pid = fork;
exit if $pid;
die "Couldn't fork: $!" unless defined($pid);

Close the three standard filehandles by reopening them to /dev/null:

for my $handle (*STDIN, *STDOUT, *STDERR) {
    open($handle, "+<", "/dev/null")
      || die "can't reopen $handle to /dev/null: $!";
}

Dissociate from the controlling terminal that started us and stop being part of whatever process group we had been a member of:

use POSIX;

POSIX::setsid( )
    or die "Can't start a new session: $!";

Trap fatal signals, setting a flag to indicate that we need to gracefully exit:

$time_to_die = 0;

sub signal_handler {
    $time_to_die = 1;
}

$SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signal_handler;
# trap or ignore $SIG{PIPE}

Wrap your actual server code in a loop:

until ($time_to_die) {
    # ...
}

17.17.3. Discussion

Before POSIX, every operating system had its own way for a process to tell the operating system "I'm going it alone, please interfere with me as little as possible." POSIX makes it much cleaner. That said, you can still take advantage of any operating system-specific calls if you want to.

The chroot call is one of those non-POSIX calls. It makes a process change where it thinks the directory / is. For instance, after chroot "/var/daemon", if the process tries to read the file /etc/passwd, it will read /var/daemon/etc/passwd. A chroot ed process needs copies of any files it will run made available inside its new /, of course. For instance, our chrooted process would need /var/daemon/bin/csh if it were going to glob files. For security reasons, only the superuser may chroot. This is done by FTP servers if you log into them anonymously. It isn't really necessary to become a daemon.

The operating system expects a child's parent to wait when the child dies. Our daemon process has no particular parent to do this, so we need to disinherit it. This we do by fork ing once and having our parent exit, so that the child is not associated with the process that started the parent. The child then closes the filehandles it got from its parent (STDIN, STDERR, and STDOUT) by reopening them to /dev/null, and then calls POSIX::setsid to ensure that it is completely dissociated from its parent's terminal.

If you want to make sure any higher numbered file descriptors are also closed, you can use the +<&=NUMBER notation to connect up an existing system file descriptor to a Perl filehandle, and then call close on that handle. Here we'll hit all descriptors above 2 and below 256:

for (my $fd = 3; $fd < 256; $fd++) {
    open(my $handle, "+<&=$fd");         # XXX: no error checking
    close $handle;                       # XXX: no error checking
}

Instead of guessing the highest possible file descriptor number, the "correct" way to handle that would be to write a C extension that called getdtablesize(3). This is an exercise we leave up to the user.

Now we're almost ready to begin. We don't want signals like SIGINT to kill us immediately (its default behavior), so we use %SIG to catch them and set a flag saying it's time to exit. Then our main program simply becomes: "While we weren't killed, do something."

The signal SIGPIPE is a special case. It's easy to get (by writing to a filehandle whose other end is closed) and has unforgiving default behavior (it terminates your process). You probably want to either ignore it ($SIG{PIPE} = 'IGNORE') or define your own signal handler to deal with it appropriately.

17.17.4. See Also

Your system's setsid(2) and chroot(1) manpage (if you have them); the chroot function in Chapter 29 of Programming Perl and in perlfunc(1); the Unix Socket FAQ at http://www.ibrado.com/sock-faq/; UNIX Network Programming

Previous | Home | Next
17.16. Writing a Multihomed Server | Book Index | 17.18. Restarting a Server on Demand
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.18. Restarting a Server on Demand

17.18.1. Problem

You want your server to shut down and restart when it receives a HUP signal, just like inetd or httpd.

17.18.2. Solution

Catch the SIGHUP. Within the handler, set harmless signal handlers, unblock signals, and re-execute your program:

use POSIX qw(:signal_h sigprocmask);

my $SELF = "/path/to/my/program";
my @ARGS = @ARGV;   # save for later

$SIG{HUP} = \&phoenix;

# your program

sub phoenix {
  # make signals harmless
  for my $nal (qw[ALRM CHLD HUP INT PIPE TERM]) {
    $SIG{$nal} = sub {  };
  }

  # reenable them
  my $s = POSIX::SigSet->new;
  my $t = POSIX::SigSet->new;
  sigprocmask(SIG_BLOCK, $s, $t);

  # and restart
  print "Restarting\n";
  exec $SELF => @ARGS;
  die "Couldn't exec $SELF => @ARGS\n";
}

17.18.3. Discussion

It sounds simple ("when I get a HUP signal, restart"), but it's tricky. You must know your own program name, and that isn't easy to find out. You could use $0 or the FindBin module. For normal programs, this is fine, but critical system utilities must be more cautious, as there's no guarantee that $0 is valid. You can hardcode the filename and arguments into your program, as we do here. That's not necessarily the most convenient solution, however, so you might want to read the program and arguments from an external file (using the filesystem's protections to ensure it hasn't been tampered with).

Be sure to install your signal handler after you define $SELF and @ARGS; otherwise there's a race condition when a SIGHUP could run restart but you don't know the program to run. This would cause your program to die.

Signals are tricky beasts. When you exec to restart your program, the reborn version inherits a set of blocked signals from its parent. Inside a signal handler, that signal is blocked. So if your signal handler simply called exec right away, the new process would have SIGHUP blocked. You could only restart your program once!

But it's not as simple as unblocking SIGHUP using the POSIX module's sigaction. Your program might have blocked other signals (ALRM, CHLD, and the others listed in the phoenix subroutine in the Solution), and those would also be blocked. If you simply unblocked them, your SIGHUP handler might be interrupted by delivery of those signals, so you must first give those signals a harmless handler. That's the purpose of the foreach loop in phoenix.

Some servers don't want to restart on receiving a SIGHUP—they just want to reread their configuration file.

$CONFIG_FILE = "/usr/local/etc/myprog/server_conf.pl";
$SIG{HUP} = \&read_config;
sub read_config {
    do $CONFIG_FILE;
}

Some observant servers even autoload their configuration files when they notice that those files have been updated. That way you don't have to go out of your way to signal them.

17.18.4. See Also

The exec function in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 8.16; Recipe 8.17; Recipe 16.15

Previous | Home | Next
17.17. Making a Daemon Server | Book Index | 17.19. Managing Multiple Streams of Input
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.19. Managing Multiple Streams of Input

17.19.1. Problem

The next input to your program could be coming from any number of filehandles, but you don't know which. You've tried using select( ), but the need to then do unbuffered I/O is more than you can deal with (and it's making your code very difficult to follow).

17.19.2. Solution

Use the IO::Multiplex module from CPAN. It calls a mux_input( ) function when input is received over a socket, and handles input and output buffering for you:

use IO::Multiplex;
$mux = IO::Multiplex->new( );
$mux->add($FH1);
$mux->add($FH2); # ... and so on for all the filehandles to manage
$mux->set_callback_object(_ _PACKAGE_ _);  # or an object
$mux->Loop( );

sub mux_input {
  my ($package, $mux, $fh, $input) = @_;
  # $input is ref to the filehandle's input buffer
  # ...
}

17.19.3. Discussion

Although you can use select to manage input coming at you from multiple directions, there are many tricks and traps. For example, you can't use <> to read a line of input, because you never know whether the client has sent a full line yet (or will ever finish sending a line). You can't print to a socket without the risk of the output buffer being full and your process blocking. You need to use non-blocking I/O and maintain your own buffers, and, consequently, life rapidly becomes unmanageably complex.

Fortunately, we have a way of hiding complexity: modules. The IO::Multiplex module from CPAN takes care of non-blocking I/O and select for you. You tell it which filehandles to watch, and it tells you when new data arrives. You can even print to the filehandles, and it'll buffer and non-blockingly output it. An IO::Multiplex object manages a pool of filehandles.

Use the add method to tell IO::Multiplex to manage a filehandle. This enables non-blocking I/O and disables the stdio buffering. When IO::Multiplex receives data on one of its managed filehandles, it calls a mux_input method on an object or class of your choosing. Specify where mux_input is by passing a package name (if your callback is a class method) or object value (if your callback is an object method) to the IO::Multiplex set_callback_object method. In the example in the Solution, we pass in the current package name so that IO::Multiplex will call the current package's mux_input method.

Your mux_input callback is called with four parameters: the object or package name that you gave to set_callback_object, the IO::Multiplex object that dispatched the callback, the filehandle from which data was received, and a reference to the input buffer. The callback should delete data from the buffer once it has been processed. For example, to process line by line:

sub mux_input {
  my ($obj, $mux, $fh, $buffer) = @_;
  my ($line) = $$buffer =~ s{^(.*)\n}{  } or return;
  # ...
}

The IO::Multiplex module also takes care of accept ing incoming connections on server sockets. Once you have a socket bound and listening (see Recipe 17.2), pass it to the listen method of an IO::Multiplex object:

use IO::Socket;
$server = IO::Socket::INET->new(LocalPort => $PORT, Listen => 10)
  or die $@;
$mux->listen($server);

When new incoming connections are accepted, the mux_connection callback is called. There are other callbacks, such as for full and partial closure of a filehandle, timeouts, and so on. For a full list of the methods you can use to control an IO::Multiplex object and a full list of the callbacks, see the IO::Multiplex documentation.

Example 17-7 is a rudimentary chat server that uses IO::Multiplex. It listens on port 6901 of the local host address and implements a very rudimentary chat protocol. Every client (see Example 17-8) has a "name," which they can change by sending a line that looks like /nick newname. Every other incoming line of text is sent out to all connected machines, prefaced with the name of the client that sent it.

To test this out, run the server in one window, then start a few clients in other windows. Type something into one and see what appears in the others.

Example 17-7. chatserver

  #!/usr/bin/perl -w
  # chatserver - very simple chat server
  use IO::Multiplex;
  use IO::Socket;
  use strict;
  my %Name;
  my $Server = IO::Socket::INET->new(LocalAddr => "localhost:6901",
                                     Listen   => 10, Reuse => 1,
                                     Proto    => 'tcp') or die $@;
  my $Mux = IO::Multiplex->new( );
  my $Person_Counter = 1;
  $Mux->listen($Server);
  $Mux->set_callback_object(_ _PACKAGE_ _);
  $Mux->loop( );
  exit;
  sub mux_connection {
    my ($package, $mux, $fh) = @_;
    $Name{$fh} = [ $fh, "Person " . $Person_Counter++ ];
  }
  sub mux_eof {
    my ($package, $mux, $fh) = @_;
    delete $Name{$fh};
  }
  sub mux_input {
    my ($package, $mux, $fh, $input) = @_;
    my $line;
    my $name;
    $$input =~ s{^(.*)\n+}{  } or return;
    $line = $1;
    if ($line =~ m{^/nick\s+(\S+)\s*}) {
      my $oldname = $Name{$fh};
      $Name{$fh} = [ $fh, $1 ];
      $line = "$oldname->[1] is now known as $1";
    } else {
      $line = "<$Name{$fh}[1]> $line";
    }
    foreach my $conn_struct (values %Name) {
      my $conn = $conn_struct->[0];
      $conn->print("$line\n");
    }
  }

Example 17-8. chatclient

  #!/usr/bin/perl -w
  # chatclient - client for the chat server
  use IO::Multiplex;
  use IO::Socket;
  use strict;
  my $sock = IO::Socket::INET->new(PeerAddr => "localhost:6901",
                                   Proto    => "tcp") or die $@;
  my $Mux = IO::Multiplex->new( );
  $Mux->add($sock);
  $Mux->add(*STDIN);
  $Mux->set_callback_object(_ _PACKAGE_ _);
  $Mux->loop( );
  exit;
  sub mux_input {
    my ($package, $mux, $fh, $input) = @_;
    my $line;
    $line = $$input;
    $$input = "";
    if (fileno($fh) =  = fileno(STDIN)) {
      print $sock $line;
    } else {
      print $line;
    }
  }

17.19.4. See Also

The documentation for the CPAN module IO::Multiplex; Recipe 17.1, Recipe 17.2, Recipe 17.20, and Recipe 17.21

Previous | Home | Next
17.18. Restarting a Server on Demand | Book Index | 17.20. Program: backsniff
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.20. Program: backsniff

This program logs attempts to connect to ports. It uses the Sys::Syslog module to log the connection attempt through a Unix socket, with logging level LOG_NOTICE and facility LOG_DAEMON. It uses getsockname to find out what port was connected to and getpeername to find out what machine made the connection. It uses getservbyport to convert the local port number (e.g., 7) into a service name (e.g, "echo").

It produces entries in the system log file like this:

May 25 15:50:22 coprolith sniffer: Connection from 207.46.131.141 to
207.46.130.164:echo

Install it in the inetd.conf file with a line like this:

echo    stream  tcp nowait  nobody /usr/scripts/snfsqrd sniffer

The program is shown in Example 17-9.

Example 17-9. backsniff

  #!/usr/bin/perl -w
  # backsniff - log attempts to connect to particular ports
  use strict;
  use Sys::Syslog qw(:DEFAULT setlogsock);
  use Socket;
  # identify my port and address
  my $sockname       = getsockname(STDIN)
                       or die "Couldn't identify myself: $!\n";
  my ($port, $iaddr) = sockaddr_in($sockname);
  my $my_address     = inet_ntoa($iaddr);
  # get a name for the service
  my $service = (getservbyport ($port, "tcp"))[0] || $port;
  # now identify remote address
  $sockname          = getpeername(STDIN)
                           or die "Couldn't identify other end: $!\n";
  ($port, $iaddr)    = sockaddr_in($sockname);
  my $ex_address     = inet_ntoa($iaddr);
  # and log the information
  setlogsock("unix");
  openlog("sniffer", "ndelay", "daemon");
  syslog("notice", "Connection from %s to %s:%s\n", $ex_address,
          $my_address, $service);
  closelog( );
Previous | Home | Next
17.19. Managing Multiple Streams of Input | Book Index | 17.21. Program: fwdport
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


17.21. Program: fwdport

Imagine that you're nestled deep inside a protective firewall. Somewhere in the outside world is a server that you'd like access to, but only processes on the firewall can reach it. You don't want to log into the firewall machine each time to access that service.

For example, this might arise if your company's ISP provides a news-reading service that seems to come from your main firewall machine, but rejects any NNTP connections from any other address. As the administrator of the firewall, you don't want dozens of people logging onto it, but you would like to let them read and post news from their own workstations.

The program in Example 17-10, fwdport, solves this problem in a generic fashion. You may run as many of these as you like, one per outside service. Sitting on the firewall, it can talk to both worlds. When someone wants to access the outside service, they contact this proxy, which connects on their behalf to the external service. To that outside service, the connection is coming from your firewall, so it lets it in. Then your proxy forks off twin processes, one only reading data from the external server and writing that data back to the internal client, the other only reading data from the internal client and writing that data back to the external server.

For example, you might invoke it this way:

% fwdport -s nntp -l fw.oursite.com -r news.bigorg.com

That means that the program will act as the server for the NNTP service, listening for local connections on the NNTP port on the host fw.oursite.com. When one comes in, it contacts news.bigorg.com (on the same port), and then ferries data between the remote server and local client.

Here's another example:

% fwdport -l myname:9191 -r news.bigorg.com:nntp

This time we listen for local connections on port 9191 of the host myname, and patch those connecting clients to the remote server news.bigorg.com on its NNTP port.

In a way, fwdport acts as both a server and a client. It's a server from the perspective of inside the firewall and a client from the perspective of the remote server outside. The program summarizes this chapter well because it demonstrates just about everything we've covered here. It has server activity, client activity, collecting of zombie children, forking and process management, plus much more thrown in.

Example 17-10. fwdport

  #!/usr/bin/perl -w
  # fwdport -- act as proxy forwarder for dedicated services

  use strict;                 # require declarations
  use Getopt::Long;           # for option processing
  use Net::hostent;           # by-name interface for host info
  use IO::Socket;             # for creating server and client sockets
  use POSIX ":sys_wait_h";    # for reaping our dead children

  my (
      %Children,              # hash of outstanding child processes
      $REMOTE,                # whom we connect to on the outside
      $LOCAL,                 # where we listen to on the inside
      $SERVICE,               # our service name or port number
      $proxy_server,          # the socket we accept( ) from
      $ME,                    # basename of this program
  );

  ($ME = $0) =~ s,.*/,,;      # retain just basename of script name

  check_args( );               # processing switches
  start_proxy( );              # launch our own server
  service_clients( );          # wait for incoming
  die "NOT REACHED";          # you can't get here from there

  # process command line switches using the extended
  # version of the getopts library.
  sub check_args {
      GetOptions(
          "remote=s"    => \$REMOTE,
          "local=s"     => \$LOCAL,
          "service=s"   => \$SERVICE,
      ) or die << EOUSAGE;
      usage: $0 [ --remote host ] [ --local interface ] [ --service service ]
  EOUSAGE
      die "Need remote"                   unless $REMOTE;
      die "Need local or service"         unless $LOCAL || $SERVICE;
  }

  # begin our server
  sub start_proxy {
      my @proxy_server_config = (
        Proto     => 'tcp',
        Reuse     => 1,
        Listen    => SOMAXCONN,
      );
      push @proxy_server_config, LocalPort => $SERVICE if $SERVICE;
      push @proxy_server_config, LocalAddr => $LOCAL   if $LOCAL;
      $proxy_server = IO::Socket::INET->new(@proxy_server_config)
                      or die "can't create proxy server: $@";
      print "[Proxy server on ", ($LOCAL || $SERVICE), " initialized.]\n";
  }

  sub service_clients {
      my (
          $local_client,              # someone internal wanting out
          $lc_info,                   # local client's name/port information
          $remote_server,             # the socket for escaping out
          @rs_config,                 # temp array for remote socket options
          $rs_info,                   # remote server's name/port information
          $kidpid,                    # spawned child for each connection
      );

      $SIG{CHLD} = \&REAPER;          # harvest the moribund

      accepting( );

      # an accepted connection here means someone inside wants out
      while ($local_client = $proxy_server->accept( )) {
          $lc_info = peerinfo($local_client);
          set_state("servicing local $lc_info");
          printf "[Connect from $lc_info]\n";

          @rs_config = (
              Proto     => 'tcp',
              PeerAddr  => $REMOTE,
          );
          push(@rs_config, PeerPort => $SERVICE) if $SERVICE;

          print "[Connecting to $REMOTE...";
          set_state("connecting to $REMOTE");                 # see below
          $remote_server = IO::Socket::INET->new(@rs_config)
                           or die "remote server: $@";
          print "done]\n";

          $rs_info = peerinfo($remote_server);
          set_state("connected to $rs_info");

          $kidpid = fork( );
          die "Cannot fork" unless defined $kidpid;
          if ($kidpid) {
              $Children{$kidpid} = time( );            # remember his start time
              close $remote_server;                   # no use to master
              close $local_client;                    # likewise
              next;                                   # go get another client
          }

          # at this point, we are the forked child process dedicated
          # to the incoming client.  but we want a twin to make i/o
          # easier.

          close $proxy_server;                        # no use to slave

          $kidpid = fork( );
          die "Cannot fork" unless defined $kidpid;

          # now each twin sits around and ferries lines of data.
          # see how simple the algorithm is when you can have
          # multiple threads of control?

          # this is the fork's parent, the master's child
          if ($kidpid) {
              set_state("$rs_info --> $lc_info");
              select($local_client); $| = 1;
              print while <$remote_server>;
              kill('TERM', $kidpid);      # kill my twin cause we're done
              }
          # this is the fork's child, the master's grandchild
          else {
              set_state("$rs_info <-- $lc_info");
              select($remote_server); $| = 1;
              print while <$local_client>;
              kill('TERM', getppid( ));    # kill my twin cause we're done
          }
          exit;                           # whoever's still alive bites it
      } continue {
          accepting( );
      }
  }

  # helper function to produce a nice string in the form HOST:PORT
  sub peerinfo {
      my $sock = shift;
      my $hostinfo = gethostbyaddr($sock->peeraddr);
      return sprintf("%s:%s",
                      $hostinfo->name || $sock->peerhost,
                      $sock->peerport);
  }

  # reset our $0, which on some systems make "ps" report
  # something interesting: the string we set $0 to!
  sub set_state { $0 = "$ME [@_]" }

  # helper function to call set_state
  sub accepting {
      set_state("accepting proxy for " . ($REMOTE || $SERVICE));
  }

  # somebody just died.  keep harvesting the dead until
  # we run out of them.  check how long they ran.
  sub REAPER {
      my $child;
      my $start;
      while (($child = waitpid(-1,WNOHANG))> 0) {
          if ($start = $Children{$child}) {
              my $runtime = time( ) - $start;
              printf "Child $child ran %dm%ss\n",
                  $runtime / 60, $runtime % 60;
              delete $Children{$child};
          } else {
              print "Bizarre kid $child exited $?\n";
          }
      }
      # If I had to choose between System V and 4.2, I'd resign. --Peter Honeyman
      $SIG{CHLD} = \&REAPER;
  };

17.21.1. See Also

Getopt::Long(3),
Net::hostent(3),
IO::Socket(3), and
POSIX(3); Recipe 16.19;
Recipe 17.10

Previous | Home | Next
17.20. Program: backsniff | Book Index | 18. Internet Services
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 18. Internet Services

Contents:

Introduction
Simple DNS Lookups
Being an FTP Client
Sending Mail
Reading and Posting Usenet News Messages
Reading Mail with POP3
Simulating Telnet from a Program
Pinging a Machine
Accessing an LDAP Server
Sending Attachments in Mail
Extracting Attachments from Mail
Writing an XML-RPC Server
Writing an XML-RPC Client
Writing a SOAP Server
Writing a SOAP Client
Program: rfrm
Program: expn and vrfy

Western Union internal memo, 1876

This "telephone" has too many shortcomings to be seriously considered as a means of communication. The device is inherently of no value to us.

18.0. Introduction

Correct use of sockets is only part of writing programs that communicate over the network. Once you have a way for two programs to talk, you still need a protocol for communication. This protocol lets each party know when to talk, and it precisely defines who is responsible for which part of the service.

Common Internet protocols are listed in Table 18-1.

Table 18-1. Common Internet protocols

Protocol | Meaning | Action
FTP | File Transfer Protocol | Copying files between remote machines
telnet |  | Remote login
rsh and rcp | Remote shell and Remote copy | Remote login and remote file copying
NNTP | Network News Transfer Protocol | Reading and posting USENET news
HTTP | Hypertext Transfer Protocol | Transferring documents on the Web
SMTP | Simple Mail Transfer Protocol | Sending mail
POP3 | Post Office Protocol | Reading mail

Even something as relatively simple as connecting to a remote computer requires intricate negotiations between client and server. If you had to write the Perl code to implement these protocols each time you wanted to use a network service, you'd probably end up writing a lot of buggy programs, trying to get demoted into a management position, or both.

Fortunately, Perl has modules for these protocols. Most modules implement the client side of the protocol rather than the server side. This is because most clients make one query at a time, whereas a server must be prepared to deal with multiple clients and that code can get quite tricky. That said, there are FTP (Net::FTPServer), HTTP (HTTP::Daemon, POE::Component::Server::HTTP), SMTP (POE::Component:Server::SMTP), and IRC (POE::Component::Server::IRC) servers on CPAN.

Most of these modules fall under the Net:: hierarchy, a common subset of which has been included standard with Perl since v5.8. We use Net::FTP to send and receive files using FTP, Net::NNTP to read and post Usenet news, Net::Telnet (from CPAN) to simulate a connection to another machine, Net::Ping to check whether a machine is alive, and Net::POP3 and Mail::Mailer (from CPAN) to receive and send mail. We cover the CGI protocol in Chapter 19, and with HTTP in Chapter 20.

Recent years have seen a growth in web services, i.e., services offered through the web's HTTP protocol. Chapter 19, Chapter 20, and Chapter 21 address the Web in more detail, but we cover web services in this chapter. The three main ways of offering web services are XML-RPC, SOAP, and REST.

XML-RPC is a simple way to make remote procedure calls. You can transport XML-RPC requests ("I want to call this method with these arguments") and responses ("this fault occurred" or "this is what the method returned") across protocols like HTTP, SMTP, Jabber, and so on. The XMLRPC::Lite modules handle translation between Perl function calls and the XML representation that goes across the wire.

SOAP is more complex than XML-RPC, providing more OO and exception support. It also offers a "document mode," where the response is an XML document rather than an encoded data structure; for example, you might submit an order and get back an XML receipt. SOAP has more built-in data types than XML-RPC and lets you define custom data types using W3C Schema. Like XML-RPC, SOAP runs over a variety of protocols. Both SOAP and XML-RPC are implemented in the SOAP-Lite distribution.

Representational State Transfer (REST) is a different way of viewing web services. Rather than writing remote procedure calls and encoding arguments, which exposes the implementation, REST offers a way to separate implementation from how the client accesses a particular resource. In REST, a URL is an object's address. You can use GET, POST, PUT, and DELETE methods to fetch, change state, create, update, and delete. Because it's more a design philosophy than an API or encoding, we don't cover it here. The book Programming Web Services with Perl, by Randy Ray and Pavel Kulchenko (O'Reilly), gives an introduction to REST.

You can thank Graham Barr, whose IO::Socket modules we used for low-level network communication in Chapter 17, for most of these modules. He also wrote Net::FTP, Net::NNTP, Net::POP3, and Mail::Mailer. Jay Rogers wrote Net::Telnet, and Paul Kulchenko developed the SOAP-Lite toolkit. Thank these folks that you don't have to reinvent these tricky wheels!

Previous | Home | Next
17.21. Program: fwdport | Book Index | 18.1. Simple DNS Lookups
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.1. Simple DNS Lookups

18.1.1. Problem

You want to find the IP address of a host or turn an IP address into a name. Network servers do this to authenticate their clients, and clients do it when the user gives them a hostname. But Perl's socket library requires an IP address. Furthermore, many servers produce log files containing IP addresses, but hostnames are more useful to analysis software and humans.

18.1.2. Solution

If you have a name like www.perl.com, use gethostbyname if you want all addresses:

use Socket;

@addresses = gethostbyname($name)   or die "Can't resolve $name: $!\n";
@addresses = map { inet_ntoa($_) } @addresses[4 .. $#addresses];
# @addresses is a list of IP addresses ("208.201.239.48", "208.201.239.49")

Or use inet_aton if you need only the first address:

use Socket;

$address = inet_ntoa(inet_aton($name));
# $address is a single IP address "208.201.239.48"

If you have an IP address like "208.201.239.48", use:

use Socket;

$name = gethostbyaddr(inet_aton($address), AF_INET)
            or die "Can't resolve $address: $!\n";
# $name is the hostname ("www.perl.com")

18.1.3. Discussion

This process is complicated because the functions are mere wrappers for C system calls, so you have to convert IP addresses from ASCII strings ("208.146.240.1") into C structures. The standard Socket module provides inet_aton to convert from ASCII to the packed numeric format and inet_ntoa to convert back:

use Socket;
$packed_address = inet_aton("208.146.140.1");
$ascii_address  = inet_ntoa($packed_address);

The gethostbyname function takes a string containing the hostname (or IP address). In scalar context, it returns the remote IP address suitable for passing to inet_ntoa (or undef on error). In list context, it returns a list of at least five elements (or an empty list on error). The returned list is:

Index | Meaning
0 | Official name of host
1 | Aliases (space-separated string)
2 | Address type (normally AF_INET)
3 | Length of address structure (irrelevant)
4,5, ... | Address structures

A hostname may have more than one address, as often seen for busy web sites where many machines serve identical web pages to share the load. In such situations, the DNS server that provides addresses rotates them to balance the load. If you need to pick an IP address to connect to, just select the first. But if it doesn't work, try the rest as well.

$packed = gethostbyname($hostname)
            or die "Couldn't resolve address for $hostname: $!\n";
$address = inet_ntoa($packed);
print "I will use $address as the address for $hostname\n";

If you're using hostnames to permit or deny access to a service, be careful. Anyone can set their DNS server to identify their machine as www.whitehouse.gov, www.yahoo.com, or this.is.not.funny. You can't know whether the machine really has the name it claims to have until you use gethostbyname and check that the original address is in the address list for the name.

# $address is the IP address I'm checking, like "128.138.243.20"
use Socket;
$name    = gethostbyaddr(inet_aton($address), AF_INET)
                or die "Can't look up $address : $!\n";
@addr    = gethostbyname($name)
                or die "Can't look up $name : $!\n";
$found   = grep { $address eq inet_ntoa($_) } @addr[4..$#addr];

It turns out that even with this algorithm, you can't be absolutely sure of the name due to a variety of mechanisms that can circumvent this technique. Even the IP address from which packets appear to be coming can be spoofed, so you should never rely on the network layer for authentication. Always do authentication yourself (with passwords or cryptographic challenges) when it matters, because the IPv4 network was not designed to provide security.

More information is kept about a host than just addresses and aliases. To access this information, use the Net::DNS module from CPAN. For instance, Example 18-1 shows how to retrieve the MX (mail exchange) records for an arbitrary host.

Example 18-1. mxhost

  #!/usr/bin/perl -w
  # mxhost - find mx exchangers for a host
  use Net::DNS;
  use strict;
  my ($host, $res, @mx);
  $host = shift or die "usage: $0 hostname\n";
  $res = Net::DNS::Resolver->new( );
  @mx = mx($res, $host)
     or die "Can't find MX records for $host (".$res->errorstring.")\n";
  foreach my $record (@mx) {
      print $record->preference, " ", $record->exchange, "\n";
  }

Here's some output:

% mxhost cnn.com
10 atlmail1.turner.com
10 atlmail4.turner.com
20 atlmail2.turner.com
30 nymail1.turner.com

The inet_aton function takes a string containing a hostname or IP address, as does gethostbyname, but it returns only the first IP address for the host. To find them all, you'll need to add more code. The Net::hostent module provides by-name access for that; Example 18-2 shows an example of its use.

Example 18-2. hostaddrs

  #!/usr/bin/perl -w
  # hostaddrs - canonize name and show addresses
  use Socket;
  use Net::hostent;
  use strict;
  my ($name, $hent, @addresses);
  $name = shift || die "usage: $0 hostname\n";
  if ($hent = gethostbyname($name)) {
         $name      = $hent->name;                # in case different
      my $addr_ref  = $hent->addr_list;
         @addresses = map { inet_ntoa($_) } @$addr_ref;
  }
  print "$name => @addresses\n";

Here's the output:

% hostaddrs www.oreilly.com
www.oreilly.com => 208.201.239.37 208.201.239.36

% hostaddrs www.whitehouse.gov
a1289.g.akamai.net => 216.241.36.232 216.241.36.230

18.1.4. See Also

The gethostbyname and gethostbyaddr functions in Chapter 29 of Programming Perl and in perlfunc(1); the documentation for the Net::DNS module from CPAN; the documentation for the standard Socket and Net::hostent modules

Previous | Home | Next
18. Internet Services | Book Index | 18.2. Being an FTP Client
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.2. Being an FTP Client

18.2.1. Problem

You want to connect to an FTP server and transfer files. For example, you might want to automate the one-time transfer of many files or automatically mirror an entire section of an FTP server.

18.2.2. Solution

Use the Net::FTP module:

use Net::FTP;

$ftp = Net::FTP->new("ftp.host.com")    or die "Can't connect: $@\n";
$ftp->login($username, $password)       or die "Couldn't login\n";
$ftp->cwd($directory)                   or die "Couldn't change directory\n";
$ftp->get($filename)                    or die "Couldn't get $filename\n";
$ftp->put($filename)                    or die "Couldn't put $filename\n";

18.2.3. Discussion

Using the Net::FTP module is a three-part process: connect to a server, identify and authenticate yourself, and transfer files. All interaction with the FTP server happens through method calls on a Net::FTP object. If an error occurs, methods return undef in scalar context or the empty list in list context.

The connection is established with the new constructor. If an error occurs, $@ is set to an error message and new returns undef. The first argument is the hostname of the FTP server, optionally followed by named options:

$ftp = Net::FTP->new("ftp.host.com",
                     Timeout => 30,
                     Debug   => 1)
    or die "Can't connect: $@\n";

The Timeout option gives the number of seconds all operations wait before giving up. Debug sets the debugging level (non-zero sends copies of all commands to STDERR). Firewall takes a string as an argument, specifying the machine acting as an FTP proxy. Port lets you select an alternate port number (the default is 21, the standard port for FTP). Finally, if the Passive option is set to true, all transfers are done passively (some firewalls and proxies require this). The Firewall and Passive options override the environment variables FTP_FIREWALL and FTP_PASSIVE.

Having connected, the next step is to authenticate. Normally, you'll want to call login with up to three arguments: username, password, and account.

$ftp->login( )
    or die "Couldn't authenticate.\n";

$ftp->login($username)
    or die "Still couldn't authenticate.\n";

$ftp->login($username, $password)
    or die "Couldn't authenticate, even with explicit username
            and password.\n";

$ftp->login($username, $password, $account)
    or die "No dice.  It hates me.\n";

If you call login with no arguments, Net::FTP uses the Net::Netrc module to find settings for the host you've connected to. If none are found, anonymous login is attempted (username anonymous, password -anonymous@). If no password is given and the username anonymous is used, the user's mail address is supplied as the password. The optional account argument is not used on most systems. If the authentication fails, login returns undef.

Once authenticated, the usual FTP commands are available as methods called on your Net::FTP object. The get and put methods fetch and send files, respectively. To send a file, use:

$ftp->put($localfile, $remotefile)
    or die "Can't send $localfile: $!\n";

If you omit the second argument, the remote file will have the same name as the local file. You can also send from a filehandle (in which case the remote filename must be given as the second argument):

$ftp->put(*STDIN, $remotefile)
    or die "Can't send from STDIN: $!\n";

If the transfer is interrupted, the remote file is not automatically deleted. The put method returns the remote filename if it succeeded, or undef on error.

To fetch a file, use the get method, which returns the local filename, or undef on error:

$ftp->get($remotefile, $localfile)
    or die "Can't fetch $remotefile : $!\n";

You can also get into a filehandle, in which case the filehandle is returned (or undef on error):

$ftp->get($remotefile, *STDOUT)
    or die "Can't fetch $remotefile: $!\n";

Pass get an optional third argument, representing an offset into the remote file, to begin the transfer at that offset. Received bytes are appended to the local file.

The type method changes the file translation mode. Pass it a string ("A", "I", "E", or "L") and it will return the previous translation mode. The ascii, binary, ebcdic, and byte methods call type with the appropriate string. If an error occurs (the FTP server does not do EBCDIC, for example), type and its helper methods return undef.

Use cwd($remotedir) and pwd to set and fetch the current remote directory. Both return true if successful, false otherwise. If you cwd(".."), the cdup method is called to change the directory to the parent of the current directory. Call cwd without an argument to change to the root directory.

$ftp->cwd("/pub/perl/CPAN/images/g-rated");
print "I'm in the directory ", $ftp->pwd( ), "\n";

mkdir($remotedir) and rmdir($remotedir) make and delete directories on the remote machine. You have the built-in mkdir and rmdir functions to make and delete empty directories on the local machine. To create all directories up to the given directory, pass a true second argument to mkdir. For instance, to create /pub, /pub/gnat, and /pub/gnat/perl directories, say:

$ftp->mkdir("/pub/gnat/perl", 1)
    or die "Can't create /pub/gnat/perl recursively: $!\n";

If mkdir succeeds, the full path to the newly created directory is returned; otherwise, it returns undef.

The ls and dir methods retrieve a list of files in a remote directory. Traditionally, dir gives you a more verbose listing than ls, but neither has a standard format. Most Unix FTP servers return the output of ls and ls -l respectively, but you can't guarantee that behavior from every FTP server. In list context, these methods return the list of lines returned by the server. In scalar context, they return a reference to an array containing those lines.

@lines = $ftp->ls("/pub/gnat/perl")
    or die "Can't get a list of files in /pub/gnat/perl: $!";
$ref_to_lines = $ftp->dir("/pub/perl/CPAN/src/latest.tar.gz")
    or die "Can't check status of latest.tar.gz: $!\n";

When you're done and want to finish gracefully, use the quit method:

$ftp->quit( )    or warn "Couldn't quit.  Oh well.\n";

Other methods rename, change ownership and permissions of remote files, check the size of the remote file, and so on. Read the Net::FTP documentation for details.

To mirror files between machines, use the excellent mirror program written in Perl by Lee McLoughlin. Look for it on the Web at http://sunsite.doc.ic.ac.uk/packages/mirror/.

18.2.4. See Also

Your system's ftp(1) and ftpd(8) manpages (if you have them); the documentation for the Net::FTP module

Previous | Home | Next
18.1. Simple DNS Lookups | Book Index | 18.3. Sending Mail
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.3. Sending Mail

18.3.1. Problem

You want your program to send mail. Some programs monitor system resources like disk space and notify appropriate people when disk space becomes dangerously low. CGI script authors may not want programs to report errors like "the database is down" to the user, preferring instead to send mail to the database administrator about the problem.

18.3.2. Solution

Use the CPAN module Mail::Mailer:

use Mail::Mailer;

$mailer = Mail::Mailer->new("sendmail");
$mailer->open({ From    => $from_address,
                To      => $to_address,
                Subject => $subject,
              })
    or die "Can't open: $!\n";
print $mailer $body;
$mailer->close( );

Or use the sendmail program directly:

open(SENDMAIL, "|/usr/lib/sendmail -oi -t -odq")
                    or die "Can't fork for sendmail: $!\n";
print SENDMAIL <<"EOF";
From: User Originating Mail <me\@host>
To: Final Destination <you\@otherhost>
Subject: A relevant subject line

Body of the message goes here, in as many lines as you like.
EOF
close(SENDMAIL)     or warn "sendmail didn't close nicely";

18.3.3. Discussion

You have three choices for sending mail from your program. You can call another program normally used to send mail, such as Mail or mailx; these are called MUAs or Mail User Agents. You can use a system-level mail program, such as sendmail; this is an MTA, or Mail Transport Agent. Or you can connect to an Simple Mail Transfer Protocol (SMTP) server. Unfortunately, there's no standard user-level mail program, sendmail doesn't have a standard location, and SMTP isn't particularly simple. The CPAN module Mail::Mailer hides these complexities from you.

Create a Mail::Mailer object with Mail::Mailer->new. If you don't pass any arguments, it uses the default mail sending method (probably a program like mail). Arguments to new select an alternate way to send the message. The first argument is the type of delivery method ("mail" for a Unix mail user agent, "sendmail" for sendmail, and "smtp" to connect to an SMTP server). The optional second argument is that program's path.

For instance, to instruct Mail::Mailer to use sendmail instead of its default:

$mailer = Mail::Mailer->new("sendmail");

Here's how to tell it to use /u/gnat/bin/funkymailer instead of mail:

$mailer = Mail::Mailer->new("mail", "/u/gnat/bin/funkymailer");

Here's how to use SMTP with the machine mail.myisp.com as the mail server:

$mailer = Mail::Mailer->new("smtp", "mail.myisp.com");

If an error occurs at any part of Mail::Mailer, die is called. To check for these exceptions, wrap your mail-sending code in eval and check $@ afterward:

eval {
    $mailer = Mail::Mailer->new("bogus", "arguments");
    # ...
};
if ($@) {
    # the eval failed
    print "Couldn't send mail: $@\n";
} else {
    # the eval succeeded
    print "The authorities have been notified.\n";
}

The new constructor raises an exception if you provide arguments it doesn't understand, or if you specify no arguments and it doesn't have a default method. Mail::Mailer won't run a program or connect to the SMTP server until you call the open method with the message headers:

$mailer->open( { From    => 'Nathan Torkington <gnat@frii.com>',
                 To      => 'Tom Christiansen <tchrist@perl.com>',
                 Subject => 'The Perl Cookbook' } );

The open method raises an exception if the program or server couldn't be opened. If open succeeds, you may treat $mailer as a filehandle and print the body of your message to it:

print $mailer << EO_SIG;
Are we ever going to finish this book?
My wife is threatening to leave me.
She says I love EMACS more than I love her.
Do you have a recipe that can help me?

Nat
EO_SIG

When you're done, call the close function on the Mail::Mailer object:

close($mailer)                      or die "can't close mailer: $!";

If you want to go it alone and communicate with sendmail directly, use something like this:

open(SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq")
            or die "Can't fork for sendmail: $!\n";
print SENDMAIL << "EOF";
From: Fancy Chef <chef@example.com>
To: Grubby Kitchenhand <hand@example.com>
Subject: Re: The Perl Cookbook

(1) We will never finish the book.
(2) No man who uses EMACS is deserving of love.
(3) I recommend coq au vi.

Frank Wah
EOF
close(SENDMAIL);

This is a straightforward use of open to run another program (see Recipe 16.4). You need to specify the full path to sendmail because its location varies from machine to machine. It is often found in places like /usr/lib or /usr/sbin. The flags we give to sendmail say not to exit when a line with only a dot is read (-oi), to read the message headers to decide whom to send it to (-t), and to queue the message instead of attempting immediate delivery (-odq). This last option is important only when sending many messages (in bulk); omitting it would quickly swamp the machine with sendmail processes. For immediate delivery of your message (for instance, you're testing your program or the mail is urgent), remove -odq from the command line.

We print an entire message, headers and then body, separated by a blank line. There are no special escapes to insert newlines (as some user mail programs have), so all text is literal. sendmail adds headers like Date and Message-ID, which you shouldn't generate yourself anyway.

Some ports of Perl (Windows and Mac OS 9 particularly) don't have sendmail or mail. In these cases, you should find yourself a receptive SMTP server.

18.3.4. See Also

The open function in Chapter 29 of Programming Perl and in perlfunc(1); Recipe 16.4; Recipe 16.10; Recipe 16.19; Recipe 19.5; the RFCs dictating the SMTP protocol, RFC 821, Simple Mail Transfer Protocol, as amended by later RFCs; the documentation for the Mail::Mailer module from CPAN

Previous | Home | Next
18.2. Being an FTP Client | Book Index | 18.4. Reading and Posting Usenet News Messages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.4. Reading and Posting Usenet News Messages

18.4.1. Problem

You want to connect to a Usenet news server to read and post messages. Your program could send a periodic posting to a newsgroup,[35] summarize a newsgroup, or identify first-time contributors in a newsgroup so you can send them a helpful welcome message.

[35]If so, be sure to check out Ian Kluft's auto-faq program at http://www.novia.net/~pschleck/auto-faq/.

18.4.2. Solution

Use the Net::NNTP module:

use Net::NNTP;

$server = Net::NNTP->new("news.host.dom")
    or die "Can't connect to news server: $@\n";
($narticles, $first, $last, $name) = $server->group( "misc.test" )
    or die "Can't select misc.test\n";
$headers  = $server->head($first)
    or die "Can't get headers from article $first in $name\n";
$bodytext = $server->body($first)
    or die "Can't get body from article $first in $name\n";
$article  = $server->article($first)
    or die "Can't get article $first from $name\n";

$server->postok( )
    or warn "Server didn't tell me I could post.\n";

$server->post( [ @lines ] )
    or die "Can't post: $!\n";

18.4.3. Discussion

Usenet is a distributed bulletin board system. Servers exchange messages to ensure that each server gets all messages for the newsgroups it carries. Each server sets its own expiration criteria for how long messages stay on the server. Client newsreaders connect to their designated server (usually belonging to their company, ISP, or university) and can read existing postings and contribute new ones.

Each message (or article, as they're also known) has a set of headers and a body, separated by a blank line. Articles are identified in two ways: the message ID header and an article number within a newsgroup. An article's message ID is stored in the message itself and is guaranteed unique no matter which news server the article was read from. When an article references others, it does so by message ID. A message ID is a string like:

<0401@jpl-devvax.JPL.NASA.GOV>

An article can also be identified by its newsgroup and article number within the group. Each news server assigns its own article numbers, so they're valid only for the news server you got them from.

The Net::NNTP constructor connects to the specified news server. If the connection couldn't be made, it returns undef and sets $@ to an error message. If the connection was successful, new returns a new Net::NNTP object:

$server = Net::NNTP->new("news.mycompany.com")
    or die "Couldn't connect to news.mycompany.com: $@\n";

Once connected, fetch a list of newsgroups with the list method. This returns a reference to a hash whose keys are newsgroup names. Each value is a reference to an array consisting of the first valid article number in the group, the last valid article number in the group, and a string of flags. Flags are typically "y", meaning you may post, but could be "m" for moderated or "=NAME", meaning that the group is an alias for the newsgroup "NAME". Your server might carry over 60,000 newsgroups, so fetching a list of all groups can take a while.

$grouplist = $server->list( )
    or die "Couldn't fetch group list\n";

foreach $group (keys %$grouplist) {
    if ($grouplist->{$group}->[2] eq 'y') {
        # I can post to $group
    }
}

Much as FTP has the concept of a current directory, the Network News Transfer Protocol (NNTP) has the concept of a current group. Set the current group with the group method:

($narticles, $first, $last, $name) = $server->group("comp.lang.perl.misc")
    or die "Can't select comp.lang.perl.misc\n";

The group method returns a four-element list: the number of articles in the group, the first article number, the last article number, and the name of the group. If the group does not exist, it returns an empty list.

There are two ways to retrieve articles: call article with a message ID, or select a group with group and then call article with an article number. In scalar context, article returns a reference to an array of lines. In list context, it returns a list of lines. If an error occurs, article returns false:

@lines = $server->article($message_id)
    or die "Can't fetch article $message_id: $!\n";

Fetch an article's header or body with the head and body methods. Like article, these methods take an article number or message ID and return a list of lines or an array reference.

@group = $server->group("comp.lang.perl.misc")
    or die "Can't select group comp.lang.perl.misc\n";
@lines = $server->head($group[1])
    or die "Can't get headers from first article in comp.lang.perl.misc\n";

To post an article, give the post method a list of lines or a reference to an array of lines. It returns true if the post succeeded, false otherwise.

$server->post(@message)
    or die "Can't post\n";

Use the postok method to find out whether you may post to that server:

unless ($server->postok( )) {
    warn "You may not post.\n";
}

Read the manpage for Net::NNTP for a complete list of methods.

18.4.4. See Also

The documentation for the Net::NNTP module; RFC 977, Network News Transfer Protocol; your system's trn(1) and innd(8) manpages (if you have them)

Previous | Home | Next
18.3. Sending Mail | Book Index | 18.5. Reading Mail with POP3
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.5. Reading Mail with POP3

18.5.1. Problem

You want to fetch mail from a POP3 server. This lets you write a program to summarize your unread mail, move it from a remote server to a local mailbox, or toggle between Internet and local mail systems.

18.5.2. Solution

Use the Net::POP3 module:

$pop = Net::POP3->new($mail_server)
    or die "Can't open connection to $mail_server : $!\n";
defined ($pop->login($username, $password))
    or die "Can't authenticate: $!\n";
$messages = $pop->list
    or die "Can't get list of undeleted messages: $!\n";
foreach $msgid (keys %$messages) {
    $message = $pop->get($msgid);
    unless (defined $message) {
        warn "Couldn't fetch $msgid from server: $!\n";
        next;
    }
    # $message is a reference to an array of lines
    $pop->delete($msgid);
}

18.5.3. Discussion

Traditionally, mail has been a three-party system: the MTA (Mail Transport Agent, a system program like sendmail) delivers mail to the spool, where it is read by the MUA (Mail User Agent, a program like mail). This dates from the days of big servers holding mail and users reading it through dumb terminals. As PCs and networks entered the picture, the need arose for MUAs like Pine to run on different machines than the one housing the spool. The Post Office Protocol (POP) implements efficient message listing, reading, and deleting over a TCP/IP session.

The Net::POP3 module is a POP client. That is, it lets your Perl program act as an MUA. The first step in using Net::POP3 is to create a new Net::POP3 object. Pass new the name of the POP3 server:

$pop = Net::POP3->new( "pop.myisp.com" )
    or die "Can't connect to pop.myisp.com: $!\n";

All Net::POP3 functions return undef or the empty list upon error, depending on the calling context. If an error occurs, the fickle $! variable just might contain a meaningful error message—but also might not.

You may optionally pass further arguments to new using named-parameter pairs. The "Timeout" parameter specifies a timeout value in seconds for all network operations.

$pop = Net::POP3->new( "pop.myisp.com",
                       Timeout => 30 )
    or die "Can't connect to pop.myisp.com : $!\n";

Authenticate yourself to the POP3 server with the login method. It takes two arguments, username and password, but both are optional. If the username is omitted, the current username is used. If the password is omitted, Net::POP3 tries to use Net::Netrc to find a password:

defined ($pop->login("gnat", "S33kr1T Pa55w0rD"))
    or die "Hey, my username and password didn't work!\n";

defined ($pop->login( "midget" ))           # use Net::Netrc to find password
    or die "Authentication failed.\n";

defined ($pop->login( ))                     # current username and Net::Netrc
    or die "Authentication failed.  Miserably.\n";

The login method sends the password in plain text across the network. This is virtually always undesirable, so you can use the apop method instead. It works exactly like login, except that it encrypts the password:

$pop->apop( $username, $password )
    or die "Couldn't authenticate: $!\n";

Once authenticated, you may then access the spool with list, get, and delete. The list method gives you a list of undeleted messages in the spool. It returns a hash where each key is a message number and each value the size in bytes of the corresponding message:

%undeleted = $pop->list( );
foreach $msgnum (keys %undeleted) {
    print "Message $msgnum is $undeleted{$msgnum} bytes long.\n";
}

To retrieve a message, call get with the message number. It returns a reference to an array of lines in the message:

print "Retrieving $msgnum : ";
$message = $pop->get($msgnum);
if ($message) {
    # succeeded
    print "\n";
    print @$message;                # print the message
} else {
        # failed
    print "failed ($!)\n";
}

The delete method marks a message as deleted. When you call quit to terminate your POP3 session, the messages marked as deleted are removed from the mailbox. The reset method undoes any delete calls made during the session. If the session is terminated by the Net::POP3 object being destroyed (e.g., the only reference to the object went out of scope), reset is called automatically.

You have probably noticed there's no way to send mail. POP3 only supports reading and deleting existing messages. To send new ones, you still have to use programs like mail or sendmail, or do SMTP. In other words, you still need Recipe 18.3.

The task attempted by POP3—connecting mail clients and mail servers—is also attempted by the IMAP protocol. IMAP has more features and is more typically seen on very large sites.

18.5.4. See Also

The documentation for the Net::POP3 module; RFC 1734, POP3 AUTHentication command; RFC 1957, Some Observations on Implementations of the Post Office Protocol

Previous | Home | Next
18.4. Reading and Posting Usenet News Messages | Book Index | 18.6. Simulating Telnet from a Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.6. Simulating Telnet from a Program

18.6.1. Problem

You want to simulate a telnet connection from your program by logging into a remote machine, issuing commands, and reacting to what is returned. This has many applications, from automating tasks on machines you can telnet to but which don't support scripting or rsh, to simply testing whether a machine's Telnet daemon is still running properly.

18.6.2. Solution

Use the CPAN module Net::Telnet:

use Net::Telnet;

$t = Net::Telnet->new( Timeout => 10,
                       Prompt  => '/%/',
                       Host    => $hostname );

$t->login($username, $password);
@files = $t->cmd("ls");
$t->print("top");
(undef, $process_string) = $t->waitfor('/\d+ processes/');
$t->close;

18.6.3. Discussion

Net::Telnet provides an object-oriented interface to the Telnet protocol. Create a connection with Net::Telnet->new, then interact with the remote machine using method calls on the resulting object.

Give the new method a list of named-parameter pairs, much like initializing a hash. We'll cover only a few possible parameters. The most important is Host, the machine you're telnetting to. The default host is localhost. To connect to a port other than the one Telnet normally uses, specify this in the Port option. Error handling is done through the function whose reference is specified in the Errmode parameter.

Another important option is Prompt. When you log in or run a command, Net::Telnet uses the Prompt pattern to determine when the login or command has completed. The default Prompt is:

/[\$%#>] $/

which matches the common Unix shell prompts. If the prompt on the remote machine doesn't match the default pattern, you have to specify your own. Remember to include slashes.

Timeout lets you control how long (in seconds) network operations wait before they give up. The default is 10 seconds.

An error or timeout in the Net::Telnet module raises an exception by default, which, if uncaught, prints a message to STDERR and exits. To change this, pass new a subroutine reference to the Errmode argument. If instead of a code subroutine you specify the string "return" as the Errmode, methods return undef (in scalar context) or an empty list (in list context) on error, with the error message available via the errmsg method:

$telnet = Net::Telnet->new( Errmode => sub { main::log(@_) }, ... );

The login method sends a username and password to the remote machine. It uses the Prompt to decide when the login is complete and times out if the machine doesn't reply with a prompt:

$telnet->login($username, $password)
    or die "Login failed: @{[ $telnet->errmsg( ) ]}\n";

To run a program and gather its output, use the cmd method. Pass it the string to send; it returns the command output as one line per list element in list context, or as one long line in scalar context. It waits for the Prompt before returning.

Separate sending the command from reception of its output with the print and waitfor methods, as we do in the Solution. The waitfor method takes either a single string containing a Perl regular expression in slashes:

$telnet->waitfor('/--more--/')

or named arguments. Timeout specifies a timeout to override the default, Match is a string containing a match operator as shown earlier, and String is a literal string to find:

$telnet->waitfor(String => 'greasy smoke', Timeout => 30)

In scalar context, waitfor returns true if the pattern or string was found. Otherwise, the Errmode action is performed. In list context, it returns two strings: any text before the match and the matching text itself.

18.6.4. See Also

The documentation for the Net::Telnet module from CPAN; RFCs 854-856, as amended by later RFCs

Previous | Home | Next
18.5. Reading Mail with POP3 | Book Index | 18.7. Pinging a Machine
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.7. Pinging a Machine

18.7.1. Problem

You want to test whether a machine is alive. Network- and system-monitoring software often use the ping program as an indication of availability.

18.7.2. Solution

Use the standard Net::Ping module:

use Net::Ping;

$p = Net::Ping->new( )
    or die "Can't create new ping object: $!\n";
print "$host is alive" if $p->ping($host);
$p->close;

18.7.3. Discussion

Testing whether a machine is up isn't as easy as it sounds. It's not only possible but also unpleasantly common for machines to respond to the ping command when they have no working services. It's better to think of ping as testing whether a machine is reachable, rather than whether the machine is doing its job. To check the latter, you must try its services (Telnet, FTP, web, NFS, etc.).

In the form shown in the Solution, Net::Ping attempts to connect to the TCP echo port (port number 7) on the remote machine. The ping method returns true if the connection could be made, false otherwise.

You can also ping using other protocols by passing the protocol name to new. Valid protocols are tcp, udp, syn, and icmp (all lowercase). A UDP ping attempts to connect to the echo port (port 7) on the remote machine, sends a datagram, and attempts to read the response. The machine is considered unreachable if it can't connect, if the reply datagram isn't received, or if the reply differs from the original datagram. An ICMP ping uses the ICMP protocol, just like the ping(8) command. On Unix machines, you must be the superuser to use the ICMP protocol:

# use TCP if we're not root, ICMP if we are
$pong = Net::Ping->new( $> ? "tcp" : "icmp" );

(defined $pong)
    or die "Couldn't create Net::Ping object: $!\n";

if ($pong->ping("kingkong.com")) {
    print "The giant ape lives!\n";
} else {
    print "All hail mighty Gamera, friend of children!\n";
}

A SYN ping is asynchronous: you first send out many ping s and then receive responses by repeatedly invoking the ack method. This method returns a list containing the hostname, round-trip time, and the IP address that responded:

$net = Net::Ping->new('syn');
foreach $host (@hosts) {
  $net->ping($host);
}
while (($host, $rtt, $ip) = $net->ack( )) {
  printf "Response from %s (%s) in %d\n", $host, $ip, $rtt;
}

Of course, most machines don't take a second or more to set up a TCP connection. If they did, you'd find web browsing painfully slow! To get anything but 0 second round-trip times back from this test, you need more granularity in your time measurements. The hires method uses Time::HiRes (see Recipe 3.9) to measure ACK times. The following code snippet enables high-resolution timers (changed code appears in bold):

$net = Net::Ping->new('syn');
$net->hires( );              # enable high-resolution timers
foreach $host (@hosts) {
  $net->ping($host);
}
while (($host, $rtt, $ip) = $net->ack( )) {
  printf "Response from %s (%s) in %.2f\n", $host, $ip, $rtt;
}

The value in $rtt is still in seconds, but it might have a decimal portion. The value is accurate to milliseconds.

If using TCP to ping, set the port that Net::Ping uses. This might mean a service is present although any industrial-grade monitoring system will also test whether the service responds to requests:

$test = Net::Ping->new('tcp');
$test->{port_num} = getservbyname("ftp", "tcp");
if (! $test->ping($host)) {
  warn "$host isn't serving FTP!\n";
}

All these ping methods are prone to failure. Some sites filter the ICMP protocol at their router, so Net::Ping would say such machines are down even though you could connect using other protocols. Similarly, many machines disable the TCP and UDP echo services, causing TCP and UDP pings to fail. There is no way to know whether the ping failed because the service is disabled or filtered, or because the machine is actually down.

18.7.4. See Also

The documentation for the Net::Ping module from CPAN; your system's ping(8), tcp(4), udp (4), and icmp(4) manpages (if you have them); RFCs 792 and 950

Previous | Home | Next
18.6. Simulating Telnet from a Program | Book Index | 18.8. Accessing an LDAP Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.8. Accessing an LDAP Server

18.8.1. Problem

You want to fetch or maintain information from a Lightweight Directory Access Protocol (LDAP) server. For example, you have a list of email addresses in your company, and you want correct names for those people.

18.8.2. Solution

Use the Net::LDAP module from CPAN. For example, to search, use:

use Net::LDAP;

$ldap = Net::LDAP->new("ldap.example.com") or die $@;
$ldap->bind( );
$mesg = $ldap->search(base => $base_dn,
                      filter => $FILTER);

$mesg->code( ) && die $mesg->error;

foreach $result ($mesg->all_entries) {
    # do something with $result
}
$ldap->unbind( );

18.8.3. Discussion

The Net::LDAP module manages an LDAP session. It is a pure Perl module, so it doesn't require a C compiler to install. To use it effectively, though, you'll need to know a little about LDAP in general and the query syntax in particular. If you're new to LDAP, you might want to read the articles at http://www.onlamp.com/topics/apache/ldap.

The four steps to working with an LDAP server are connecting, authenticating, interacting, and logging off. Interacting includes searching, adding, deleting, and altering records.

The connect method establishes a connection to the LDAP server and is immediately followed by a call to the bind method. If you give no argument to bind, you log into the LDAP server anonymously. You can give a fully qualified Distinguished Name (DN) and password to authenticate yourself:

$ldap->bind("cn=directory manager,ou=gurus,dc=oreilly,dc=com",
            password => "timtoady") or die $@;

This sends the username and password unencrypted over the wire. For encrypted access, pass a sasl parameter to bind to use an Authen::SASL object to authenticate with.

The search method returns an object containing a set of entries. You can fetch that entire set of entries with all_entries as shown in the Solution, or one by one thus:

$num_entries = $mesg->count( );
for ($i=0; $i < $num_entries; $i++) {
  my $entry = $mesg->entry($i);
  # ...
}

You can even pop entries off the results stack:

while (my $entry = $mesg->shift_entry) {
  # ...
}

Each entry is an object with methods for querying attributes:

foreach $attr ($entry->attributes) {
  @values = $entry->get($attr);
  print "$attr : @values\n";
}

For a complete list of valid entry methods, see the Net::LDAP::Entry documentation. The DN is not an attribute of an entry, so to obtain the DN for an entry, use the dn method:

$dn = $entry->dn;

The basic components of a search are the base and the filter. The base marks the top of the tree being searched, and filter indicates which records you're interested in:

$mesg = $ldap->search(base => "o=oreilly.com",
                      filter => "uid=gnat");

You can limit how much of the tree is searched with an additional scope parameter: setting it to "base" searches only the base node of the tree. A value of "one" searches only nodes directly beneath the named node. The default value is "sub", meaning every node under the one named.

You can also administrate as well as search. For example, the add method inserts a record into the LDAP database:

$res = $ldap->add("cn=Sherlock Holmes, o=Sleuths B Us, c=gb",
       attr => [ cn    => ["Sherlock Holmes", "S Holmes"],
                 sn    => "Holmes",
                 mail  => 'sherlock@221b.uk',
                 objectclass => [qw(top person organizationalPerson
                                    inetOrgPerson)] ]);

$res->code && warn "Couldn't add record: " . $res->error;

Similarly, you can delete records:

$res = $ldap->delete($DN);
$res && warn "Couldn't delete: " . $res->error;

The powerful modify method lets you make substantial changes to the information on a particular DN. See the documentation for Net::LDAP for information beyond these examples:

$res = $ldap->modify("cn=Sherlock Holmes, o=Sleuths B Us, c=gb",
       add     => { phone => '555 1212' },
       replace => { mail  => 'sholmes@braintrust.uk' },
       delete  => { cn => [ 'S Holmes' ] });

18.8.4. See Also

The documentation for the CPAN module Net::LDAP; the Net::LDAP home page at http://perl-ldap.sourceforge.net/

Previous | Home | Next
18.7. Pinging a Machine | Book Index | 18.9. Sending Attachments in Mail
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.9. Sending Attachments in Mail

18.9.1. Problem

You want to send mail that includes attachments; for example, you want to mail a PDF document.

18.9.2. Solution

Use the MIME::Lite module from CPAN. First, create a MIME::Lite object representing the multipart message:

use MIME::Lite;

$msg = MIME::Lite->new(From    => 'sender@example.com',
                       To      => 'recipient@example.com',
                       Subject => 'My photo for the brochure',
                       Type    => 'multipart/mixed');

Then, add content through the attach method:

$msg->attach(Type        => 'image/jpeg',
             Path        => '/Users/gnat/Photoshopped/nat.jpg',
             Filename    => 'gnat-face.jpg');

$msg->attach(Type        => 'TEXT',
             Data        => 'I hope you can use this!');

Finally, send the message, optionally specifying how to send it:

$msg->send( );            # default is to use sendmail(1)
# alternatively
$msg->send('smtp', 'mailserver.example.com');

18.9.3. Discussion

The MIME::Lite module creates and sends mail with MIME-encoded attachments. MIME stands for Multimedia Internet Mail Extensions, and is the standard way of attaching files and documents. It can't, however, extract attachments from mail messages—for that you need to read Recipe 18.10.

When creating and adding to a MIME::Lite object, pass parameters as a list of named parameter pairs. The pair conveys both mail headers (e.g., From, To, Subject) and those specific to MIME::Lite. In general, mail headers should be given with a trailing colon:

$msg = MIME::Lite->new('X-Song-Playing:' => 'Natchez Trace');

However, MIME::Lite accepts the headers in Table 18-1 without a trailing colon. * indicates a wildcard, so Content-* includes Content-Type and Content-ID but not Dis-Content.

Table 18-2. MIME::Lite headers

Approved | Encrypted | Received | Sender
Bcc | From | References | Subject
Cc | Keywords | Reply-To | To
Comments | Message-ID | Resent-* | X-*
Content-* | MIME-Version | Return-Path |
Date | Organization |  |

The full list of MIME::Lite options is given in Table 18-2Table 18-2.

Table 18-3. MIME::Lite options

Data | FH | ReadNow
Datestamp | Filename | Top
Disposition | Id | Type
Encoding | Length |
Filename | Path |

The MIME::Lite options and their values govern what is attached (the data) and how:

Path
The file containing the data to attach.

Filename
The default filename for the reader of the message to save the file as. By default this is the filename from the Path option (if Path was specified).

Data
The data to attach.

Type
The Content-Type of the data to attach.

Disposition
Either inline or attachment. The former indicates that the reader should display the data as part of the message, not as an attachment. The latter indicates that the reader should display an option to decode and save the data. This is, at best, a hint.

FH
An open filehandle from which to read the attachment data.

There are several useful content types: TEXT means text/plain, which is the default; BINARY similarly is short for application/octet-stream; multipart/mixed is used for a message that has attachments; application/msword for Microsoft Word files; application/vnd.ms-excel for Microsoft Excel files; application/pdf for PDF files; image/gif, image/jpeg, and image/png for GIF, JPEG, and PNG files, respectively; audio/mpeg for MP3 files; video/mpeg for MPEG movies; video/quicktime for Quicktime (.mov) files.

The only two ways to send the message are using sendmail(1) or using Net::SMTP. Indicate Net::SMTP by calling send with a first argument of "smtp". Remaining arguments are parameters to the Net::SMTP constructor:

# timeout of 30 seconds
$msg->send("smtp", "mail.example.com", Timeout => 30);

If you plan to make more than one MIME::Lite object, be aware that invoking send as a class method changes the default way to send messages:

MIME::Lite->send("smtp", "mail.example.com");
$msg = MIME::Lite->new(%opts);
# ...
$msg->send( );                   # sends using SMTP

If you're going to process multiple messages, also look into the ReadNow parameter. This specifies that the data for the attachment should be read from the file or filehandle immediately, rather than when the message is sent, written, or converted to a string.

Sending the message isn't the only thing you can do with it. You can get the final message as a string:

$text = $msg->as_string;

The print method writes the string form of the message to a filehandle:

$msg->print($SOME_FILEHANDLE);

Example 18-3 is a program that mails filenames given on the command line as attachments.

Example 18-3. mail-attachment

#!/usr/bin/perl -w
# mail-attachment - send files as attachments

use MIME::Lite;
use Getopt::Std;

my $SMTP_SERVER = 'smtp.example.com';           # CHANGE ME
my $DEFAULT_SENDER = 'sender@example.com';      # CHANGE ME
my $DEFAULT_RECIPIENT = 'recipient@example.com';# CHANGE ME

MIME::Lite->send('smtp', $SMTP_SERVER, Timeout=>60);

my (%o, $msg);

# process options

getopts('hf:t:s:', \%o);

$o{f} ||= $DEFAULT_SENDER;
$o{t} ||= $DEFAULT_RECIPIENT;
$o{s} ||= 'Your binary file, sir';

if ($o{h} or !@ARGV) {
    die "usage:\n\t$0 [-h] [-f from] [-t to] [-s subject] file ...\n";
}

# construct and send email

$msg = new MIME::Lite(
    From => $o{f},
    To   => $o{t},
    Subject => $o{s},
    Data => "Hi",
    Type => "multipart/mixed",
);

while (@ARGV) {
  $msg->attach('Type' => 'application/octet-stream',
               'Encoding' => 'base64',
               'Path' => shift @ARGV);
}

$msg->send( );

18.9.4. See Also

The documentation for MIME::Lite

Previous | Home | Next
18.8. Accessing an LDAP Server | Book Index | 18.10. Extracting Attachments from Mail
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.10. Extracting Attachments from Mail

18.10.1. Problem

You have one or more mail messages with MIME attachments, and you want to process these messages with a Perl program to extract files or otherwise manipulate attachments.

18.10.2. Solution

Use the MIME-Tools bundle from CPAN:

use MIME::Parser;

$parser = MIME::Parser->new( );
$parser->output_to_core(1);      # don't write attachments to disk

$message  = $parser->parse_data($MESSAGE);    # die( )s if can't parse
# OR
$message  = $parser->parse($FILEHANDLE);      # die( )s if can't parse

$head     = $message->head( );                 # object--see docs
$preamble = $message->preamble;               # ref to array of lines
$epilogue = $message->epilogue;               # ref to array of lines

$num_parts = $message->parts;
for (my $i=0; $i < $num_parts; $i++) {
  my $part         = $message->parts($i);
  my $content_type = $part->mime_type;
  my $body         = $part->as_string;
}

18.10.3. Discussion

Formally, a MIME message has only two parts: the head (containing headers such as From and Subject) and the body (containing the message, rather than its metadata). The body, however, has three parts: the preamble (text before the first attachment), a series of parts (the attachments), and the epilogue (text after the last attachment). This is shown in Figure 18-1.

Figure 18-1. Composition of a MIME message

In the Solution, we disable the default behavior of MIME::Parser that writes the attachments to disk. Doing so increases memory consumption because now the decoded attachments must be stored in memory, but prevents the need to clean up temporary files and directories once the attachments are no longer needed.

To write attachments to a file, replace the call to output_to_core with calls to methods that specify the directory in which to store the attachments and what to name the files. The output_under method specifies a directory under which each message will get its own subdirectory; those subdirectories will contain the decoded attachments:

$parser->output_under("/tmp");
# parsing creates files like /tmp/msg-1048509652-16134-0/foo.png

Alternatively, output_dir specifies a directory into which all attachment files go:

$parser->output_dir("/tmp");
# parsing creates files like /tmp/foo.png

To clean up temporary files once parsing is done, say:

$parser->filer->purge;

Because parsing can trigger exceptions, catch the exceptions if you want to clean up:

eval { $message = $parser->parse($FILEHANDLE) };
# ...
$parser->filer->purge;

Whether you create files on disk, you can still treat the attachments as files by using the open method on an individual part:

for (my $i=0; $i < $num_parts; $i++) {
  my $part = $message->parts($i);
  my $fh = $part->open("r") or die "Can't open for reading: $!\n";
  while (<$fh>) {
    # reading lines from the current attachment
  }
}

There are actually six different classes that form part of the MIME-Tools distribution, and each is well-documented. Start with the MIME::Tools manpage and explore from there.

18.10.4. See Also

The MIME::Tools manpage and other documentation for the MIME-Tools distribution

Previous | Home | Next
18.9. Sending Attachments in Mail | Book Index | 18.11. Writing an XML-RPC Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.11. Writing an XML-RPC Server

18.11.1. Problem

You want to write a server for an XML-RPC web service.

18.11.2. Solution

Use the SOAP-Lite distribution from CPAN, which supports XML-RPC. Your server can be either standalone:

use XMLRPC::Transport::HTTP;

$daemon = XMLRPC::Transport::HTTP::Daemon
          ->new(LocalPort => $PORT)
          ->dispatch_to('ClassName')
          ->handle( );

or a CGI script:

use XMLRPC::Transport::HTTP;

$daemon = XMLRPC::Transport::HTTP::CGI
          ->dispatch_to('ClassName')
          ->handle( );

In both cases, incoming methods will be invoked on the class named in the dispatch_to method (it will be require d if it is not already loaded):

package ClassName;

sub handler {
  my ($class, $arg_hash_ref) = @_;
  # ...
}

18.11.3. Discussion

The SOAP-Lite toolkit's modules take care of translating between Perl's native data structures and the XML representation of those values. However, it's up to you how the server decides which method to invoke when a request arrives. This process of matching an XML-RPC request to a Perl function is known as dispatching.

It looks strange to see all those chained method invocation in the Solution. When used to set a value, XMLRPC::Lite methods return their invocation, which lets you chain methods rather than repeat $daemon over and over again:

$daemon = XMLRPC::Transport::HTTP::Daemon;
$daemon->new(LocalPort => $PORT);
$daemon->dispatch_to('ClassName');
$daemon->handle( );

The new constructor takes IO::Socket::INET's constructor parameters as well, so you can say ReuseAddr => 1, for example.

When you give the dispatch_to method a class name argument (as in the Solution), the XML-RPC server looks for methods in that class. If the server in the Solution receives a request for the ClassName.hasBeen method (XML-RPC methods are typically in IntraCaps), it invokes the ClassName->hasBeen method for a response.

Give dispatch_to a method name or list of method names, optionally qualified with a package name. This tells Perl that only those methods should be invoked. For example, the following code ensures that only the hasBeen and willBe methods from the main package and the canDo method from the MonkeySea class are valid:

$daemon->dispatch_to('hasBeen', 'willBe', 'MonkeySea::canDo')

Finally, give dispatch_to a pathname (optionally, as with method names or class names), and XMLRPC::Lite will load modules as needed from that directory at runtime:

$daemon->dispatch_to('/path/to/exposed/modules', 'MyClass::API');

This means "all modules in /path/to/exposed/modules and MyClass::API can be called through XML-RPC." MyClass::API might have been preloaded, or it might be found in @INC. This specifically does not mean "only dispatch to the MyClass::API in /path/to/exposed/modules."

18.11.4. See Also

Recipe 18.12; Recipe 18.13

Previous | Home | Next
18.10. Extracting Attachments from Mail | Book Index | 18.12. Writing an XML-RPC Client
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.12. Writing an XML-RPC Client

18.12.1. Problem

You want to write a client for an XML-RPC service.

18.12.2. Solution

Use the XMLRPC::Lite module from the SOAP-Lite distribution:

use XMLRPC::Lite;

$server = XMLRPC::Lite->proxy("http://server.example.com/path");
$result = $server->call('ClassName.handler', @ARGS);
die $call->faultstring if $call->fault;
print $call->result;

18.12.3. Discussion

A single XML-RPC server may run many services, differentiated by their method name: ClassName.handler corresponds to ClassName->handler on the server side; A.B.method corresponds to A::B->method; and a call to handler corresponds to main->handler.

The proxy is the actual URL of the server. If you're using a CGI server, the proxy method looks something like this:

$server->proxy("http://server.example.com/path/to/server.cgi")

There are three ways to invoke remote methods. The first way is to use the call method on your XMLRPC::Lite object. The first argument to call is the remote method name, and the remaining arguments are parameters for the remote method:

$returned = $server
         -> call("getRecordByNumber", 12, { format => "CSV" })
         -> result;

The second way to invoke a remote method is to call that method on the XMLRPC::Lite object. This works only when the remote method name isn't the same as a method provided by the XMLRPC::Lite object. For example:

$returned = $server
         -> getRecordByNumber(12, { format => "CSV" })
         -> result;

The last way to invoke a remote method is with autodispatch, turning unrequired function calls and method invocations in your Perl program into XML-RPC requests. Enable autodispatch with:

use XMLRPC::Lite +autodispatch =>
  proxy => "http://server.example.com/path";

$returned = getRecordByNumber(12, { format => "CSV" });

A critical difference between autodispatch and the other styles is that autodispatch automatically decodes the result into a Perl value for you. When you use an XMLRPC::Lite object, you must explicitly invoke the result method to decode the XML-RPC response into a Perl value.

18.12.4. See Also

Recipe 18.11; Recipe 18.14

Previous | Home | Next
18.11. Writing an XML-RPC Server | Book Index | 18.13. Writing a SOAP Server
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.13. Writing a SOAP Server

18.13.1. Problem

You want to write a web service where SOAP is the transport.

18.13.2. Solution

Use the SOAP-Lite distribution from CPAN. Your server can be either standalone:

use SOAP::Transport::HTTP;

$daemon = SOAP::Transport::HTTP::Daemon
          ->new(LocalPort => $PORT)
          ->dispatch_to('ClassName')
          ->handle( );

or a CGI script:

use SOAP::Transport::HTTP;

$daemon = SOAP::Transport::HTTP::CGI
          ->dispatch_to('ClassName')
          ->handle( );

In both cases, the only methods that SOAP clients are permitted to invoke are those in the classes named in the argument to dispatch_to (those classes will be require d if not already loaded):

package ClassName;

sub handler {
  my ($class, $arg_hash_ref) = @_;
  # ...
}

18.13.3. Discussion

The SOAP-Lite toolkit contains SOAP and XML-RPC modules. Writing a SOAP service is similar to writing an XML-RPC service. Control method dispatch in SOAP as in XML-RPC. See Recipe 18.11 for details.

18.13.4. See Also

Recipe 18.14; Recipe 18.11

Previous | Home | Next
18.12. Writing an XML-RPC Client | Book Index | 18.14. Writing a SOAP Client
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.14. Writing a SOAP Client

18.14.1. Problem

You want to write a client for a SOAP web service.

18.14.2. Solution

Use the SOAP::Lite module from the SOAP-Lite distribution:

use SOAP::Lite;

$server = SOAP::Lite
       -> uri("http://localhost/Namespace")
       -> proxy("http://server.example.com/path");
$result = $server->call('ClassName.handler', @ARGS);
die $call->faultstring if $call->fault;
print $call->result;

18.14.3. Discussion

A single SOAP server may offer remote access to the methods of many classes. A client identifies the class upon which it wishes to invoke methods with the uri parameter. The hostname in the argument is irrelevant; only the path portion (the class name) matters. For example, these two URIs are equivalent:

http://modacrylic.clue.com/GimpyMod
http://weenies.mit.edu/GimpyMod

As with XML-RPC, the proxy argument is the server's URL. For example, if your SOAP server is implemented as a CGI script, the proxy call looks like this:

$server->proxy("http://server.example.com/path/to/server.cgi");

Invoke remote methods as you do with XML-RPC, either with the call method:

$returned = $server
         -> call("getRecordByNumber", 12, { format => "CSV" })
         -> result;

or by invoking the method on a SOAP::Lite object directly:

$returned = $server
         -> getRecordByNumber(12, { format => "CSV" })
         -> result;

or using autodispatch:

use SOAP::Lite +autodispatch =>
  uri   => "http://identifier.example.com/Namespace",
  proxy => "http://server.example.com/path";

$returned = getRecordByNumber(12, { format => "CSV" });

You can also use this with OO syntax:

$returned = Some::Remote::Module->getRecordByNumber(12, { format => "CSV" });

18.14.4. See Also

There's a lot more to SOAP than we can explain here. The books Programming Web Services with SOAP, by James Snell, Pavel Kulchenko, and Doug Tidwell (O'Reilly), and Programming Web Services with Perl, by Randy Ray and Pavel Kulchenko (O'Reilly), form a comprehensive guide to the standards and implementations. Also see Recipe 18.11; Recipe 18.13

Previous | Home | Next
18.13. Writing a SOAP Server | Book Index | 18.15. Program: rfrm
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.15. Program: rfrm

This program fetches a list of messages waiting on a POP3 server and summarizes that list:

# ./rfrm
Nathan Torkington    Re: YAPC
Rob Brown            Re: Net::Ping syn round trip time
Rael Dornfest        Re: Book Proposal - Blosxom in a Nutshell
spam@example.com     Extend your ping times 633%!!!!

Tell the program which POP3 server to contact and the username and password to authenticate with using a ~/.rfrmrc file like this:

SERVER=pop3.example.com
USER=gnat
PASS=I(heart)Perl

The program verifies that your .rfrmrc file isn't readable or writable by anyone but you, and stops if it is.

The program is shown in Example 18-4.

Example 18-4. rfrm

#!/usr/bin/perl -w
# rfrm - get a list of mail messages waiting on a pop server

use Net::POP3;
use strict;

my ($Pop_host, $Pop_user, $Pop_pass) = read_conf( ) or usage( );

my $pop = Net::POP3->new($Pop_host)
  or die "Can't connect to $Pop_host: $!\n";
defined ($pop->login($Pop_user, $Pop_pass))
  or die "Can't authenticate\n";

my $messages = $pop->list
  or die "Can't get a list of messages\n";

foreach my $msgid (sort { $a <=> $b } keys %$messages) {
  my ($msg, $subject, $sender, $from);

  $msg = $pop->top($msgid, 0); # returns ref to array
  $msg = join "\n", @$msg;     # now it's one big string

  # extract From and Subject lines, and boil From down
  $subject = $sender = '';
  if ($msg =~ /^Subject: (.*)/m) { $subject = $1 }
  if ($msg =~ /^From: (.*)/m)    { $sender  = $1 }
  ($from = $sender) =~ s{<.*>}{  };
  if ($from =~ m{\(.*\)}) { $from = $1 }
  $from ||= $sender;

  # print boiled down summary of this message
  printf("%-20.20s %-58.58s\n", $from, $subject);
}

sub usage {
  die <<EOF ;
usage: rfrm
Configure with ~/.rfrmrc thus:
  SERVER=pop.mydomain.com
  USER=myusername
  PASS=mypassword
EOF
}

sub read_conf {
  my ($server, $user, $pass, @stat);

  open(FH, "< $ENV{HOME}/.rfrmrc") or return;

  # paranoia check
  @stat = stat(FH) or die "Can't stat ~/.rfrmrc: $!\n";
  if ($stat[2] & 177) {
    die "~/.rfrmrc should be mode 600 or tighter\n";
  }

  # read config file
  while (<FH>) {
    if (/SERVER=(.*)/) { $server = $1 }
    if (/USER=(.*)/)   { $user   = $1 }
    if (/PASS=(.*)/)   { $pass   = $1 }
  }
  close FH;

  # must have something for every value
  return unless $server && $user && $pass;

  return ($server, $user, $pass);
}
Previous | Home | Next
18.14. Writing a SOAP Client | Book Index | 18.16. Program: expn and vrfy
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


18.16. Program: expn and vrfy

This program uses Net::SMTP to talk to an SMTP server and uses the EXPN and VRFY commands to figure out whether an address is going to work. It isn't perfect, because it relies on the remote SMTP giving meaningful information with the EXPN and VRFY commands—they are common ways for spammers to harvest email addresses, and so many servers have disabled these options. It uses Net::DNS if available, but can also work without it.

This program inspects $0 (the program name) to see how it was called. If run as expn, it uses the EXPN command; if called as vrfy, it uses the VRFY command. Use links to install it with two names (on a system without links, simply copy the program code in Example 18-5):

% cat > expn
#!/usr/bin/perl -w
...
^D
% ln expn vrfy

When given an email address as an argument, the program reports what the mail server says when you try to EXPN or VRFY the address. If you have Net::DNS installed, it tries all hosts listed as mail exchangers in the DNS entry for the address.

Here's what it looks like without Net::DNS:

% expn gnat@frii.com
Expanding gnat at frii.com (gnat@frii.com):
calisto.frii.com Hello coprolith.frii.com [207.46.130.14],
    pleased to meet you
gnat@mail.frii.com

And here's the same address with Net::DNS installed:

% expn gnat@frii.com
Expanding gnat at mail.frii.net (gnat@frii.com):
deimos.frii.com Hello coprolith.frii.com [207.46.130.14],
    pleased to meet you
Nathan Torkington <gnat@deimos.frii.com>

Expanding gnat at mx1.frii.net (gnat@frii.com):
phobos.frii.com Hello coprolith.frii.com [207.46.130.14],
    pleased to meet you
gnat@mail.frii.com

Expanding gnat at mx2.frii.net (gnat@frii.com):
europa.frii.com Hello coprolith.frii.com [207.46.130.14],
    pleased to meet you
gnat@mail.frii.com

Expanding gnat at mx3.frii.net (gnat@frii.com):
ns2.winterlan.com Hello coprolith.frii.com [207.46.130.14],
    pleased to meet you
550 gnat... User unknown

The program is shown in Example 18-5.

Example 18-5. expn

  #!/usr/bin/perl -w
  # expn -- convince smtp to divulge an alias expansion
  use strict;
  use Net::SMTP;
  use Sys::Hostname;
  my $fetch_mx = 0;
  # try loading the module, but don't blow up if missing
  eval {
      require Net::DNS;
      Net::DNS->import('mx');
      $fetch_mx = 1;
  };
  my $selfname = hostname( );
  die "usage: $0 address\@host ...\n" unless @ARGV;
  # Find out whether called as "vrfy" or "expn".
  my $VERB = ($0 =~ /ve?ri?fy$/i)  ? 'VRFY' : 'EXPN';
  my $multi = @ARGV > 1;
  my $remote;
  # Iterate over addresses give on command line.
  foreach my $combo (@ARGV) {
      my ($name, $host) = split(/\@/, $combo);
      my @hosts;
      $host ||= 'localhost';
      @hosts = map { $_->exchange } mx($host)     if $fetch_mx;
      @hosts = ($host)   unless @hosts;
      foreach my $host (@hosts) {
          print $VERB eq 'VRFY' ? "Verify" : "Expand",
              "ing $name at $host ($combo):";
          $remote = Net::SMTP->new($host, Hello => $selfname);
          unless ($remote) {
              warn "cannot connect to $host\n";
              next;
          }
          print "\n";
          if ($VERB eq 'VRFY') {
              $remote->verify($name);
          } elsif ($VERB eq 'EXPN') {
              $remote->expand($name);
          }
          last if $remote->code =  = 221;
          next if $remote->code =  = 220;
          print $remote->message;
          $remote->quit;
          print "\n" if $multi;
      }
  }
Previous | Home | Next
18.15. Program: rfrm | Book Index | 19. CGI Programming
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 19. CGI Programming

Contents:

Introduction
Writing a CGI Script
Redirecting Error Messages
Fixing a 500 Server Error
Writing a Safe CGI Program
Executing Commands Without Shell Escapes
Formatting Lists and Tables with HTML Shortcuts
Redirecting to a Different Location
Debugging the Raw HTTP Exchange
Managing Cookies
Creating Sticky Widgets
Writing a Multiscreen CGI Script
Saving a Form to a File or Mail Pipe
Program: chemiserie

Stephen C. Johnson

A successful tool is one that was used to do something undreamt of by its author.

19.0. Introduction

Changes in the environment or the availability of food can make certain species more successful than others at finding food or avoiding predators. Many scientists believe a comet struck the Earth millions of years ago, throwing an enormous cloud of dust into the atmosphere. Subsequent radical changes to the environment proved too much for some organisms, say dinosaurs, and hastened their extinction. Other creatures, such as mammals, found new food supplies and freshly exposed habitats to compete in.

Much as the comet altered the environment for prehistoric species, the Web has altered the environment for modern programming languages. It's opened up new vistas, and although some languages have found themselves eminently unsuited to this new world order, Perl has positively thrived. Because of its strong background in text processing and system glue, Perl has readily adapted itself to the task of providing information using text-based protocols.

19.0.1. Architecture

The Web is driven by plain text. Web servers and web browsers communicate using a text protocol called HTTP, Hypertext Transfer Protocol. Many of the documents exchanged are encoded in a text markup system called HTML, Hypertext Markup Language. This grounding in text is the source of much of the Web's flexibility, power, and success. The only notable exception to the predominance of plain text is the Secure Socket Layer (SSL) protocol that encrypts other protocols like HTTP into binary data that snoopers can't decode.

Web pages are identified using the Uniform Resource Locator (URL) naming scheme. URLs look like this:

http://www.perl.com/CPAN/
http://www.perl.com:8001/bad/mojo.html
ftp://gatekeeper.dec.com/pub/misc/netlib.tar.Z
ftp://anonymous@myplace:gatekeeper.dec.com/pub/misc/netlib.tar.Z
file:///etc/motd

The first part (http, ftp, file) is called the scheme, which identifies how the file is retrieved. The next part (://) means a hostname will follow, whose interpretation depends on the scheme. After the hostname comes the path identifying the document. This path information is also called a partial URL.

The Web is a client-server system. Client browsers like Netscape and Lynx request documents (identified by a partial URL) from web servers like Apache. This browser-to-server dialog is governed by the HTTP protocol. Most of the time, the server merely sends back the file contents. Sometimes, however, the web server runs another program to return a document that could be HTML text, binary image, or any other document type.

The server-to-program dialog can be handled in two ways. Either the code to handle the request is part of the web server process, or else the web server runs an external program to generate a response. The first scenario is the model of Java servlets and mod_perl (covered in Chapter 21). The second is governed by the Common Gateway Interface (CGI) protocol, so the server runs a CGI program (sometimes known as a CGI script). This chapter deals with CGI programs.

The server tells the CGI program what page was requested, what values (if any) came in through HTML forms, where the request came from, whom they authenticated as (if they authenticated at all), and much more. The CGI program's reply has two parts: headers to say "I'm sending back an HTML document," "I'm sending back a GIF image," or "I'm not sending you anything; go to this page instead," and a document body, perhaps containing image data, plain text, or HTML.

The CGI protocol is easy to implement wrong and hard to implement right, which is why we recommend using Lincoln Stein's excellent CGI.pm module. It provides convenient functions for accessing the information the server sends you, and for preparing the CGI response the server expects. It's so useful, it's included in the standard Perl distribution, along with helper modules such as CGI::Carp and CGI::Fast. We show it off in Recipe 19.1.

Some web servers come with a Perl interpreter embedded in them. This lets Perl generate documents without starting a new process. The system overhead of reading an unchanging page isn't noticeable on infrequently accessed pages, even when it's happening several times a second. CGI accesses, however, bog down the machine running the web server. Chapter 21 shows how to use mod_perl, the Perl interpreter embedded in the Apache web server to get the benefits of CGI programs without the overhead.

19.0.2. Behind the Scenes

CGI programs are called each time the web server needs a dynamic document generated. It is important to understand that your CGI program doesn't run continuously, with the browser calling different parts of the program. Each request for a partial URL corresponding to your program starts a new copy. Your program generates a page for that request, then quits.

A browser can request a document in several distinct ways called methods. (Don't confuse HTTP methods with the methods of object-orientation. They have nothing to do with each other). The GET method is the most common, indicating a simple request for a document. The HEAD method supplies information about the document without actually fetching it. The POST method submits form values.

Form values can be encoded in both GET and POST methods. With the GET method, values are encoded directly in the URL, leading to ugly URLs like this:

http://www.perl.com/cgi-bin/program?name=Johann&born=1685

With the POST method, values are encoded in a separate part of the HTTP request that the client browser sends the server. If the form values in the previous example URL were sent with a POST request, the user, server, and CGI script would all see the URL:

http://www.perl.com/cgi-bin/program

The GET and POST methods differ in another respect: idempotency. This simply means that making a GET request for a particular URL once or multiple times should be no different. The HTTP protocol definition says that a GET request may be cached by the browser, the server, or an intervening proxy. POST requests cannot be cached, because each request is independent and matters. Typically, POST requests any changes or depends on the state of the server (query or update a database, send mail, or purchase a computer).

Most servers log requests to a file (the access log) for later analysis by the webmaster. Error messages produced by CGI programs don't by default go to the browser. Instead they are logged to a file on the server (the error log), and the browser simply gets a "500 Server Error" message, which means that the CGI program didn't uphold its end of the CGI bargain.

Error messages are useful in debugging any program, but they are especially so with CGI scripts. Sometimes, though, the authors of CGI programs either don't have access to the error log or don't know where it is. Sending error messages to a more convenient location is discussed in Recipe 19.2. Tracking down errors is covered in Recipe 19.3.

Recipe 19.8 shows how to learn what your browser and server are really saying to one another. Unfortunately, some browsers do not implement the HTTP specification correctly, and this recipe helps you determine whether your program or your browser is the cause of a problem.

19.0.3. Security

CGI programs let anyone run a program on your system. Sure, you get to pick the program, but the anonymous user from Out There can send unexpected values, hoping to trick it into doing the wrong thing. Thus security is a big concern on the Web.

Some sites address this concern by banning CGI programs. Sites that can't do without the power and utility of CGI programs must find ways to secure their CGI programs. Recipe 19.4 gives a checklist of considerations for writing a secure CGI script, briefly covering Perl's tainting mechanism for guarding against accidental use of unsafe data. Recipe 19.5 shows how your CGI program can safely run other programs.

19.0.4. HTML and Forms

Some HTML tags let you create forms, where the user can fill in values to submit to the server. The forms are composed of widgets, such as text entry fields and check boxes. CGI programs commonly return HTML, so the CGI module has helper functions to create HTML for everything from tables to form widgets.

In addition to Recipe 19.6, this chapter also has Recipe 19.10, which shows how to create forms that retain values over multiple calls. Recipe 19.11 shows how to make a single CGI script that produces and responds to a set of pages, such as a product catalog and ordering system.

10.0.5. Web-Related Resources

Unsurprisingly, some of the best references on the Web are found on the Web:

WWW Security FAQ
http://www.w3.org/Security/Faq/

Web FAQ
http://www.boutell.com/faq/

CGI FAQ
http://www.webthing.com/tutorials/cgifaq.html

HTTP Specification
http://www.w3.org/pub/WWW/Protocols/HTTP/

HTML Specification
http://www.w3.org/TR/REC-html40/

http://www.w3.org/pub/WWW/MarkUp/

CGI Specification
http://www.w3.org/CGI/

CGI Security FAQ
http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt

We recommend CGI Programming with Perl, by Scott Guelich, Shishir Gundavaram, and Gunther Birznieks (O'Reilly); HTML & XHTML: The Definitive Guide, by Chuck Musciano and Bill Kennedy (O'Reilly); and HTTP: The Definitive Guide, by David Gourley and Brian Totty, et al (O'Reilly).

Previous | Home | Next
18.16. Program: expn and vrfy | Book Index | 19.1. Writing a CGI Script
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.1. Writing a CGI Script

19.1.1. Problem

You want to write a CGI script to process the contents of an HTML form. In particular, you want to access the form contents and produce valid output in return.

19.1.2. Solution

A CGI script is a server-side program launched by a web server to generate dynamic content. It receives encoded information from the remote client (user's browser) via STDIN and environment variables, and it must produce a valid HTTP header and body on STDOUT. The standard CGI module, shown in Example 19-1, painlessly manages input and output encoding.

Example 19-1. hiweb

  #!/usr/bin/perl -w
  # hiweb - load CGI module to decode information given by web server
  use strict;

  use CGI qw(:standard escapeHTML);

  # get a parameter from a form
  my $value = param('PARAM_NAME');

  # output a document
  print header( ), start_html("Howdy there!"),
        p("You typed: ", tt(escapeHTML($value))),
        end_html( );

19.1.3. Discussion

CGI is just a protocol, a formal agreement between a web server and a separate program. The server encodes the client's form input data, and the CGI program decodes the form and generates output. The protocol says nothing regarding which language the program must be written in; programs and scripts that obey the CGI protocol have been written in C, shell, Rexx, C++, VMS DCL, Smalltalk, Tcl, Python, and of course Perl.

The full CGI specification lays out which environment variables hold which data (such as form input parameters) and how it's all encoded. In theory, it should be easy to follow the protocol to decode the input, but in practice, it is surprisingly tricky to get right. That's why we strongly recommend using the CGI module. The hard work of handling the CGI requirements correctly and conveniently has already been done, freeing you to write the core of your program without getting bogged down in network protocols.

CGI scripts are called in two main ways, referred to as methods—but don't confuse HTTP methods with Perl object methods! The HTTP GET method is used in document retrievals where an identical request will produce an identical result, such as a dictionary lookup. A GET stores form data in the URL. This means it can be conveniently bookmarked for canned requests, but has limitations on the total request size. The HTTP POST method sends form data separate from the request. It has no size limitations, but cannot be bookmarked. Forms that update information on the server, such as mailing in feedback or modifying a database entry, should use POST. Client browsers and intervening proxies are free to cache and refresh the results of GET requests behind your back, but they may not cache POST requests. GET is suitable only for short read-only requests, whereas POST works for forms of any size, as well as for updates and feedback responses. By default, therefore, the CGI module uses POST for all forms it generates.

With few exceptions, mainly related to file permissions and highly interactive work, CGI scripts can do nearly anything other programs can do. They can send results back in many formats: plain text, HTML documents, XML files, sound files, pictures, or anything else specified in the HTTP header. Besides producing plain text or HTML text, they can also redirect the client browser to another location, set server cookies, request authentication, and give errors.

The CGI module provides two different interfaces: a procedural one for casual use, and an object-oriented one for power users with complicated needs. Virtually all CGI scripts should use the simple procedural interface, but unfortunately, most of CGI.pm's documentation uses examples with the original object-oriented approach. Due to backward compatibility, if you want the simple procedural interface, you need to specifically ask for it using the :standard import tag. See Chapter 12 for more on import tags.

To read the user's form input, pass the param function a field name. If you have a form field named "favorite", then param("favorite") returns its value. With some types of form fields, such as scrolling lists, the user can choose more than one option. For these, param returns a list of values, which you could assign to an array.

For example, here's a script that pulls in values of three form fields, the last one having many return values:

use CGI qw(:standard);
$who   = param("Name");
$phone = param("Number");
@picks = param("Choices");

Called without arguments, param returns a list of valid form parameters in list context or how many form parameters there were in scalar context.

That's all there is to accessing the user's input. Do with it whatever you please, then generate properly formatted output. This is nearly as easy. Remember that unlike regular programs, a CGI script's output must be formatted in a particular way: it must first emit a set of headers followed by a blank line before any normal output.

As shown in the Solution, the CGI module helps with output as well as input. The module provides functions for generating HTTP headers and HTML code. The header function builds the header for you. By default, it produces headers for a text/html document, but you can change the Content-Type and supply other optional header parameters as well:

print header( -TYPE    => 'text/plain',
              -EXPIRES => '+3d' );

CGI.pm can also be used to generate HTML. It may seem trivial, but this is where the CGI module shines: the creation of dynamic forms, especially stateful ones such as shopping carts. The CGI module even has functions for generating forms and tables.

When printing form widgets, the characters &, <, >, and " in HTML output are automatically replaced with their entity equivalents. This is not the case with arbitrary user output. That's why the Solution imports and makes use of the escapeHTML function—if the user types any of those special characters, they won't cause formatting errors in the HTML.

For a full list of functions and their calling conventions, see CGI.pm's documentation.

19.1.4. See Also

The documentation for the standard CGI module; http://www.w3.org/CGI/; Recipe 19.6

Previous | Home | Next
19. CGI Programming | Book Index | 19.2. Redirecting Error Messages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.2. Redirecting Error Messages

19.2.1. Problem

You're having trouble tracking down your script's warnings and error messages, or your script's STDERR output is confusing your server.

19.2.2. Solution

Use the CGI::Carp module from the standard Perl distribution to prefix each line on STDERR with the program name and current date. You can also send warnings and errors to a file or the browser if you wish.

19.2.3. Discussion

Tracking down error messages from CGI scripts is notoriously annoying. Even if you manage to find the server error log, you still can't determine which message came from which script, or at what time. Some unfriendly web servers even abort the script if it has the audacity to emit anything out its STDERR before the Content-Type header is generated on STDOUT, so warnings can get you into trouble.

Enter the CGI::Carp module. It replaces warn and die—plus the normal Carp module's carp, croak, cluck, and confess functions—with more verbose and safer versions. It still sends them to the normal server error log.

use CGI::Carp;
warn "This is a complaint";
die "But this one is serious";

The following use of CGI::Carp also redirects errors to a file of your choice, placed in a BEGIN block to catch compile-time warnings as well:

BEGIN {
    use CGI::Carp qw(carpout);
    open(LOG, ">>/var/local/cgi-logs/mycgi-log")
        or die "Unable to append to mycgi-log: $!\n";
    carpout(*LOG);
}

You can even arrange for fatal errors to show up at the client browser, which is nice for your own debugging but might confuse the end user.

use CGI::Carp qw(fatalsToBrowser);
die "Bad error here";

Even if the error happens before you get the HTTP header out, the module will try to detect this and avoid the dreaded 500 Server Error. Normal warnings still go to the server error log (or wherever you've sent them with carpout) with the program name and date stamp prepended.

19.2.4. See Also

The documentation for the standard CGI::Carp module; the discussion on BEGIN in Recipe 12.3

Previous | Home | Next
19.1. Writing a CGI Script | Book Index | 19.3. Fixing a 500 Server Error
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.3. Fixing a 500 Server Error

19.3.1. Problem

Your CGI script gives you a 500 Server Error.

19.3.2. Solution

Follow the checklist given in the discussion.

19.3.3. Discussion

This checklist is aimed at a Unix audience, but the general principles embodied in the questions apply to all systems.

19.3.3.1. Make sure the web server can run the script

Check ownership and permissions with ls -l. The appropriate read and execute bits must be set on the script before the web server can run it. The script should be readable and executable by everyone (or at least by whomever the server runs scripts as). Use chmod 0755 scriptname if it's owned by you, or otherwise chmod 0555 scriptname if owned by the designated anonymous web user, assuming you are running as that user or the superuser. All directories in the path must also have their execute bit set (most FTP clients support changing protections on uploaded files if you don't have shell access to your server).

Make sure the script can be identified as a script by the web server. Most web servers have a system-wide cgi-bin, and all files in that directory will be run as scripts. Some servers identify a CGI script as any file whose name ends in a particular extension, such as .cgi or .plx. Some servers have options to permit access via the GET method alone, not through the POST method that your form likely uses. Consult your web server documentation, configuration files, webmaster, and (if all else fails) technical support.

If you're running on Unix, do you have the right path to the Perl executable on the #! line? The #! line must be the first line in the script; you can't even have blank lines before the #! line. Some operating systems have ridiculously short limits on the number of characters that can be in this line, so you may need to make a link (e.g., from /home/richh/perl to /opt/installed/third-party/software/perl-5.004/bin/perl, to pick a hypothetical, pathological example).

If you're running on Win32, have you associated your Perl scripts with the correct Perl executable? Or, if your server uses #! lines, have you given the correct path in the #! line?

19.3.3.2. Make sure the script has permissions to do what it's trying to do

Identify the user the script runs as with the simple code shown in Example 19-2.

Example 19-2. webwhoami

  #!/usr/bin/perl
  # webwhoami - show web users id
  print "Content-Type: text/plain\n\n";
  print "Running as ", scalar getpwuid($>), "\n";

This prints the username the script is running as.

Identify the resources the script is trying to access. List files, network connections, system calls, and so on, that require special privilege. Then make sure they can be accessed by the user the script is running as. Are there disk or network quotas? Do protections on the file allow access? Are you trying to get the encrypted password field using getpwent on a shadow password system (since usually only the superuser can get shadow passwords)?

Set permissions on any files the script needs to write to at 0666, or better yet to 0644 if they're owned by the effective user ID the script is running under. If new files are to be created or old ones moved or removed, write and execute permission on the enclosing directory of those files is also needed.

19.3.3.3. Is the script valid Perl?

Try to run it from a shell prompt. CGI.pm lets you run and debug your scripts from the command line or from standard input. Here, ^D represents whatever you type to get an end-of-file.

% perl -wc cgi-script                        # just compilation

% perl -w  cgi-script                        # parms from stdin
(offline mode: enter name=value pairs on standard input)
name=joe
number=10
^D

% perl -w  cgi-script name=joe number=10    # run with mock form input
% perl -d  cgi-script name=joe number=10    # ditto, under the debugger

# POST method script in csh
% (setenv HTTP_METHOD POST; perl -w cgi-script name=joe number=10)
# POST method script in sh
% HTTP_METHOD=POST perl -w cgi-script name=joe number=10

Check the server's error log. Most web servers redirect CGI process's STDERR into a file. Find that file (try /usr/local/etc/httpd/logs/error_log, /usr/local/www/logs/error_log, or just ask your administrator) and see whether any warnings or error messages are showing up there.

Are you using an old version of Perl? Type perl -v to find out. If you're not using 5.004 or better, you or your admins should upgrade because 5.003 and earlier releases were not protected against buffer overruns. This is a grave security matter.

Are you using an old version of the libraries? You can grep -i version in the library file (probably in /usr/lib/perl5/, /usr/local/lib/perl5, /usr/lib/perl5/site_perl, or some such). For CGI.pm, and in fact, with any module, you can do this to figure out which version you're using:

% perl -MCGI -le 'print CGI->VERSION'
2.49

Are you running the latest version of your web server? It's not often that it happens, but sometimes a web server has bugs that can interfere with your scripts.

Are you running with the -w switch or use warnings? This makes Perl gripe about things like using uninitialized variables, reading from a write-only filehandle, and so on.

Are you running with the -T flag? If Perl complains about insecure actions, you might be assuming things about your script's input and environment that aren't true. Make it taint-clean (read Recipe 19.4, see the perlsec manpage or Chapter 23 of Programming Perl to find out about tainting and its consequences for your program, and check the CGI Security FAQ for particular web traps to avoid) and you may sleep easier at night as well as have a working script.

Are you running with use strict? It makes you declare variables before you use them and quote your strings to avoid any confusion with subroutines, and in doing so finds a lot of errors.

Are you checking return values from every system call? Many people blindly believe that every open or system or rename or unlink in their programs will work all the time. These functions return a value so you can find out whether they worked or not—check them!

Can Perl find the libraries you're using? Write a small script that just prints @INC (Perl's array of directories it looks for modules and libraries in). Check permissions on the libraries (they must be readable by the user the script runs as). Don't copy modules from one machine to another—a lot of them have compiled and autoloaded components hidden in the Perl library directory. Install them yourself from scratch.

Is Perl giving you warnings or errors? Try using CGI::Carp (see Recipe 19.2) to send Perl's error messages and warnings to the browser or a file you have access to.

19.3.3.4. Is the script upholding its end of the CGI protocol?

The HTTP header must come before the text or image you return. Don't forget the blank line between the header and body. Also, because STDOUT is not automatically autoflushed but STDERR is, if your script generates warnings or errors to STDERR, the web server might see them before it sees your HTTP header and can generate an error on some servers. Add this at the top of your script (after the #! line) to also flush STDOUT:

$| = 1;

Don't ever try to decode the incoming form data by parsing the environment and standard input yourself. There are just too many places where it can go wrong. Use the CGI module and spend your time writing cool programs or reading slashdot instead of tracking down bugs in your implementation of an arcane protocol.

19.3.3.5. Asking for help elsewhere

Check the FAQs and other documents mentioned at the end of the Introduction to this chapter. There is still a chance that you have made a common mistake on whatever system you're using—read the relevant FAQs to make sure you don't embarrass yourself by asking the CGI equivalent of "why doesn't my car run when it's out of gas and oil?"

Ask a friend. Almost everyone knows somebody they can ask for help. You'll probably get a reply much sooner than if you asked the Net.

Post to comp.infosystems.www.authoring.misc if your question is about a CGI script (the CGI module, decoding cookies, finding out where the user is coming from, etc.).

19.3.4. See Also

Recipe 19.2; the discussion on buffering in the Introduction of Chapter 8; the CGI FAQ at http://www.webthing.com/tutorials/cgifaq.html

Previous | Home | Next
19.2. Redirecting Error Messages | Book Index | 19.4. Writing a Safe CGI Program
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.4. Writing a Safe CGI Program

19.4.1. Problem

Because CGI programs allow external users to run programs on systems they would not otherwise have access on, all CGI programs represent a potential security risk. You want to minimize your exposure.

19.4.2. Solution

  • Use taint mode (the -T switch on the #! line).

  • Don't blindly untaint data. (See the Discussion.)

  • Sanity-check everything, including all form widget return values, even hidden widgets or values generated by JavaScript code. Many people naïvely assume that just because they tell JavaScript to check the form's values before the form is submitted, the form's values will actually be checked. Not at all! The user can trivially circumvent this by disabling JavaScript in their browser, by downloading the form and altering the JavaScript, or quit by talking HTTP without a browser using any of the examples in Chapter 20.

  • Check return conditions from system calls.

  • Be conscious of race conditions (described in the Discussion).

  • Run with use warnings and use strict to make sure Perl isn't assuming things incorrectly.

  • Don't run anything setuid unless you absolutely must. If you must, think about running setgid instead if you can. Certainly avoid setuid root at all costs. If you must run setuid or setgid, use a wrapper unless Perl is convinced your system has secure setuid scripts and you know what this means.

  • Always encode login passwords, credit card numbers, social security numbers, and anything else you'd not care to read pasted across the front page of your local newspaper. Use a secure protocol like SSL when dealing with such data. Ensuring that a CGI only ever runs as HTTPS can be as simple as:

    croak "This CGI works only over HTTPS"
  if $ENV{'SERVER_PORT'} && !$ENV{'HTTPS'};

    Moreover, never pass secure data through email. If you need to mail a user some secure data, instead mail them an https: URL to a page that will display the secure data only if the user provides the correct password—a password that has never been sent over an insecure protocol like email or http. Keep secure data around only as needed, and consider the likelihood and consequences of anyone wrongly accessing the secure data.

19.4.3. Discussion

Many of these suggestions are good ideas for any program—using warnings and checking the return values of your system calls are obviously applicable even when security isn't the first thing on your mind. The use warnings pragma makes Perl issue warnings about dubious constructs, like using an undefined variable as though it had a legitimate value, or writing to a read-only filehandle.

Apart from unanticipated shell escapes, the most common security threat lies in forged values in a form submission. It's trivial for anyone to save the source to your form, edit the HTML, and submit the altered form. Even if you're certain that a field can return only "yes" or "no", they can always edit it up to return "maybe" instead. Even fields marked as type HIDDEN in the form can be tampered with. If the program at the other end blindly trusts its form values, it can be fooled into deleting files, creating new user accounts, mailing password or credit card databases, or innumerable other malicious abuses. This is why you must never blindly trust data (like prices) stored in hidden fields when writing CGI shopping cart applications.

Even worse is when the CGI script uses a form value as the basis of a filename to open or a command to run. Bogus values submitted to the script could trick it into opening arbitrary files. Situations like this are precisely why Perl has a taint mode. If a program runs setuid or in taint mode, data from program arguments, environment variables, directory listings, or files are considered tainted, and cannot be used directly or indirectly to affect the outside world.

Running under taint mode, Perl insists that you set your path variable first, even if specifying a complete pathname to call a program. That's because you have no assurance that the command you run won't turn around and invoke some other program using a relative pathname. You must also untaint any externally derived data for safety.

For instance, when running in taint mode:

#!/usr/bin/perl -T
open(FH, "> $ARGV[0]") or die;

Perl warns with:

Insecure dependency in open while running with -T switch at ...

This is because $ARGV[0] (having come from outside your program) is not trustworthy. The only way to change tainted data into untainted data is by using regular expression backreferences:

$file = $ARGV[0];                                   # $file tainted
unless ($file =~ m#^([\w.-]+)$#) {                  # $1 is untainted
    die "filename '$file' has invalid characters.\n";
}
$file = $1;                                         # $file untainted

Tainted data can come from anything outside your program, such as from your program arguments or environment variables, the results of reading from filehandles or directory handles, and stat or locale information. Operations considered insecure with tainted data include system(STRING), exec(STRING), backticks, glob, open with any access mode except read-only, unlink, mkdir, rmdir, chown, chmod, umask, link, symlin k, the -s command-line switch, kill, require, eval, truncate, ioctl, fcntl, socket, socketpair, bind, connect, chdir, chroot, setpgrp, setpriority, and syscall.

A common attack exploits what's known as a race condition. That's a situation where, between two actions of yours, an attacker can race in and change something to make your program misbehave. A notorious race condition occurred in the way older Unix kernels ran setuid scripts: between the kernel reading the file to find which interpreter to run and the now-setuid interpreter reading the file, a malicious person could substitute their own script.

Race conditions crop up even in apparently innocuous places. Consider what would happen if not one but many copies of the following code ran simultaneously.

unless (-e $filename) {                     # WRONG!
    open(FH, "> $filename");
    # ...
}

There's a race between testing whether the file exists and opening it for writing. Similar race conditions can occur in such common situations as reading data from a file, updating the data, and writing it back out to that file.

Still worse, if someone replaced the file with a link to something important, like one of your personal configuration files, the code just shown would erase that file. The correct way to do this is to do a non-destructive create with the sysopen function, described in Recipe 7.1.

A setuid CGI script runs with different permissions than the web server does. This lets the CGI script access resources (files, shadow password databases, etc) that it otherwise could not. This can be convenient, but it can also be dangerous. Weaknesses in setuid scripts may let crackers access not only files that the low-privilege web server user can access, but also any that could be accessed by the user the script runs as. For a poorly written setuid root script, this could let anyone change passwords, delete files, read credit card records, and other malicious acts. Always make sure your programs run with the lowest privilege possible, normally the user the web server runs as: nobody.

Finally (and this recommendation may be the hardest to follow), be conscious of the physical path your network traffic takes. Are you sending passwords over an unencrypted connection? Do these unencrypted passwords travel through insecure networks? A form's PASSWORD input field only protects you from someone looking over your shoulder. Always use SSL when real passwords are involved. If you're serious about security, fire up your browser and a packet sniffer to see how easily your traffic is decoded.

19.4.4. See Also

The section on "Talking to Yourself" in Chapter 16 of Programming Perl; the section on "Accessing Commands and Files Under Reduced Privilege" in Chapter 23 of Programming Perl; perlsec(1); the CGI and HTTP specs and the CGI Security FAQ, all mentioned in the Introduction to this chapter; the section on "Avoiding Denial of Service Attacks" in the standard CGI module documentation; Recipe 19.5

Previous | Home | Next
19.3. Fixing a 500 Server Error | Book Index | 19.5. Executing Commands Without Shell Escapes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.5. Executing Commands Without Shell Escapes

19.5.1. Problem

You need to use a user's input as part of a command, but you don't want to allow the user to trick the shell into running other commands or looking at other files. If you just blindly call the system function or backticks on a single string containing a command line derived from untested user input, the shell might be used to run the command. This would be unsafe.

19.5.2. Solution

Unlike its single-argument version, the list form of the system function is safe from shell escapes. When the command's arguments involve user input from a form, never use this:

system("command $input @files");            # UNSAFE

Write it this way instead:

system("command", $input, @files);          # safer

19.5.3. Discussion

Because Perl was designed as a glue language, it's easy to use it to call other programs—too easy, in some cases.

If you're merely trying to run a shell command but don't need to capture its output, it's easy enough to call system using its multiple argument form. But what happens if you're using the command in backticks or as part of a piped open? Now you have a real problem, because those don't permit the multiple argument form that system does. The solution (prior to v5.8; see later in this Discussion) is to manually fork and exec the child processes on your own. It's more work, but at least stray shell escapes won't be ruining your day.

It's safe to use backticks in a CGI script only if the arguments you give the program are internally generated, as in:

chomp($now = `date`);

But if the command within the backticks contains user-supplied input, perhaps like this:

@output = `grep $input @files`;

you have to be much more careful.

die "cannot fork: $!" unless defined ($pid = open(SAFE_KID, "-|"));
if ($pid =  = 0) {
    exec('grep', $input, @files) or die "can't exec grep: $!";
} else {
    @output = <SAFE_KID>;
    close SAFE_KID;                 # $? contains status
}

This works because exec, like system, permits a calling convention that's immune to shell escapes. When passed a list, no shell is called, and so no escapes can occur.

Similar circumlocutions are needed when using open to start up a command. Here's a safe backtick or piped open for read. Instead of using this unsafe code:

open(KID_TO_READ, "$program @options @args |");    # UNSAFE

use this more complicated but safer code:

# add error processing as above
die "cannot fork: $!" unless defined($pid = open(KID_TO_READ, "-|"));

if ($pid) {   # parent
   while (<KID_TO_READ>) {
       # do something interesting
   }
   close(KID_TO_READ)               or warn "kid exited $?";

} else {      # child
   # reconfigure, then
   exec($program, @options, @args)  or die "can't exec program: $!";
}

Here's a safe piped open for writing. Instead of using this unsafe code:

open(KID_TO_WRITE, "|$program $options @args");   # UNSAFE

use this more complicated but safer code:

die "cannot fork: $!" unless defined($pid = open(KID_TO_WRITE, "-|"));
$SIG{PIPE} = sub { die "whoops, $program pipe broke" };

if ($pid) {  # parent
   for (@data) { print KID_TO_WRITE $_ }
   close(KID_TO_WRITE)              or warn "kid exited $?";

} else {     # child
   # reconfigure, then
   exec($program, @options, @args)  or die "can't exec program: $!";
}

Put any extra security measures you'd like where the comment in the code says reconfigure. You can change environment variables, reset temporary user or group ID values, change directories or umasks, etc. You're in the child process now, where changes won't propagate back to the parent.

If you don't have any reconfiguration to do in the child process, and you're running at least the v5.8 release of Perl, open supports a list of separate parameters that works as system and exec do when passed a list; that is, it avoids the shell altogether. Those two calls would be:

open(KID_TO_READ, "-|", $program, @options, @args)
    || die "can't run $program: $!";

and:

open(KID_TO_WRITE, "|-", $program, $options, @args)
      || die "can't run $program: $!";

This doesn't help you, of course, if you run a setuid program that can be exploited with the data you give it. The mail program sendmail is a setuid program commonly run from CGI scripts. Know the risks before you call sendmail or any other setuid program.

19.5.4. See Also

The system, exec, and open functions in Chapter 29 of Programming Perl and in perlfunc(1); the section on "Talking to Yourself" in Chapter 16 of Programming Perl; the section on "Accessing Commands and Files Under Reduced Privilege" in Chapter 23 of Programming Perl; perlsec(1); Recipe 16.1; Recipe 16.2; Recipe 16.3

Previous | Home | Next
19.4. Writing a Safe CGI Program | Book Index | 19.6. Formatting Lists and Tables with HTML Shortcuts
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.6. Formatting Lists and Tables with HTML Shortcuts

19.6.1. Problem

You have several lists and tables to generate and wish they were easier to output.

19.6.2. Solution

The CGI module provides HTML helper functions that, when passed array references, apply themselves to each element of the referenced array:

print ol( li([ qw(red blue green)]) );
<OL><LI>red</LI><LI>blue</LI><LI>green</LI></OL>
@names = qw(Larry Moe Curly);
print ul( li({ -TYPE => "disc" }, \@names) );
<UL><LI TYPE="disc">Larry</LI> <LI TYPE="disc">Moe</LI>
    <LI TYPE="disc">Curly</LI></UL>

19.6.3. Discussion

The HTML-generating functions in CGI.pm can make it easy to generate lists and tables. Passed a simple string, these functions produce HTML for that string. But passed an array reference, they work on all strings in that array.

print li("alpha");
<LI>alpha</LI>
print li( [ "alpha", "omega"] );
<LI>alpha</LI> <LI>omega</LI>

The shortcut functions for lists are loaded when you use the :standard import tag, but you need to ask for :html3 explicitly to get helper functions for tables. There's also a conflict between the <TR> tag, which would normally make a tr( ) function, and Perl's built-in tr/// operator. Therefore, to make a table row, use the Tr( ) function.

This example generates an HTML table starting with a hash of arrays. The keys will be the row headers, and the array of values are the columns.

use CGI qw(:standard :html3);

%hash = (
    "Wisconsin"  => [ "Superior", "Lake Geneva", "Madison" ],
    "Colorado"   => [ "Denver", "Fort Collins", "Boulder" ],
    "Texas"      => [ "Plano", "Austin", "Fort Stockton" ],
    "California" => [ "Sebastopol", "Santa Rosa", "Berkeley" ],
);

$\ = "\n";

print "<TABLE><CAPTION>Cities I Have Known</CAPTION>";
print Tr(th [qw(State Cities)]);
for $k (sort keys %hash) {
    print Tr(th($k), td( [ sort @{$hash{$k}} ] ));
}
print "</TABLE>";

That generates text like this:

<TABLE> <CAPTION>Cities I Have Known</CAPTION>
    <TR><TH>State</TH> <TH>Cities</TH></TR>
    <TR><TH>California</TH> <TD>Berkeley</TD> <TD>Santa Rosa</TD>
        <TD>Sebastopol</TD> </TR>
    <TR><TH>Colorado</TH> <TD>Boulder</TD> <TD>Denver</TD>
        <TD>Fort Collins</TD> </TR>
    <TR><TH>Texas</TH> <TD>Austin</TD> <TD>Fort Stockton</TD>
        <TD>Plano</TD> </TR>
    <TR><TH>Wisconsin</TH> <TD>Lake Geneva</TD> <TD>Madison</TD>
        <TD>Superior</TD></TR>
</TABLE>

You can produce the same output using one print statement, although it is slightly trickier because you have to use a map to create the implicit loop. This print statement produces output identical to that displayed previously:

print table
        caption('Cities I have Known'),
        Tr(th [qw(State Cities)]),
        map { Tr(th($_), td( [ sort @{$hash{$_}} ] )) } sort keys %hash;

This is especially useful for formatting the results of a database query, as in Example 19-3 (see Chapter 14 for more on databases).

Example 19-3. salcheck

  #!/usr/bin/perl
  # salcheck - check for salaries
  use DBI;
  use strict;
  use CGI qw(:standard :html3);

  my $limit = param("LIMIT");

  print header( ), start_html("Salary Query"),
        h1("Search"),
        start_form( ),
        p("Enter minimum salary", textfield("LIMIT")),
        submit( ),
        end_form( );

  if (defined $limit) {
      my $dbh = DBI->connect("dbi:mysql:somedb:server.host.dom:3306",
          "username", "password")
          or die "Connecting: $DBI::errstr";
      my $sth = $dbh->prepare("SELECT name,salary FROM employees
          WHERE salary > $limit")
          or die "Preparing: ", $dbh->errstr;
      $sth->execute
          or die "Executing: ", $sth->errstr;

      print h1("Results"), "<TABLE BORDER=1>";

      while (my $row = $sth->fetchrow_arrayref( )) {
             print Tr( td( $row ) );
      }

      print "</TABLE>\n";
      $sth->finish;
      $dbh->disconnect;
  }

  print end_html( );

19.6.4. See Also

The documentation for the standard CGI module; Recipe 14.9

Previous | Home | Next
19.5. Executing Commands Without Shell Escapes | Book Index | 19.7. Redirecting to a Different Location
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.7. Redirecting to a Different Location

19.7.1. Problem

You need to tell the client's browser to look elsewhere for a page.

19.7.2. Solution

Instead of a normal header, just issue a location redirect and exit. Don't forget the extra newline at the end of the header.

$url = "http://www.perl.com/CPAN/";
print "Location: $url\n\n";
exit;

19.7.3. Discussion

Sometimes your CGI program doesn't need to generate the document on its own. It only needs to tell the client at the other end to fetch a different document instead. In that case, the HTTP header needs to include this directive as a Location line followed by the URL you want to send them to. Make sure to use an absolute URL, not a relative one.

The direct and literal solution given in the Solution is usually sufficient, but if you already have the CGI module loaded, use the redirect function. You might use this code for building and setting a cookie, as shown in Example 19-4.

Example 19-4. oreobounce

  #!/usr/bin/perl -w
  # oreobounce - set a cookie and redirect the browser
  use CGI qw(:cgi);
  use strict;

  my $oreo = cookie( -NAME    => 'filling',
                     -VALUE   => "vanilla crème",
                     -EXPIRES => '+3M',    # M for month, m for minute
                     -DOMAIN  => '.perl.com');

  my $whither  = "http://somewhere.perl.com/nonesuch.html";

  print redirect( -URL     => $whither,
                  -COOKIE  => $oreo);

That would produce:

Status: 302 Moved Temporarily
Set-Cookie: filling=vanilla%20cr%E4me; domain=.perl.com;
    expires=Tue, 21-Jul-1998 11:58:55 GMT
Date: Tue, 21 Apr 1998 11:55:55 GMT
Location: http://somewhere.perl.com/nonesuch.html
Content-Type: text/html
<<blank line here>>

Example 19-5 is a complete program that looks at the client browser name and redirects it to a page in Eric Raymond's edition of the Jargon File that talks about the user's browser. It's also a nice example of a different approach to building a switch statement in Perl (see Recipe 10.17).

Example 19-5. os_snipe

  #!/usr/bin/perl
  # os_snipe - redirect to a Jargon File entry about current OS
  $dir = 'http://www.wins.uva.nl/%7Emes/jargon';
  for ($ENV{HTTP_USER_AGENT}) {
      $page  =    /Mac/            && 'm/Macintrash.html'
               || /Win(dows )?NT/  && 'e/evilandrude.html'
               || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html'
               || /Linux/          && 'l/Linux.html'
               || /HP-UX/          && 'h/HP-SUX.html'
               || /SunOS/          && 's/ScumOS.html'
               ||                     'a/AppendixB.html';
  }
  print "Location: $dir/$page\n\n";

The os_snipe program uses dynamic redirection because you don't always send every user to the same place. If you did, it would usually make more sense to arrange for a static redirect line in the server's configuration file, since that would be more efficient than running a CGI script for each redirection.

Telling the client's browser that you don't plan to produce any output is not the same as redirecting nowhere:

use CGI qw(:standard);
print header( -STATUS => '204 No response' );

That produces this:

Status: 204 No response
Content-Type: text/html
<<blank line here>>

Use this, for instance, when the user submits a form request but you don't want their page to change or even update.

It may seem silly to provide a content type and then no content, but that's what the module does. If you were hand-coding this, the content type wouldn't be required, but the blank line still would be.

#!/bin/sh

cat <<EOCAT
Status: 204 No response

EOCAT

19.7.4. See Also

The documentation for the standard CGI module

Previous | Home | Next
19.6. Formatting Lists and Tables with HTML Shortcuts | Book Index | 19.8. Debugging the Raw HTTP Exchange
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.8. Debugging the Raw HTTP Exchange

19.8.1. Problem

Your CGI script is misbehaving strangely with your browser, and you suspect something in the HTTP header is missing. You want to find out exactly what your browser is sending to the server in the HTTP header.

19.8.2. Solution

Create your own fake web server and point your browser at it, as shown in Example 19-6.

Example 19-6. dummyhttpd

  #!/usr/bin/perl -w
  # dummyhttpd - start an HTTP daemon and print what the client sends

  use strict;
  use LWP 5.32;  # minimal good version
  use HTTP::Daemon;

  my $server = HTTP::Daemon->new(Timeout => 60, LocalPort => 8989);
  print "Please contact me at: <URL:", $server->url, ">\n";

  while (my $client = $server->accept) {
    CONNECTION:
      while (my $answer = $client->get_request) {
          print $answer->as_string;
          $client->autoflush;
    RESPONSE:
          while (<STDIN>) {
              last RESPONSE   if $_ eq ".\n";
              last CONNECTION if $_ eq "..\n";
              print $client $_;
          }
          print "\nEOF\n";
      }
      print "CLOSE: ", $client->reason, "\n";
      $client->close;
      undef $client;
  }

19.8.3. Discussion

It's hard to keep track of which versions of all browsers still have which bugs. The fake server program can save you days of head scratching, because sometimes a misbehaving browser doesn't send the server the right thing. Historically, we have seen aberrant browsers lose their cookies, mis-escape a URL, send the wrong status line, and other blunders even less obvious.

The fake server is best run on the same machine as the real server. That way your browser still sends any cookies destined for that domain. Then instead of pointing your browser at:

http://somewhere.com/cgi-bin/whatever

use the alternate port given in the new constructor in the Solution. You don't need to be the superuser to run the server if you use the alternate port.

http://somewhere.com:8989/cgi-bin/whatever

If you convince yourself that the client is behaving properly but wonder about the server, it's easiest to use the telnet program to manually talk to the remote server.

% telnet www.perl.com 80
GET /bogotic HTTP/1.0
<<blank line here>>
HTTP/1.1 404 File Not Found
Date: Tue, 21 Apr 1998 11:25:43 GMT
Server: Apache/1.2.4
Connection: close
Content-Type: text/html

<HTML><HEAD>
<TITLE>404 File Not Found </TITLE>
</HEAD><BODY>
<H1>File Not Found</H1>
The requested URL /bogotic was not found on this server.<P>
</BODY></HTML>

If you have LWP installed on your system, you can use the GET alias for the lwp-request program. This will follow any redirection chains, which can shed light on your problem. For example:

% GET -esuSU http://mox.perl.com/perl/bogotic
GET http://language.perl.com/bogotic
Host: mox.perl.com
User-Agent: lwp-request/1.32

GET http://mox.perl.com/perl/bogotic --> 302 Moved Temporarily
GET http://www.perl.com/perl/bogotic --> 302 Moved Temporarily
GET http://language.perl.com/bogotic --> 404 File Not Found
Connection: close
Date: Tue, 21 Apr 1998 11:29:03 GMT
Server: Apache/1.2.4
Content-Type: text/html
Client-Date: Tue, 21 Apr 1998 12:29:01 GMT
Client-Peer: 208.201.239.47:80
Title: Broken perl.com Links

<HTML>
<HEAD><TITLE>An Error Occurred</TITLE></HEAD>
<BODY>
<H1>An Error Occurred</h1>
404 File Not Found
</BODY>
</HTML>

19.8.4. See Also

The documentation for the standard CGI module; Recipe 19.9; lwp-request(1)

Previous | Home | Next
19.7. Redirecting to a Different Location | Book Index | 19.9. Managing Cookies
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.9. Managing Cookies

19.9.1. Problem

You want to get or set a cookie to help manage sessions or user preferences.

19.9.2. Solution

Using CGI.pm, retrieve an existing cookie like this:

$preference_value = cookie("preference name");

To prepare a cookie, do this:

$packed_cookie = cookie( -NAME    => "preference name",
                         -VALUE   => "whatever you'd like",
                         -EXPIRES => "+2y");

To save a cookie back to the client browser, you must include it in the HTTP header, probably using either the header or redirect functions:

print header(-COOKIE => $packed_cookie);

19.9.3. Discussion

Cookies store information on the client's browser. If you're using Netscape under Unix, you can inspect your own ~/.netscape/cookies file, although this doesn't show your current cookies. It holds only those cookies present when you last exited the browser. Think of them as per-application user preferences or a way to help with transactions. Benefits of cookies are that they can be shared between several different programs on your server, and they persist even across browser invocations.

However, cookies can be used for dubious purposes like traffic analysis and click tracing. This makes some folks very nervous about who is collecting their personal data and what use will be made of their page viewing habits. Cookies don't travel well, either. If you use a browser at home or in someone else's office, it won't have the cookies from the browser at your office. For this reason, do not expect every browser to accept the cookies you give it. As if that weren't bad enough, browsers can't guarantee they'll keep cookies around forever. Here's an excerpt from the HTTP State Management Mechanism RFC (number 2109):

Because user agents have finite space in which to store cookies, they may also discard older cookies to make space for newer ones, using, for example, a least-recently-used algorithm, along with constraints on the maximum number of cookies that each origin server may set.

While in theory a browser can delete cookies at any time, a browser that freely did so with session cookies or with recently used longer-term cookies would quite annoy its users.

Due to their unreliability, you should probably not place too much faith in cookies. Use them for simple, stateful transactions, and avoid traffic analysis for reasons of privacy.

Example 19-7 is a complete program that remembers the user's last choice.

Example 19-7. ic_cookies

  #!/usr/bin/perl -w
  # ic_cookies - sample CGI script that uses a cookie
  use CGI qw(:standard);

  use strict;

  my $cookname = "favorite ice cream";
  my $favorite = param("flavor");
  my $tasty    = cookie($cookname) || 'mint';

  unless ($favorite) {
      print header( ), start_html("Ice Cookies"), h1("Hello Ice Cream"),
            hr( ), start_form( ),
              p("Please select a flavor: ", textfield("flavor",$tasty)),
                end_form( ), hr( );
      exit;
  }

  my $cookie = cookie(
                  -NAME    => $cookname,
                  -VALUE   => $favorite,
                  -EXPIRES => "+2y",
              );

  print header(-COOKIE => $cookie),
        start_html("Ice Cookies, #2"),
        h1("Hello Ice Cream"),
        p("You chose as your favorite flavor `$favorite'.");

A more extensible approach is to send a single cookie containing a unique semi-random session identifier (such as sprintf "%x-%x-%x", time( ), $$, int rand 0x10000) and use that to map to a file (or database record) on the server that maintains any state you associate with that session. Just be sure that accessing that file or record doesn't create a race condition, as described in Recipe 19.4. Also be sure to occasionally purge old session files on the server, and gracefully cope with session cookies that no longer exist on the server. There are already Perl modules for intelligently implementing just this kind of server-side data, such as CGI::Session.

19.9.4. See Also

The documentation for the standard CGI module; the documentation for the CGI::Session module; Recipe 19.4; RFC 2109

Previous | Home | Next
19.8. Debugging the Raw HTTP Exchange | Book Index | 19.10. Creating Sticky Widgets
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.10. Creating Sticky Widgets

19.10.1. Problem

You want form fields to default to the last values submitted. For instance, you want a search form like Google (http://www.google.com/) where the keywords you searched for appear in the search dialog above the results.

19.10.2. Solution

Use CGI.pm's HTML shortcuts to create your form, which automatically provides previous values as defaults:

print textfield("SEARCH");          # previous SEARCH value is the default

19.10.3. Discussion

Example 19-8 is a simple script for producing the list of users currently logged in.

Example 19-8. who.cgi

  #!/usr/bin/perl -wT
  # who.cgi - run who(1) on a user and format the results nicely

  $ENV{IFS}='';
  $ENV{PATH}='/bin:/usr/bin';

  use CGI qw(:standard);

  # print search form
  print header( ), start_html("Query Users"), h1("Search");
  print start_form( ), p("Which user?", textfield("WHO")); submit( ), end_form( );

  # print results of the query if we have someone to look for
  $name = param("WHO");
  if ($name) {
      print h1("Results");
      $html = '';

      # call who and build up text of response
      foreach (`who`) {
          next unless /^$name\s/o;            # only lines matching $name
          s/&/&amp;/g;                        # escape HTML
          s/</&lt;/g;
          s/>/&gt;/g;
          $html .= $_;
      }
      # nice message if we didn't find anyone by that name
      $html = $html || "$name is not logged in";

      print pre($html);
  }

  print end_html( );

The call to textfield generates HTML for a text entry field whose parameter name is WHO. After printing the form, we check whether we were called with a value for the WHO parameter. If so, we try to find lines in the output from who for that user.

19.10.4. See Also

The documentation for the standard CGI module; Recipe 19.4; Recipe 19.6

Previous | Home | Next
19.9. Managing Cookies | Book Index | 19.11. Writing a Multiscreen CGI Script
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.11. Writing a Multiscreen CGI Script

19.11.1. Problem

You want a single CGI script that can return several different pages to the browser. For instance, you want a single script for administering a database of products. The script will be called to display the form to add a product, to process the add-product form, to display a list of products to delete, to process the delete-product form, to display a list of product to edit, to display a form of the product's attributes for the user to change, and to process the edit-product form. You can use these multiscreen CGI scripts to form an elementary shopping-cart application.

19.11.2. Solution

Use a hidden field to encode the current screen.

19.11.3. Discussion

It is easy to generate sticky hidden fields with the CGI module. The hidden function returns HTML for a hidden widget and uses the widget's current value if you pass hidden only the widget name:

use CGI qw(:standard);
print hidden("bacon");

To determine which page ("display product list", "display all items in shopping cart", "confirm order") to display, use another hidden field. We'll call this one .State so it won't conflict with any field we might have called State (for instance, in credit card billing information). To let the user move from page to page, use submit buttons that set .State to the name of the page to go to. For instance, to make a button to take the user to the "Checkout" page, use:

print submit(-NAME => ".State", -VALUE => "Checkout");

We wrap this in a function to make it easier to type:

sub to_page { return submit( -NAME => ".State", -VALUE => shift ) }

To decide what code to display, check the .State parameter:

$page = param(".State") || "Default";

Put the code to generate each page in separate subroutines. You could decide which subroutine to call with a long if ... elsif ... elsif:

if ($page eq "Default") {
    front_page( );
} elsif ($page eq "Checkout") {
    checkout( );
} else {
    no_such_page( );         # when we get a .State that doesn't exist
}

This is tedious and clumsy. Instead use a hash that maps a page name to a subroutine. This is another strategy for implementing a C-style switch statement in Perl:

%States = (
    'Default'     => \&front_page,
    'Shirt'       => \&shirt,
    'Sweater'     => \&sweater,
    'Checkout'    => \&checkout,
    'Card'        => \&credit_card,
    'Order'       => \&order,
    'Cancel'      => \&front_page,
);

if ($States{$page}) {
    $States{$page}->( );   # call the correct subroutine
} else {
    no_such_page( );
}

Each page will have some persistent widgets. For instance, the page that lets the user order t-shirts will want the number of t-shirts to persist even when the user continues and orders shoes as well. We do this by calling the page-generating subroutines with a parameter that lets them know whether they're the active page. If they're not the active page, they should only send back hidden fields for any persistent data:

while (($state, $sub) = each %States) {
    $sub->( $page eq $state );
}

The eq comparison returns true if the page is the current page, false otherwise. The page-generating subroutine then looks like this:

sub t_shirt {
    my $active = shift;

    unless ($active) {
        print hidden("size"), hidden("color");
        return;
    }

    print p("You want to buy a t-shirt?");
    print p("Size: ", popup_menu('size', [ qw(XL L M S XS) ]));
    print p("Color:", popup_menu('color', [ qw(Black White) ]));

    print p( to_page("Shoes"), to_page("Checkout") );
}

Because the subroutines all generate HTML, we have to print the HTTP header and start the HTML document and form before we call the subroutines. This lets us print a standard header and footer for all pages. Here, we assume we have subroutines standard_header and standard_footer for printing headers and footers:

print header("Program Title"), start_html( );
print standard_header( ), begin_form( );
while (($state, $sub) = each %States) {
    $sub->( $page eq $state );
}
print standard_footer( ), end_form( ), end_html( );

Don't make the mistake of encoding prices in the forms. Calculate prices based on the values of the hidden widgets, and sanity-check the information where you can. For example, compare against known products to make sure they're not trying to order a burgundy XXXXXXL t-shirt. You can identify items by any string, whether it's a text string like "sweater_xl_plain" that's a key to a hash of prices, or whether you want to use a product "SKU" number that you look up in an external database.

Using hidden data is more robust than using cookies, because you can't rely on the browser supporting or accepting cookies. A full explanation is in Recipe 19.9. On the other hand, using hidden data means that every link the user follows must be a form submit button instead of a normal hyperlink.

We show a simple shopping cart application as the program chemiserie at the end of this chapter.

19.11.4. See Also

The documentation for the standard CGI module.

Previous | Home | Next
19.10. Creating Sticky Widgets | Book Index | 19.12. Saving a Form to a File or Mail Pipe
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.12. Saving a Form to a File or Mail Pipe

19.12.1. Problem

Your CGI script needs to save or mail the entire form contents to a file.

19.12.2. Solution

To store a form, use the CGI module's save_parameters function or save method, which take a filehandle argument. You can save to a file:

# first open and exclusively lock the file
open(FH, ">>/tmp/formlog")              or die "can't append to formlog: $!";
flock(FH, 2)                            or die "can't flock formlog: $!";

# either using the procedural interface
use CGI qw(:standard);
save_parameters(*FH);                   # with CGI::save

# or using the object interface
use CGI;
$query = CGI->new( );
$query->save(*FH);

close(FH)                               or die "can't close formlog: $!";

or save to a pipe, such as one connected to a mailer process:

use CGI qw(:standard);
open(MAIL, "|/usr/lib/sendmail -oi -t") or die "can't fork sendmail: $!";
print MAIL <<EOF;
From: $0 (your cgi script)
To: hisname\@hishost.com
Subject: mailed form submission

EOF
save_parameters(*MAIL);
close(MAIL)                             or die "can't close sendmail: $!";

19.12.3. Discussion

Sometimes all you want to do with form data is to save it for later use. The save_parameters function and save method in CGI.pm write form parameters to an open filehandle. That filehandle can be attached to an open file (preferably one opened in append mode and locked, as in the Solution), or to a pipe whose other end is a mail program.

File entries are stored one per line as variable=value pairs, with any funny characters URL-escaped. Each record is separated by a line with a single equals sign. These are typically read back by invoking the CGI->new method with a filehandle argument that manages all of the unescaping automatically, as described later.

If you want to add extra information to your query before you save it, the param function (or method, if you're using the object-oriented interface) can take more than one argument, setting the value(s) of a form parameter. For example, here's how to save a time stamp and the entire environment:

param("_timestamp", scalar localtime);
param("_environs", %ENV);

Once you have the forms in a file, process them by using the object interface.

To load a query object from a filehandle, call the new method with a filehandle argument. Each time you do this, it returns a complete form. When end of file is hit, the returned form has no parameters. The following code demonstrates this approach. It keeps a running total of all "items request" parameters, but only if the form was not submitted from a perl.com site. Remember, we added the _environs and _timestamp parameters when we wrote the file.

use CGI;
open(FORMS, "< /tmp/formlog")       or die "can't read formlog: $!";
flock(FORMS, 1)                     or die "can't lock formlog: $!";
while ($query = CGI->new(*FORMS)) {
    last unless $query->param( );     # means end of file
    %his_env = $query->param('_environs');
    $count  += $query->param('items requested')
                unless $his_env{REMOTE_HOST} =~ /(^|\.)perl\.com$/
}
print "Total orders: $count\n";

File ownership and access permissions are an issue here, as for any files created by CGI scripts.

19.12.4. See Also

Recipe 18.3; Recipe 19.3

Previous | Home | Next
19.11. Writing a Multiscreen CGI Script | Book Index | 19.13. Program: chemiserie
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


19.13. Program: chemiserie

The CGI script in Example 19-9 lets people order t-shirts and sweaters over the Web, using techniques described in Recipe 19.11. Its output isn't elegant or beautiful, but illustrating the multiscreen technique in a short program was challenging enough without trying to make it pretty as well.

The shirt and sweater subroutines check their widget values. If the user somehow submits an invalid color or size, the value is reset to the first in the list of allowable colors or sizes.

Example 19-9. chemiserie

  #!/usr/bin/perl -w
  # chemiserie - simple CGI shopping for shirts and sweaters

  use strict;
  use CGI qw(:standard);
  use CGI::Carp qw(fatalsToBrowser);

  my %States;                    # state table mapping pages to functions
  my $Current_Screen;            # the current screen
  croak "This CGI works only over HTTPS"
    if $ENV{'SERVER_PORT'} && !$ENV{'HTTPS'};
  # Since we deal with sensitive data like credit card numbers
  # Hash of pages and functions.

  %States = (
      'Default'     => \&front_page,
      'Shirt'       => \&shirt,
      'Sweater'     => \&sweater,
      'Checkout'    => \&checkout,
      'Card'        => \&credit_card,
      'Order'       => \&order,
      'Cancel'      => \&front_page,
  );

  $Current_Screen = param(".State") || "Default";
  die "No screen for $Current_Screen" unless $States{$Current_Screen};

  # Generate the current page.

  standard_header( );

  while (my($screen_name, $function) = each %States) {
      $function->($screen_name eq $Current_Screen);
  }
  standard_footer( );
  exit;

  ################################
  # header, footer, menu functions
  ################################

  sub standard_header {
      print header( ), start_html(-Title => "Shirts", -BGCOLOR=>"White");
      print start_form( ); # start_multipart_form( ) if file upload
  }

  sub standard_footer { print end_form( ), end_html( ) }

  sub shop_menu {
      print p(defaults("Empty My Shopping Cart"),
          to_page("Shirt"),
          to_page("Sweater"),
          to_page("Checkout"));
  }

  #############################
  # subroutines for each screen
  #############################

  # The default page.
  sub front_page {
      my $active = shift;
      return unless $active;

      print "<H1>Hi!</H1>\n";
      print "Welcome to our Shirt Shop!  Please make your selection from ";
      print "the menu below.\n";

      shop_menu( );
  }

  # Page to order a shirt from.
  sub shirt {
      my $active = shift;
      my @sizes  = qw(XL L M S);
      my @colors = qw(Black White);

      my ($size, $color, $count) =
        (param("shirt_size"), param("shirt_color"), param("shirt_count"));

      # sanity check
      if ($count) {
          $color = $colors[0] unless grep { $_ eq $color } @colors;
          $size  = $sizes[0]  unless grep { $_ eq $size  } @sizes;
          param("shirt_color", $color);
          param("shirt_size",  $size);
      }

      unless ($active) {
          print hidden("shirt_size")  if $size;
          print hidden("shirt_color") if $color;
          print hidden("shirt_count") if $count;
          return;
      }

      print h1("T-Shirt");
      print p("What a shirt!  This baby is decked out with all the options.",
          "It comes with full luxury interior, cotton trim, and a collar",
          "to make your eyes water!  Unit price: \$33.00");

      print h2("Options");
      print p("How Many?", textfield("shirt_count"));
      print p("Size?",  popup_menu("shirt_size",  \@sizes ),
          "Color?", popup_menu("shirt_color", \@colors));

      shop_menu( );
  }

  # Page to order a sweater from.
  sub sweater {
      my $active = shift;
      my @sizes  = qw(XL L M);
      my @colors = qw(Chartreuse Puce Lavender);

      my ($size, $color, $count) =
        (param("sweater_size"), param("sweater_color"), param("sweater_count"));

      # sanity check
      if ($count) {
          $color = $colors[0] unless grep { $_ eq $color } @colors;
          $size  = $sizes[0]  unless grep { $_ eq $size  } @sizes;
          param("sweater_color", $color);
          param("sweater_size",  $size);
      }

      unless ($active) {
          print hidden("sweater_size")  if $size;
          print hidden("sweater_color") if $color;
          print hidden("sweater_count") if $count;
          return;
      }

      print h1("Sweater");
      print p("Nothing implies preppy elegance more than this fine",
          "sweater.  Made by peasant workers from black market silk,",
          "it slides onto your lean form and cries out \"Take me,",
          "for I am a god!\".  Unit price: \$49.99.");

      print h2("Options");
      print p("How Many?", textfield("sweater_count"));
      print p("Size?",  popup_menu("sweater_size",  \@sizes));
      print p("Color?", popup_menu("sweater_color", \@colors));

      shop_menu( );
  }

  # Page to display current order for confirmation.
  sub checkout {
      my $active = shift;

      return unless $active;

      print h1("Order Confirmation");
      print p("You ordered the following:");
      print order_text( );
      print p("Is this right?  Select 'Card' to pay for the items",
          "or 'Shirt' or 'Sweater' to continue shopping.");
      print p(to_page("Card"),
          to_page("Shirt"),
          to_page("Sweater"));
  }

  # Page to gather credit-card information.
  sub credit_card {
      my $active = shift;
      my @widgets = qw(Name Address1 Address2 City Zip State Phone Card Expiry);

      unless ($active) {
          print map { hidden($_) } @widgets;
          return;
      }

      print pre(p("Name:          ", textfield("Name")),
                p("Address:       ", textfield("Address1")),
                p("               ", textfield("Address2")),
                p("City:          ", textfield("City")),
                p("Zip:           ", textfield("Zip")),
                p("State:         ", textfield("State")),
                p("Phone:         ", textfield("Phone")),
                p("Credit Card #: ", textfield("Card")),
                p("Expiry:        ", textfield("Expiry")));

      print p("Click on 'Order' to order the items.  Click on 'Cancel'
to return shopping.");

      print p(to_page("Order"), to_page("Cancel"));
  }

  # Page to complete an order.
  sub order {
      my $active = shift;

      unless ($active) {
          return;
      }

      # you'd check credit card values here

      print h1("Ordered!");
      print p("You have ordered the following toppings:");
      print order_text( );

      print p(defaults("Begin Again"));
  }

  # Returns HTML for the current order ("You have ordered ...")
  sub order_text {
      my $html = '';

      if (param("shirt_count")) {
          $html .= p("You have ordered ", param("shirt_count"),
                     " shirts of size ",  param("shirt_size"),
                     " and color ", param("shirt_color"), ".");
      }
      if (param("sweater_count")) {
          $html .= p("You have ordered ",  param("sweater_count"),
                     " sweaters of size ", param("sweater_size"),
                     " and color ", param("sweater_color"), ".");
      }
      $html = p("Nothing!") unless $html;
      $html .= p("For a total cost of ", calculate_price( ));
      return $html;
  }

  sub calculate_price {
      my $shirts   = param("shirt_count")   || 0;
      my $sweaters = param("sweater_count") || 0;
      return sprintf("\$%.2f", $shirts*33 + $sweaters * 49.99);
  }

  sub to_page { submit(-NAME => ".State", -VALUE => shift) }
Previous | Home | Next
19.12. Saving a Form to a File or Mail Pipe | Book Index | 20. Web Automation
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 20. Web Automation

Contents:

Introduction
Fetching a URL from a Perl Script
Automating Form Submission
Extracting URLs
Converting ASCII to HTML
Converting HTML to ASCII
Extracting or Removing HTML Tags
Finding Stale Links
Finding Fresh Links
Using Templates to Generate HTML
Mirroring Web Pages
Creating a Robot
Parsing a Web Server Log File
Processing Server Logs
Using Cookies
Fetching Password-Protected Pages
Fetching https:// Web Pages
Resuming an HTTP GET
Parsing HTML
Extracting Table Data
Program: htmlsub
Program: hrefsub

Robert Louis Stevenson, On some Technical Elements of Style in Literature (1885)

The web, then, or the pattern, a web at once sensuous and logical, an elegant and pregnant texture: that is style, that is the foundation of the art of literature.

20.0. Introduction

Chapter 19 concentrated on responding to browser requests and producing documents using CGI. This chapter approaches the Web from the other side: instead of responding to a browser, you pretend to be one, generating requests and processing returned documents. We make extensive use of modules to simplify this process because the intricate network protocols and document formats are tricky to get right. By letting existing modules handle the hard parts, you can concentrate on the interesting part—your own program.

The relevant modules can all be found under the following URL:

http://search.cpan.org/modlist/World_Wide_Web

There you'll find modules for computing credit card checksums, interacting with Netscape or Apache server APIs, processing image maps, validating HTML, and manipulating MIME. The largest and most important modules for this chapter, though, are found in the libwww-perl suite of modules, referred to collectively as LWP. Table 20-1 lists just a few modules included in LWP.

Table 20-1. LWP modules (continued)

Module name | Purpose
LWP::UserAgent | WWW user agent class
LWP::RobotUA | Develop robot applications
LWP::Protocol | Interface to various protocol schemes
LWP::Authen::Basic | Handle 401 and 407 responses
LWP::MediaTypes | MIME types configuration (text/html, etc.)
LWP::Debug | Debug logging module
LWP::Simple | Simple procedural interface for common functions
HTTP::Headers | MIME/RFC 822-style headers
HTTP::Message | HTTP-style message
HTTP::Request | HTTP request
HTTP::Response | HTTP response
HTTP::Daemon | HTTP server class
HTTP::Status | HTTP status code (200 OK, etc.)
HTTP::Date | Date-parsing module for HTTP date formats
HTTP::Negotiate | HTTP content negotiation calculation
WWW::RobotRules | Parse robots.txt files
File::Listing | Parse directory listings

The HTTP:: and LWP:: modules request documents from a server. The LWP::Simple module offers an easy way to fetch a document. However, the module can't access individual components of the HTTP response. For these, use HTTP::Request, HTTP::Response, and LWP::UserAgent. We show both sets of modules in Recipe 20.1, Recipe 20.2, and Recipe 20.10.

Once distributed with LWP, but now in distributions of their own, are the HTML:: modules. These parse HTML. They provide the basis for Recipe 20.5, Recipe 20.4, Recipe 20.6, Recipe 20.3, Recipe 20.7, and the programs htmlsub and hrefsub.

Recipe 20.12 gives a regular expression to decode fields in your web server's log files and shows how to interpret the fields. We use this regular expression and the Logfile::Apache module in Recipe 20.13 to show two ways of summarizing data in web server log files.

For detailed guidance on the LWP modules, see Sean Burke's Perl & LWP (O'Reilly) This book expands on much of this chapter, picking up where recipes such as Recipe 20.5 on converting HTML to ASCII, Recipe 20.14 on fetching pages that use cookies, and Recipe 20.15 on fetching password-protected pages leave off.

Previous | Home | Next
19.13. Program: chemiserie | Book Index | 20.1. Fetching a URL from a Perl Script
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.1. Fetching a URL from a Perl Script

20.1.1. Problem

You have a URL whose contents you want to fetch from a script.

20.1.2. Solution

Use the get function from the CPAN module LWP::Simple, part of LWP.

use LWP::Simple;
$content = get($URL);

20.1.3. Discussion

The right library makes life easier, and the LWP modules are the right ones for this task. As you can see from the Solution, LWP makes this task a trivial one.

The get function from LWP::Simple returns undef on error, so check for errors this way:

use LWP::Simple;
unless (defined ($content = get $URL)) {
    die "could not get $URL\n";
}

When called that way, however, you can't determine the cause of the error. For this and other elaborate processing, you'll have to go beyond LWP::Simple.

Example 20-1 is a program that fetches a remote document. If it fails, it prints out the error status line. Otherwise, it prints out the document title and the number of bytes of content. We use three modules, two of which are from LWP.

LWP::UserAgent
This module creates a virtual browser. The object returned from the new constructor is used to make the actual request. We've set the name of our agent to "Schmozilla/v9.14 Platinum" just to give the remote webmaster browser-envy when they see it in their logs. This is useful on obnoxious web servers that needlessly consult the user agent string to decide whether to return a proper page or an infuriating "you need Internet Navigator v12 or later to view this site" cop-out.

HTTP::Response
This is the object type returned when the user agent actually runs the request. We check it for errors and contents.

URI::Heuristic
This curious little module uses Netscape-style guessing algorithms to expand partial URLs. For example:

Simple | Guess
perl | http://www.perl.com
www.oreilly.com | http://www.oreilly.com
ftp.funet.fi | ftp://ftp.funet.fi
/etc/passwd | file:/etc/passwd

Although the simple forms listed aren't legitimate URLs (their format is not in the URI specification), Netscape tries to guess the URLs they stand for. Because Netscape does it, most other browsers do, too.

The source is in Example 20-1.

Example 20-1. titlebytes

  #!/usr/bin/perl -w
  # titlebytes - find the title and size of documents
  use strict;
  use LWP::UserAgent;
  use HTTP::Response;
  use URI::Heuristic;
  my $raw_url = shift                      or die "usage: $0 url\n";
  my $url = URI::Heuristic::uf_urlstr($raw_url);
  $| = 1;                                  # to flush next line
  printf "%s =>\n\t", $url;
  # bogus user agent
  my $ua = LWP::UserAgent->new( );
  $ua->agent("Schmozilla/v9.14 Platinum"); # give it time, it'll get there
  # bogus referrer to perplex the log analyzers
  my $response = $ua->get($url, Referer => "http://wizard.yellowbrick.oz");
  if ($response->is_error( )) {
    printf " %s\n", $response->status_line;
  } else {
    my $content = $response->content( );
    my $bytes = length $content;
    my $count = ($content =~ tr/\n/\n/);
    printf "%s (%d lines, %d bytes)\n",
      $response->title( ) || "(no title)", $count, $bytes;
  }

When run, the program produces output like this:

% titlebytes http://www.tpj.com/
http://www.tpj.com/ =>
    The Perl Journal (109 lines, 4530 bytes)

Yes, "referer" is not how "referrer" should be spelled. The standards people got it wrong when they misspelled HTTP_REFERER. Please use double r's when referring to things in English.

The first argument to the get method is the URL, and subsequent pairs of arguments are headers and their values.

20.1.4. See Also

The documentation for the CPAN module LWP::Simple, and the lwpcook(1) and lwptut(1) manpages that came with LWP; the documentation for the modules LWP::UserAgent, HTTP::Response, and URI::Heuristic; Recipe 20.2 and Perl & LWP

Previous | Home | Next
20. Web Automation | Book Index | 20.2. Automating Form Submission
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.2. Automating Form Submission

20.2.1. Problem

You want to submit form values to a CGI script from your program. For example, you want to write a program that searches Amazon and notifies you when new books with a particular keyword in the title or new books by a particular author appear.

20.2.2. Solution

If you're submitting form values with GET, use the get method on an LWP::UserAgent object:

use LWP::Simple;
use URI::URL;

$url = url("http://www.amazon.com/exec/obidos/search-handle-url/index=books");
$url->query_form("field-author" => "Larry Wall"); # more params if needed
$page = get($url);

If you're using the POST method, create your own user agent and encode the content appropriately:

use LWP::UserAgent;

$ua = LWP::UserAgent->new( );
$resp = $ua->post("www.amazon.com/exec/obidos/search-handle-form",
                  { "url"            => "index-books",
                    "field-keywords" => "perl" });
$content = $resp->content;

20.2.3. Discussion

For simple operations, the procedural interface of the LWP::Simple module is sufficient. For fancier ones, the LWP::UserAgent module provides a virtual browser object, which you manipulate using method calls.

The format of a query string is:

field1=value1&field2=value2&field3=value3

In GET requests, this is encoded in the URL being requested:

script.cgi?field1=value1&field2=value2&field3=value3

Fields must still be properly escaped, so setting the arg form parameter to "this isn't <EASY> & <FUN>" would yield:

http://www.site.com/path/to/
        script.cgi?arg=%22this+isn%27t+%3CEASY%3E+%26+%3CFUN%3E%22

The query_form method called on a URL object correctly escapes the form values for you, or you could use the URI::Escape::uri_escape or CGI::escape_html functions on your own. In POST requests, the query string is in the body of the HTTP document sent to the CGI script.

You can use the LWP::Simple module to submit data in a GET request, but there is no corresponding LWP::Simple interface for POST requests. Instead, the $ua->post method creates and submits the request in one fell swoop.

If you need to go through a proxy, construct your user agent and tell it to use a proxy this way:

$ua->proxy('http' => 'http://proxy.myorg.com:8081');

If a proxy handles multiple protocols, pass an array reference as the first argument:

$ua->proxy(['http', 'ftp'] => 'http://proxy.myorg.com:8081');

That says that HTTP and FTP requests through this user agent should be routed through the proxy on port 8081 at proxy.myorg.com.

20.2.4. See Also

The documentation for the CPAN modules LWP::Simple, LWP::UserAgent, HTTP::Request::Common, URI::Escape, and URI::URL; Recipe 20.1; Perl & LWP

Previous | Home | Next
20.1. Fetching a URL from a Perl Script | Book Index | 20.3. Extracting URLs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.3. Extracting URLs

20.3.1. Problem

You want to extract all URLs from an HTML file. For example, you have downloaded a page that lists the MP3 files downloadable from some site. You want to extract those MP3s' URLS so you can filter the list and write a program to download the ones you want.

20.3.2. Solution

Use the HTML::LinkExtor module from CPAN:

use HTML::LinkExtor;

$parser = HTML::LinkExtor->new(undef, $base_url);
$parser->parse_file($filename);
@links = $parser->links;
foreach $linkarray (@links) {
    my @element = @$linkarray;
    my $elt_type = shift @element;                  # element type

    # possibly test whether this is an element we're interested in
    while (@element) {
        # extract the next attribute and its value
        my ($attr_name, $attr_value) = splice(@element, 0, 2);
        # ... do something with them ...
    }
}

20.3.3. Discussion

You can use HTML::LinkExtor in two different ways: either by calling links to get a list of all links in the document once it is completely parsed, or by passing a code reference in the first argument to new. The referenced function is called on each link as the document is parsed.

The links method clears the link list, so call it only once per parsed document. It returns a reference to an array of elements. Each element is itself an array reference with an HTML::Element object at the front followed by a list of attribute name and attribute value pairs. For instance, the HTML:

<A HREF="http://www.perl.com/">Home page</A>
<IMG SRC="images/big.gif" LOWSRC="images/big-lowres.gif">

would return a data structure like this:

[
  [ a,   href   => "http://www.perl.com/" ],
  [ img, src    => "images/big.gif",
         lowsrc => "images/big-lowres.gif" ]
]

Here's an example of how to use $elt_type and $attr_name to print out and anchor an image:

if ($elt_type eq 'a' && $attr_name eq 'href') {
    print "ANCHOR: $attr_value\n"
        if $attr_value->scheme =~ /http|ftp/;
}
if ($elt_type eq 'img' && $attr_name eq 'src') {
    print "IMAGE:  $attr_value\n";
}

To extract links only to MP3 files, you'd say:

foreach my $linkarray (@links) {
     my ($elt_type, %attrs) = @$linkarray;

     if ($elt_type eq 'a' && $attrs{'href'} =~ /\.mp3$/i) {
       # do something with $attr{'href'}, the URL of the mp3 file
     }
 }

Example 20-2 is a complete program that takes as its arguments a URL, such as file:///tmp/testing.html or http://www.ora.com/, and produces on standard output an alphabetically sorted list of unique URLs linked from that site.

Example 20-2. xurl

  #!/usr/bin/perl -w
  # xurl - extract unique, sorted list of links from URL
  use HTML::LinkExtor;
  use LWP::Simple;

  $base_url = shift;
  $parser = HTML::LinkExtor->new(undef, $base_url);
  $parser->parse(get($base_url))->eof;
  @links = $parser->links;
  foreach $linkarray (@links) {
      my @element  = @$linkarray;
      my $elt_type = shift @element;
      while (@element) {
          my ($attr_name , $attr_value) = splice(@element, 0, 2);
          $seen{$attr_value}++;
      }
  }
  for (sort keys %seen) { print $_, "\n" }

This program does have a limitation: if the get of $base_url involves a redirection, links resolve using the original URL instead of the URL after the redirection. To fix this, fetch the document with LWP::UserAgent and examine the response code to find out whether a redirection occurred. Once you know the post-redirection URL (if any), construct the HTML::LinkExtor object accordingly.

Here's an example of the run:

% xurl http://www.perl.com/CPAN
ftp://ftp@ftp.perl.com/CPAN/CPAN.html
http://language.perl.com/misc/CPAN.cgi
http://language.perl.com/misc/cpan_module
http://language.perl.com/misc/getcpan
http://www.perl.com/index.html
http://www.perl.com/gifs/lcb.xbm

In mail or Usenet messages, you may see URLs written as:

<URL:http://www.perl.com>

This is supposed to make it easy to pick URLs from messages:

@URLs = ($message =~ /<URL:(.*?)>/g);

20.3.4. See Also

The documentation for the CPAN modules LWP::Simple, HTML::LinkExtor, and HTML::Entities; Recipe 20.1

Previous | Home | Next
20.2. Automating Form Submission | Book Index | 20.4. Converting ASCII to HTML
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.4. Converting ASCII to HTML

20.4.1. Problem

You want to convert ASCII text to HTML. For example, you have mail you want to display intelligently on a web page.

20.4.2. Solution

Use the simple little encoding filter in Example 20-3.

Example 20-3. text2html

  #!/usr/bin/perl -w -p00
  # text2html - trivial html encoding of normal text
  # -p means apply this script to each record.
  # -00 mean that a record is now a paragraph

  use HTML::Entities;
  $_ = encode_entities($_, "\200-\377");

  if (/^\s/) {
      # Paragraphs beginning with whitespace are wrapped in <PRE>
      s{(.*)$}        {<PRE>\n$1</PRE>\n}s;           # indented verbatim
  } else {
      s{^(>.*)}       {$1<BR>}gm;                     # quoted text
      s{<URL:(.*?)>}    {<A HREF="$1">$1</A>}gs       # embedded URL  (good)
                      ||
      s{(http:\S+)}   {<A HREF="$1">$1</A>}gs;        # guessed URL   (bad)
      s{*(\S+)*}    {<STRONG>$1</STRONG>}g;           # this is *bold* here
      s{\b_(\S+)\_\b} {<EM>$1</EM>}g;                 # this is _italics_ here
      s{^}            {<P>\n};                        # add paragraph tag
  }

20.4.3. Discussion

Converting arbitrary plain text to HTML has no general solution because there are too many conflicting ways to represent formatting information. The more you know about the input, the better you can format it.

For example, if you knew that you would be fed a mail message, you could add this block to format the mail headers:

BEGIN {
    print "<TABLE>";
    $_ = encode_entities(scalar <>);
    s/\n\s+/ /g;  # continuation lines
    while ( /^(\S+?:)\s*(.*)$/gm ) {                # parse heading
        print "<TR><TH ALIGN='LEFT'>$1</TH><TD>$2</TD></TR>\n";
    }
    print "</TABLE><HR>";
}

The CPAN module HTML::TextToHTML has options for headers, footers, indentation, tables, and more.

20.4.4. See Also

The documentation for the CPAN modules HTML::Entities and HTML::TextToHTML

Previous | Home | Next
20.3. Extracting URLs | Book Index | 20.5. Converting HTML to ASCII
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.5. Converting HTML to ASCII

20.5.1. Problem

You want to convert an HTML file into formatted, plain ASCII. For example, you want to mail a web document to someone.

20.5.2. Solution

If you have an external formatter like lynx, call an external program:

$ascii = `lynx -dump $filename`;

If you want to do it within your program and don't care about the things that the HTML::FormatText formatter doesn't yet handle well (tables and frames):

use HTML::FormatText 3;
$ascii = HTML::FormatText->format_file(
  $filename,
  leftmargin => 0, rightmargin => 50
);

20.5.3. Discussion

These examples both assume the HTML is in a file. If your HTML is in a variable, you need to write it to a file for lynx to read. With HTML::FormatText, use the format_string( ) method:

use HTML::FormatText 3;
$ascii = HTML::FormatText->format_string(
  $filename,
  leftmargin => 0, rightmargin => 50
);

If you use Netscape, its "Save as" option with the type set to "Text" does the best job with tables.

20.5.4. See Also

The documentation for the CPAN modules HTML::TreeBuilder and HTML::FormatText; your system's lynx(1) manpage; Recipe 20.6

Previous | Home | Next
20.4. Converting ASCII to HTML | Book Index | 20.6. Extracting or Removing HTML Tags
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.6. Extracting or Removing HTML Tags

20.6.1. Problem

You want to remove HTML tags from a string, leaving just plain text. For example, you are indexing a document but don't want your index to show "words" like <B> and <body>.

20.6.2. Solution

The following oft-cited solution is simple but wrong on all but the most trivial HTML:

($plain_text = $html_text) =~ s/<[^>]*>//gs;     # WRONG

A correct but slower and slightly more complicated way is to use the technique from Recipe 20.5:

use HTML::FormatText 2;
$plain_text = HTML::FormatText->format_string($html_text);

20.6.3. Discussion

As with almost everything else in Perl, there is more than one way to do it. Each solution attempts to strike a balance between speed and flexibility. Occasionally you may find HTML that's simple enough that a trivial command-line call works:

% perl -pe 's/<[^>]*>//g' file

However, this breaks with files whose tags cross line boundaries, like this:

<IMG SRC = "foo.gif"
     ALT = "Flurp!">

So, you'll see people doing this instead:

% perl -0777 -pe 's/<[^>]*>//gs' file

or its scripted equivalent:

{
    local $/;               # temporary whole-file input mode
    $html = <FILE>;
    $html =~ s/<[^>]*>//gs;
}

But even that isn't good enough except for simplistic HTML without any interesting bits in it. This approach fails for the following examples of valid HTML (among many others):

<IMG SRC = "foo.gif" ALT = "A > B">

<!-- <A comment> -->

<script>if (a<b && a>c)</script>

<# Just data #>

<![INCLUDE CDATA [ >>>>>>>>>>>> ]]>

If HTML comments include other tags, those solutions would also break on text like this:

<!-- This section commented out.
    <B>You can't see me!</B>
-->

The only solution that works well here is to use the HTML parsing routines from CPAN. The second code snippet shown in the Solution demonstrates this better technique.

For more flexible parsing, subclass the HTML::Parser class and record only the text elements you see:

package MyParser;
use HTML::Parser;
use HTML::Entities qw(decode_entities);

@ISA = qw(HTML::Parser);

sub text {
    my($self, $text) = @_;
    print decode_entities($text);
}

package main;
MyParser->new->parse_file(*F);

If you're only interested in simple tags that don't contain others nested inside, you can often make do with an approach like the following, which extracts the title from a non-tricky HTML document:

($title) = ($html =~ m#<TITLE>\s*(.*?)\s*</TITLE>#is);

Again, the regex approach has its flaws, so a more complete solution using LWP to process the HTML is shown in Example 20-4.

Example 20-4. htitle

  #!/usr/bin/perl
  # htitle - get html title from URL
  use LWP;
  die "usage: $0 url ...\n" unless @ARGV;
  foreach $url (@ARGV) {
      $ua = LWP::UserAgent->new( );
      $res = $ua->get($url);
      print "$url: " if @ARGV > 1;
      if ($res->is_success) {
          print $res->title, "\n";
      } else {
          print $res->status_line, "\n";
      }
  }

Here's an output example:

% htitle http://www.ora.com
www.oreilly.com -- Welcome to O'Reilly & Associates!

% htitle http://www.perl.com/ http://www.perl.com/nullvoid
http://www.perl.com/: The www.perl.com Home Page
http://www.perl.com/nullvoid: 404 File Not Found

20.6.4. See Also

The documentation for the CPAN modules HTML::TreeBuilder, HTML::Parser, HTML::Entities, and LWP::UserAgent; Recipe 20.5

Previous | Home | Next
20.5. Converting HTML to ASCII | Book Index | 20.7. Finding Stale Links
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.7. Finding Stale Links

20.7.1. Problem

You want to check a document for invalid links.

20.7.2. Solution

Use the technique outlined in Recipe 20.3 to extract each link, and then use LWP::Simple's head function to make sure that link exists.

20.7.3. Discussion

Example 20-5 is an applied example of the link-extraction technique. Instead of just printing the name of the link, we call LWP::Simple's head function on it. The HEAD method fetches the remote document's metainformation without downloading the whole document. If it fails, the link is bad, so we print an appropriate message.

Because this program uses the get function from LWP::Simple, it is expecting a URL, not a filename. If you want to supply either, use the URI::Heuristic module described in Recipe 20.1.

Example 20-5. churl

  #!/usr/bin/perl -w
  # churl - check urls
  use HTML::LinkExtor;
  use LWP::Simple;
  $base_url = shift
      or die "usage: $0 <start_url>\n";
  $parser = HTML::LinkExtor->new(undef, $base_url);
  $html = get($base_url);
  die "Can't fetch $base_url" unless defined($html);
  $parser->parse($html);
  @links = $parser->links;
  print "$base_url: \n";
  foreach $linkarray (@links) {
      my @element  = @$linkarray;
      my $elt_type = shift @element;
      while (@element) {
          my ($attr_name , $attr_value) = splice(@element, 0, 2);
          if ($attr_value->scheme =~ /\b(ftp|https?|file)\b/) {
              print "  $attr_value: ", head($attr_value) ? "OK" : "BAD", "\n";
          }
      }
  }

Here's an example of a program run:

% churl http://www.wizards.com
http://www.wizards.com:
  FrontPage/FP_Color.gif:  OK
  FrontPage/FP_BW.gif:  BAD
  #FP_Map:  OK
  Games_Library/Welcome.html:  OK

This program has the same limitation as the HTML::LinkExtor program in Recipe 20.3.

20.7.4. See Also

The documentation for the CPAN modules HTML::LinkExtor, LWP::Simple, LWP::UserAgent, and HTTP::Response; Recipe 20.8

Previous | Home | Next
20.6. Extracting or Removing HTML Tags | Book Index | 20.8. Finding Fresh Links
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.8. Finding Fresh Links

20.8.1. Problem

Given a list of URLs, you want to determine which have been modified most recently. For example, you want to sort your bookmarks so those most recently updated are on the top.

20.8.2. Solution

The program in Example 20-6 reads URLs from standard input, rearranges them by date, and prints them to standard output with those dates prepended.

Example 20-6. surl

  #!/usr/bin/perl -w
  # surl - sort URLs by their last modification date
  use strict;
  use LWP::UserAgent;
  use HTTP::Request;
  use URI::URL qw(url);
  my %Date;
  my $ua = LWP::UserAgent->new( );
  while ( my $url = url(scalar <>) ) {
      my $ans;
      next unless $url->scheme =~ /^(file|https?)$/;
      $ans = $ua->head($url);
      if ($ans->is_success) {
          $Date{$url} = $ans->last_modified || 0;  # unknown
      } else {
          warn("$url: Error [", $ans->code, "] ", $ans->message, "!\n");
      }
  }
  foreach my $url ( sort { $Date{$b} <=> $Date{$a} } keys %Date ) {
      printf "%-25s %s\n", $Date{$url} ? (scalar localtime $Date{$url})
                                       : "<NONE SPECIFIED>", $url;
  }

20.8.3. Discussion

The surl script works more like a traditional filter program. It reads from standard input one URL per line. (Actually, it uses ARGV to read, which defaults to STDIN when @ARGV is empty.) The last-modified date on each URL is fetched by a HEAD request. That date is stored in a hash with the URL as key. Then a simple sort by value is run on the hash to reorder the URLs by date. On output, the internal date is converted into localtime format.

Here's an example of using the xurl program from the earlier recipe to extract the URLs, then running that program's output to feed into surl.

% xurl http://use.perl.org/~gnat/journal | surl | head
Mon Jan 13 22:58:16 2003  http://www.nanowrimo.org/
Sun Jan 12 19:29:00 2003  http://www.costik.com/gamespek.html
Sat Jan 11 20:57:03 2003  http://www.cpan.org/ports/index.html
Sat Jan 11 09:46:19 2003  http://jakarta.apache.org/gump/
Tue Jan  7 20:27:30 2003  http://use.perl.org/images/menu_gox.gif
Tue Jan  7 20:27:30 2003  http://use.perl.org/images/menu_bgo.gif
Tue Jan  7 20:27:30 2003  http://use.perl.org/images/menu_gxg.gif
Tue Jan  7 20:27:30 2003  http://use.perl.org/images/menu_ggx.gif
Tue Jan  7 20:27:30 2003  http://use.perl.org/images/menu_gxx.gif
Tue Jan  7 20:27:30 2003  http://use.perl.org/images/menu_gxo.gif

Having a variety of small programs that each do one thing and can be combined into more powerful constructs is the hallmark of good programming. You could even argue that xurl should work on files, and that some other program should actually fetch the URL's contents over the Web to feed into xurl, churl, or surl. That program would probably be called gurl, except that program already exists: the LWP module suite has a program called lwp-request with aliases HEAD, GET, and POST to run those operations from shell scripts.

20.8.4. See Also

The documentation for the CPAN modules LWP::UserAgent, HTTP::Request, and URI::URL; Recipe 20.7

Previous | Home | Next
20.7. Finding Stale Links | Book Index | 20.9. Using Templates to Generate HTML
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.9. Using Templates to Generate HTML

20.9.1. Problem

You want to store a parameterized template in an external file, read that template from your CGI script, and substitute your own variables for escapes embedded in the text. This separates your program from the static parts of the document.

20.9.2. Solution

To expand only variable references, use this template function:

sub template {
    my ($filename, $fillings) = @_;
    my $text;
    local $/;                    # slurp mode (undef)
    open(my $fh, "<", $filename) or return;
    $text = <$fh>;               # read whole file
    close($fh);                  # ignore retval
    # replace quoted words with value in %$fillings hash
    $text =~ s{ %% ( .*? ) %% }
              { exists( $fillings->{$1} )
                      ? $fillings->{$1}
                      : ""
              }gsex;
    return $text;
}

on a data file like this:

<!-- simple.template for internal template( ) function -->
<HTML><HEAD><TITLE>Report for %%username%%</TITLE></HEAD>
<BODY><H1>Report for %%username%%</H1>
%%username%% logged in %%count%% times, for a total of %%total%% minutes.

If you can guarantee the data file is secure from tampering, use the CPAN module Text::Template to expand full expressions. A data file for Text::Template looks like this:

<!-- fancy.template for Text::Template -->
<HTML><HEAD><TITLE>Report for {$user}</TITLE></HEAD>
<BODY><H1>Report for {$user}</H1>
{ lcfirst($user) } logged in {$count} times, for a total of
{ int($total / 60) } minutes.

For a complete templating solution, see the Template Toolkit's Template module This offers a scripting language and mod_perl integration, and is covered in Recipe 21.17.

20.9.3. Discussion

Parameterized output for your CGI scripts is a good idea for many reasons. Separating your program from its data lets other people (art directors, for instance) change the HTML but not the program. Even better, two programs can share the same template, so style changes in the template are immediately reflected in both programs' output.

For example, suppose you have the first template from the Solution stored in a file. Then your CGI program contains the definition of the template subroutine shown earlier and makes appropriate settings for variables $username, $count, and $total. You can fill in the template by simply using:

%fields = (
            username => $whats_his_name,
            count    => $login_count,
            total    => $minute_used,
);

print template("/home/httpd/templates/simple.template", \%fields);

The template file contains keywords surrounded by double percent symbols (%%KEYWORD%%). These keywords are looked up in the %$fillings hash whose reference was passed as the second argument to template. Example 20-7 is a more elaborate example using an SQL database.

Example 20-7. userrep1

  #!/usr/bin/perl -w
  # userrep1 - report duration of user logins using SQL database

  use DBI;
  use CGI qw(:standard);

  # template( ) defined as in the Solution section above

  $user = param("username")                   or die "No username";

  $dbh = DBI->connect("dbi:mysql:connections:mysql.domain.com",
      "connections", "seekritpassword")       or die "Couldn't connect\n";
  $sth = $dbh->prepare(<<"END_OF_SELECT")     or die "Couldn't prepare SQL";
      SELECT COUNT(duration),SUM(duration)
      FROM logins WHERE username='$user'
  END_OF_SELECT

  # this time the duration is assumed to be in seconds
  if (@row = $sth->fetchrow_array( )) {
      ($count, $seconds) = @row;
  } else {
      ($count, $seconds) = (0,0);
  }

  $sth->finish( );
  $dbh->disconnect;

  print header( );
  print template("report.tpl", {
      'username' => $user,
      'count'    => $count,
      'total'    => $total
  });

For a fancier, more flexible solution, look at the second template in the Solution section, which relies upon the CPAN module Text::Template. Contents of braces found within the template file are evaluated as Perl code. Ordinarily, these substitutions are just simple variables:

You owe: {$total}

but they can also include full expressions:

The average was {$count ?  ($total/$count) : 0}.

Example 20-8 is an example of using that template.

Example 20-8. userrep2

  #!/usr/bin/perl -w
  # userrep2 - report duration of user logins using SQL database

  use Text::Template;
  use DBI;
  use CGI qw(:standard);

  $tmpl = "/home/httpd/templates/fancy.template";
  $template = Text::Template->new(-type => "file", -source => $tmpl);
  $user = param("username")                   or die "No username";

  $dbh = DBI->connect("dbi:mysql:connections:mysql.domain.com",
      "connections", "secret passwd")         or die "Couldn't db connect\n";
  $sth = $dbh->prepare(<<"END_OF_SELECT")     or die "Couldn't prepare SQL";
      SELECT COUNT(duration),SUM(duration)
      FROM logins WHERE username='$user'
  END_OF_SELECT

  $sth->execute( )                             or die "Couldn't execute SQL";

  if (@row = $sth->fetchrow_array( )) {
      ($count, $total) = @row;
  } else {
      $count = $total = 0;
  }

  $sth->finish( );
  $dbh->disconnect;

  print header( );
  print $template->fill_in( );

But this approach raises security concerns. Anyone who can write to the template file can insert code that your program will run. See Recipe 8.17 for ways to lessen this danger.

20.9.4. See Also

The documentation for the CPAN modules Text::Template and Template; Recipe 8.16; Recipe 14.9

Previous | Home | Next
20.8. Finding Fresh Links | Book Index | 20.10. Mirroring Web Pages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.10. Mirroring Web Pages

20.10.1. Problem

You want a local copy of a web page kept up-to-date.

20.10.2. Solution

Use LWP::Simple's mirror function:

use LWP::Simple;
mirror($URL, $local_filename);

20.10.3. Discussion

Although closely related to the get function discussed in Recipe 20.1, the mirror function doesn't download the file unconditionally. It adds the If-Modified-Since header to the GET request it creates, so the server does not transfer the file unless the file has been updated.

The mirror function mirrors only a single page, not a full tree. To mirror a set of pages, use this recipe in conjunction with Recipe 20.3. A good solution to mirroring an entire directory hierarchy can be found in the w3mir program, also found on CPAN, and the wget program from ftp.gnu.org.

Be careful! It's possible (and easy) to write programs that run amok and begin downloading all web pages on the net. This is not only poor etiquette, it's also an infinite task, since some pages are dynamically generated. It could also get you into trouble with someone who doesn't want their pages downloaded en masse.

20.10.4. See Also

The documentation for the CPAN module LWP::Simple; the HTTP specification at http://www.w3.org/pub/WWW/Protocols/HTTP/

Previous | Home | Next
20.9. Using Templates to Generate HTML | Book Index | 20.11. Creating a Robot
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.11. Creating a Robot

20.11.1. Problem

You want to create a script that navigates the Web on its own (i.e., a robot), and you'd like to respect the remote sites' wishes.

20.11.2. Solution

Instead of writing your robot with LWP::UserAgent, use LWP::RobotUA instead:

use LWP::RobotUA;
$ua = LWP::RobotUA->new('websnuffler/0.1', 'me@wherever.com');

20.11.3. Discussion

To avoid marauding robots and web crawlers hammering their servers, sites are encouraged to create a file with access rules called robots.txt. If you're fetching only one document, this is no big deal, but if your script fetches many documents from the same server, you could easily exhaust that site's bandwidth.

When writing scripts to run around the Web, it's important to be a good net citizen: don't request documents from the same server too often, and heed the advisory access rules in their robots.txt file.

The easiest way to handle this is to use the LWP::RobotUA module instead of LWP::UserAgent to create agents. This agent automatically knows to fetch data slowly when calling the same server repeatedly. It also checks each site's robots.txt file to see whether you're trying to grab a file that is off-limits. If you do, you'll get a response like this:

403 (Forbidden) Forbidden by robots.txt

Here's an example robots.txt file, fetched using the GET program that comes with the LWP module suite:

% GET http://www.webtechniques.com/robots.txt
User-agent: *
     Disallow: /stats
     Disallow: /db
     Disallow: /logs
     Disallow: /store
     Disallow: /forms
     Disallow: /gifs
     Disallow: /wais-src
     Disallow: /scripts
     Disallow: /config

A more interesting and extensive example is at http://www.cnn.com/robots.txt. This file is so big, they even keep it under RCS control!

% GET http://www.cnn.com/robots.txt | head
# robots, scram
# $I d : robots.txt,v 1.2 1998/03/10 18:27:01 mreed Exp $
User-agent: *
Disallow: /
User-agent:     Mozilla/3.01 (hotwired-test/0.1)
Disallow:   /cgi-bin
Disallow:   /TRANSCRIPTS
Disallow:   /development

20.11.4. See Also

The documentation for the CPAN module LWP::RobotUA(3); http://info.webcrawler.com/mak/projects/robots/robots.html for a description of how well-behaved robots act

Previous | Home | Next
20.10. Mirroring Web Pages | Book Index | 20.12. Parsing a Web Server Log File
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.12. Parsing a Web Server Log File

20.12.1. Problem

You want to extract selected information from a web server log file.

20.12.2. Solution

Pull apart the log file as follows:

while (<LOGFILE>) {
  my ($client, $identuser, $authuser, $date, $time, $tz, $method,
      $url, $protocol, $status, $bytes) =
  /^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] "(\S+) (.*?) (\S+)"
      (\S+) (\S+)$/;
  # ...
}

20.12.3. Discussion

This regular expression pulls apart entries in Common Log Format, an informal standard that most web servers adhere to. The fields are listed in Table 20-1.

Table 20-2. Common Log Format fields

Field | Meaning
client | IP address or hostname of browser's machine
identuser | If IDENT (RFC 1413) was used, what it returned
authuser | If username/password authentication was used, whom they logged in as
date | Date of request (e.g., 01/Mar/1997)
time | Time of request (e.g., 12:55:36)
tz | Time zone (e.g., -0700)
method | Method of request (e.g., GET, POST, or PUT)
url | URL in request (e.g., /~user/index.html)
protocol | HTTP/1.0 or HTTP/1.1
status | Returned status (200 is okay, 500 is server error)
bytes | Number of bytes returned (could be "-" for errors, redirects, and other non-document transfers)

Other formats include the referrer and agent information. The pattern needs only minor changes to work with other log file formats. Beware that spaces in the URL field are not escaped, so we can't use \S* to extract the URL. .* would cause the regex to match the entire string and then backtrack until it could satisfy the rest of the pattern. We use .*? and anchor the pattern to the end of the string with $ to make the regular expression engine initially match nothing but then add characters until the entire pattern is satisfied.

20.12.4. See Also

The CLF spec at http://www.w3.org/Daemon/User/Config/Logging.html

Previous | Home | Next
20.11. Creating a Robot | Book Index | 20.13. Processing Server Logs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.13. Processing Server Logs

20.13.1. Problem

You need to summarize your server logs, but you don't have a customizable program to do it.

20.13.2. Solution

Parse the error log yourself with regular expressions, or use the Logfile modules from CPAN.

20.13.3. Discussion

Example 20-9 is a sample report generator for an Apache weblog.

Example 20-9. sumwww

  #!/usr/bin/perl -w
  # sumwww - summarize web server log activity

  $lastdate = "";
  daily_logs( );
  summary( );
  exit;

  # read CLF files and tally hits from the host and to the URL
  sub daily_logs {
      while (<>) {
          ($type, $what) = /"(GET|POST)\s+(\S+?) \S+"/ or next;
          ($host, undef, undef, $datetime) = split;
          ($bytes) = /\s(\d+)\s*$/ or next;
          ($date)  = ($datetime =~ /\[([^:]*)/);
          $posts  += ($type eq POST);
          $home++ if m, / ,;
          if ($date ne $lastdate) {
              if ($lastdate) { write_report( )     }
              else           { $lastdate = $date  }
          }
          $count++;
          $hosts{$host}++;
          $what{$what}++;
          $bytesum += $bytes;
      }
      write_report( ) if $count;
  }

  # use *typeglob aliasing of global variables for cheap copy
  sub summary  {
      $lastdate = "Grand Total";
      *count   = *sumcount;
      *bytesum = *bytesumsum;
      *hosts   = *allhosts;
      *posts   = *allposts;
      *what    = *allwhat;
      *home    = *allhome;
      write;
  }

  # display the tallies of hosts and URLs, using formats
  sub write_report {
      write;

      # add to summary data
      $lastdate    = $date;
      $sumcount   += $count;
      $bytesumsum += $bytesum;
      $allposts   += $posts;
      $allhome    += $home;

      # reset daily data
      $posts = $count = $bytesum = $home = 0;
      @allwhat{keys %what}   = keys %what;
      @allhosts{keys %hosts} = keys %hosts;
      %hosts = %what = ( );
  }

  format STDOUT_TOP =
  @|||||||||| @|||||| @||||||| @||||||| @|||||| @|||||| @|||||||||||||
  "Date",     "Hosts", "Accesses", "Unidocs", "POST", "Home", "Bytes"
  ----------- ------- -------- -------- ------- ------- --------------
  .

  format STDOUT =
  @>>>>>>>>>> @>>>>>> @>>>>>>> @>>>>>>> @>>>>>> @>>>>>> @>>>>>>>>>>>>>
  $lastdate,  scalar(keys %hosts),
              $count, scalar(keys %what),
                               $posts,  $home,   $bytesum
  .

Here's sample output from that program:

    Date      Hosts  Accesses Unidocs   POST    Home       Bytes
----------- ------- -------- -------- ------- ------- --------------
19/May/1998     353     6447     3074     352      51       16058246
20/May/1998    1938    23868     4288     972     350       61879643
21/May/1998    1775    27872     6596    1064     376       64613798
22/May/1998    1680    21402     4467     735     285       52437374
23/May/1998    1128    21260     4944     592     186       55623059
Grand Total    6050   100849    10090    3715    1248      250612120

Use the Logfile::Apache module from CPAN, shown in Example 20-10, to write a similar, but less specific, program. This module is distributed with other Logfile modules in a single Logfile distribution (Logfile-0.115.tar.gz at the time of this writing).

Example 20-10. aprept

  #!/usr/bin/perl -w
  # aprept - report on Apache logs

  use Logfile::Apache;

  $l = Logfile::Apache->new(
      File  => "-",                   # STDIN
      Group => [ Domain, File ]);

  $l->report(Group => Domain, Sort => Records);
  $l->report(Group => File,   List => [Bytes,Records]);

The new constructor reads a log file and builds indices internally. Supply a filename with the parameter named File and the fields to index in the Group parameter. The possible fields are Date (date request), Hour (time of day the request was received), File (file requested), User (username parsed from request), Host (hostname requesting the document), and Domain (Host translated into "France", "Germany", etc.).

To produce a report on STDOUT, call the report method. Give the index to use with the Group parameter, and optionally say how to sort (Records is by number of hits, Bytes by number of bytes transferred) or how to break it down further (by number of bytes or number of records).

Here's some sample output:

Domain                  Records
= == == == == == == == == == == == == == == ==
US Commercial        222 38.47%
US Educational       115 19.93%
Network               93 16.12%
Unresolved            54  9.36%
Australia             48  8.32%
Canada                20  3.47%
Mexico                 8  1.39%
United Kingdom         6  1.04%

File                               Bytes          Records
= == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
/                           13008  0.89%         6  1.04%
/cgi-bin/MxScreen           11870  0.81%         2  0.35%
/cgi-bin/pickcards          39431  2.70%        48  8.32%
/deckmaster                143793  9.83%        21  3.64%
/deckmaster/admin           54447  3.72%         3  0.52%

20.13.4. See Also

The documentation for the CPAN module Logfile::Apache; perlform(1) and Chapter 7 of Programming Perl

Previous | Home | Next
20.12. Parsing a Web Server Log File | Book Index | 20.14. Using Cookies
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.14. Using Cookies

20.14.1. Problem

You want to fetch web pages, but the server is using cookies to track you. For example, some sites use a cookie to remember that you've authenticated. If you don't send the right cookie, you'll never get past the login screen.

20.14.2. Solution

Let LWP::UserAgent handle cookies for you. You can enable cookies for just this program run with:

$ua->cookie_jar({  });

Or instead store cookies in a file between invocations with:

$ua->cookie_jar({ file => "$ENV{HOME}/.cookies" });

20.14.3. Discussion

The default behavior of LWP::UserAgent is never to send a Cookie: header, even when the server offers cookies in a response. To keep track of cookies LWP::UserAgent receives and send them when appropriate, provide the user agent object with a special "cookie jar" object to hold the cookies: an HTTP::Cookies object.

Pass the cookie_jar method either an HTTP::Cookies object to use that object as the cookie jar, or else a hash reference whose contents go into a new HTTP::Cookies object.

Without parameters, an HTTP::Cookies object keeps cookies in memory, so they're no longer available once your program exits. The file parameter in the cookie_jar method call specifies a filename to use for initializing the cookie jar and for saving updated or new cookies. This is how you give cookies a shelf life beyond a single run of your program.

To disable cookies, call cookie_jar with no parameters:

$ua->cookie_jar( );

20.14.4. See Also

The documentation for the CPAN modules LWP::UserAgent and HTTP::Cookie

Previous | Home | Next
20.13. Processing Server Logs | Book Index | 20.15. Fetching Password-Protected Pages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.15. Fetching Password-Protected Pages

20.15.1. Problem

You want to use LWP to fetch web pages or submit forms, but the web server requires authentication.

20.15.2. Solution

Set the username and password for a particular realm with the user agent's credentials method:

$ua->credentials('http://www.perlcabal.com/cabal_only/',
                 'Secret Perl Cabal Files',
                 'username' => 'password');

20.15.3. Discussion

To access pages protected by basic authentication, a browser must supply the username and password for the realm of the authentication. The realm is just a string that identifies which username and password the user must supply. The credentials method tells the user agent to send the username and password for a particular realm.

A somewhat kludgey solution is to specify URLs with the username and password in them:

http://user:password@www.example.com/private/pages/

This is kludgey because links within the returned document do not have your username and password encoded in them. Solutions that rely entirely on URL-encoded usernames and passwords often quickly degenerate into code that wishes it had used credentials to begin with.

20.15.4. See Also

The documentation for the CPAN module LWP::UserAgent

Previous | Home | Next
20.14. Using Cookies | Book Index | 20.16. Fetching https:// Web Pages
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.16. Fetching https:// Web Pages

20.16.1. Problem

You want to work with a web server over a secure (SSL) connection. For example, you want to automate ordering supplies for your company from an online store, and the online store wisely protects its transactions with SSL.

20.16.2. Solution

Install Crypt::SSLeay and https: URLs automatically work with LWP. You do not need to reinstall LWP.

20.16.3. Discussion

When LWP sends a request to an https server, it checks whether there is a module installed to do SSL. The two modules that LWP can use are, in order of preference, Crypt::SSLeay and IO::Socket::SSL. Of the two, Crypt::SSLeay is the more fully featured, but requires the OpenSSL libraries from http://www.openssl.org.

20.16.4. See Also

The documentation for the CPAN module Crypt::SSLeay; the README.SSL file in the libwww-perl distribution

Previous | Home | Next
20.15. Fetching Password-Protected Pages | Book Index | 20.17. Resuming an HTTP GET
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.17. Resuming an HTTP GET

20.17.1. Problem

You have part of a file and want to download the rest without refetching the content you already have. For example, your initial download was interrupted, so you want to complete it.

20.17.2. Solution

Use the HTTP 1.1 Range header in your GET request:

use LWP;
$have = length($file);
$response = $ua->get($URL,
                     'Range', "bytes=$have-");
# $response->content hold the rest of the file

20.17.3. Discussion

The Range header lets you specify which bytes to fetch. The 0th byte is the first in the file, so the range "bytes=0-" fetches the whole file.

You can also specify a range with two endpoints: "0-25", for example, fetches the first 26 bytes of the file. If you want to fetch an interior range, use "26-99".

Some servers don't support ranges, even though they claim to understand HTTP 1.1. In this case you'll be sent the whole file, not the range you asked for. To detect this, use HEAD to see the size of the file and then use a GET with a range to fetch the rest. If the content in the GET response is the same length as the original file, your range was ignored.

Here is the full list of ranges possible in the HTTP 1.1 specification:

[start]- | From start on (inclusive)
[start]-[end] | From start to end (inclusive)
-[ num] | The last num bytes
[ num] | From offset num on
0-0 | The first byte
-1 | The last byte

The HTTP specification also permits lists of ranges (e.g., "0-5,10-15,20-"). This returns a multipart response.

20.17.4. See Also

LWP documentation; the HTTP spec at http://www.ietf.org/rfc/rfc2616.txt

Previous | Home | Next
20.16. Fetching https:// Web Pages | Book Index | 20.18. Parsing HTML
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.18. Parsing HTML

20.18.1. Problem

You need to extract complex information from a web page or pages. For example, you want to extract news stories from web sites like CNN.com or news.bbc.co.uk.

20.18.2. Solution

Use regular expressions for data that's well identified:

# story is everything from <!-- story --> to <!-- /story -->
if ($html =~ m{<!-- story -->(.*?)<!-- /story -->}s) {
  my $story = $1;
  # ...
} else {
  warn "No story found in the page";
}

But for tables and data identifiable only by complex patterns of HTML, use a parser:

use HTML::TokeParser;

my $parser = HTML::TokeParser->new($FILENAME)
    or die "Can't open $FILENAME: $!\n";
while (my $token = $parser->get_token( )) {
    my $type = $token->[0];
    if    ($type eq 'S')  { ... }   # start tag
    elsif ($type eq 'E')  { ... }   # end tag
    elsif ($type eq 'T')  { ... }   # text
    elsif ($type eq 'C')  { ... }   # comment
    elsif ($type eq 'D')  { ... }   # declaration
    elsif ($type eq 'PI') { ... }   # processing instruction
    else { die "$type isn't a valid HTML token type" }
}

20.18.3. Discussion

Regular expressions are a convenient way to extract information from HTML. However, as the complexity of the HTML and the amount of information to be extracted go up, the maintainability of the regular expressions goes down. For a few well-defined fields, regular expressions are fine. For anything else, use a proper parser.

As an example of processing HTML with regular expressions, let's get the list of recent O'Reilly book releases. The list is found on http://www.oreilly.com/catalog/new.html, but there's also a navigation bar and a list of upcoming releases, so we can't simply extract all links.

The relevant HTML from the page looks like this:

<!--  New titles  -->
<h3>New Titles</h3>
<ul><li><a href="netwinformian/">.NET Windows Forms in a
Nutshell</a> <em>(March)</em></li><li><a href="actscrptpr/">
ActionScript for Flash MX Pocket Reference</a> <em>(March)</em>
</li><li><a href="abcancer/">After Breast Cancer</a> <em>(March)
...
<li><a href="samba2/">Using Samba, 2nd Edition</a> <em>(February)
</em></li><li><a href="vbscriptian2/">VBScript in a Nutshell, 2nd
Edition</a> <em>(March)</em></li><li><a href="tpj2/">Web, Graphics
& Perl/Tk</a> <em>(March)</em></li></ul></td>
<td valign="top">
<!--  Upcoming titles  -->

In fact, it's even uglier than this at the time of this writing—there are no newlines in the list of new books. It's all on one long line. Fortunately, this turns out to be comparatively simple to match. First we extract the HTML for the new titles, and then we extract the individual book links using the list anchors to anchor the regular expression:

($new_titles) = $html =~ m{<!--  New titles  -->(.*?)<!--  Upcoming titles  -->}s
  or die "Couldn't find new titles HTML";

while (m{<li>            # list item
         <a\ href="
         ([^\"]+)        # link to book = $1 = everything to next quote
         \">
         ([^<]+)         # book title = $2 = everything up to </a>
         </a>\ <em>\(
         ([^)]+)         # month = $3 = everything in the parentheses
        }gx) {
  printf("%-1010s%s\n", $3, $2); # could use $1 if we wanted
}

This produces output like:

March     .NET Windows Forms in a Nutshell
March     ActionScript for Flash MX Pocket Reference
March     After Breast Cancer
...
February  Using Samba, 2nd Edition
March     VBScript in a Nutshell, 2nd Edition
March     Web, Graphics & Perl/Tk

Regular expressions are difficult for this problem because they force you to work at the level of characters. The CPAN module HTML::TokeParser treats your HTML file as a series of HTML-y things: starting tags, closing tags, text, comments, etc. It decodes entities for you automatically, so you don't have to worry about converting &amp; back into & in your code.

The argument to the new constructor of HTML::TokeParser is either a filename, a filehandle (or any object providing a read method), or a reference to the HTML text to be parsed:

$parser = HTML::TokeParser->new("foo.html") or die;
$parser = HTML::TokeParser->new(*STDIN) or die;
$parser = HTML::TokeParser->new(\$html) or die;

Each time you invoke get_token on the parser object, you get back a reference to an array. The first element in the array is a string identifying what type of token you have: start tag, end tag, etc. The rest of the array varies depending on what type of token it is. The four types of tokens that most people are interested in are starting tags, ending tags, text, and comments.

Starting tags have four more values in the token array: the tag name (in lowercase), a reference to a hash of attributes (lowercased attribute name as key), a reference to an array containing lowercased attribute names in the order they appeared in the tag, and a string containing the opening tag as it appeared in the text of the document. Parsing the following HTML:

<IMg SRc="/perl6.jpg" ALT="Steroidal Camel">

creates a token like this:

[ 'S',
  'img',
  { "src" => "/perl6.jpg",
    "alt" => "Steroidal Camel"
  },
  [ "src", "alt" ],
  '<IMg SRc="/perl6.jpg" ALT="Steroidal Camel">'
]

Since ending tags have fewer possibilities than opening tags, it follows that their tokens have a simpler structure. A token for an end tag contains "E" (identifying it as an end tag), the lowercased name of the tag being closed (e.g., "body"), and the tag as it appeared in the source (e.g., "</BODY>").

A token for a text tag has three values: "T" (to identify it as a text token), the text, and a flag identifying whether you need to decode entities on it (decode only if this flag is false).

use HTML::Entities qw(decode_entities);

if ($token->[0] eq "T") {
    $text = $token->[1];
    decode_entities($text) unless $token->[2];
    # do something with $text
}

Even simpler, a comment token contains only "C" (to indicate that it is a comment) followed by the comment text.

For a detailed introduction to parsing with tokens, see Perl & LWP by Sean Burke (O'Reilly).

20.18.4. See Also

HTML::TokeParser documentation; LWP documentation; Perl & LWP

Previous | Home | Next
20.17. Resuming an HTTP GET | Book Index | 20.19. Extracting Table Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.19. Extracting Table Data

20.19.1. Problem

You have data in an HTML table, and you would like to turn that into a Perl data structure. For example, you want to monitor changes to an author's CPAN module list.

20.19.2. Solution

Use the HTML::TableContentParser module from CPAN:

use HTML::TableContentParser;

$tcp = HTML::TableContentParser->new;
$tables = $tcp->parse($HTML);

foreach $table (@$tables) {
  @headers = map { $_->{data} } @{ $table->{headers} };
  # attributes of table tag available as keys in hash
  $table_width = $table->{width};

  foreach $row (@{ $tables->{rows} }) {
    # attributes of tr tag available as keys in hash
    foreach $col (@{ $row->{cols} }) {
      # attributes of td tag available as keys in hash
      $data = $col->{data};
    }
  }
}

20.19.3. Discussion

The HTML::TableContentParser module converts all tables in the HTML document into a Perl data structure. As with HTML tables, there are three layers of nesting in the data structure: the table, the row, and the data in that row.

Each table, row, and data tag is represented as a hash reference. The hash keys correspond to attributes of the tag that defined that table, row, or cell. In addition, the value for a special key gives the contents of the table, row, or cell. In a table, the value for the rows key is a reference to an array of rows. In a row, the cols key points to an array of cells. In a cell, the data key holds the HTML contents of the data tag.

For example, take the following table:

<table width="100%" bgcolor="#ffffff">
  <tr>
    <td>Larry &amp; Gloria</td>
    <td>Mountain View</td>
    <td>California</td>
  </tr>
  <tr>
    <td><b>Tom</b></td>
    <td>Boulder</td>
    <td>Colorado</td>
  </tr>
  <tr>
    <td>Nathan &amp; Jenine</td>
    <td>Fort Collins</td>
    <td>Colorado</td>
  </tr>
</table>

The parse method returns this data structure:

[
  {
    'width' => '100%',
    'bgcolor' => '#ffffff',
    'rows' => [
               {
                'cells' => [
                            { 'data' => 'Larry &amp; Gloria' },
                            { 'data' => 'Mountain View' },
                            { 'data' => 'California' },
                           ],
                'data' => "\n      "
               },
               {
                'cells' => [
                            { 'data' => '<b>Tom</b>' },
                            { 'data' => 'Boulder' },
                            { 'data' => 'Colorado' },
                           ],
                'data' => "\n      "
               },
               {
                'cells' => [
                            { 'data' => 'Nathan &amp; Jenine' },
                            { 'data' => 'Fort Collins' },
                            { 'data' => 'Colorado' },
                           ],
                'data' => "\n      "
               }
              ]
  }
]

The data tags still contain tags and entities. If you don't want the tags and entities, remove them by hand using techniques from Recipe 20.6.

Example 20-11 fetches a particular CPAN author's page and displays in plain text the modules they own. You could use this as part of a system that notifies you when your favorite CPAN authors do something new.

Example 20-11. Dump modules for a particular CPAN author

  #!/usr/bin/perl -w
  # dump-cpan-modules-for-author - display modules a CPAN author owns
  use LWP::Simple;
  use URI;
  use HTML::TableContentParser;
  use HTML::Entities;
  use strict;
  our $URL = shift || 'http://search.cpan.org/author/TOMC/';
  my $tables = get_tables($URL);
  my $modules = $tables->[4];    # 5th table holds module data
  foreach my $r (@{ $modules->{rows} }) {
    my ($module_name, $module_link, $status, $description) =
        parse_module_row($r, $URL);
    print "$module_name <$module_link>\n\t$status\n\t$description\n\n";
  }
  sub get_tables {
    my $URL = shift;
    my $page = get($URL);
    my $tcp = new HTML::TableContentParser;
    return $tcp->parse($page);
  }
  sub parse_module_row {
    my ($row, $URL) = @_;
    my ($module_html, $module_link, $module_name, $status, $description);
    # extract cells
    $module_html = $row->{cells}[0]{data};  # link and name in HTML
    $status      = $row->{cells}[1]{data};  # status string and link
    $description = $row->{cells}[2]{data};  # description only
    $status =~ s{<.*?>}{  }g; # naive link removal, works on this simple HTML
    # separate module link and name from html
    ($module_link, $module_name) = $module_html =~ m{href="(.*?)".*?>(.*)<}i;
    $module_link = URI->new_abs($module_link, $URL); # resolve relative links
    # clean up entities and tags
    decode_entities($module_name);
    decode_entities($description);
    return ($module_name, $module_link, $status, $description);
  }

20.19.4. See Also

The documentation for the CPAN module HTML::TableContentParser; http://search.cpan.org

Previous | Home | Next
20.18. Parsing HTML | Book Index | 20.20. Program: htmlsub
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.20. Program: htmlsub

This program makes substitutions in HTML files so changes happen only in normal text. If you had the file scooby.html that contained:

<HTML><HEAD><TITLE>Hi!</TITLE></HEAD>
<BODY><H1>Welcome to Scooby World!</H1>
I have <A HREF="pictures.html">pictures</A> of the crazy dog
himself.  Here's one!<P>
<IMG SRC="scooby.jpg" ALT="Good doggy!"><P>
<BLINK>He's my hero!</BLINK>  I would like to meet him some day,
and get my picture taken with him.<P>
P.S. I am deathly ill.  <A HREF="shergold.html">Please send
cards</A>.
</BODY></HTML>

you could use htmlsub to change every occurrence of the word "picture" in the document text to read "photo". It prints the new document on STDOUT:

% htmlsub picture photo scooby.html
<HTML><HEAD><TITLE>Hi!</TITLE></HEAD>
<BODY><H1>Welcome to Scooby World!</H1>
I have <A HREF="pictures.html">photos</A> of the crazy dog
himself.  Here's one!<P>
<IMG SRC="scooby.jpg" ALT="Good doggy!"><P>
<BLINK>He's my hero!</BLINK>  I would like to meet him some day,
and get my photo taken with him.<P>
P.S. I am deathly ill.  <A HREF="shergold.html">Please send
cards</A>.
</BODY></HTML

The program is shown in Example 20-12.

Example 20-12. htmlsub

  #!/usr/bin/perl -w
  # htmlsub - make substitutions in normal text of HTML files
  # from Gisle Aas <gisle@aas.no>

  sub usage { die "Usage: $0 <from> <to> <file>...\n" }

  my $from = shift or usage;
  my $to   = shift or usage;
  usage unless @ARGV;

  # Build the HTML::Filter subclass to do the substituting.

  package MyFilter;
  use HTML::Filter;
  @ISA=qw(HTML::Filter);
  use HTML::Entities qw(decode_entities encode_entities);

  sub text
  {
     my $self = shift;
     my $text = decode_entities($_[0]);
     $text =~ s/\Q$from/$to/go;       # most important line
     $self->SUPER::text(encode_entities($text));
  }

  # Now use the class.

  package main;
  foreach (@ARGV) {
      MyFilter->new->parse_file($_);
  }
Previous | Home | Next
20.19. Extracting Table Data | Book Index | 20.21. Program: hrefsub
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


20.21. Program: hrefsub

hrefsub makes substitutions in HTML files, so changes apply only to text in <A HREF="..." > tags. For instance, if you had the scooby.html file from the previous recipe, and you've moved shergold.html to be cards.html, you need but say:

% hrefsub shergold.html cards.html scooby.html
<HTML><HEAD><TITLE>Hi!</TITLE></HEAD>
<BODY><H1>Welcome to Scooby World!</H1>
I have <A HREF="pictures.html">pictures</A> of the crazy dog
himself.  Here's one!<P>
<IMG SRC="scooby.jpg" ALT="Good doggy!"><P
<BLINK>He's my hero!</BLINK>  I would like to meet him some day,
and get my picture taken with him.<P>
P.S. I am deathly ill.  <a href="cards.html">Please send
cards</A>.
</BODY></HTML>

The HTML::Filter manual page has a BUGS section that says:

Comments in declarations are removed from the declarations and then inserted as separate comments after the declaration. If you turn on strict_comment( ), then comments with embedded "-\|-" are split into multiple comments.

This version of hrefsub (shown in Example 20-13) always lowercases the a and the attribute names within this tag when substitution occurs. If $foo is a multiword string, then the text given to MyFilter->text may be broken such that these words do not come together; i.e., the substitution does not work. There should probably be a new option to HTML::Parser to make it not return text until the whole segment has been seen. Also, some people may not be happy with having their 8-bit Latin-1 characters replaced by ugly entities, so htmlsub does that, too.

Example 20-13. hrefsub

  #!/usr/bin/perl -w
  # hrefsub - make substitutions in <A HREF="..."> fields of HTML files
  # from Gisle Aas <gisle@aas.no>

  sub usage { die "Usage: $0 <from> <to> <file>...\n" }

  my $from = shift or usage;
  my $to   = shift or usage;
  usage unless @ARGV;

  # The HTML::Filter subclass to do the substitution.

  package MyFilter;
  use HTML::Filter;
  @ISA=qw(HTML::Filter);
  use HTML::Entities qw(encode_entities);

  sub start {
     my($self, $tag, $attr, $attrseq, $orig) = @_;
     if ($tag eq 'a' && exists $attr->{href}) {
             if ($attr->{href} =~ s/\Q$from/$to/g) {
                 # must reconstruct the start tag based on $tag and $attr.
                 # wish we instead were told the extent of the 'href' value
                 # in $orig.
                 my $tmp = "<$tag";
                 for (@$attrseq) {
                     my $encoded = encode_entities($attr->{$_});
                     $tmp .= qq( $_="$encoded ");
                 }
                 $tmp .= ">";
                 $self->output($tmp);
                 return;
             }
     }
     $self->output($orig);
  }

  # Now use the class.

  package main;
  foreach (@ARGV) {
          MyFilter->new->parse_file($_);
  }
Previous | Home | Next
20.20. Program: htmlsub | Book Index | 21. mod_perl
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 21. mod_perl

Contents:

Introduction
Authenticating
Setting Cookies
Accessing Cookie Values
Redirecting the Browser
Interrogating Headers
Accessing Form Parameters
Receiving Uploaded Files
Speeding Up Database Access
Customizing Apache's Logging
Transparently Storing Information in URLs
Communicating Between mod_perl and PHP
Migrating from CGI to mod_perl
Sharing Information Between Handlers
Reloading Changed Modules
Benchmarking a mod_perl Application
Templating with HTML::Mason
Templating with Template Toolkit

James Poe

Speed is good only when wisdom leads the way.

21.0. Introduction

The mod_perl project (http://perl.apache.org/) integrates Perl with the Apache web server. That way, you can use Perl to configure Apache, manipulate and respond to requests, write to log files, and much more.

Most people begin using mod_perl to avoid the performance penalty of CGI. With CGI programs, the web server starts a separate process for each request. This can be a costly business on most operating systems, with lots of kernel data structures to copy and file I/O to load the new process's binary. If you serve a lot of requests, the operating system may be unable to keep up with the demand for new processes, leaving your web server (and indeed the whole machine) unresponsive.

By embedding the Perl interpreter within the Apache process, mod_perl removes the need to start a separate process to generate dynamic content. Indeed, the Apache::Registry and Apache::PerlRun modules provide a CGI environment within this persistent Perl interpreter (and form the basis of Recipe 21.12). This gives you an immediate performance boost over CGI (some report 10-100x performance) but doesn't take full advantage of the integration of Perl with Apache. For that, you need to write your own handlers.

21.0.1 Handlers

Because Apache has access to Perl at every step as it processes a request (and vice versa), you can write code (handlers) for every phase of a request-response cycle. There are 13 phases for which you can write handlers, and each phase has a default handler (so you don't have to install a handler for every phase).

You must do three things to install a handler for a specific phase: write the code, load the code into mod_perl, and tell mod_perl to call the code.

Handlers are simply subroutines. They're passed an Apache request object as the first argument, and through that object they can learn about the request, change Apache's information about the request, log errors, generate the response, and more. The return value of a handler determines whether the current phase continues with other handlers, the current phase ends successfully and execution proceeds to the next phase, or the current phase ends with an error. The return values are constants from the Apache::Constants module.

Although you can put your handler code in Apache's httpd.conf file, it's tidier to put your handlers in a module:

# in MyApp/Content.pm
package MyApp::Content;
use Apache::Constants ':common';

sub handler {
  my $r = shift;   # get the request object
  # ...
  return OK;       # for example
}

The subroutine can be named anything, but mod_perl makes it convenient to name every handler subroutine handler and to store different handlers in different modules. So MyApp::Content holds the handler for content generation, whereas MyApp::Logging might hold the handler that logs the request.

Because the Perl interpreter doesn't go away after each request, you have to program tidily if you want to use mod_perl. This means using lexical (my) variables instead of globals and closing filehandles when done with them (or using lexical filehandles). Unclosed filehandles remain open until the next time that process runs your CGI script (when they are reopened), and global variables whose values aren't undef ed will still have those values the next time that process runs your CGI script. The mod_perl_traps manpage that comes with mod_perl contains details of common mod_perl gotchas.

Load your handler module with a PerlModule directive in httpd.conf:

PerlModule MyApp::Content

This behaves like use in a Perl script: it loads and runs the module. Now that mod_perl has your code loaded, tell Apache to call it.

Directives used in httpd.conf to install handlers are:

PerlChildInitHandler
PerlPostReadRequestHandler
PerlInitHandler
PerlTransHandler
PerlHeaderParserHandler
PerlAccessHandler
PerlAuthenHandler
PerlAuthzHandler
PerlTypeHandler
PerlFixupHandler
PerlHandler
PerlLogHandler
PerlCleanupHandler
PerlChildExitHandler
PerlDispatchHandler
PerlRestartHandler

21.0.2 Apache Phases

Understanding the phases of a request-response transaction requires some knowledge of how Apache works and consequences of the various ways of configuring it. Apache keeps a pool of server processes (children) to handle requests in parallel. The ChildInit and ChildExit phases represent the start and end of a child process, respectively.

A PostReadRequestHandler handler is called as soon as Apache reads the request from the client. Apache extracts the URL and virtual host name, but doesn't yet attempt to figure out to which file the request maps. Therefore you can't install such a handler from a .htaccess file or the <Location>, <Directory>, or <Files> sections (or their *Match variants) of httpd.conf.

The translation phase is responsible for decoding the incoming request and guessing the file that corresponds to the URL. It is here that you could affect your own aliases and redirects. Once Apache knows the requested URL and the corresponding file to look for, it can check the <Location>, <Directory>, and <Files> sections of httpd.conf and begin looking for .htaccess files. Install a translation handler with PerlTransHandler.

The header parsing phase is misleadingly named. The headers have already been parsed and stored in the request object. The intent of this phase is to give you an opportunity to act based on the headers once you know the file that the URL corresponds to. You can examine headers within a PostReadRequestHandler, but the file isn't known yet. PostReadRequestHandler is per-server, whereas HeaderParserHandler can be per-location, per-file, or per-directory. This is the first phase of the request for which you can install a handler from any part of an httpd.conf or .htaccess file.

The PerlInitHandler is an alias for "the first available handler." Inside the <Location>, <Directory>, and <Files> sections of httpd.conf or anywhere in a .htaccess file, it is an alias for PerlHeaderParserHandler. Everywhere else, PerlInitHandler is an alias for PerlPostReadRequestHandler.

Next come the authorization and authentication phases. Add a PerlAccessHandler to limit access without requiring usernames and passwords. The authentication phase decodes the username and password from the request and decides whether the user is a valid one. The authorization phase determines whether the user is allowed to access the requested resource. Apache splits authentication from authorization so separate areas of your web site can share a user database but grant different types of access to each area. We talk about writing authentication and authorization handlers in Recipe 21.1. Most people stick to basic authentication, which trivially encodes the password as part of the request header. If you want more secure authentication, you can use digest authentication (which is tricky to implement in a way that works on all browsers) or simply encrypt the entire request by using https:// URLs to a secure server.

Once Apache has established that the client is allowed to access the requested document, the type determination phase occurs. Here Apache checks httpd.conf and .htaccess to see whether a specific content type has been forced on the requested file. If not, it uses the filename and its list of MIME types to figure out the file type. You can install a PerlTypeHandler to determine your own types.

Apache then offers you the chance to make any last-minute changes to the request via PerlFixupHandler. We use it in Recipe 21.10 to reinsert part of the URL removed earlier in a PerlHeaderParserHandler.

Then a handler must generate content. This is such a common use for mod_perl that the directive to install a content handler is simply PerlHandler. Once the content is generated, the logging phase begins, and it is normally here that the access log entry is written. You can, of course, write your own logging code to replace or augment Apache's (for example, logging to a database). This is the subject of Recipe 21.9.

The logging phase occurs before the connection to the client is closed. You can install code to run after the response is sent through a PerlCleanupHandler. Because a slow logging handler keeps the connection open (and thus the child waiting for more responses), a common mod_perl idiom is to use the cleanup phase for logging when the act of logging could take a long time (for example, when it involves a lot of I/O). Using the cleanup phase to actually clean up turns out to be rare.

That concludes the main phases and handlers. There are other handlers you can install. We don't use PerlDispatchHandler in this chapter, but it is an alternative mechanism to the system of registering handlers for every phase. If you register a PerlDispatchHandler, that handler is called for every phase. A PerlRestartHandler lets you run code whenever the Apache server restarts.

Much of the difficulty in getting started with mod_perl resides in learning how to do what you already knew how to do with CGI.pm. Cookies and form parameters are cumbersome to manipulate with pure mod_perl. This is why Recipe 21.2 and Recipe 21.3 discuss these seemingly simple topics.

21.0.3 More Documentation

There is a wealth of CPAN modules for mod_perl, and we don't hesitate to use them where possible. People often use an existing module until they run into limitations, then extend or replace the module. The convention is that mod_perl modules begin with Apache::; you can find a list of them at http://search.cpan.org/modlist/World_Wide_Web/Apache.

There are many good references for mod_perl developers. There's only one API reference book for mod_perl, Writing Apache Modules in Perl and C by Doug MacEachern and Lincoln Stein (O'Reilly). Although it was written for an early version of mod_perl, it is still highly relevant today.

If you're developing in mod_perl, get a copy of Practical mod_perl by Stas Bekman and Eric Cholet (O'Reilly). It's a rewrite and expansion of the online mod_perl guide (http://perl.apache.org/guide). Apache Pocket Reference, by Andrew Ford (O'Reilly), also includes a useful summary of mod_perl directives and methods.

To keep this chapter brief, we answer only initial questions about mod_perl. Deeper questions are answered by the mod_perl Developer's Cookbook by Geoffrey Young, Randy Kobes, and Paul Lindner (Sams). This is a great reference book, in a format similar to this book. The authors maintain a web site, http://www.modperlcookbook.org, with sample chapters, full source code, and further resources for mod_perl developers.

And, of course, mod_perl comes with its own documentation. Use the mod_perl(1) manpage for help with directives, and Apache(1) for help with the methods invokable on an Apache request object. Study the mod_perl_traps(1) manpage closely when you begin to migrate CGI scripts to mod_perl. If the documentation fails you, the mod_perl mailing list is a great way to get questions answered and keep up with the mod_perl world. See http://apache.perl.org for details on how to subscribe to the mailing list.

21.0.4. mod_perl 2

As this chapter goes to press, developers are putting the finishing touches on mod_perl 2.0. This is a major revision and rewrite of mod_perl for the Apache 2.0 system. The changes between 1.0 and 2.0 are too numerous to list: they affect configuration directives and Perl classes. There's an Apache::compat module that emulates the 1.0 handler API, but (as with using Apache::Registry to emulate CGI) there's a cost to the emulation. For maximum performance and flexibility, modify your modules to use the 2.0 API.

One of the biggest changes in 2.0 is the support for threads. Not only can you now have multiple Apache processes running at once, you can also have multiple threads of execution within each process. Some tasks are easier with threads, and you may see better performance with threads. However, it's trickier to write code—especially correct code—under threading.

For more on mod_perl 2.0, see http://perl.apache.org/docs/2.0/.

Previous | Home | Next
20.21. Program: hrefsub | Book Index | 21.1. Authenticating
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.1. Authenticating

21.1.1. Problem

You want to verify the username and password supplied by users who are authenticating themselves.

21.1.2. Solution

Get the password with $r->get_basic_auth_pw, and the username with $r->connection->user. Indicate success by returning OK. Indicate failure by calling $r->note_basic_auth_failure and returning AUTH_REQUIRED.

package Your::Authentication::Package;
use Apache::Constants ':common';

sub handler {
  my $r = shift;

  return OK unless $r->is_main;    # skip for subrequests

  my ($res, $sent_pw) = $r->get_basic_auth_pw;
  if ($res != OK) {
    $r->note_basic_auth_failure;
    return $res;
  }

  my $user = $r->user;

  # check username and password, setting $failed if they don't match

  if ($failed) {
    $r->note_basic_auth_failure;
    return AUTH_REQUIRED;
  }

  return OK;
}

Install the handler for a directory or set of files with:

# the realm
AuthName "Holiday Photos"
# next line shouldn't be changed
AuthType Basic
PerlAuthenHandler Your::Authentication::Package
require valid-user

21.1.3. Description

The realm is what the user sees when their browser prompts for a username and password. If you set the realm to "Holiday Photos", the user is prompted to "enter username and password for Holiday Photos". You need at least one require directive to trigger the call to the authentication handler.

When you invoke $r->get_basic_auth_pw, Apache processes any authentication information sent by the client. Therefore you can't call $r->user before you call $r->get_basic_auth_pw (well, you can, but you won't get anything back).

The call to $r->get_basic_auth_pw returns two values, a status code and a password. If the status is OK, the browser agreed to authenticate and provided information. If the status is DECLINED, either the area isn't protected by basic authentication or there's no AuthType specified in httpd.conf. If the status is SERVER_ERROR, there's no realm defined for this area. If the status is AUTH_REQUIRED, the browser mangled or omitted basic authentication. If you decide to return AUTH_REQUIRED, first call $r->note_basic_auth_failure to ensure Apache sends realm information to the browser.

The status code returned from $r->get_basic_auth_pw tells you whether the browser knows to authenticate these pages. When the browser sends no authentication information, you respond "no password, no access." To do this, note the authentication failure and return the AUTH_REQUIRED that $r->get_basic_auth_pw gave you.

We invoke $r->is_main to learn whether we're the main request. Apache often makes subrequests, and there's no point in doing the (potentially slow) authentication lookup for the subrequests. This doesn't result in less security, since if the authentication fails for the main request, the content handler isn't run. This avoids messy problems like recursion and multiple attempts to parse POST data.

21.1.4. See Also

The Apache.pm manpage; Writing Apache Modules with Perl and C; Recipe 13.3 in mod_perl Developer's Cookbook

Previous | Home | Next
21. mod_perl | Book Index | 21.2. Setting Cookies
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.2. Setting Cookies

21.2.1. Problem

You want to send a cookie to a client as part of a response.

21.2.2. Solution

Use the Apache::Cookie module from CPAN. From within your content handler, create a new cookie and attach it to the outgoing headers:

use Apache::Cookie;
$cookie = Apache::Cookie->new($r,
                              -name    => "cookie name",
                              -value   => "its value",
                              -expires => "+1d" );
$cookie->bake;

Don't forget to send the headers before generating content:

$r->send_http_header;

$r->print("...");

21.2.3. Description

The Apache::Cookie module builds a string that represents a cookie. To specify an expiration time for your cookie, use one of these formats:

+30s | 30 seconds from now
+10m | 10 minutes from now
+1h | 1 hour from now
-1d | 1 day ago
now | Now
+3M | Three months from now
+10y | Ten years from now
Thursday, 25-Apr-1999 00:30:31 GMT | Then

Call the bake method once you finish changing the cookie's parameters. This adds the cookie in its current state to mod_perl's planned response. If you change the cookie object after calling bake, changes won't be reflected in the header sent by mod_perl.

Apache maintains two sets of headers: error headers (which, confusingly, are always sent, regardless of whether the response code indicates an error) and ordinary headers (which are sent only for successful responses). Apache::Cookie sets the cookie in the error headers, so the cookie will be sent even for redirection responses.

The CGI::Cookie module is a slower pure Perl module with the same interface, which should be used only when the XS module Apache::Cookie is unavailable. To use it, substitute "CGI::Cookie" for "Apache::Cookie" in your code and remove the request object from the call to new. You can't call bake either—instead you must say:

$r->err_headers_out->add("Set-Cookie", $cookie->as_string);

We use err_headers_out rather than err_header_out because the former method allows for multiple values for a header, whereas the latter does not. That is, err_headers_out lets you build up a header over time by adding to its existing value before it's sent, as we might do here if we independently set three cookies. The err_header_out method always replaces, never augments.

21.2.4. See Also

The documentation for the CGI::Cookie and Apache::Cookie modules on CPAN; the Netscape cookie specification at http://wp.netscape.com/newsref/std/cookie_spec.html; Recipe 3.7 in mod_perl Developer's Cookbook; the Apache.pm manpage

Previous | Home | Next
21.1. Authenticating | Book Index | 21.3. Accessing Cookie Values
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.3. Accessing Cookie Values

21.3.1. Problem

You want to examine values client sent you in a cookie.

21.3.2. Solution

Use the CPAN module Apache::Cookie to populate a hash of cookie objects derived from the header sent by the client.

use Apache::Cookie;
$ac = Apache::Cookie->new($r);
%all_cookies = $ac->parse( );

Now each element of that hash is an object representing a single cookie:

$one_cookie = $all_cookies{COOKIE_NAME};

Interrogate the object to learn about that cookie's values:

$one_cookie->value( )     $one_cookie->name( )
$one_cookie->domain( )    $one_cookie->path( )
$one_cookie->expires( )   $one_cookie->secure( )

21.3.3. Discussion

To test whether a cookie was sent by the browser, use exists on the hash element:

unless (exists $all_cookies{chocolate}) {
  $r->header_out(Location => "http://www.site.com/login");
  return REDIRECT;
}

Don't simply test for truth:

unless ($all_cookies{chocolate}) {  # BAD

Valid cookie values include the empty string and 0, both false to Perl. See the Introduction to Chapter 1 for more.

The CGI::Cookie module is a pure Perl substitute for Apache::Cookie. Its strategy for getting a hash of cookies is slightly different from that of Apache::Cookies:

use CGI::Cookie;
%all_cookies = CGI::Cookie->fetch;

This hash of cookies works the same as the one by Apache::Cookie.

21.3.4. See Also

Writing Apache Modules with Perl and C; Recipe 20.14; Recipe 3.7 in mod_perl Developer's Cookbook; the Apache.pm manpage; documentation for the CGI::Cookie and Apache::Cookie modules from CPAN

Previous | Home | Next
21.2. Setting Cookies | Book Index | 21.4. Redirecting the Browser
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.4. Redirecting the Browser

21.4.1. Problem

You want to send a redirection back to the browser.

21.4.2. Solution

Use $r->header_out to set the Location header, then return REDIRECT:

$r->header_out(Location => "http://www.example.com/somewhere");
return REDIRECT;

21.4.3. Discussion

If you set the Location header and return REDIRECT, the client knows the address of the new page. This is called an external redirection, because the browser (external to the web server) handles the mechanics of requesting the new page. The URL should be a complete URL (with http, etc.), never a partial one.

An internal redirection is one where Apache sends back another page from the same site. The browser never knows that the page has changed, which means relative URLs from the page could be broken. Request an internal redirection with:

$r->internal_redirect($new_partial_url);
return OK;

Apache treats internal redirections almost as though they were new requests: each phase of the request cycle is called again for the new request. Unlike the Location header, internal_redirect takes only a partial URL. You should have no logic after calling internal_redirect other than to return OK.

21.4.4. See Also

Writing Apache Modules with Perl and C; Recipe 19.7; Recipe 8.5 in mod_perl Developer's Cookbook; the Apache.pm manpage

Previous | Home | Next
21.3. Accessing Cookie Values | Book Index | 21.5. Interrogating Headers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.5. Interrogating Headers

21.5.1. Problem

You want to learn the value of a header sent by the client.

21.5.2. Solution

Use the $r->header_in method:

$value = $r->header_in("Header-name");

21.5.3. Discussion

For example, suppose you want to discover the client's preferred language (as sent in the Accept-Language header).

if ($r->header_in("Accept-Language") !~ /\ben-US\b/i) {
  $r->print("No furriners!");
  return OK;
}

If you want to access more than one header, use the $r->headers_in method, which returns a list of key-value pairs of all clients' request headers, which are typically assigned to a hash:

%h = $r->headers_in;
if ($h{"Accept-Language"} !~ /\ben-US\b/i) {
  $r->print("No furriners!");
  return OK;
}

21.5.4. See Also

Writing Apache Modules with Perl and C; Recipe 3.4 in mod_perl Developer's Cookbook; the Apache.pm manpage

Previous | Home | Next
21.4. Redirecting the Browser | Book Index | 21.6. Accessing Form Parameters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.6. Accessing Form Parameters

21.6.1. Problem

You want the values for form fields submitted by the client.

21.6.2. Solution

To access the form's various parameters, use $r->content to access POSTed parameters and $r->args to access GET parameters encoded in the URL.

%post_parameters = $r->content;
%get_parameters  = $r->args;

You can call $r->content only once per request because the first call consumes all POSTed data.

The Apache::Request module from CPAN gives you a $r->param method to access specific parameters, regardless of whether they're from GET or POST:

use Apache::Request;

sub handler {
  my $r = Apache::Request->instance(shift);
  my @param_names = $r->param;
  my $value       = $r->param("username");  # single value
  my @values      = $r->param("toppings");  # multiple values

  # ...
}

21.6.3. Discussion

Processing form parameters without Apache::Request is problematic with values that occur multiple times. For example, a SELECT list with MULTIPLE enabled sends repeated entries for the same parameter name. Putting them into a hash preserves only one of those entries. Apache::Request solves this problem by accumulating multiply-submitted parameters in an array.

Form parameters POSTed to your handler can be a problem. The nature of Apache is that once one handler reads the POSTed data, another handler cannot come along later and reread that same information. So if you're going to process POSTed form parameters, you had better keep the decoded parameters around in case another handler wants to access them. The instance constructor handles this for us. When two handlers both call the instance constructor, the second handler gets back the Apache::Request object populated by the first, with form parameters already decoded.

The Apache::Request $r->param interface is based on the CGI module's parameter-parsing interface.

21.6.4. See Also

The Apache.pm manpage; Writing Apache Modules with Perl and C; Recipe 3.5 in mod_perl Developer's Cookbook; the Apache::Request manpage; Recipe 20.2

Previous | Home | Next
21.5. Interrogating Headers | Book Index | 21.7. Receiving Uploaded Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.7. Receiving Uploaded Files

21.7.1. Problem

You want a mod_perl handler that processes an uploaded file. For example, an image gallery might let the owner upload image files to the gallery.

21.7.2. Solution

Use the Apache::Request module's $r->upload and $r->param methods from within your handler (assuming the file upload field was called fileParam):

use Apache::Request;

my $TEN_MEG = 10 * 2 ** 20;       # 10 megabytes
sub handler {
  my $r = Apache::Request->new(shift,
                               DISABLE_UPLOADS => 0,
                               POST_MAX        => $TEN_MEG);
  $r->parse;
  my $uploaded_file = $r->upload("fileParam");
  my $filename      = $uploaded_file->filename;  # filename
  my $fh            = $uploaded_file->fh;        # filehandle
  my $size          = $uploaded_file->size;      # size in bytes
  my $info          = $uploaded_file->info;      # headers
  my $type          = $uploaded_file->type;      # Content-Type
  my $tempname      = $uploaded_file->tempname;  # temporary name
  # ...
}

21.7.3. Discussion

By default, Apache::Request won't process uploaded file data. This is because the file is read into memory, which might not be released to the operating system once the request is over. If you do enable uploaded files (by setting DISABLE_UPLOADS to false), set an upper limit on the size of the file you will accept. This prevents a malicious attacker from sending an infinite stream of data and exhausting your system's memory. The POST_MAX value (10M in the Solution code) is that maximum value, specified in bytes.

The $r->upload method processes the POSTed file data and returns an Apache::Upload object. This object has the following methods for accessing information on the uploaded file:

Method | Returns
fh | Filehandle from which to read the uploaded data
filename | Client-supplied filename
info | Apache::Table object containing HTTP headers sent by the client
name | The name of the form field this file was submitted as
size | Size of the uploaded file in bytes
tempname | Apache::Request's temporary filename
type | Client-supplied content-type of the uploaded file

You can invoke $r->upload only once per request, as the first invocation consumes all POSTed data. Sometimes multiple handlers need access to the same uploaded file but can't coordinate among themselves by designating one handler to read the file and save its name somewhere that the others can access. In this case, make each handler use the Apache::Request module's $r->instance method to get a request object instead of directly shifting it from the argument list:

use Apache::Request;
# ...
sub handler {
  my $r = Apache::Request->instance(shift,
                                    DISABLE_UPLOADS => 0,
                                    POST_MAX        => 10 * 2**20);
  # ...
}

21.7.4. See Also

Writing Apache Modules with Perl and C; Recipe 3.8 in mod_perl Developer's Cookbook; the Apache.pm manpage

Previous | Home | Next
21.6. Accessing Form Parameters | Book Index | 21.8. Speeding Up Database Access
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.8. Speeding Up Database Access

21.8.1. Problem

You use the DBI module within your mod_perl handler, but connecting to the database server for each request is slowing down your web application unacceptably.

21.8.2. Solution

To cache database connections transparently, load the Apache::DBI module before the DBI module:

use Apache::DBI;
use DBI;

21.8.3. Discussion

Many sites load the Apache::DBI module from the httpd.conf file to ensure it's loaded before anything else:

PerlModule Apache::DBI

The Apache::DBI module intercepts the DBI->connect method, returning a previously opened handle if the handle had the same connection parameters as the current request. The module also prevents $dbh->disconnect from closing connections. This lets you add use Apache::DBI to the start of an existing program without having to touch the rest of your code.

The Apache::DBI module uses an open database connection for each different database login in each Apache child process. You might need to change your database server's configuration to increase its maximum number of connections. With commercial database systems, you might even need to buy more client licenses.

This proliferation of connections can lead to situations where Apache::DBI isn't the best choice. For example, if each user of your site has his own database login, you'll need as many concurrent database connections as the number of active users multiplied by however many httpd processes are running worth of database connections, which might well be more than your server supports! Similarly, if you have many Apache child processes running concurrently, this could open more simultaneous database connections than your server supports.

One strategy for optimizing database access is to batch requests where possible. For example, if you're logging to a database, consider accumulating log information and updating the database only after every 5 or 10 hits.

Another strategy is to cache information in the client. For example, if you use a database to map user IDs to real names and that mapping never changes, then use a persistent hash in your handler to store real names for user IDs you've encountered—this avoids repeated database lookups on unchanging information. To prevent the hash from consuming too much memory, you might want to use the Tie::Cache::LRU module from CPAN or reimplement some other form of flushing the least-recently-used entries once the cache reaches a particular size.

21.8.4. See Also

Documentation for the Apache::DBI and Tie::Cache::LRU modules from CPAN; the Apache.pm manpage; Recipes 2.11 and 2.12 in mod_perl Developer's Cookbook

Previous | Home | Next
21.7. Receiving Uploaded Files | Book Index | 21.9. Customizing Apache's Logging
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.9. Customizing Apache's Logging

21.9.1. Problem

You want to change how Apache logs requests. For example, you want a database of URLs and access counts, or per-user logs.

21.9.2. Solution

Install a handler with PerlLogHandler:

PerlModule Apache::MyLogger
PerlLogHandler Apache::MyLogger

Within the handler, methods on the request object obtain information about the completed request. In the following code, $r is the request object and $c is the connection object obtained from $r->connection:

$r->the_request               GET /roast/chickens.html HTTP/1.1
$r->uri                       /roast/chickens.html
$r->header_in("User-Agent")   Mozilla-XXX
$r->header_in("Referer")      http://gargle.com/?search=h0t%20chix0rz
$r->bytes_sent                1648
$c->get_remote_host           208.201.239.56
$r->status_line               200 OK
$r->server_hostname           www.myserver.com

21.9.3. Discussion

Apache calls logging handlers after sending the response to the client. You have full access to the request and response parameters, such as client IP address, headers, status, and even content. Access this information through method calls on the request object.

You'll probably want to escape values before writing them to a text file because spaces, newlines, and quotes could spoil the formatting of the files. Two useful functions are:

# return string with newlines and double quotes escaped
sub escape {
  my $a = shift;
  $a =~ s/([\n\"])/sprintf("%%%02x", ord($1))/ge;
 return $a;
}

# return string with newlines, spaces, and double quotes escaped
sub escape_plus {
  my $a = shift;
  $a =~ s/([\n \"])/sprintf("%%%02x", ord($1))/ge;
  return $a;
}

Two prebuilt logging modules on CPAN are Apache::Traffic and Apache::DBILogger. Apache::Traffic lets you assign owner strings (either usernames, UIDs, or arbitrary strings) to your web server's directories in httpd.conf. Apache::Traffic builds a DBM database as Apache serves files from these directories. For each owner, the database records the number of hits their directories received each day and the total number of bytes transferred by those hits.

Apache::DBILogger is a more general interface, logging each hit as a new entry in a table. The table has columns for data such as which virtual host delivered the data, the client's IP address, the user agent (browser), the date, the number of bytes transferred, and so on. Using this table and suitable indexes and queries, you can answer almost any question about traffic on your web site.

Because the logging handler runs before Apache has closed the connection to the client, don't use this phase if you have a slow logging operation. Instead, install the handler with PerlCleanupHandler so that it runs after the connection is closed.

21.9.4. See Also

Writing Apache Modules with Perl and C; Chapter 16 of mod_perl Developer's Cookbook; documentation for the Apache::Traffic and Apache::DBILogger CPAN modules; the Apache.pm manpage

Previous | Home | Next
21.8. Speeding Up Database Access | Book Index | 21.10. Transparently Storing Information in URLs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.10. Transparently Storing Information in URLs

21.10.1. Problem

You want to store information like session IDs in the URL, but you don't want to figure out to how work around the extra data when constructing relative URLs.

21.10.2. Solution

Store the ID at the start of the URL:

http://www.example.com/ID/12345678/path/to/page

Extract it with a PerlTransHandler, and store it in a pnote, a hash entry accessible by other Perl handlers in this request:

sub trans {
  my $r = shift;

  my $uri = $r->uri( );
  if ($uri =~ s{/ID/(\d{8})}{  }) {
    $r->pnotes("ID", $1);
  }
  $r->uri($uri);
  return DECLINED;
}

Restore the URL in a PerlFixupHandler:

sub fixup {
  my $r = shift;

  my $id = $r->pnotes("ID");
  if ($id) {
    $r->uri("/ID/$id" . $r->uri);
  }
  return DECLINED;
}

Consult the pnote in the content handler:

use Apache::URI;

sub content {
  my $r = shift;
  my $id = $r->pnotes("ID");

  unless ($id) {
    join(('', map { int rand 10 } (1..8));
    my $uri = Apache::URI->parse($r);
    $uri->path("ID/$id" . $uri->path);
    $r->header_out(Location => $uri->unparse);
    return REDIRECT;
  }

  # use $id

  return OK;
}

21.10.3. Discussion

The client thinks your pages have a URL like http://www.example.com/ID/12345678/path/to/page.html. Your PerlTransHandler intercepts the incoming request and removes the /ID/12345678 part before Apache tries to translate the request into a file location. Just before your content handler runs, your PerlFixupHandler reinserts the ID. When your content handler calls $r->uri, it gets a URI that includes the ID.

We returned DECLINED from our PerlTransHandler and PerlFixupHandler to indicate that any other translation or fixup handlers that were installed should also be run. If we returned OK in the PerlTransHandler, Apache would not call any subsequent translation handlers. In PerlFixupHandlers, DECLINED and OK both mean a successful fixup, and that other fixup handlers should also run.

This solution doesn't look at the HTML emitted by your handler, so it only preserves the ID across relative links. If you give absolute links in your HTML (HREF="/elsewhere/"), then you'll lose the ID and have to re-establish it.

21.10.4. See Also

Recipe 12.3 of mod_perl Developer's Cookbook; Recipe 21.11

Previous | Home | Next
21.9. Customizing Apache's Logging | Book Index | 21.11. Communicating Between mod_perl and PHP
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.11. Communicating Between mod_perl and PHP

21.11.1. Problem

You want to build your site from both mod_perl and PHP. For example, you might want to use mod_perl for authentication and logging, while PHP generates the actual content. However, doing so means that Perl and PHP must share values; for example, so the PHP content handler knows which username successfully authenticated through mod_perl.

21.11.2. Solution

Use Apache notes. From Perl, you simply say:

$main = $r->main || $r;
$main->notes($KEY => $VALUE);
$VALUE = $main->notes($KEY);

From PHP, you say:

apache_note($KEY, $VALUE);
$VALUE = apache_note($KEY);

21.11.3. Discussion

A note is a string value attached to an Apache request. They're a perfect way to pass information between handlers, even when those handlers are written in different programming languages. Each request has a different set of notes, so from Perl always identify the main request and use it to communicate with PHP code.

Don't confuse the $r->notes method with the $r->pnotes method. The latter is only available to Perl modules.

21.11.4. See Also

Recipe 21.10

Previous | Home | Next
21.10. Transparently Storing Information in URLs | Book Index | 21.12. Migrating from CGI to mod_perl
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.12. Migrating from CGI to mod_perl

21.12.1. Problem

Your CGI script is called so often that your web server's performance deteriorates unacceptably. You'd like to use mod_perl to make things faster.

21.12.2. Solution

Use Apache::Registry or Apache::PerlRun:

PerlModule Apache::Registry
# or Apache::PerlRun
PerlModule CGI
PerlSendHeader On

Alias /perl/ /real/path/to/perl/scripts/
<Location /perl>
SetHandler  perl-script
PerlHandler Apache::Registry
# or Apache::PerlRun
Options ExecCGI
</Location>

21.12.3. Discussion

The Solution tells Apache that requests with URLs starting in /perl/ are in /real/path/to/perl/scripts/ and that Apache::Registry handles them. This module runs them in a CGI environment. PerlModule CGI preloads the CGI module, and PerlSendHeader On makes most CGI scripts work out of the box with mod_perl.

We have configured /perl/ to work analogously to /cgi-bin/. To make the suffix .perl indicate mod_perl CGI scripts, just as the suffix .cgi indicates regular CGI scripts, use the following in your Apache configuration file:

<Files *.perl>
SetHandler  perl-script
PerlHandler Apache::Registry
Options ExecCGI
</Files>

Because the Perl interpreter that runs your CGI script doesn't shut down when your script is done, as would occur when the web server runs your script as a separate program, you cannot rely on global variables being undefined when the script runs repeatedly. The warnings and strict pragmas check for many bad habits in these kinds of scripts. There are other gotchas, too—see the mod_perl_traps manpage.

The Apache::PerlRun handler can work around some of these traps. This is like Apache::Registry, but doesn't cache the compiled module. If your CGI program is sloppy and doesn't initialize variables or close filehandles, you can still gain speed by not starting a new process for every request. To use it, substitute Apache::PerlRun for Apache::Registry.

Your scripts aren't preloaded, so each web server process carries its own copy around. To share the code between processes, load them during Apache configuration with either the Apache::RegistryLoader module, PerlModule sections of httpd.conf, or a startup.pl file.

21.12.4. See Also

The Apache.pm manpage; the documentation for Bundle::Apache, Apache, Apache::Registry, Apache::RegistryLoader, and Apache::PerlRun from CPAN; http://perl.apache.org; the mod_perl FAQ at http://perl.apache.org/faq/; the mod_perl(3) and cgi_to_mod_perl(1) manpages (if you have them); Recipes 2.1 through 2.5 in mod_perl Developer's Cookbook

Previous | Home | Next
21.11. Communicating Between mod_perl and PHP | Book Index | 21.13. Sharing Information Between Handlers
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.13. Sharing Information Between Handlers

21.13.1. Problem

You want to share information between handlers, but global variables are global to a process and not automatically cleaned up after every request.

21.13.2. Solution

Use Apache pnotes (Perl notes):

# in one handler
$r->pnotes("Name", $name);

# in another handler
$name = $r->pnotes("Name");

21.13.3. Discussion

Apache modules communicate with each other using notes (see Recipe 21.11). Apache notes act like a hash attached to a request—one handler stores a value for a key in the hash, so that another handler can read it later. The Perl notes features is also a hash attached to the request object, but it's only for the Perl handlers.

To set a pnote, pass a key and a value to the $r->pnotes method. To retrieve a pnote, pass only the key. You can store complex data structures:

$r->pnotes("Person", { Name => "Nat",
                       Age  => 30,
                       Kids => 2 });
# later
$person = $r->pnotes("Person");

and even objects:

$person = new Person;
$person->name("Nat");
$person->age(30);
$person->kids(2);

$r->pnotes(Person => $person);

# later

$person = $r->pnotes("Person");
# $person is a reference to the same object

21.13.4. See Also

Recipe 8.11 in mod_perl Developer's Cookbook; Apache::Table; pnotes method in the Apache manpage

Previous | Home | Next
21.12. Migrating from CGI to mod_perl | Book Index | 21.14. Reloading Changed Modules
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.14. Reloading Changed Modules

21.14.1. Problem

You've updated your mod_perl modules, but you have to restart the web server for Apache to notice the change.

21.14.2. Solution

Use Apache::StatINC (standard with mod_perl) to automatically reload any code when it changes on disk:

PerlModule Apache::StatINC
PerlInitHandler Apache::StatINC

Or use the CPAN module Apache::Reload to limit the monitoring to specific modules:

PerlModule Apache::Reload
PerlInitHandler Apache::Reload
PerlSetVar ReloadAll Off
PerlSetVar ReloadModules "Example::One Example::Two Example::Three"

21.14.3. Discussion

Apache::Reload includes the functionality of Apache::StatINC. Simply saying:

PerlModule Apache::Reload
PerlInitHandler Apache::Reload

is enough to duplicate the functionality of Apache::StatINC. That is, at the start of each request, Apache::Reload goes through all currently loaded modules, checking timestamps to see which have changed. Because checking every module on every request is a burden on popular sites, Apache::Reload also lets you specify which modules to check and reload.

21.14.4. See Also

The documentation for the Apache::StatINC and Apache::Reload modules; Recipe 8.1 in mod_perl Developer's Cookbook; the mod_perl guide at http://perl.apache.org/guide

Previous | Home | Next
21.13. Sharing Information Between Handlers | Book Index | 21.15. Benchmarking a mod_perl Application
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.15. Benchmarking a mod_perl Application

21.15.1. Problem

You have an idea to speed up your application, but you're not sure whether your change will help.

21.15.2. Solution

Use Apache::Timeit to time how long your content handler takes to run:

PerlModule Apache::Timeit
PerlFixupHandler Apache::Timeit

For more detailed analysis, use the Apache::DProf module available from CPAN:

PerlModule Apache::DProf

21.15.3. Discussion

The Apache::Timeit module is available at http://perl.apache.org/dist/contrib/Timeit.pm.

This module records in the error log the amount of time that elapsed while the content handler ran. By scanning the logs and averaging these numbers, you can see which pages take longer to generate, and you can then start to figure out why.

To drill down into your code and figure out which parts of the content handler are taking the most time, use the Apache::DProf module. This module connects the standard (as of v5.8) Devel::DProf module to Apache and mod_perl.

The profiler records time spent in every subroutine the Perl module executes. The record of times is written to a file named dprof/$$/tmon.out ($$ is the process ID of the Apache child process), located under the ServerRoot directory. This file corresponds to every Perl subroutine encountered during the lifetime of the Apache child process. To profile just a single request, set the MaxRequestsPerChild directive in the httpd.conf file:

MaxRequestsPerChild 1

You must create and chmod this directory yourself:

cd $APACHE_SERVER_ROOT
mkdir logs/dprof
chmod 777 logs/dprof

To analyze the output, use the dprofpp program:

dprofpp -r dprof/13169/tmon.out
Total Elapsed Time = 89.93962 Seconds
         Real Time = 89.93962 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 0.01   0.010  0.010      1   0.0100 0.0100  Apache::Reload::handler
 0.00   0.000 -0.000      1   0.0000      -  Apache::DProf::handler
 0.00   0.000 -0.000      1   0.0000      -  MP002::trans
 0.00   0.000 -0.000      1   0.0000      -  MP002::fixup
 0.00   0.000 -0.000      1   0.0000      -  MP002::content

The -r option makes dprofpp display elapsed time instead of the default CPU time. The difference is important for mod_perl applications, where I/O and other non-CPU tasks are often significant causes of user-perceived delay.

There are a lot of options to dprofpp that refine and manipulate timing data. For example, -R gives separate timing data for each anonymous subroutine in a package, rather than lumping them together; -l sorts by the number of times the subroutine was called, rather than how long it took. See the dprofpp manpage for a complete list.

21.15.4. See Also

Recipe 9.12 in mod_perl Developer's Cookbook; documentation for the CPAN module Apache::DProf; documentation for the standard module Devel::DProf; the dprofpp(1) manpage; the section "The Perl Profiler" in Chapter 20 of Programming Perl

Previous | Home | Next
21.14. Reloading Changed Modules | Book Index | 21.16. Templating with HTML::Mason
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.16. Templating with HTML::Mason

21.16.1. Problem

You want to separate presentation (HTML formatting) from logic (Perl code) in your program. Your web site has a lot of components with only slight variations between them. You'd like to abstract out common elements and build your pages from templates without having a lot of "if I'm in this page, then print this; else if I'm in some other page . . . " conditional statements in a single master template.

21.16.2. Solution

Use HTML::Mason components and inheritance.

21.16.3. Discussion

HTML::Mason (also simply called Mason) offers the power of Perl in templates. The basic unit of a web site built with Mason is the component—a file that produces output. The file can be HTML, Perl, or a mixture of both. Components can take arguments and execute arbitrary Perl code. Mason has many features, documented at http://masonhq.com and in Embedding Perl in HTML with Mason by Dave Rolsky and Ken Williams (O'Reilly; online at http://masonbook.com).

Mason works equally well with CGI, mod_perl, and non-web programs. For the purposes of this recipe, however, we look at how to use it with mod_perl. The rest of this recipe contains a few demonstrations to give you a feel for what you can do with Mason and how your site will be constructed. There are more tricks, traps, and techniques for everything we discuss, though, so be sure to visit the web site and read the book for the full story.

21.16.3.1. Configuration

Install the HTML-Mason distribution from CPAN and add the following to your httpd.conf:

PerlModule HTML::Mason::ApacheHandler
<Location /mason>
  SetHandler perl-script
  PerlHandler HTML::Mason::ApacheHandler
  DefaultType text/html
</Location>

This tells mod_perl that every URL that starts with /mason is handled by Mason. So if you request /mason/hello.html, the file mason/hello.html in your document directory will be compiled and executed as a Mason component. The DefaultType directive lets you omit the .html from component names.

Next create a directory for Mason to cache the compiled components in. Mason does this to speed up execution.

cd $SERVER_ROOT
mkdir mason

Then make a mason directory for components to live in:

cd $DOCUMENT_ROOT
mkdir mason

Now you're ready for "Hello, World". Put this in mason/hello:

Hello, <% ("World", "Puny Human")[rand 2] %>

Restart Apache and load up the mason/hello page. If you reload it, you should see "Hello, World" and "Hello, Puny Human" randomly. If not, look at the Mason FAQ (http://www.masonhq.com/docs/faq/), which answers most commonly encountered problems.

21.16.3.2. Basic Mason syntax

There are four types of new markup in Mason components: substitutions, Perl code, component calls, and block tags. You saw a substitution in the "Hello World" example: <% ... %> evaluates the contents as Perl code and inserts the result into the surrounding text.

Perl code is marked with a % at the start of the line:

% $now = localtime;   # embedded Perl
This page was generated on <% $now %>.

Because substitutions can be almost any Perl code you like, this could have been written more simply as:

This page was generated on <% scalar localtime %>.

If either of these variations were saved in footer.mas, you could include it simply by saying:

<& footer.mas &>

This is an example of a component call—Mason runs the component and inserts its result into the document that made the call.

Block tags define different regions of your component. <%perl> ... </%perl> identifies Perl code. While % at the start of a line indicates that just that line is Perl code, you can have any number of lines in a <%perl> block.

A <%init> ... </%init> block is like an INIT block in Perl. The code in the block is executed before the main body of code. It lets you store definitions, initialization, database connections, etc. at the bottom of your component, where they're out of the way of the main logic.

The <%args> ... </%args> block lets you define arguments to your component, optionally with default values. For example, here's greet.mas:

<%args>
   $name => "Larry"
   $town => "Mountain View"
</%args>
Hello, <% $name %>.  How's life in <% $town %>?

Calling it with:

<& greet.mas &>

emits:

Hello, Larry.  How's life in Mountain View?

You can provide options on the component call:

<& greet.mas, name => "Nat", town => "Fort Collins" &>

That emits:

Hello, Nat.  How's life in Fort Collins?

Because there are default values, you can supply only some of the arguments:

<& greet.mas, name => "Bob" &>

That emits:

Hello, Bob.  How's life in Mountain View?

Arguments are also how Mason components access form parameters. Take this form:

<form action="compliment">
  How old are you?  <input type="text" name="age"> <br />
  <input type="submit">
</form>

Here's a compliment component that could take that parameter:

<%args>
  $age
</%args>
Hi.  Are you really <% $age %>?  You don't look it!

21.16.3.3. Objects

All Mason components have access to a $m variable, which contains an HTML::Mason::Request object. Methods on this object give access to Mason features. For example, you can redirect with:

$m->redirect($URL);

The $r variable is the mod_perl request object, so you have access to the information and functions of Apache from your Mason handlers. For example, you can discover the client's IP address with:

$ip = $r->connection->remote_ip;

21.16.3.4. Autohandlers

When a page is requested through Mason, Mason can do more than simply execute the code in that page. Mason inspects each directory between the component root and the requested page, looking for components called autohandler. This forms a wrapping chain, with the top-level autohandler at the start of the chain and the requested page at the end. Mason then executes the code at the start of the chain. Each autohandler can say "insert the output of the next component in the chain here."

Imagine a newspaper site. Some parts don't change, regardless of which article you're looking at: the banner at the top, the random selection of ads, the list of sections down the lefthand side. However, the actual article text varies from article to article. Implement this in Mason with a directory structure like this:

/sports
/sports/autohandler
/sports/story1
/sports/story2
/sports/story3

The individual story files contain only the text of each story. The autohandler builds the page (the banner, the ads, the navigation bar), and when it wants to insert the content of the story, it says:

% $m->call_next;

This tells Mason to call the next component in the chain (the story) and insert its output here.

The technique of having a chain of components is called inheritance, and autohandlers aren't the only way to do it. In a component, you can designate a parent with:

<%flags>
  inherit = 'parent.mas'
</%flags>

This lets you have different types of content in the one directory, and each contained component gets to identify its surrounding page (its parent).

21.16.3.5. Dhandlers

Sometimes it's nice to provide the illusion of a directory full of pages, when in reality they are all dynamically generated. For example, stories kept in a database could be accessed through URLs like:

/sports/1
/sports/2
/sports/3

The Mason way to dynamically generate the pages at these URLs is with a component called dhandler in the sports directory. The dhandler component accesses the name of the missing page (123 in this case) by calling:

$m->dhandler_arg

You could then use this to retrieve the story from the database and insert it into a page template.

21.16.4. See Also

Recipe 15.11 in mod_perl Developer's Cookbook; Embedding Perl in HTML with Mason; http://www.masonhq.com and http://www.masonbook.com

Previous | Home | Next
21.15. Benchmarking a mod_perl Application | Book Index | 21.17. Templating with Template Toolkit
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


21.17. Templating with Template Toolkit

21.17.1. Problem

You want to separate presentation (HTML formatting) from logic (Perl code) in your program. You want designers and other people who don't speak Perl to be able to edit the templates.

21.17.2. Solution

Use the Template Toolkit and Apache::Template.

21.17.3. Discussion

The Template Toolkit (TT2) is a general templating system that can be used not just for web pages, but for any kind of templated text. The Apache::Template module is an Apache content handler that uses TT2 to build the returned page. The biggest benefit of TT2 is that it has a simple language for variables, loops, and data structures, which can be used instead of Perl for presentation logic. This simple language can be read and written by people who don't know Perl.

This recipe documents Version 2 of the Template Toolkit. As with HTML::Mason, there's far more to TT2 that we can possibly cover here. This recipe is just a tour of some of the highlights of TT2's syntax and functionality. The Template Toolkit is well documented at http://www.template-toolkit.org, and in the upcoming book Perl Template Toolkit, by Darren Chamberlain, Dave Cross, and Andy Wardley (O'Reilly).

21.17.3.1. Configuration

Install the Template and Apache::Template modules from CPAN. Add this to your httpd.conf file:

PerlModule Apache::Template

TT2EvalPerl On
TT2Params all

TT2IncludePath /usr/local/apache/htdocs/tt2

<Location /tt2>
  SetHandler perl-script
  PerlHandler Apache::Template
  DefaultType text/html
</Location>

The TT2EvalPerl directive lets us embed Perl code in our templates as well as the TT2 language. TT2Params tells Apache::Template to give our templates access to form parameters, Apache environment variables, notes, cookies, and more. TT2IncludePath tells the Template Toolkit where to look for templates that our templates include. Finally, we designate the /tt2 area of our server for pages generated by the Template Toolkit.

21.17.3.2. Syntax

Templates are regular HTML files with directives embedded in [% ... %] tags. The tag delimiters are customizable, but in practice they're rarely changed. The use of square brackets rather than angle brackets means that templates can be edited in HTML editors without fear that a templating directive will be confused for an HTML tag.

This is a simple template:

<b>This is how you count to three:</b>
[% FOREACH i = [1 .. 3] %]
  [% i %] ...
[% END %]
Wasn't that easy?

When TT2 executes this template, it will produce:

<b>This is how you count to three:</b> 1 ... 2 ... 3 ... Wasn't that easy?

Store that in the file tt2/count and point your browser at the equivalent URL.

The FOREACH loop is an example of a TT2 directive. The i variable is the loop iterator, and it takes each value in turn from the list on the righthand side of the =. Loops, like every TT2 block, are terminated by an END directive. Variables in TT2 code have no type sigil like $, @, or %.

To display the value of a variable or expression, simply enclose it in the [% ... %] tags. You can't put arbitrary Perl code there, though, only TT2 syntax.

21.17.3.3. Perl code

If you want to execute Perl, use a PERL directive:

[% PERL %]
  my @numbers = (1 .. 3);
  print join(" ... ", @numbers);
[% END %]

Anything printed from within a PERL block becomes part of the final document. PERL blocks execute under use strict, so it pays to use lexical variables.

These lexical variables are separate from the TT2 variables like i, the loop iterator in the earlier example. To make a Perl value accessible to TT2 code, or vice versa, you must use the stash. This is the TT2 symbol table, and is accessible through the $stash variable automatically present in PERL blocks:

[% PERL %]
  my @numbers = (1 .. 3);
  my $text = join(" ... ", @numbers);
  $stash->set(counting => $text);
[% END %]
Here's how you count to three: [% counting %].  Wasn't that easy?

Normally you use Perl code for business logic (e.g., fetching values from databases) and TT2 code for presentation logic (e.g., building tables). The Perl code sets TT2 variables with the results of the business logic (e.g., the values from the database) so that the presentation logic has values to put into the template. In practice, most people prefer to disable TT2EvalPerl and keep Perl code out of their templates. this strict separation of business from presentation logic means a customized version of Apache::Template is needed to load the Perl code and place data in the stash.

You can initialize TT2 variables from TT2 as well:

[% text = "1 ... 2 ... 3" %]                    <!-- string -->
[% names = [ "Larry", "Tom", "Tim" ] %]         <!-- array  -->
[% language = { Larry => "Perl 6",              <!-- hash   -->
                Tom   => "Perl 5",
                Tim   => "Latin" } %]
[% people = { Larry => { Language => "Perl 6",  <!-- nested structure -->
                         Town     => "Mountain View" },
              Tom   => { Language => "Perl 5",
                         Town     => "Boulder" } } %]

Similarly, you can fetch TT2 values from the stash:

[% FOREACH i = [1 .. 3] %]
  [% PERL %]
    my $number = $stash->get("i");
    $stash->set(doubled => 2*$number);
  [% END %]
  [% doubled %] ...
[% END %]
2 ... 4 ... 6 ...

From within a PERL block, you can also use modules. It's more efficient, however, to load the modules when Apache starts up by replacing the PERL block's use Some::Thing with a PerlModule Some::Thing in httpd.conf.

21.17.3.4. Data structures

The stash lets you put scalars, arrays, hashes, even subroutines into the world of TT2 code. Here's an array definition and access:

[% names = [ "Nat", "Jenine", "William", "Raley" ] %]
The first person is [% names.0 %].
The first person is Nat.

The period (.) separates the structure name from the field you want to access. This works for hashes as well:

[% age = { Nat => 30, Jenine => 36, William => 3, Raley => 1.5 } %]
Nat is [% age.Nat %] (and he feels it!)
Nat is 30 (and feels it!)

Unlike Perl, TT2 code doesn't put [ ] or { } around the array position or hash key whose value you're accessing. This is part of the simplicity of TT2 code, and why non-programmers can easily modify it. It also hides the implementation—age.1 could just as easily be implemented through an array, a hash, or an object, without requiring changes in the template.

If your index is stored in another variable, use a $:

[% age = { Nat => 30, Jenine => 36, William => 3, Raley => 1.5 } %]
[% name = "Nat" %]
Nat is [% age.$name %] (and he feels it)
Nat is 30 (and feels it!)

Loop over an array or hash with FOREACH:

[% FOREACH name = names %]
  Hi, [% name %]!
[% END %]
Hi, Nat! Hi, Jenine! Hi, William! Hi, Raley!

[% FOREACH person = age %]
  [% person.key %] = [% person.value %].
[% END %]
Nat is 30. Jenine is 36. William is 3. Raley is 1.5.

The key and person methods can be called on a hash loop iterator to get the current key and value, respectively. TT2 also makes a loop variable available in loops, from which you can access the current position, find out whether the current position is the first or last, and more. Table 21-1 lists the loop variable methods and their meanings.

Table 21-1. loop variable methods

Method | Meaning
size | Number of elements in the list
max | Index number of last element (size - 1)
index | Index of current iteration from 0 to max
count | Iteration counter from 1 to size (i.e., index + 1)
first | True if the current iteration is the first
last | True if the current iteration is the last
prev | Return the previous item in the list
next | Return the next item in the list

To build a table with alternating row colors, do the following:

[% folks = [ [ "Larry",  "Mountain View" ],
             [ "Tom",    "Boulder"       ],
             [ "Jarkko", "Helsinki"      ],
             [ "Nat",    "Fort Collins"  ] ] %]
<table>
[% FOREACH row = folks %]
  <tr [% IF loop.index % 2 %]
          bgcolor="#ffff00"
      [% ELSE %]
          bgcolor="#ffff80"
      [% END %] >
  [% FOREACH col = row %]
    <td>[% col %]</td>
  [% END %]
  </tr>
[% END %]
</table>

21.17.3.5. Subroutines

If you build a lot of tables like this, you should abstract out the code into a subroutine. In TT2 syntax, a subroutine is a block. Here's a simple block that takes no parameters:

[% BLOCK greet %]
  Hello, world!
[% END %]

To call it, use the INCLUDE directive:

[% INCLUDE greet %]

Here's how you'd write a generic HTML table routine:

[% BLOCK table %]
  <table>
  [% FOREACH row = array %]
    <tr [% IF loop.index % 2 %]
            bgcolor="#ffff00"
        [% ELSE %]
            bgcolor="#ffff80"
        [% END %] >
    [% FOREACH col = row %]
      <td>[% col %]</td>
    [% END %]
    </tr>
  [% END %]
  </table>
[% END %]

To call this table block and tell it to print the array folks, you'd say:

[% INCLUDE table array=folks %]

21.17.3.6. Including other templates

The same syntax that you used to call a block defined within a template can be used to load and execute another file:

[% INCLUDE "header.tt2" %]

An INCLUDEd file is treated as a TT2 template. To insert a file that doesn't contain TT2 directives, it's faster to use INSERT:

[% INSERT "header.html" %]

INSERTed files are not processed by TT2 in any way. Their contents are simply inserted verbatim into the document being built.

21.17.3.7. Parameters

Apache::Template provides you with several TT2 variables corresponding to various parts of your web environment. Table 21-2 lists these variables and what they contain.

Table 21-2. Template Toolkit variables provided by Apache::Template

Variable | Contains
uri | String containing URI of current page
env | Hash of environment variables
params | Hash of form parameters
pnotes | Hash of Apache request's pnotes
cookies | Hash of cookies
uploads | Array of Apache::Upload objects

Here's a form:

<form action="consult">
  Whose city do you want to look up?
  <select name="person">
    <option value="larry">Larry</option>
    <option value="tom">Tom</option>
    <option value="nat">Nat</option>
  </select><p>
  <input type="submit">
</form>

The person form parameter contains the person's name. Here's the consult template:

[% cities = { larry => "Mountain View",
              tom   => "Boulder",
              nat   => "Fort Collins" } %]

[% name = params.person %]
[% name %] lives in [% cities.$name %]

21.17.3.8. Plug-ins

The Template Toolkit comes with many plug-ins. The most useful is probably the DBI plug-in:

[% USE DBI('dbi:mysql:library', 'user', 'pass') %]

[% FOREACH book = DBI.query( 'SELECT title,authors FROM books' ) %]
  [% book.authors %] wrote [% book.title %]<br>
[% END %]

Once the plug-in is loaded with the USE directive, you can use the TT2 variable DBI to issue SQL queries. The query method returns an array of rows, each row is a hash mapping column name to value.

The HTML plug-in is also useful. It offers methods to HTML-escape strings:

[% USE HTML %]

[% string = 'Over -----> Here' %]
Look [% HTML.escape(string) %]
Look Over -----> Here

21.17.4. See Also

The documentation for the Template and Apache::Template modules from CPAN; http://www.template-toolkit.org; Perl Template Toolkit; Recipe 15.9 in mod_perl Developer's Cookbook

Previous | Home | Next
21.16. Templating with HTML::Mason | Book Index | 22. XML
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 22. XML

Contents:

Introduction
Parsing XML into Data Structures
Parsing XML into a DOM Tree
Parsing XML into SAX Events
Making Simple Changes to Elements or Text
Validating XML
Finding Elements and Text Within an XML Document
Processing XML Stylesheet Transformations
Processing Files Larger Than Available Memory
Reading and Writing RSS Files
Writing XML

John Donne, Holy Sonnets

I am a little world made cunningly. Of elements, and an angelic sprite

22.0. Introduction

The Extensible Markup Language (XML) standard was released in 1998. It quickly became the standard way to represent and exchange almost every kind of data, from books to genes to function calls.

XML succeeded where other past "standard" data formats failed (including XML's ancestor, SGML—the Standard Generalized Markup Language). There are three reasons for XML's success: it is text-based instead of binary, it is simple rather than complex, and it has a superficial resemblance to HTML.

Text
Unix realized nearly 30 years before XML that humans primarily interact with computers through text. Thus text files are the only files any system is guaranteed to be able to read and write. Because XML is text, programmers can easily make legacy systems emit XML reports.

Simplicity
As we'll see, a lot of complexity has arisen around XML, but the XML standard itself is very simple. There are very few things that can appear in an XML document, but from those basic building blocks you can build extremely complex systems.

HTML
XML is not HTML, but XML and HTML share a common ancestor: SGML. The superficial resemblance meant that the millions of programmers who had to learn HTML to put data on the web were able to learn (and accept) XML more easily.

22.0.1. Syntax

Example 22-1 shows a simple XML document.

Example 22-1. Simple XML document

<?xml version="1.0" encoding="UTF-8"?>
<books>
  <!-- Programming Perl 3ed -->
  <book id="1">
    <title>Programming Perl</title>
    <edition>3</edition>
    <authors>
      <author>
        <firstname>Larry</firstname>
        <lastname>Wall</lastname>
      </author>
      <author>
        <firstname>Tom</firstname>
        <lastname>Christiansen</lastname>
      </author>
      <author>
        <firstname>Jon</firstname>
        <lastname>Orwant</lastname>
      </author>
    </authors>
    <isbn>0-596-00027-8</isbn>
  </book>
  <!-- Perl & LWP -->
  <book id="2">
    <title>Perl &amp; </title>
    <edition>1</edition>
    <authors>
      <author>
        <firstname>Sean</firstname>
        <lastname>Burke</lastname>
      </author>
    </authors>
    <isbn>0-596-00178-9</isbn>
  </book>
  <book id="3">
    <!-- Anonymous Perl -->
    <title>Anonymous Perl</title>
    <edition>1</edition>
    <authors />
    <isbn>0-555-00178-0</isbn>
  </book>
</books>

At first glance, XML looks a lot like HTML: there are elements (e.g., <book> </book>), entities (e.g., &amp; and &lt;), and comments (e.g., <!-- Perl & LWP -->). Unlike HTML, XML doesn't define a standard set of elements, and defines only a minimum set of entities (for single quotes, double quotes, less-than, greater-than, and ampersand). The XML standard specifies only syntactic building blocks like the < and > around elements. It's up to you to create the vocabulary, that is, the element and attribute names like books, authors, etc., and how they nest.

XML's opening and closing elements are familiar from HTML:

<book>
</book>

XML adds a variation for empty elements (those with no text or other elements between the opening and closing tags):

<author />

Elements may have attributes, as in:

<book id="1">

Unlike HTML, the case of XML elements, entities, and attributes matters: <Book> and <book> start two different elements. All attributes must be quoted, either with single or double quotes (id='1' versus id="1"). Unicode letters, underscores, hyphens, periods, and numbers are all acceptable in element and attribute name, but the first character of a name must be a letter or an underscore. Colons are allowed only in namespaces (see Namespaces, later in this chapter).

Whitespace is surprisingly tricky. The XML specification says anything that's not a markup character is content. So (in theory) the newlines and whitespace indents between tags in Example 22-1 are text data. Most XML parsers offer the choice of retaining whitespace or sensibly folding it (e.g., to ignore newlines and indents).

22.0.2. XML Declaration

The first line of Example 22-1 is the XML declaration:

<?xml version="1.0" encoding="UTF-8" ?>

This declaration is optional—Version 1.0 of XML and UTF-8 encoded text are the defaults. The encoding attribute specifies the Unicode encoding of the document. Some XML parsers can cope with arbitrary Unicode encodings, but others are limited to ASCII and UTF-8. For maximum portability, create XML data as UTF-8.

22.0.3. Processing Instructions

Similar to declarations are processing instructions, which are instructions for XML processors. For example:

<title><?pdf font Helvetica 18pt?>XML in Perl</title>

Processing instructions have the general structure:

<?target data ... ?>

When an XML processor encounters a processing instruction, it checks the target. Processors should ignore targets they don't recognize. This lets one XML file contain instructions for many different processors. For example, the XML source for this book might have separate instructions for programs that convert to HTML and to PDF.

22.0.4. Comments

XML comments have the same syntax as HTML comments:

<!-- ... -->

The comment text can't contain --, so comments don't nest.

22.0.5. CDATA

Sometimes you want to put text in an XML document without having to worry about encoding entities. Such a literal block is called CDATA in XML, written:

<![CDATA[literal text here]]>

The ugly syntax betrays XML's origins in SGML. Everything after the initial <![CDATA[ and up to the ]]> is literal data in which XML markup characters such as < and & have no special meaning.

For example, you might put sample code that contains a lot of XML markup characters in a CDATA block:

<para>The code to do this is as follows:</para>
<code><![CDATA[$x = $y << 8 & $z]]>

22.0.6. Well-Formed XML

To ensure that all XML documents are parsable, there are some minimum requirements expected of an XML document. The following list is adapted from the list in Perl & XML, by Erik T. Ray and Jason McIntosh (O'Reilly):

  • The document must have one and only one top-level element (e.g., books in Example 22-1).

  • Every element with content must have both a start and an end tag.

  • All attributes must have values, and those values must be quoted.

  • Elements must not overlap.

  • Markup characters (<, >, and &) must be used to indicate markup only. In other words, you can't have <title>Perl & XML</title> because the & can only indicate an entity reference. CDATA sections are the only exception to this rule.

If an XML document meets these rules, it's said to be "well-formed." Any XML parser that conforms to the XML standard should be able to parse a well-formed document.

22.0.6. Schemas

There are two parts to any program that processes an XML document: the XML parser, which manipulates the XML markup, and the program's logic, which identifies text, the elements, and their structure. Well-formedness ensures that the XML parser can work with the document, but it doesn't guarantee that the elements have the correct names and are nested correctly.

For example, these two XML fragments encode the same information in different ways:

<book>
  <title>Programming Perl</title>
  <edition>3</edition>
  <authors>
    <author>
      <firstname>Larry</firstname>
      <lastname>Wall</lastname>
    </author>
    <author>
      <firstname>Tom</firstname>
      <lastname>Christiansen</lastname>
    </author>
    <author>
      <firstname>Jon</firstname>
      <lastname>Orwant</lastname>
    </author>
  </authors>
</book>

<work>
  <writers>Larry Wall, Tom Christiansen, and Jon Orwant</writers>
  <name edition="3">Programming Perl</name>
</work>

The structure is different, and if you wrote code to extract the title from one ("get the contents of the book element, then find the contents of the title element within that") it would fail completely on the other. For this reason, it is common to write a specification for the elements, attributes, entities, and the ways to use them. Such a specification lets you be confident that your program will never be confronted with XML it cannot deal with. The two formats for such specifications are DTDs and schemas.

DTDs are the older and more limited format, acquired by way of XML's SGML past. DTDs are not written in XML, so you need a custom (complex) parser to work with them. Additionally, they aren't suitable for many uses—simply saying "the book element must contain one each of the title, edition, author, and isbn elements in any order" is remarkably difficult.

For these reasons, most modern content specifications take the form of schemas. The World Wide Web Consortium (W3C), the folks responsible for XML and a host of related standards, have a standard called XML Schema (http://www.w3.org/TR/xmlschema-0/). This is the most common schema language in use today, but it is complex and problematic. An emerging rival for XML Schema is the OASIS group's RelaxNG; see http://www.oasis-open.org/committees/relax-ng/spec-20011203.html for more information.

There are Perl modules for working with schemas. The most important action you do with a schemas, however, is to validate an XML document against a schema. Recipe 22.5 shows how to use XML::LibXML to do this. XML::Parser does not support validation.

22.0.7. Namespaces

One especially handy property of XML is nested elements. This lets one document encapsulate another. For example, you want to send a purchase order document in a mail message. Here's how you'd do that:

<mail>
  <header>
    <from>me@example.com</from>
    <to>you@example.com</to>
    <subject>PO for my trip</subject>
  </header>
  <body>
    <purchaseorder>
      <for>Airfare</for>
      <bill_to>Editorial</bill_to>
      <amount>349.50</amount>
    </purchaseorder>
  </body>
</mail>

It worked, but we can easily run into problems. For example, if the purchase order used <to> instead of <bill_to> to indicate the department to be charged, we'd have two elements named <to>. The resulting document is sketched here:

<mail>
  <header>
    <to>you@example.com</to>
  </header>
  <body>
    <to>Editorial</to>
  </body>
</mail>

This document uses to for two different purposes. This is similar to the problem in programming where a global variable in one module has the same name as a global variable in another module. Programmers can't be expected to avoid variable names from other modules, because that would require them to know every module's variables.

The solution to the XML problem is similar to the programming problem's solution: namespaces. A namespace is a unique prefix for the elements and attributes in an XML vocabulary, and is used to avoid clashes with elements from other vocabularies. If you rewrote your purchase-order email example with namespaces, it might look like this:

<mail xmlns:email="http://example.com/dtds/mailspec/">
  <email:from>me@example.com</email:from>
  <email:to>you@example.com</email:to>
  <email:subject>PO for my trip</email:subject>
  <email:body>
    <purchaseorder xmlns:po="http://example.com/dtd/purch/">
      <po:for>Airfare</po:for>
      <po:to>Editorial</po:to>
      <po:amount>349.50</po:amount>
    </purchaseorder>
  </email:body>
</mail>

An attribute like xmnls:prefix="URL" identifies the namespace for the contents of the element that the attribute is attached to. In this example, there are two namespaces: email and po. The email:to element is different from the po:to element, and processing software can avoid confusion.

Most of the XML parsers in Perl support namespaces, including XML::Parser and XML::LibXML.

22.0.8. Transformations

One of the favorite pastimes of XML hackers is turning XML into something else. In the old days, this was accomplished with a program that knew a specific XML vocabulary and could intelligently turn an XML file that used that vocabulary into something else, like a different type of XML, or an entirely different file format, such as HTML or PDF. This was such a common task that people began to separate the transformation engine from the specific transformation, resulting in a new specification: XML Stylesheet Language for Transformations (XSLT).

Turning XML into something else with XSLT involves writing a stylesheet. A stylesheet says "when you see this in the input XML, emit that." You can encode loops and branches, and identify elements (e.g., "when you see the book element, print only the contents of the enclosed title element").

Transformations in Perl are best accomplished through the XML::LibXSLT module, although XML::Sablotron and XML::XSLT are sometimes also used. We show how to use XML::LibXSLT in Recipe 22.7.

22.0.9. Paths

Of the new vocabularies and tools for XML, possibly the most useful is XPath. Think of it as regular expressions for XML structure—you specify the elements you're looking for ("the title within a book"), and the XPath processor returns a pointer to the matching elements.

An XPath expression looks like:

/books/book/title

Slashes separate tests. XPath has syntax for testing attributes, elements, and text, and for identifying parents and siblings of nodes.

The XML::LibXML module has strong support for XPath, and we show how to use it in Recipe 22.6. XPath also crops up in the XML::Twig module shown in Recipe 22.8.

22.0.10. History of Perl and XML

Initially, Perl had only one way to parse XML: regular expressions. This was prone to error and often failed to deal with well-formed XML (e.g., CDATA sections). The first real XML parser in Perl was XML::Parser, Larry Wall's Perl interface to James Clark's expat C library. Most other languages (notably Python and PHP) also had an expat wrapper as their first correct XML parser.

XML::Parser was a prototype—the mechanism for passing components of XML documents to Perl was experimental and intended to evolve over the years. But because XML::Parser was the only XML parser for Perl, people quickly wrote applications using it, and it became impossible for the interface to evolve. Because XML::Parser has a proprietary API, you shouldn't use it directly.

XML::Parser is an event-based parser. You register callbacks for events like "start of an element," "text," and "end of an element." As XML::Parser parses an XML file, it calls the callbacks to tell your code what it's found. Event-based parsing is quite common in the XML world, but XML::Parser has its own events and doesn't use the standard Simple API for XML (SAX) events. This is why we recommend you don't use XML::Parser directly.

The XML::SAX modules provide a SAX wrapper around XML::Parser and several other XML parsers. XML::Parser parses the document, but you write code to work with XML::SAX, and XML::SAX translates between XML::Parser events and SAX events. XML::SAX also includes a pure Perl parser, so a program for XML::SAX works on any Perl system, even those that can't compile XS modules. XML::SAX supports the full level 2 SAX API (where the backend parser supports features such as namespaces).

The other common way to parse XML is to build a tree data structure: element A is a child of element B in the tree if element B is inside element A in the XML document. There is a standard API for working with such a tree data structure: the Document Object Model (DOM). The XML::LibXML module uses the GNOME project's libxml2 library to quickly and efficiently build a DOM tree. It is fast, and it supports XPath and validation. The XML::DOM module was an attempt to build a DOM tree using XML::Parser as the backend, but most programmers prefer the speed of XML::LibXML. In Recipe 22.2 we show XML::LibXML, not XML::DOM.

So, in short: for events, use XML::SAX with XML::Parser or XML::LibXML behind it; for DOM trees, use XML::LibXML; for validation, use XML::LibXML.

22.0.11. Further Reading

While the XML specification itself is simple, the specifications for namespaces, schemas, stylesheets, and so on are not. There are many good books to help you learn and use these technologies:

  • For help with all of the nuances of XML, try Learning XML, by Erik T. Ray (O'Reilly), and XML in a Nutshell, Second Edition, by Elliotte Rusty Harold and W. Scott Means (O'Reilly).

  • For help with XML Schemas, try XML Schema, by Eric van der Vlist (O'Reilly).

  • For examples of stylesheets and transformations, and help with the many non-trivial aspects of XSLT, see XSLT, by Doug Tidwell (O'Reilly), and XSLT Cookbook, by Sal Mangano (O'Reilly).

  • For help with XPath, try XPath and XPointer, by John E. Simpson (O'Reilly).

If you're the type that relishes the pain of reading formal specifications, the W3C web site, http://www.w3c.org, has the full text of all of their standards and draft standards.

Previous | Home | Next
21.17. Templating with Template Toolkit | Book Index | 22.1. Parsing XML into Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.1. Parsing XML into Data Structures

22.1.1. Problem

You want a Perl data structure (a combination of hashes and arrays) that corresponds to the structure and content of an XML file. For example, you have XML representing a configuration file, and you'd like to say $xml->{config}{server}{hostname} to access the contents of <config><server><hostname>...</hostname>.

22.1.2. Solution

Use the XML::Simple module from CPAN. If your XML is in a file, pass the filename to XMLin:

use XML::Simple;
$ref = XMLin($FILENAME, ForceArray => 1);

If your XML is in a string, pass the string to XMLin:

use XML::Simple;
$ref = XMLin($STRING, ForceArray => 1);

22.1.3. Discussion

Here's the data structure that XML::Simple produces from the XML in Example 22-1:

{

'book' => {
  '1' => {
    'authors' => [
      {
        'author' => [
          {
            'firstname' => [ 'Larry' ],
            'lastname'  => [ 'Wall'  ]
          },
          {
            'firstname' => [ 'Tom' ],
            'lastname'  => [ 'Christiansen' ]
          },
          {
            'firstname' => [ 'Jon' ],
            'lastname'  => [ 'Orwant' ]
          }
        ]
      }
    ],
    'edition' => [ '3' ],
    'title'   => [ 'Programming Perl' ],
    'isbn'    => [ '0-596-00027-8' ]
  },
  '2' => {
    'authors' => [
      {
        'author' => [
          {
            'firstname' => [ 'Sean' ],
            'lastname'  => [ 'Burke' ]
          }
        ]
      }
    ],
    'edition' => [ '1' ],
    'title'   => [ 'Perl & LWP' ],
    'isbn'    => [ '0-596-00178-9' ]
  },
  '3' => {
    'authors' => [ {  } ],
    'edition' => [ '1' ],
    'title'   => [ 'Anonymous Perl' ],
    'isbn'    => [ '0-555-00178-0' ]
  },
}
  }

The basic function of XML::Simple is to turn an element that contains other elements into a hash. If there are multiple identically named elements inside a single containing element (e.g., book), they become an array of hashes unless XML::Simple knows they are uniquely identified by attributes (as happens here with the id attribute).

By default, XML::Simple assumes that if an element has an attribute called id, name, or key, then that attribute is a unique identifier for the element. This is controlled by the KeyAttr option to the XMLin function. For example, set KeyAttr to an empty list to disable this conversion from arrays of elements to a hash by attribute:

$ref = XMLin($xml, ForceArray => 1, KeyAttr => [  ]);

For more fine-grained control, specify a hash that maps the element name to the attribute that holds a unique identifier. For example, to create a hash on the id attribute of book elements and no others, say:

$ref = XMLin($xml, ForceArray => 1, KeyAttr => { book => "id" });

The ForceArray option creates all of those one-element arrays in the data structure. Without it, XML::Simple compacts one-element arrays:

'3' => {
  'authors' => {  },
  'edition' => '1',
  'title' => 'Anonymous Perl',
  'isbn' => '0-555-00178-0'
},

Although this format is easier to read, it's also harder to program for. If you know that no element repeats, you can leave ForceArray off. But if some elements repeat and some don't, you need ForceArray to ensure a consistent data structure. Having the data sometimes directly available, sometimes inside an array, complicates the code.

The XML::Simple module has options that control the data structure built from the XML. Read the module's manpage for more details. Be aware that XML::Simple is only really useful for highly structured data, like the kind used in configuration files. It's awkward to use with XML that represents documents rather than data structures, and doesn't let you work with XML features like processing instructions or comments. We recommend that, for all but the most simple XML, you look to DOM and SAX parsing for your XML parsing needs.

22.1.4. See Also

The documentation for the CPAN module XML::Simple; Recipe 22.10

Previous | Home | Next
22. XML | Book Index | 22.2. Parsing XML into a DOM Tree
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.2. Parsing XML into a DOM Tree

22.2.1. Problem

You want to use the Document Object Model (DOM) to access and perhaps change the parse tree of an XML file.

22.2.2. Solution

Use the XML::LibXML module from CPAN:

use XML::LibXML;
my $parser = XML::LibXML->new( );
my $dom    = $parser->parse_string($XML);
# or
my $dom    = $parser->parse_file($FILENAME);
my $root   = $dom->getDocumentElement;

22.2.3. Discussion

DOM is a framework of classes for representing XML parse trees. Each element is a node in the tree, with which you can do operations like find its children nodes (the XML elements in this case), add another child node, and move the node somewhere else in the tree. The parse_string, parse_file, and parse_fh (filehandle) constructors all return a DOM object that you can use to find nodes in the tree.

For example, given the books XML from Example 22-1, Example 22-2 shows one way to print the titles.

Example 22-2. dom-titledumper

#!/usr/bin/perl -w
# dom-titledumper -- display titles in books file using DOM

use XML::LibXML;
use Data::Dumper;
use strict;

my $parser = XML::LibXML->new;
my $dom = $parser->parse_file("books.xml") or die;

# get all the title elements
my @titles = $dom->getElementsByTagName("title");
foreach my $t (@titles) {
    # get the text node inside the <title> element, and print its value
    print $t->firstChild->data, "\n";
}

The getElementsByTagName method returns a list of elements as nodes within the document that have the specific tag name. Here we get a list of the title elements, then go through each title to find its contents. We know that each title has only a single piece of text, so we assume the first child node is text and print its contents.

If we wanted to confirm that the node was a text node, we could say:

die "the title contained something other than text!"
  if $t->firstChild->nodeType != 3;

This ensures that the first node is of type 3 (text). Table 22-1 shows LibXML's numeric node types, which the nodeType method returns.

Table 22-1. LibXML's numeric node types

Node type | Number
Element | 1
Attribute | 2
Text | 3
CDATA Section | 4
Entity Ref | 5
Entity | 6
Processing Instruction | 7
Comment | 8
Document | 9
Document Type | 10
Document Fragment | 11
Notation | 12
HTML Document | 13
DTD Node | 14
Element Decl | 15
Attribute Decl | 16
Entity Decl | 17
Namespace Decl | 18
XInclude Start | 19
XInclude End | 20

You can also create and insert new nodes, or move and delete existing ones, to change the parse tree. Example 22-23 shows how you would add a randomly generated price value to each book element.

Example 22-3. dom-addprice

#!/usr/bin/perl -w
# dom-addprice -- add price element to books

use XML::LibXML;
use Data::Dumper;
use strict;

my $parser = XML::LibXML->new;
my $dom = $parser->parse_file("books.xml") or die;
my $root = $dom->documentElement;

# get list of all the "book" elements
my @books = $root->getElementsByTagName("book");

foreach my $book (@books) {
  my $price = sprintf("\$%d.95", 19 + 5 * int rand 5); # random price
  my $price_text_node = $dom->createTextNode($price);  # contents of <price>
  my $price_element   = $dom->createElement("price");  # create <price>
  $price_element->appendChild($price_text_node);       # put contents into <price>
  $book->appendChild($price_element);                  # put <price> into <book>
}

print $dom->toString;

We use createTextNode and createElement to build the new price tag and its contents. Then we use appendChild to insert the tag onto the end of the current book tag's existing contents. The toString method emits a document as XML, which lets you easily write XML filters like this one using DOM.

The XML::LibXML::DOM manpage gives a quick introduction to the features of XML::LibXML's DOM support and references the manpages for the DOM classes (e.g., XML::LibXML::Node). Those manpages list the methods for the objects.

22.2.4. See Also

The documentation for the XML::LibXML::DOM, XML::LibXML::Document, XML::LibXML::Element, and XML::LibXML::Node modules

Previous | Home | Next
22.1. Parsing XML into Data Structures | Book Index | 22.3. Parsing XML into SAX Events
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.3. Parsing XML into SAX Events

22.3.1. Problem

You want to receive Simple API for XML (SAX) events from an XML parser because event-based parsing is faster and uses less memory than parsers that build a DOM tree.

22.3.2. Solution

Use the XML::SAX module from CPAN:

use XML::SAX::ParserFactory;
use MyHandler;

my $handler = MyHandler->new( );
my $parser = XML::SAX::ParserFactory->parser(Handler => $handler);

$parser->parse_uri($FILENAME);
# or
$parser->parse_string($XML);

Logic for handling events goes into the handler class (MyHandler in this example), which you write:

# in MyHandler.pm
package MyHandler;

use base qw(XML::SAX::Base);

sub start_element {   # method names are specified by SAX
  my ($self, $data) = @_;
  # $data is hash with keys like Name and Attributes
  # ...
}

# other possible methods include end_element( ) and characters( )

1;

22.3.3. Discussion

An XML processor that uses SAX has three parts: the XML parser that generates SAX events, the handler that reacts to them, and the stub that connects the two. The XML parser can be XML::Parser, XML::LibXML, or the pure Perl XML::SAX::PurePerl that comes with XML::SAX. The XML::SAX::ParserFactory module selects a parser for you and connects it to your handler. Your handler takes the form of a class that inherits from XML::SAX::Base. The stub is the program shown in the Solution.

The XML::SAX::Base module provides stubs for the different methods that the XML parser calls on your handler. Those methods are listed in Table 22-2, and are the methods defined by the SAX1 and SAX2 standards at http://www.saxproject.org/. The Perl implementation uses more Perl-ish data structures and is described in the XML::SAX::Intro manpage.

Table 22-2. XML::SAX::Base methods

start_document | end_document | characters
start_element | end_element | processing_instruction
ignorable_whitespace | set_document_locator | skipped_entity
start_prefix_mapping | end_prefix_mapping | comment
start_cdata | end_cdata | entity_reference
notation_decl | unparsed_entity_decl | element_decl
attlist_decl | doctype_decl | xml_decl
entity_decl | attribute_decl | internal_entity_decl
start_dtd | end_dtd | external_entity_decl
resolve_entity | start_entity | end_entity
warning | error | fatal_error

The two data structures you need most often are those representing elements and attributes. The $data parameter to start_element and end_element is a hash reference. The keys of the hash are given in Table 22-3.

Table 22-3. An XML::SAX element hash

Key | Meaning
Prefix | XML namespace prefix (e.g., email:)
LocalName | Attribute name without prefix (e.g., to)
Name | Fully qualified attribute name (e.g., email:to)
Attributes | Hash of attributes of the element
NamespaceURI | URI of the XML namespace for this attribute

An attribute hash has a key for each attribute. The key is structured as "{namespaceURI}attrname". For example, if the current namespace URI is http://example.com/dtds/mailspec/ and the attribute is msgid, the key in the attribute hash is:

{http://example.com/dtds/mailspec/}msgid

The attribute value is a hash; its keys are given in Table 22-4.

Table 22-4. An XML::SAX attribute hash

Key | Meaning
Prefix | XML namespace prefix (e.g., email:)
LocalName | Element name without prefix (e.g., to)
Name | Fully qualified element name (e.g., email:to)
Value | Value of the attribute
NamespaceURI | URI of the XML namespace for this element

Example 22-4 shows how to list the book titles using SAX events. It's more complex than the DOM solution because with SAX we must keep track of where we are in the XML document.

Example 22-4. sax-titledumper

# in TitleDumper.pm
# TitleDumper.pm -- SAX handler to display titles in books file
package TitleDumper;

use base qw(XML::SAX::Base);

my $in_title = 0;

# if we're entering a title, increase $in_title
sub start_element {
  my ($self, $data) = @_;
  if ($data->{Name} eq 'title') {
    $in_title++;
  }
}

# if we're leaving a title, decrease $in_title and print a newline
sub end_element {
  my ($self, $data) = @_;
  if ($data->{Name} eq 'title') {
    $in_title--;
    print "\n";
  }
}

# if we're in a title, print any text we get
sub characters {
  my ($self, $data) = @_;
  if ($in_title) {
    print $data->{Data};
  }
}

1;

The XML::SAX::Intro manpage provides a gentle introduction to XML::SAX parsing.

22.3.4. See Also

Chapter 5 of Perl & XML; the documentation for the CPAN modules XML::SAX, XML::SAX::Base, and XML::SAX::Intro

Previous | Home | Next
22.2. Parsing XML into a DOM Tree | Book Index | 22.4. Making Simple Changes to Elements or Text
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.4. Making Simple Changes to Elements or Text

22.4.1. Problem

You want to filter some XML. For example, you want to make substitutions in the body of a document, or add a price to every book described in an XML document, or you want to change <book id="1"> to <book> <id>1</id>.

22.4.2. Solution

Use the XML::SAX::Machines module from CPAN:

#!/usr/bin/perl -w

use MySAXFilter1;
use MySAXFilter2;
use XML::SAX::ParserFactory;
use XML::SAX::Machines qw(Pipeline);

my $machine = Pipeline(MySAXFilter1 => MySAXFilter2); # or more
$machine->parse_uri($FILENAME);

Write a handler, inheriting from XML::SAX::Base as in Recipe 22.3, then whenever you need a SAX event, call the appropriate handler in your superclass. For example:

$self->SUPER::start_element($tag_struct);

22.4.3. Discussion

A SAX filter accepts SAX events and triggers new ones. The XML::SAX::Base module detects whether your handler object is called as a filter. If so, the XML::SAX::Base methods pass the SAX events onto the next filter in the chain. If your handler object is not called as a filter, then the XML::SAX::Base methods consume events but do not emit them. This makes it almost as simple to write events as it is to consume them.

The XML::SAX::Machines module chains the filters for you. Import its Pipeline function, then say:

my $machine = Pipeline(Filter1 => Filter2 => Filter3 => Filter4);
$machine->parse_uri($FILENAME);

SAX events triggered by parsing the XML file go to Filter1, which sends possibly different events to Filter2, which in turn sends events to Filter3, and so on to Filter4. The last filter should print or otherwise do something with the incoming SAX events. If you pass a reference to a typeglob, XML::SAX::Machines writes the XML to the filehandle in that typeglob.

Example 22-5 shows a filter that turns the id attribute in book elements from the XML document in Example 22-1 into a new id element. For example, <book id="1"> becomes <book><id>1</id>.

Example 22-5. filters-rewriteids

package RewriteIDs;
# RewriteIDs.pm -- turns "id" attributes into elements

use base qw(XML::SAX::Base);

my $ID_ATTRIB = "{  }id";   # the attribute hash entry we're interested in

sub start_element {
    my ($self, $data) = @_;

    if ($data->{Name} eq 'book') {
        my $id = $data->{Attributes}{$ID_ATTRIB}{Value};
        delete $data->{Attributes}{$ID_ATTRIB};
        $self->SUPER::start_element($data);

        # make new element parameter data structure for the <id> tag
        my $id_node = {  };
        %$id_node = %$self;
        $id_node->{Name} = 'id';     # more complex if namespaces involved
        $id_node->{Attributes} = {  };

        # build the <id>$id</id>
        $self->SUPER::start_element($id_node);
        $self->SUPER::characters({ Data => $id });
        $self->SUPER::end_element($id_node);
    } else {
        $self->SUPER::start_element($data);
    }
}

1;

Example 22-6 is the stub that uses XML::SAX::Machines to create the pipeline for processing books.xml and print the altered XML.

Example 22-6. filters-rewriteprog

#!/usr/bin/perl -w
# rewrite-ids -- call RewriteIDs SAX filter to turn id attrs into elements

use RewriteIDs;
use XML::SAX::Machines qw(:all);

my $machine = Pipeline(RewriteIDs => *STDOUT);
$machine->parse_uri("books.xml");

The output of Example 22-6 is as follows (truncated for brevity):

<book><id>1</id>
    <title>Programming Perl</title>
 ...
<book><id>2</id>
    <title>Perl &amp; LWP</title>
 ...

To save the XML to the file new-books.xml, use the XML::SAX::Writer module:

#!/usr/bin/perl -w

use RewriteIDs;
use XML::SAX::Machines qw(:all);
use XML::SAX::Writer;

my $writer = XML::SAX::Writer->new(Output => "new-books.xml");
my $machine = Pipeline(RewriteIDs => $writer);
$machine->parse_uri("books.xml");

You can also pass a scalar reference as the Output parameter to have the XML appended to the scalar; as an array reference to have the XML appended to the array, one array element per SAX event; or as a filehandle to have the XML printed to that filehandle.

22.4.4. See Also

The documentation for the modules XML::SAX::Machines and XML::SAX::Writer

Previous | Home | Next
22.3. Parsing XML into SAX Events | Book Index | 22.5. Validating XML
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.5. Validating XML

22.5.1. Problem

You want to ensure that the XML you're processing conforms to a DTD or XML Schema.

22.5.2. Solution

To validate against a DTD, use the XML::LibXML module:

use XML::LibXML;
my $parser = XML::LibXML->new;
$parser->validation(1);
$parser->parse_file($FILENAME);

To validate against a W3C Schema, use the XML::Xerces module:

use XML::Xerces;

my $parser = XML::Xerces::DOMParser->new;
$parser->setValidationScheme($XML::Xerces::DOMParser::Val_Always);

my $error_handler = XML::Xerces::PerlErrorHandler->new( );
$parser->setErrorHandler($error_handler);

$parser->parse($FILENAME);

22.5.3. Discussion

The libxml2 library, upon which XML::LibXML is based, can validate as it parses. The validation method on the parser enables this option. At the time of this writing, XML::LibXML could only validate with DOM parsing—validation is not available with SAX-style parsing.

Example 22-7 is a DTD for the books.xml file in Example 22-1.

Example 22-7. validating-booksdtd

<!ELEMENT books (book*)>
<!ELEMENT book (title,edition,authors,isbn)>
<!ELEMENT authors (author*)>
<!ELEMENT author (firstname,lastname)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT edition (#PCDATA)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT isbn (#PCDATA)>

<!ATTLIST book
  id    CDATA    #REQUIRED
>

To make XML::LibXML parse the DTD, add this line to the books.xml file:

<!DOCTYPE books
  SYSTEM "books.dtd">

Example 22-8 is a simple driver used to parse and validate.

Example 22-8. validating-bookchecker

#!/usr/bin/perl -w
# bookchecker - parse and validate the books.xml file

use XML::LibXML;

$parser = XML::LibXML->new;
$parser->validation(1);
$parser->parse_file("books.xml");

When the document validates, the program produces no output—XML::LibXML successfully parses the document into a DOM structure that is quietly destroyed when the program ends. Edit the books.xml file, however, and you see the errors the XML::LibXML emits when it discovers broken XML.

For example, changing the id attribute to unique_id causes this error message:

'books.xml:0: validity error: No declaration for attribute unique_id
of element book
    <book unique_id="1">
                       ^
books.xml:0: validity error: Element book does not carry attribute id
    </book>
          ^
' at /usr/local/perl5-8/Library/Perl/5.8.0/darwin/XML/LibXML.pm line
405.
 at checker-1 line 7

XML::LibXML does a good job of reporting unknown attributes and tags. However, it's not so good at reporting out-of-order elements. If you return books.xml to its correct state, and then swap the order of a title and an edition element, you get this message:

'books.xml:0: validity error: Element book content does not follow the
DTD
    </book>
          ^
' at /usr/local/perl5-8/Library/Perl/5.8.0/darwin/XML/LibXML.pm line
405.
 at checker-1 line 7

In this case, XML::LibXML says that something in the book element didn't follow the DTD, but it couldn't tell us precisely what it violated in the DTD or how.

At the time of this writing, you must use XML::Xerces to validate while using SAX, or to validate against W3C Schema. Both of these features (and RelaxNG validation) are planned for XML::LibXML, but weren't available at the time of printing.

Here's how you build a DOM tree while validating a DTD using XML::Xerces:

use XML::Xerces;

# create a new parser that always validates
my $p = XML::Xerces::DOMParser->new( );
$p->setValidationScheme($XML::Xerces::DOMParser::Val_Always);

# make it die when things fail to parse
my $error_handler = XML::Xerces::PerlErrorHandler->new( );
$p->setErrorHandler($error_handler);

$p->parse($FILENAME);

To validate against a schema, you must tell XML::Xerces where the schema is and that it should be used:

$p->setFeature("http://xml.org/sax/features/validation", 1);
$p->setFeature("http://apache.org/xml/features/validation/dynamic", 0);
$p->setFeature("http://apache.org/xml/features/validation/schema", $SCHEMAFILE);

You can pass three possible values to setValidationScheme:

$XML::Xerces::DOMParser::Val_Always
$XML::Xerces::DOMParser::Val_Never
$XML::Xerces::DOMParser::Val_Auto

The default is to never validate. Always validating raises an error if the file does not have a DTD or Schema. Auto raises an error only if the file has a DTD or Schema, but it fails to validate against that DTD or Schema.

XML::Xerces requires the Apache Xerces C++ XML parsing library, available from http://xml.apache.org/xerces-c. At the time of writing, the XML::Xerces module required an archived, older version of the Xerces library (1.7.0) and was appallingly lacking in documentation—you can learn how it works only by reading the documentation for the C++ library and consulting the examples in the samples/ directory of the XML::Xerces distribution.

22.5.4. See Also

The documentation for the CPAN module XML::LibXML; http://xml.apache.org/xerces-c; http://xml.apache.org/xerces-p/

Previous | Home | Next
22.4. Making Simple Changes to Elements or Text | Book Index | 22.6. Finding Elements and Text Within an XML Document
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.6. Finding Elements and Text Within an XML Document

22.6.1. Problem

You want to get to a specific part of the XML; for example, the href attribute of an a tag whose contents are an img tag with alt text containing the word "monkey".

22.6.2. Solution

Use XML::LibXML and construct an XPath expression to find nodes you're interested in:

use XML::LibXML;

my $parser = XML::LibXML->new;
$doc = $parser->parse_file($FILENAME);
my @nodes = $doc->findnodes($XPATH_EXPRESSION);

22.6.3. Discussion

Example 22-9 shows how you would print all the titles in the book XML from Example 22-1.

Example 22-9. xpath-1

#!/usr/bin/perl -w

use XML::LibXML;

my $parser = XML::LibXML->new;
$doc = $parser->parse_file("books.xml");

# find title elements
my @nodes = $doc->findnodes("/books/book/title");

# print the text in the title elements
foreach my $node (@nodes) {
  print $node->firstChild->data, "\n";
}

The difference between DOM's getElementsByTagName and findnodes is that the former identifies elements only by their name. An XPath expression specifies a set of steps that the XPath engine takes to find nodes you're interested in. In Example 22-9 the XPath expression says "start at the top of the document, go into the books element, go into the book element, and then go into the title element."

The difference is important. Consider this XML document:

<message>
  <header><to>Tom</to><from>Nat</from></header>
  <body>
    <order><to>555 House St, Mundaneville</to>
           <product>Fish sticks</product>
    </order>
  </body>
</message>

There are two to elements here: one in the header and one in the body. If we said $doc->getElementsByTagName("to"), we'd get both to elements. The XPath expression "/message/header/to" restricts output to the to element in the header.

XPath expressions are like regular expressions that operate on XML structure instead of text. As with regular expressions, there are a lot of things you can specify in XPath expressions—far more than the simple "find this child node and go into it" that we've been doing.

Let's return to the books file and add another entry:

<book id="4">
  <!-- Perl Cookbook -->
  <title>Perl Cookbook</title>
  <edition>2</edition>
  <authors>
    <author>
      <firstname>Nathan</firstname>
      <lastname>Torkington</lastname>
    </author>
    <author>
      <firstname>Tom</firstname>
      <lastname>Christiansen</lastname>
    </author>
  </authors>
  <isbn>123-345-678-90</isbn>
</book>

To identify all books by Tom Christiansen, we need simply say:

my @nodes = $doc->findnodes("/books/book/authors/author/
        firstname[text( )='Tom']/../
        lastname[text( )='Christiansen']/
        ../../../title/text( )");

foreach my $node (@nodes) {
  print $node->data, "\n";
}

We find the author with firstname equal to "Tom" and lastname equal to "Christiansen", then back out to the "title" element and get its text child nodes. Another way to write the backing out is "head out until you find the book element again":

my @nodes = $doc->findnodes("/books/book/authors/author/
      firstname[text( )='Tom']/../
      lastname[text( )='Christiansen']/
      ancestor::book/title/text( )");

XPath is a very powerful system, and we haven't begun to touch the surface of it. For details on XPath, see XPath and XPointer, by John E. Simpson (O'Reilly), or the W3C specification at http://www.w3.org/TR/xpath. Advanced users should look at the XML::LibXML::XPathContext module (also available from CPAN), which lets you write your own XPath functions in Perl.

22.6.4. See Also

The documentation for the modules XML::LibXML and XML::LibXML::XPathContext; http://www.w3.org/TR/xpath; XPath and XPointer

Previous | Home | Next
22.5. Validating XML | Book Index | 22.7. Processing XML Stylesheet Transformations
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.7. Processing XML Stylesheet Transformations

22.7.1. Problem

You have an XML stylesheet that you want to use to convert XML into something else. For example, you want to produce HTML from files of XML using the stylesheet.

22.7.2. Solution

Use XML::LibXSLT:

use XML::LibXSLT;

my $xslt       = XML::LibXSLT->new;

my $stylesheet = $xslt->parse_stylesheet_file($XSL_FILENAME);
my $results    = $stylesheet->transform_file($XML_FILENAME);

print $stylesheet->output_string($results);

22.7.3. Discussion

XML::LibXSLT is built on the fast and powerful libxslt library from the GNOME project. To perform a transformation, first build a stylesheet object from the XSL source and then use it to transform an XML file. If you wanted to (for example, your XSL is dynamically generated rather than being stored in a file), you could break this down into separate steps:

use XML::LibXSLT;
use XML::LibXML;

my $xml_parser  = XML::LibXML->new;
my $xslt_parser = XML::LibXSLT->new;

my $xml         = $xml_parser->parse_file($XML_FILENAME);
my $xsl         = $xml_parser->parse_file($XSL_FILENAME);

my $stylesheet  = $xslt_parser->parse_stylesheet($xsl);
my $results     = $stylesheet->transform($xml);
my $output      = $stylesheet->output_string($results);

To save the output to a file, use output_file:

$stylesheet->output_file($OUTPUT_FILENAME);

Similarly, write the output to an already-opened filehandle with output_fh:

$stylesheet->output_fh($FILEHANDLE);

It's possible to pass parameters to the transformation engine. For example, your transformation might use parameters to set a footer at the bottom of each page:

$stylesheet->transform($xml, footer => "'I Made This!'");

The strange quoting is because the XSLT engine expects to see quoted values. In the preceding example, the double quotes tell Perl it's a string, whereas the single quotes are for the XSLT engine.

You can even retrieve data unavailable to XSLT (from a database, etc.) or manipulate runtime XSLT data with Perl. Consider the file in Example 22-10, which has multilingual title tags.

Example 22-10. test.xml

   <list>
     <title>System</title>
     <TituloGrande>Products</TituloGrande>
     <sublist>
       <SubTitleOne>Book</SubTitleOne>
     </sublist>
   </list>

You'd like to call a Perl function match_names from the XSLT template, test.xsl, given in Example 22-11.

Example 22-11. test.xsl

   <?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
     xmlns:test="urn:test">
   <xsl:template match="/">

     <xsl:variable name="matched" select="test:match_names('title |
titulo | titre | titolo', . )" />

     <xsl:for-each select="$matched">
       <xsl:copy-of select="." />
     </xsl:for-each>

   </xsl:template>
   </xsl:stylesheet>

The arguments to match_names are a regex and a node list, and the function is expected to return a node list object. Use XML::LibXML::NodeList methods to work with the parameters and create the return value. The match_names subroutine is given in Example 22-12.

Example 22-12. match_names subroutine

   sub match_names {
     my $pattern = shift;
     my $nodelist = shift;
     my $matches = XML::LibXML::NodeList->new;
     foreach my $context ($nodelist->get_nodelist) {
       foreach my $node ($context->findnodes('//*')) {
         if ($node->nodeName =~ /$pattern/ix) {
           $matches->push($node);
         }
       }
     }
     return $matches;
   }

Use XML::LibXSLT's register_function method to register your function for use from an XSLT template. Here's how you'd process the template from Example 22-10:

use strict;
use XML::LibXML;
use XML::LibXSLT;

my $xml_parser = XML::LibXML->new;
my $xslt_parser = XML::LibXSLT->new;

sub match_names { ... }   # as in example 22-10
$xslt_parser->register_function("urn:test", "match_names", \&match_names);
my $dom = $xml_parser->parse_file('test.xml');
my $xslt_dom = $xml_parser->parse_file('test.xsl');
my $xslt = $xslt_parser->parse_stylesheet($xslt_dom);
my $result_dom = $xslt->transform($dom);
print $result_dom->toString;

Use closures to let XSLT access to Perl variables, illustrated here with an Apache request object:

   $xslt->register_function("urn:test", "get_request",
                            sub { &get_request($apache_req,@_) } );

The get_request XSLT function (named in the second argument to register_function calls the Perl subroutine get_request (named in the code that is the third argument) with $apache_req preceding any arguments given to the XSLT function. You might use this to return a node list containing HTTP form parameters, or to wrap DBI database queries.

22.7.4. See Also

The documentation for the modules XML::LibXSLT and XML::LibXML

Previous | Home | Next
22.6. Finding Elements and Text Within an XML Document | Book Index | 22.8. Processing Files Larger Than Available Memory
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.8. Processing Files Larger Than Available Memory

22.8.1. Problem

You want to work with a large XML file, but you can't read it into memory to form a DOM or other kind of tree because it's too big.

22.8.2. Solution

Use SAX (as described in Recipe 22.3) to process events instead of building a tree.

Alternatively, use XML::Twig to build trees only for the parts of the document you want to work with (as specified by XPath expressions):

use XML::Twig;

my $twig = XML::Twig->new( twig_handlers => {
                               $XPATH_EXPRESSION => \&HANDLER,
                               # ...
                            });
$twig->parsefile($FILENAME);
$twig->flush( );

You can call a lot of DOM-like functions from within a handler, but only the elements identified by the XPath expression (and whatever those elements enclose) go into a tree.

22.8.3. Discussion

DOM modules turn the entire document into a tree, regardless of whether you use all of it. With SAX modules, there are no trees built—if your task depends on document structure, you must keep track of that structure yourself. A happy middle ground is XML::Twig, which creates DOM trees only for the bits of the file that you're interested in. Because you work with files a piece at a time, you can cope with very large files by processing pieces that fit in memory.

For example, to print the titles of books in books.xml (Example 22-1), you could write:

use XML::Twig;

my $twig = XML::Twig->new( twig_roots => { '/books/book' => \&do_book });
$twig->parsefile("books.xml");
$twig->purge( );

sub do_book {
  my($title) = $_->find_nodes("title");
  print $title->text, "\n";
}

For each book element, XML::Twig calls do_book on its contents. That subroutine finds the title node and prints its text. Rather than having the entire file parsed into a DOM structure, we keep only one book element at a time.

Consult the XML::Twig manpages for details on how much DOM and XPath the module supports—it's not complete, but it's growing all the time. XML::Twig uses XML::Parser for its XML parsing, and as a result the functions available on nodes are slightly different from those provided by XML::LibXSLT's DOM parsing.

22.8.4. See Also

Recipe 22.6; the documentation for the module XML::Twig

Previous | Home | Next
22.7. Processing XML Stylesheet Transformations | Book Index | 22.9. Reading and Writing RSS Files
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.9. Reading and Writing RSS Files

22.9.1. Problem

You want to create an Rich Site Summary (RSS) file, or read one produced by another application.

22.9.2. Solution

Use the CPAN module XML::RSS to read an existing RSS file:

use XML::RSS;

my $rss = XML::RSS->new;
$rss->parsefile($RSS_FILENAME);

my @items = @{$rss->{items}};
foreach my $item (@items) {
  print "title: $item->{'title'}\n";
  print "link: $item->{'link'}\n\n";
 }

To create an RSS file:

use XML::RSS;

my $rss  = XML::RSS->new (version => $VERSION);
$rss->channel( title       => $CHANNEL_TITLE,
               link        => $CHANNEL_LINK,
               description => $CHANNEL_DESC);
$rss->add_item(title       => $ITEM_TITLE,
               link        => $ITEM_LINK,
               description => $ITEM_DESC,
               name        => $ITEM_NAME);
print $rss->as_string;

22.9.3. Discussion

There are at least four variations of RSS extant: 0.9, 0.91, 1.0, and 2.0. At the time of this writing, XML::RSS understood all but RSS 2.0. Each version has different capabilities, so methods and parameters depend on which version of RSS you're using. For example, RSS 1.0 supports RDF and uses the Dublin Core metadata (http://dublincore.org/). Consult the documentation for what you can and cannot call.

XML::RSS uses XML::Parser to parse the RSS. Unfortunately, not all RSS files are well-formed XML, let alone valid. The XML::RSSLite module on CPAN offers a looser approach to parsing RSS—it uses regular expressions and is much more forgiving of incorrect XML.

Example 22-13 uses XML::RSSLite and LWP::Simple to download The Guardian's RSS feed and print out the items whose descriptions contain the keywords we're interested in.

Example 22-13. rss-parser

#!/usr/bin/perl -w
# guardian-list -- list Guardian articles matching keyword

use XML::RSSLite;
use LWP::Simple;
use strict;

# list of keywords we want
my @keywords = qw(perl internet porn iraq bush);

# get the RSS
my $URL = 'http://www.guardian.co.uk/rss/1,,,00.xml';
my $content = get($URL);

# parse the RSS
my %result;
parseRSS(\%result, \$content);

# build the regex from keywords
my $re = join "|", @keywords;
$re = qr/\b(?:$re)\b/i;

# print report of matching items
foreach my $item (@{ $result{items} }) {
  my $title = $item->{title};
  $title =~ s{\s+}{ };  $title =~ s{^\s+}{  }; $title =~ s{\s+$}{  };

  if ($title =~ /$re/) {
    print "$title\n\t$item->{link}\n\n";
  }
}

The following is sample output from Example 22-13:

UK troops to lead Iraq peace force
        http://www.guardian.co.uk/Iraq/Story/0,2763,989318,00.html?=rss

Shia cleric challenges Bush plan for Iraq
        http://www.guardian.co.uk/Iraq/Story/0,2763,989364,00.html?=rss

We can combine this with XML::RSS to generate a new RSS feed from the filtered items. It would be easier, of course, to do it all with XML::RSS, but this way you get to see both modules in action. Example 22-14 shows the finished program.

Example 22-14. rss-filter

#!/usr/bin/perl -w
# guardian-filter -- filter the Guardian's RSS feed by keyword
use XML::RSSLite;
use XML::RSS;
use LWP::Simple;
use strict;

# list of keywords we want
my @keywords = qw(perl internet porn iraq bush);

# get the RSS
my $URL = 'http://www.guardian.co.uk/rss/1,,,00.xml';
my $content = get($URL);

# parse the RSS
my %result;
parseRSS(\%result, \$content);

# build the regex from keywords
my $re = join "|", @keywords;
$re = qr/\b(?:$re)\b/i;

# make new RSS feed
my $rss = XML::RSS->new(version => '0.91');
$rss->channel(title       => $result{title},
              link        => $result{link},
              description => $result{description});

foreach my $item (@{ $result{items} }) {
  my $title = $item->{title};
  $title =~ s{\s+}{ };  $title =~ s{^\s+}{  }; $title =~ s{\s+$}{  };

  if ($title =~ /$re/) {
    $rss->add_item(title => $title, link => $item->{link});
  }
}
print $rss->as_string;

Here's an example of the RSS feed it produces:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
            "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">

<channel>
<title>Guardian Unlimited</title>
<link>http://www.guardian.co.uk</link>
<description>Intelligent news and comment throughout the day from The Guardian
newspaper</description>

<item>
<title>UK troops to lead Iraq peace force</title>
<link>http://www.guardian.co.uk/Iraq/Story/0,2763,989318,00.html?=rss</link>
</item>

<item>
<title>Shia cleric challenges Bush plan for Iraq</title>
<link>http://www.guardian.co.uk/Iraq/Story/0,2763,989364,00.html?=rss</link>
</item>

</channel>
</rss>

22.9.4. See Also

The documentation for the modules XML::RSS and XML::RSSLite

Previous | Home | Next
22.8. Processing Files Larger Than Available Memory | Book Index | 22.10. Writing XML
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


22.10. Writing XML

22.10.1. Problem

You have a data structure that you'd like to convert to XML.

22.10.2. Solution

Use XML::Simple's XMLout function:

use XML::Simple qw(XMLout);

my $xml = XMLout($hashref);

22.10.3. Discussion

The XMLout function takes a data structure and produces XML from it. For example, here's how to generate part of the book data:

#!/usr/bin/perl -w

use XML::Simple qw(XMLout);

$ds =  {
    book => [
              {
                id      => 1,
                title   => [ "Programming Perl" ],
                edition => [ 3 ],
              },
              {
                id      => 2,
                title   => [ "Perl & LWP" ],
                edition => [ 1 ],
              },
              {
                id      => 3,
                title   => [ "Anonymous Perl" ],
                edition => [ 1 ],
              },
             ]
  };

print XMLout($ds, RootName => "books" );

This produces:

<books>
  <book id="1">
    <edition>3</edition>
    <title>Programming Perl</title>
  </book>
  <book id="2">
    <edition>1</edition>
    <title>Perl &amp; </title
  </book>
  <book id="3">
    <edition>1</edition>
    <title>Anonymous Perl</title>
  </book>
</books>

The rule is: if you want something to be text data, rather than an attribute value, put it in an array. Notice how we used the RootName option to XMLout to specify that books is the top-level element. Pass undef or the empty string to generate an XML fragment with no top-level fragment. The default value is opt.

The id entry in each hash became an attribute because the default behavior of XMLout is to do this for the id, key, and name fields. Prevent this with:

XMLout($ds, RootName => "books", KeyAttr => [  ]);

As with XMLin (see Recipe 22.1), you can identify the hash values that are to become attributes for specific elements:

XMLout($ds, RootName => "books", KeyAttr => [ "car" => "license" ]);

That instructs XMLout to create attributes only for the license field in a car hash.

XML::Simple observes the convention that a hash key with a leading hyphen (e.g., -name) is private and should not appear in the XML output.

22.10.4. See Also

The documentation for the module XML::Simple; Recipe 22.1

Previous | Home | Next
22.9. Reading and Writing RSS Files | Book Index | Index
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Perl Cookbook: Index

Perl Cookbook
Previous Next

Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Symbols & Numbers

- (hyphen)
-0 command-line option: 8.. Basic Operations
-a command-line option, writing filters: 7.14.3.2. Command-line options
-e command-line option, writing filters: 7.14.3.2. Command-line options
-> (arrow) operator: 11.. References
13.. Methods
-> (infix) notation: 11.. References
-i command-line option
modifying files with: 7.16.2. Solution
writing filters: 7.14.3.2. Command-line options
-I command-line switch: 12.8.2. Solution
-n command-line option, writing filters: 7.14.3.2. Command-line options
-p command-line option
modifying files with: 7.16.2. Solution
writing filters: 7.14.3.2. Command-line options
-t command-line option: 15.2.2. Solution
- (minus sign), modifiers and: 6.18.3. Discussion
( ) (parentheses): 1.. Introduction
autouse pragma: 12.3.3. Discussion
prototyping functions: 10.11.3.1. Omitting parentheses
substitution: 6.1.3. Discussion
* (asterisk), typeglobs: 7.5.1. Problem
@ (at sign)
@_ array: 10.1.2. Solution
@EXPORT array (use pragma): 12.1.3. Discussion
@EXPORT_OK array (use pragma): 12.1.3. Discussion
@EXPORT_TAGS array (use pragma): 12.1.3. Discussion
@INC array: 12.8.3. Discussion
references to arrays: 11.1.2. Solution
splice( ): 4.12.3. Discussion
\ (backslash)
\1, \2, . . . (backreferences): 6.16.2. Solution
` string metacharacter: 1.18.3. Discussion
\a for terminal bell: 15.7.2. Solution
creating arrays: 11.6.2. Solution
creating references: 11.. Anonymous Data
\E string metacharacter: 1.18.3. Discussion
escaping characters: 1.18.1. Problem
\G anchor: 6.14.3. Discussion
\l string escape: 1.13.2. Solution
references to arrays: 11.1.3. Discussion
references to scalars: 11.5.2. Solution
\u string escape: 1.13.2. Solution
\X metacharacter: 1.8.3. Discussion
` (backtick)
executing commands without shell escapes: 19.5.3. Discussion
expanding: 1.15.3. Discussion
gathering program output: 16.1.2. Solution
running another program: 16.2.3. Discussion
: (colon)
module names: 12.. Modules
package names: 12.. Introduction
, (comma)
in numbers: 2.16.1. Problem
printing lists with: 4.2.1. Problem
-0 command-line option: 8.. Basic Operations
{} (curly braces): 1.. Introduction
creating anonymous arrays and hashes: 11.. References
$ (dollar sign)
$1, $2, . . . (backreferences): 1.11.3. Discussion
6.. Special Variables
finding doubled words: 6.16.2. Solution
$| variable: 7.. I/O Operations
7.19.2. Solution
$* variable (deprecated): 6.. Pattern-Matching Modifiers
$& variable: 1.11.3. Discussion
6.. Special Variables
$#ARRAY variable: 4.3.2. Solution
$^F variable: 12.7.3. Discussion
hashes: 5.. Introduction
$^I variable: 7.16.3. Discussion
$^O variable: 7.25. Program: lockarea
9.10.3. Discussion
$VERSION variable (use pragma): 12.1.3. Discussion
$^W variable: 12.14.3. Discussion
. (dot)
. . and . . . range operators: 6.8.2. Solution
period in numbers: 2.16.1. Problem
= (equals sign)
=~ operator: 1.1.3. Discussion
=begin pod directive: 12.20.3. Discussion
=end pod directive: 12.20.3. Discussion
=> operator: 5.. Introduction
/ (forward slash)
/e substitution modifier: 1.12.3. Discussion
6.. Pattern-Matching Modifiers
/g pattern-matching modifier: 6.. Pattern-Matching Modifiers
finding Nth matches: 6.5.2. Solution
where last pattern ended: 6.14.3. Discussion
/i pattern-matching modifier: 6.. Pattern-Matching Modifiers
/m pattern-matching modifier: 6.. Pattern-Matching Modifiers
multiple lines: 6.6.2. Solution
/o pattern-matching modifier: 6.10.2. Solution
root directory: 9.. Introduction
/s pattern-matching modifier: 6.. Pattern-Matching Modifiers
multiple lines: 6.6.2. Solution
/x pattern modifier: 1.12.3. Discussion
comments in regular expressions: 6.4.3. Discussion
% (percent sign)
hashes: 5.. Introduction
%SIG hash: 16.15.2. Solution
+ (plus sign), file-access modes: 7.1.3. Discussion
# (pound sign), with printf( ): 2.15.3. Discussion
' (single quote): 1.. Introduction
escaping: 14.10.1. Problem
[] (square brackets): 1.. Introduction
creating anonymous arrays and hashes: 11.. References
~ (tilde), in filenames, expanding: 7.3.1. Problem
_ (underscore), file stat cache: 9.. Introduction
$0 variable: 7.12.3. Discussion
| (vertical bar)
||= (assignment) operator: 1.2.2. Solution
|| operator
vs. or operator: 1.2.3. Discussion
separating multiple comparisons: 4.16.3. Discussion
& (ampersand), && operator: 1.2.3. Discussion
> (right angle bracket), file-access modes: 7.. I/O Operations
7.1.3. Discussion
< (left angle bracket)
file-access modes: 7.. I/O Operations
7.1.3. Discussion
<&= and <& open modes: 7.9.2. Solution
<FH> line input operator: 7.. I/O Operations
<=> numerical comparison operator: 4.15.2. Solution
<> (angle brackets): 1.. Introduction
globbing: 9.6.2. Solution
line input operator: 7.14.2. Solution
reading strings from binary files: 8.14.2. Solution
" (double quote): 1.. Introduction
escaping: 14.10.1. Problem

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

-a command-line option, writing filters: 7.14.3.2. Command-line options
\a for terminal bell: 15.7.2. Solution
abbrev( ): 6.20.3. Discussion
abbreviations, matching: 6.20.1. Problem
accept( ): 17.2.3. Discussion
IO::Multiplex module: 17.19.2. Solution
access log, web server: 19.. Behind the Scenes
20.12.1. Problem
access to databases (see database access)
addresses, email, matching: 6.19.1. Problem
adist( ): 1.22.3. Discussion
advisory locking: 7.18.2. Solution
alarm( ): 3.9.3. Discussion
16.21.2. Solution
alarm, ringing: 15.7.1. Problem
Alias module: 13.3.3. Discussion
aliases
for filehandles: 7.10.1. Problem
for functions: 10.14.3. Discussion
for list elements: 4.5.3. Discussion
American Standard Code for Information Interchange (see ASCII)
ampersand (&), && operator: 1.2.3. Discussion
AND functionality in regular expressions: 6.18.1. Problem
angle brackets (<>): 1.. Introduction
9.6.2. Solution
line input operator: 7.14.2. Solution
reading strings from binary files: 8.14.2. Solution
angles, in degrees vs. radians: 2.10.1. Problem
anonymous data: 11.. Anonymous Data
Apache web server
(see also mod_perl)
handlers, writing: 21.. Handlers
internal redirection: 21.4.3. Discussion
log files: 20.12.1. Problem
logging requests, customizing: 21.9.1. Problem
notes: 21.11.3. Discussion
phases of request-response transaction: 21.. Apache Phases
pnotes, sharing information between handlers: 21.13.2. Solution
Apache::Cookie module: 21.2.2. Solution
accessing values: 21.3.2. Solution
Apache::DBI module: 21.8.2. Solution
Apache::DBILogger module: 21.9.3. Discussion
Apache::DProf module: 21.15.2. Solution
Apache::PerlRun module: 21.. Introduction
migrating from CGI to mod_perl: 21.12.2. Solution
Apache::Registry module: 21.. Introduction
migrating from CGI to mod_perl: 21.12.2. Solution
Apache::Reload module: 21.14.2. Solution
Apache::Request module
accessing form parameters: 21.6.2. Solution
receiving uploaded files: 21.7.2. Solution
Apache::StatINC module: 21.14.2. Solution
Apache::Template module (see Template Toolkit)
Apache::Timeit module: 21.15.2. Solution
Apache::Traffic module: 21.9.3. Discussion
appendChild( ): 22.2.3. Discussion
appendhash_demo program: 13.15.5. Tie Example: Make a Hash That Always Appends
appending arrays to each other: 4.10.1. Problem
applications
mod_perl, benchmarking: 21.15.1. Problem
shopping cart: 19.11.1. Problem
approximate matching: 6.13.1. Problem
arguments, subroutine: 10.1.1. Problem
function prototypes: 10.11.1. Problem
passing by named parameter: 10.7.1. Problem
passing by reference: 10.5.1. Problem
ARGV line input operator: 7.. I/O Operations
ARGV, magic: 8.25. Program: tctee
16.6.3. Discussion
arithmetic
complex (imaginary) numbers: 2.14.1. Problem
matrix multiplication: 2.13.1. Problem
$#ARRAY variable: 4.3.2. Solution
arrays: 4.. Introduction
anonymous: 11.. Anonymous Data
appending multiple: 4.10.1. Problem
changing size of: 4.3.1. Problem
circular: 4.17.1. Problem
extracting
elements: 4.7.1. Problem
subsets: 4.14.1. Problem
subsets with grep: 4.14.2. Solution
hashes of: 11.2.1. Problem
initializing: 4.1.1. Problem
initializing, with comma-separated values: 4.1.2. Solution
iterating
over by reference: 4.6.1. Problem
through all elements: 4.5.1. Problem
through elements: 4.13.1. Problem
last valid index ($#ARRAY): 4.3.3. Discussion
vs. lists: 4.. Introduction
matrix multiplication: 2.13.1. Problem
multidimensional: 4.. Introduction
permute program: 4.20. Program: permute
printing elements with commas: 4.2.1. Problem
processing multiple elements: 4.12.1. Problem
randomizing: 4.18.1. Problem
randomly selecting from: 2.6.3. Discussion
reading files backwards: 8.4.1. Problem
references to: 11.1.1. Problem
reversing elements of: 4.11.1. Problem
of scalar references: 11.6.1. Problem
sorting
by computable field: 4.16.1. Problem
elements numerically: 4.15.1. Problem
sparse, implementing: 4.4.1. Problem
treating files as: 8.18.1. Problem
unions, intersections, differences: 4.8.1. Problem
words program: 4.19. Program: words
arrow (->) operator: 11.. References
13.. Methods
ASCII (American Standard Code for Information Interchange): 1.. The Universal Character Code
characters (see characters)
converting HTML to: 20.5.1. Problem
assignment (||=) operator: 1.2.2. Solution
assignment, list: 1.3.2. Solution
associative arrays (see hashes)
asterisk (*), typeglobs: 7.5.1. Problem
at sign (@)
@_ array: 10.1.2. Solution
@EXPORT array (use pragma): 12.1.3. Discussion
@EXPORT_OK array (use pragma): 12.1.3. Discussion
@EXPORT_TAGS array (use pragma): 12.1.3. Discussion
@INC array: 12.8.3. Discussion
references to arrays: 11.1.2. Solution
splice( ): 4.12.3. Discussion
atime field, inode structure: 9.. Introduction
attach( ): 18.9.2. Solution
attributes, object: 13.3.1. Problem
Authen::SASL module: 18.8.3. Discussion
authentication
fetching password-protected web pages: 20.15.1. Problem
with mod_perl: 21.1.1. Problem
realms: 20.15.3. Discussion
autoflush( ): 7.19.2. Solution
16.10.3. Discussion
AUTOLOAD mechanism: 13.. Methods
generating methods: 13.12.1. Problem
trapping undefining function calls: 10.15.2. Solution
AutoLoader module: 12.11.1. Problem
autouse pragma: 12.3.3. Discussion
autovivification: 11.. Anonymous Data

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

B-tree implementation, DB_File: 14.5.3. Description
backreferences
\1, \2, . . .: 6.. Special Variables
finding doubled words: 6.16.2. Solution
backslash (\)
\1, \2, . . . (backreferences): 6.16.2. Solution
` string metacharacter: 1.18.3. Discussion
\a for terminal bell: 15.7.2. Solution
creating arrays: 11.6.2. Solution
creating references: 11.. Anonymous Data
\E string metacharacter: 1.18.3. Discussion
escaping characters: 1.18.1. Problem
\G anchor: 6.14.3. Discussion
\l string escape: 1.13.2. Solution
passing arrays and hashes by references: 10.5.2. Solution
10.5.2. Solution
references to arrays: 11.1.3. Discussion
references to scalars: 11.5.2. Solution
\u string escape: 1.13.2. Solution
\X metacharacter: 1.8.3. Discussion
backsniff program: 17.20. Program: backsniff
backtick (`)
executing commands without shell escapes: 19.5.3. Discussion
expanding: 1.15.3. Discussion
gathering program output: 16.1.2. Solution
running another program: 16.2.3. Discussion
backtracking
finding doubled words: 6.16.3. Discussion
in pattern matching: 6.. The Tricky Bits
bake( ): 21.2.3. Description
base class: 13.. Some Notes on Object Terminology
empty base class test: 13.10.3. Discussion
basename( ), splitting filenames: 9.10.3. Discussion
=begin pod directive: 12.20.3. Discussion
bell, ringing: 15.7.1. Problem
benchmarking mod_perl applications: 21.15.1. Problem
Berkeley DB library: 14.. Introduction
bgets program: 8.14.3. Discussion
biased random numbers, generating: 2.9.1. Problem
bidirectional clients: 17.10.1. Problem
binary
files: 8.11.1. Problem
reading null-terminated strings: 8.14.1. Problem
numbers, converting: 2.15.1. Problem
trees: 11.17. Program: Binary Trees
bind( ), LDAP server: 18.8.3. Discussion
binding, databases: 14.12.3. Discussion
binmode( ): 8.. I/O Layers
8.11.2. Solution
bless( ): 13.. Under the Hood
13.1.2. Solution
blocking( ): 7.. Getting a Handle on the File
blocking file access: 7.18.1. Problem
netlock program: 7.24. Program: netlock
reading a line from a filehandle without: 7.23.1. Problem
region-specific locks: 7.25. Program: lockarea
blocking signals: 16.20.1. Problem
Boolean connectives in patterns: 6.18.1. Problem
browsers
redirecting
with CGI: 19.7.1. Problem
with mod_perl: 21.4.1. Problem
support for Unicode fonts: 8.21.3. Discussion
buffered input/output: 7.. I/O Operations
7.19.3. Discussion
8.. Advanced Operations
controlling for other programs: 16.8.1. Problem
socket programming and: 17.3.3. Discussion
building
C extension modules: 12.19.1. Problem
modules from CPAN: 12.21.1. Problem
bytes, determining number of unread: 7.21.1. Problem
bytes I/O layer: 8.. I/O Layers

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C
extension modules, building: 12.19.1. Problem
writing modules in: 12.18.1. Problem
-C command-line switch: 8.21.3. Discussion
8.21.3. Discussion
C header files, translating with h2ph: 12.17.1. Problem
cacheout( ): 7.7.3. Discussion
caching open filehandles: 7.7.1. Problem
calc_new_date( ): 3.4.2. Solution
calc_new_date_time( ): 3.4.2. Solution
calculating prime numbers: 2.18. Program: Calculating Prime Factors
caller( ): 12.6.2. Solution
names of subroutines: 10.4.2. Solution
can( ): 13.8.3. Discussion
can_read( ): 7.23.3. Discussion
capitalization
case-insensitive hashes: 13.15.6. Tie Example: Case-Insensitive Hash
converting case: 1.13.1. Problem
honoring locale when matching: 6.12.1. Problem
of titles and headlines: 1.14.1. Problem
Carp module: 12.14.2. Solution
carriage returns (see line breaks whitespace)
cascading menu entries: 15.14.3. Discussion
case sensitivity
capitalizing titles and headlines: 1.14.1. Problem
converting case: 1.13.1. Problem
hashes: 13.15.6. Tie Example: Case-Insensitive Hash
honoring locale when matching: 6.12.1. Problem
cbreak mode: 15.6.2. Solution
CDATA, XML: 22.. CDATA
ceil( ): 2.2.3. Discussion
CGI programming: 19.. Introduction
chemiserie program: 19.13. Program: chemiserie
cookies: 19.9.1. Problem
debugging raw HTTP exchange: 19.8.1. Problem
fixing 500 server errors: 19.3.1. Problem
form parameters: 19.1.3. Discussion
19.12.3. Discussion
HTTP methods: 19.. Behind the Scenes
19.1.3. Discussion
improving efficiency of: 21.12.1. Problem
migrating to mod_perl: 21.12.1. Problem
multiscreen scripts: 19.11.1. Problem
performance: 21.. Introduction
21.. Introduction
redirecting browsers: 19.7.1. Problem
redirecting error messages: 19.2.1. Problem
saving and mailing HTML forms: 19.12.1. Problem
security and: 19.. Security
19.4.1. Problem
executing user commands: 19.5.1. Problem
shopping cart application, developing: 19.11.1. Problem
sticky widgets: 19.10.1. Problem
writing scripts: 19.1.1. Problem
CGI::Carp module: 19.2.2. Solution
19.3.3.3. Is the script valid Perl?
CGI::Cookie module: 21.2.3. Description
accessing values: 21.3.3. Discussion
CGI.pm module: 19.. Architecture
creating sticky widgets: 19.10.2. Solution
HTML helper functions: 19.6.2. Solution
managing cookies: 19.9.1. Problem
writing CGI scripts: 19.1.3. Discussion
characters
converting ASCII to and from HTML: 20.4.1. Problem
converting between values: 1.4.1. Problem
converting case: 1.13.1. Problem
escaping: 1.18.1. Problem
matching letters: 6.2.1. Problem
parsing command-line arguments: 15.1.1. Problem
processing individually: 1.6.1. Problem
reversing: 1.7.1. Problem
text color, changing: 15.5.1. Problem
charnames: 1.5.3. Discussion
charnames::viacode( ): 1.5.3. Discussion
charnames::vianame( ): 1.5.3. Discussion
checkbutton menu entries: 15.14.3. Discussion
chemiserie program: 19.13. Program: chemiserie
chr( ): 1.4.3. Discussion
circular
data structures: 13.13.1. Problem
lists: 4.17.1. Problem
class attributes (see class data)
class data: 13.4.1. Problem
circular data structures: 13.13.1. Problem
class methods: 13.. Methods
13.. Some Notes on Object Terminology
13.4.2. Solution
classes: 13.. Under the Hood
accessing overridden methods: 13.11.1. Problem
determining subclass membership: 13.9.1. Problem
generating methods with AUTOLOAD: 13.. Methods
13.12.1. Problem
generic: 13.. Some Notes on Object Terminology
inheritance: 13.. Inheritance
13.10.1. Problem
as structs: 13.5.1. Problem
superclasses: 13.. Some Notes on Object Terminology
Class::Struct module: 13.5.2. Solution
cleaning up after modules: 12.7.1. Problem
clear command, clearing the screen: 15.3.2. Solution
clearerr( ): 8.5.3. Discussion
clients
bidirectional: 17.10.1. Problem
FTP: 18.2.1. Problem
TCP: 17.1.1. Problem
UDP, setting up: 17.4.1. Problem
close( )
file descriptors: 7.9.1. Problem
file locks: 7.18.3. Discussion
filehandles: 7.. I/O Operations
closedir( ): 9.. Introduction
closures: 10.16.3. Discussion
11.4.3. Discussion
12.16.3. Discussion
as objects: 11.7.1. Problem
code handlers (see handlers)
code points, Unicode: 1.. Unicode Support in Perl
code size, library: 14.. Introduction
colon (:)
module names: 12.. Modules
package names: 12.. Introduction
color( ): 15.5.3. Discussion
color of text, changing: 15.5.1. Problem
columns
arranging du command output: 5.17. Program: dutree
outputting text by: 4.19. Program: words
parsing data by: 1.1.3. Discussion
wrapping paragraphs by: 1.17.1. Problem
comma (,)
in numbers: 2.16.1. Problem
printing lists with: 4.2.1. Problem
comma-separated values (see CSV)
command
entry, menu items: 15.14.3. Discussion
interpreters: 1.18.3. Discussion
command-line arguments, parsing: 15.1.1. Problem
comments
pod documentation for modules: 12.20.1. Problem
in regular expressions: 6.4.1. Problem
XML: 22.. Comments
commify( ): 2.16.3. Discussion
commify_series program: 4.2.2. Solution
commit( ): 14.15.2. Solution
Common Log Format standard: 20.12.3. Discussion
communicating between mod_perl and PHP: 21.11.1. Problem
compare( ): 8.22.3. Discussion
comparing
contents of two files: 8.22.1. Problem
filehandles: 8.22.3. Discussion
floating-point numbers: 2.3.1. Problem
currency: 2.3.3. Discussion
keys of hashes: 5.12.1. Problem
complex numbers: 2.14.1. Problem
Comprehensive Perl Archive Network (see CPAN)
compressing tabs: 1.11.1. Problem
confess( ): 12.14.2. Solution
Config module: 16.13.2. Solution
configuration files
Boolean connectives in patterns: 6.18.1. Problem
reading: 8.16.1. Problem
Configure event, Tk: 15.16.2. Solution
connect( ), LDAP server: 18.8.3. Discussion
constants: 1.21.1. Problem
constructors: 13.. Methods
13.1.1. Problem
accessing overridden methods: 13.11.1. Problem
cloning parent objects: 13.6.1. Problem
continuation characters, reading data with: 8.1.1. Problem
converting
ASCII to and from HTML: 20.4.1. Problem
character case: 1.13.1. Problem
characters and values: 1.4.1. Problem
date and time to and from Epoch seconds: 3.2.1. Problem
DBM files: 14.3.1. Problem
degrees and radians: 2.10.1. Problem
HTML tables into Perl data structures: 20.19.1. Problem
HTML to ASCII: 20.5.1. Problem
Microsoft files to Unicode: 8.21.1. Problem
numbers: 2.15.1. Problem
Roman numerals and: 2.5.1. Problem
pod into other languages: 12.20.3. Discussion
shell wildcards for regular expression matching: 6.9.1. Problem
strings
case of: 1.13.1. Problem
between characters and values: 1.4.2. Solution
non-numeric: 2.. Introduction
cookie_jar( ): 20.14.3. Discussion
cookies
accessing values with mod_perl: 21.3.1. Problem
CGI: 19.9.1. Problem
setting in mod_perl: 21.2.1. Problem
web automation and: 20.14.1. Problem
copy( ): 9.3.3. Discussion
copy constructors: 13.7.1. Problem
copying
data structures: 11.12.1. Problem
directory trees: 9.12. Program: symirror
filehandles: 7.10.1. Problem
files: 9.3.1. Problem
parent objects: 13.6.1. Problem
surface vs. deep copies: 11.12.3. Discussion
cos( ): 2.11.2. Solution
counting lines in files: 8.2.1. Problem
CPAN (Comprehensive Perl Archive Network): 12.. Not Reinventing the Wheel
building and installing modules from: 12.21.1. Problem
registering as developer: 12.9.3. Discussion
CPANPLUS module: 12.21.3. Discussion
12.23. Program: Finding Versions and Descriptions of Installed Modules
createElement( ): 22.2.3. Discussion
createTextNode( ): 22.2.3. Discussion
creating
charts: 15.18.1. Problem
15.23. Program: graphbox
magic variables: 13.15.1. Problem
menus with Tk toolkit: 15.14.1. Problem
processes: 16.. Process Creation
references to methods: 11.8.1. Problem
robots for Web traversal: 20.11.1. Problem
sticky widgets: 19.10.1. Problem
temporary files: 7.11.1. Problem
credentials( ): 20.15.2. Solution
crlf I/O layer: 8.. I/O Layers
8.. I/O Layers
8.11.3. Discussion
croak( ): 12.14.2. Solution
Crypt::SSLeay module: 20.16.2. Solution
CSV (comma-separated values)
initializing arrays with: 4.1.2. Solution
parsing: 1.20.1. Problem
reading records from: 6.7.1. Problem
CSV files, saving results of SQL queries: 14.8.1. Problem
ctime field, inode structure: 9.. Introduction
Ctrl-C, catching: 16.18.1. Problem
curly braces ({}): 1.. Introduction
creating anonymous arrays and hashes: 11.. References
currency, comparing floating-point numbers: 2.3.3. Discussion
Curses module: 15.12.2. Solution
curses toolkit: 15.. Introduction
customizing
Apache logging requests: 21.9.1. Problem
warnings: 12.15.1. Problem
Cwd module: 12.12.3. Discussion

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

-d file test operator: 9.7.3. Discussion
daemon servers: 16.23. Program: sigrand
17.17.1. Problem
data, relationships between
5.16.1. Problem
(see also variables)
data structures
binary trees: 11.17. Program: Binary Trees
circular, coping with, using weak references: 11.15.1. Problem
complex, creating on the fly: 11.. Anonymous Data
copying: 11.12.1. Problem
outlines: 11.16. Program: Outlines
parsing XML into: 22.1.1. Problem
printing: 11.11.1. Problem
storing to disk: 11.13.1. Problem
transparently persistent: 11.14.1. Problem
__DATA__ token: 7.12.2. Solution
data types
circular data structures: 13.13.1. Problem
classes as structs: 13.5.1. Problem
database access: 14.. Introduction
DBM files
converting between: 14.3.1. Problem
emptying: 14.2.1. Problem
making and using: 14.1.1. Problem
merging: 14.4.1. Problem
sorting: 14.5.1. Problem
storing complex data in: 14.6.1. Problem
dealing with errors: 14.11.1. Problem
ggh program: 14.19. Program: ggh—Grep Netscape Global History
persistent data: 14.7.1. Problem
speeding up with mod_perl: 21.8.1. Problem
SQL: 20.9.3. Discussion
queries: 14.9.1. Problem
14.14.1. Problem
19.6.3. Discussion
using transactions: 14.15.1. Problem
viewing data one page at a time: 14.16.1. Problem
Data::Dumper module: 11.11.2. Solution
datagram sockets: 17.4.3. Discussion
date and time values: 3.. Introduction
arithmetic with: 3.4.1. Problem
converting to and from Epoch seconds: 3.2.1. Problem
Date::DateCalc: 3.4.1. Problem
Date::Manip module: 3.8.3. Discussion
3.11. Program: hopdelta
days, calculating: 3.6.1. Problem
number between two dates: 3.5.1. Problem
file access timestamps: 9.1.1. Problem
high-resolution timers: 3.9.1. Problem
hopdelta program: 3.11. Program: hopdelta
parsing information from strings: 3.7.1. Problem
printing: 3.8.1. Problem
seconds passed since Epoch: 3.. Introduction
sleeps: 3.10.1. Problem
sorting mail by: 10.18. Program: Sorting Your Mail
Time::gmtime module: 3.3.2. Solution
Time::HiRes module: 3.9.2. Solution
Time::Local module: 3.2.2. Solution
Time::timelocal module: 3.3.2. Solution
timing out operations: 16.21.1. Problem
today's date, finding: 3.1.1. Problem
years: 3.. Introduction
DateCalc( ): 3.11. Program: hopdelta
Date::Calc module: 3.4.2. Solution
3.6.2. Solution
Date::DateCalc module: 3.. Introduction
Date::Manip module: 3.. Introduction
3.7.2. Solution
3.11. Program: hopdelta
day, month, year, hour, minute, seconds (DMYHMS): 3.. Introduction
Day_of_week( ): 3.6.2. Solution
Day_of_Year( ): 3.6.2. Solution
days (see date and time values)
DBD module: 14.9.2. Solution
DBD::CSV module: 14.17.2. Solution
DBD::SQLite module: 14.. Introduction
14.18.2. Solution
DB_File module: 11.14.2. Solution
DB_RECNO access method: 8.8.2. Solution
sorting large DBM files: 14.5.2. Solution
db2gdbm program: 14.3.2. Solution
DBI module: 14.9.2. Solution
DBIx::Dump module: 14.8.2. Solution
DBM files
complex data in: 14.6.1. Problem
converting between: 14.3.1. Problem
emptying: 14.2.1. Problem
GDBM files: 14.3.2. Solution
making and using: 14.1.1. Problem
merging: 14.4.1. Problem
sorting: 14.5.1. Problem
DBM libraries: 14.. Introduction
dclone( ): 11.12.2. Solution
13.7.2. Solution
debugging
CGI scripts: 19.. Behind the Scenes
19.3.3.3. Is the script valid Perl?
raw HTTP exchange: 19.8.1. Problem
deep copies: 11.12.3. Discussion
default values for variables: 1.2.1. Problem
defined operator: 1.2.3. Discussion
definedness: 1.. Introduction
1.2.3. Discussion
deg2rad( ): 2.10.3. Discussion
delaying module loading: 12.3.1. Problem
delete( ): 5.4.2. Solution
compared to undef( ): 5.4.3. Discussion
multiple hash key values: 5.8.3. Discussion
deleting
clearing the screen: 15.3.1. Problem
directories and their contents: 9.8.1. Problem
DOS shell window: 15.17.1. Problem
emptying DBM files: 14.2.1. Problem
files: 9.2.1. Problem
last line of: 8.10.1. Problem
hash elements: 5.4.1. Problem
HTML tags from strings: 20.6.1. Problem
selected subroutine return values: 10.8.1. Problem
whitespace at string ends: 1.19.1. Problem
delimiters: 1.. Introduction
Delta_Days( ): 3.5.3. Discussion
Delta_DHMS( ): 3.5.3. Discussion
dequote( ): 1.16.3. Discussion
dereferencing (see references)
destructors: 13.. Methods
13.2.1. Problem
Devel::Peek module: 11.15.3. Description
diacritics: 1.8.3. Discussion
converting case and: 1.13.3. Discussion
dialog boxes with Tk toolkit: 15.15.1. Problem
DialogBox widget, Tk: 15.15.2. Solution
die function: 10.12.2. Solution
__DIE__ signal: 16.15.3. Discussion
differences of lists: 4.8.1. Problem
computing: 4.9.1. Problem
simple and symmetric: 4.9.3. Discussion
directories: 9.. Introduction
copying and moving files: 9.3.1. Problem
deleting: 9.8.1. Problem
deleting files: 9.2.1. Problem
multiple names for same file: 9.4.1. Problem
of modules: 12.8.1. Problem
parsing filenames: 9.10.1. Problem
processing all files in: 9.5.1. Problem
recursively: 9.7.1. Problem
recursively duplicating: 9.12. Program: symirror
renaming files: 9.9.1. Problem
sorting contents of: 9.. Introduction
9.13. Program: lst
timestamps: 9.1.1. Problem
directory handles: 9.. Executive Summary
dirname( ): 9.10.3. Discussion
disk usage, library: 14.. Introduction
Distinguished Name (DN): 18.8.3. Discussion
DMYHMS (day, month, year, hour, minute, seconds): 3.. Introduction
DMYHMS values (see date and time values)
DN (Distinguished Name): 18.8.3. Discussion
DNS lookups: 18.1.1. Problem
do( ): 10.. Introduction
configuration files, reading: 8.16.3. Discussion
finding number of rows returned by SQL queries: 14.14.2. Solution
Document Object Model (DOM): 22.. History of Perl and XML
dollar sign ($)
$1, $2, . . . (backreferences): 1.11.3. Discussion
6.. Special Variables
finding doubled words: 6.16.2. Solution
$| variable: 7.. I/O Operations
7.19.2. Solution
$* variable (deprecated): 6.. Pattern-Matching Modifiers
$& variable: 1.11.3. Discussion
6.. Special Variables
$#ARRAY variable: 4.3.2. Solution
$^F variable: 12.7.3. Discussion
hashes: 5.. Introduction
$^I variable: 7.16.3. Discussion
$^O variable: 7.25. Program: lockarea
9.10.3. Discussion
$VERSION variable (use pragma): 12.1.3. Discussion
$^W variable: 12.14.3. Discussion
DOM (Document Object Model): 22.. History of Perl and XML
trees: 22.. History of Perl and XML
building while validating XML: 22.5.3. Discussion
parsing XML into: 22.2.1. Problem
domains for sockets: 17.. Introduction
DOS shell window, removing: 15.17.1. Problem
dot (.)
. . and . . . range operators: 6.8.2. Solution
periods in numbers: 2.16.1. Problem
double quote ("): 1.. Introduction
escaping: 14.10.1. Problem
double words, finding: 6.16.1. Problem
du command, sorting output of: 5.17. Program: dutree
Dump( ): 11.15.3. Description
Dumpvalue module: 5.6.3. Discussion
duplicate list elements, extracting: 4.7.1. Problem
dutree program: 5.17. Program: dutree
dynamic scoping: 10.13.3.3. Using local( ) on parts of aggregates

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

-e command-line option, writing filters: 7.14.3.2. Command-line options
\E string metacharacter: 1.18.3. Discussion
/e substitution modifier: 1.12.3. Discussion
6.. Pattern-Matching Modifiers
each( ): 5.5.2. Solution
hashes
merging: 5.11.3. Discussion
ordering elements of: 5.7.1. Problem
traversing: 5.5.3. Discussion
eager pattern matching: 6.. The Tricky Bits
echo and password input: 15.10.1. Problem
editing
files (see file contents)
input: 15.11.1. Problem
elements
of arrays (see arrays)
of hashes (see hashes)
email
attachments
extracting: 18.10.1. Problem
sending: 18.9.1. Problem
matching valid addresses: 6.19.1. Problem
random signatures: 16.23. Program: sigrand
reading with POP3: 18.5.1. Problem
sending: 18.3.1. Problem
HTML forms via: 19.12.1. Problem
sorting: 10.18. Program: Sorting Your Mail
tracking time path of: 3.11. Program: hopdelta
Email::Valid module: 6.19.3. Discussion
empty
base class test: 13.10.3. Discussion
strings (""): 1.. Introduction
Encode module: 8.20.3. Discussion
encoding attribute, XML: 22.. XML Declaration
=end pod directive: 12.20.3. Discussion
__END__ token: 7.12.2. Solution
environment variables
MHCONTEXTFD: 7.9.3. Discussion
PERL_UNICODE: 8.21.3. Discussion
Epoch (see date and time values)
equals sign (=)
=~ operator: 1.1.3. Discussion
=begin pod directive: 12.20.3. Discussion
=end pod directive: 12.20.3. Discussion
=> operator: 5.. Introduction
error log, web server: 19.. Behind the Scenes
errors
(see also exceptions)
CGI scripts: 19.. Behind the Scenes
fixing 500 server in: 19.3.1. Problem
redirecting messages from: 19.2.1. Problem
controlling for other programs: 16.9.1. Problem
database: 14.11.1. Problem
reading STDERR from programs: 16.7.1. Problem
reporting filenames in: 7.4.1. Problem
reporting like built-ins: 12.14.1. Problem
subroutines
exceptions in: 10.12.1. Problem
returning failure from: 10.10.1. Problem
trapping in require and use statements: 12.2.1. Problem
trapping undefined function calls: 10.15.1. Problem
turning signals into: 16.22.1. Problem
web server error log: 20.13.1. Problem
escaping characters: 1.18.1. Problem
eval( )
with require and use statements: 12.2.2. Solution
in substitution: 1.12.3. Discussion
6.. Pattern-Matching Modifiers
events, Tk resize: 15.16.1. Problem
Excel, saving SQL query results to: 14.8.1. Problem
exceptions
handling in subroutines: 10.12.1. Problem
trapping undefined function calls: 10.15.1. Problem
exclusive locks: 7.18.3. Discussion
exec( )
replacing programs: 16.3.2. Solution
shell escapes: 19.5.3. Discussion
exists( ): 5.2.2. Solution
multiple hash key values: 5.8.3. Discussion
expanding
tabs: 1.11.1. Problem
variables in user input: 1.12.1. Problem
Expect module: 15.13.2. Solution
controlling programs with: 15.13.1. Problem
EXPN command: 18.16. Program: expn and vrfy
expn program: 18.16. Program: expn and vrfy
@EXPORT array (use pragma): 12.1.3. Discussion
Exporter module: 12.. Import/Export Regulations
12.1.1. Problem
exporting to modules: 12.. Import/Export Regulations
@EXPORT_OK array (use pragma): 12.1.3. Discussion
@EXPORT_TAGS array (use pragma): 12.1.3. Discussion
expressions, interpolating within strings: 1.15.1. Problem
Extensible Markup Language (see XML)
extension modules, C, building: 12.19.1. Problem
external redirection: 21.4.3. Discussion
extract_bracketed( ), matching nested patterns: 6.17.2. Solution
extracting array subsets: 4.14.2. Solution
extracting from arrays (see arrays)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

factorial( ): 4.20. Program: permute
failure, returning from subroutines: 10.10.1. Problem
false values: 1.. Introduction
fcntl( ), return values: 10.10.3. Discussion
FETCH( ): 13.15.3. Discussion
fetching URLs from Perl scripts: 20.1.1. Problem
<FH> line input operator: 8.. Basic Operations
FIFOs (named pipes): 16.11.1. Problem
file access
9.. Introduction
(see also directories file contents)
access modes: 7.. I/O Operations
7.1.3. Discussion
copying and moving files: 9.3.1. Problem
editing files (see file contents)
filehandles: 7.. Getting a Handle on the File
7.. Standard Filehandles
caching open: 7.7.1. Problem
copying: 7.10.1. Problem
printing to multiple: 7.8.1. Problem
reading a line from, without blocking: 7.23.1. Problem
reading from multiple: 7.22.1. Problem
filtering filename input: 7.14.1. Problem
command-line options: 7.14.3.2. Command-line options
flushing output: 7.19.1. Problem
locking files: 7.18.1. Problem
netlock program: 7.24. Program: netlock
region-specific locks: 7.25. Program: lockarea
non-blocking I/O: 7.20.1. Problem
opening and closing file descriptors: 7.9.1. Problem
processing all files in directories: 9.5.1. Problem
recursively: 9.7.1. Problem
storing files in program text: 7.12.1. Problem
timestamps: 9.1.1. Problem
unread bytes, determining number of: 7.21.1. Problem
file contents: 8.. Introduction
9.. Introduction
(see also directories; file access)
adding records to wtmp file: 8.24. Program: tailwtmp
comparing two files: 8.22.1. Problem
configuration files, reading: 8.16.1. Problem
continually growing files, reading: 8.5.1. Problem
converting Microsoft files to Unicode: 8.21.1. Problem
counting lines, paragraphs, and records: 8.2.1. Problem
extracting single line: 8.8.1. Problem
fixed-length records: 8.. Advanced Operations
reading: 8.15.1. Problem
I/O layers: 8.. I/O Layers
modifying
with -i switch: 7.16.1. Problem
with temporary files: 7.15.1. Problem
without temporary files: 7.17.1. Problem
processing all words in: 8.3.1. Problem
processing binary files: 8.11.1. Problem
random access
input/output: 8.12.1. Problem
updating: 8.13.1. Problem
random lines from, selecting: 8.6.1. Problem
randomizing line order: 8.7.1. Problem
reading
backwards: 8.4.1. Problem
lines with continuation characters: 8.1.1. Problem
null-terminated strings from binary files: 8.14.1. Problem
reading and writing hash records to file: 11.10.1. Problem
reading and writing Unicode from filehandles: 8.20.1. Problem
setting default I/O layers: 8.19.1. Problem
tctee program: 8.25. Program: tctee
testing for trustworthiness: 8.17.1. Problem
treating
files as arrays: 8.18.1. Problem
strings as files: 8.23.1. Problem
variable-length text fields: 8.9.1. Problem
viewing lastlog file information: 8.26. Program: laston
file descriptors, opening and closing: 7.9.1. Problem
file extensions: 12.. Other Kinds of Library Files
__FILE__ symbol: 10.4.3. Discussion
file test operators: 9.. Introduction
File::Basename module: 9.10.2. Solution
FileCache module: 7.7.2. Solution
File::chmod module: 9.11.3. Discussion
File::Compare module: 8.22.2. Solution
File::Copy module: 9.3.1. Problem
9.3.2. Solution
File::Find module: 9.7.2. Solution
removing directories recursively: 9.8.2. Solution
File::Glob module: 7.3.3. Discussion
filehandles: 7.. Getting a Handle on the File
autovivified: 7.5.3. Discussion
caching: 7.7.1. Problem
comparing: 8.22.3. Discussion
copying: 7.10.1. Problem
local: 10.13.3.2. Using local( ) for local handles
non-blocking I/O: 7.20.1. Problem
passing: 10.13.3.2. Using local( ) for local handles
12.6.3. Discussion
printing to multiple simultaneously: 7.8.1. Problem
reading
a line from, without blocking: 7.23.1. Problem
from many: 7.22.1. Problem
reading and writing Unicode from: 8.20.1. Problem
reporting filenames in errors: 7.4.1. Problem
seek offset: 7.. I/O Operations
standard: 7.. Standard Filehandles
storing in variables: 7.5.1. Problem
tied: 13.15.1. Problem
using filename as: 7.4.2. Solution
File::KGlob module: 6.9.3. Discussion
File::LockDir module: 7.24. Program: netlock
filenames
expanding tildes in: 7.3.1. Problem
filtering as input: 7.14.1. Problem
command-line options: 7.14.3.2. Command-line options
globbing: 9.6.1. Problem
multiple, for same file: 9.4.1. Problem
parsing: 9.10.1. Problem
renaming: 9.9.1. Problem
reporting in errors: 7.4.1. Problem
sorting: 9.. Introduction
9.13. Program: lst
unusual, opening files with: 7.2.1. Problem
using as filehandle: 7.4.2. Solution
File::NFSLock module: 7.18.3. Discussion
fileparse( ): 9.10.3. Discussion
File::Path module: 9.8.2. Solution
files
binary: 8.11.1. Problem
reading null-terminated strings: 8.14.1. Problem
C header, translating with h2ph: 12.17.1. Problem
comparing file contents: 8.22.1. Problem
configuration, reading: 8.16.1. Problem
creating temporary: 7.11.1. Problem
deleting: 9.2.1. Problem
last line of: 8.10.1. Problem
downloading, resuming HTTP GET: 20.17.1. Problem
locking: 7.18.1. Problem
advisory locking: 7.18.2. Solution
netlock program: 7.24. Program: netlock
Microsoft, converting to Unicode: 8.21.1. Problem
opening: 7.1.1. Problem
processing all in directories: 9.5.1. Problem
random-access, updating: 8.13.1. Problem
RSS, reading and writing: 22.9.1. Problem
storing in program text: 7.12.1. Problem
treating
as arrays: 8.18.1. Problem
strings as: 8.23.1. Problem
with unusual filenames, opening: 7.2.1. Problem
uploaded, receiving with mod_perl handler: 21.7.1. Problem
XML, larger than available memory, processing: 22.8.1. Problem
File::stat module: 8.5.3. Discussion
9.. Introduction
filesystem (see directories)
File::Temp module: 7.11.2. Solution
filtering
filenames as input: 7.14.1. Problem
command-line options: 7.14.3.2. Command-line options
output: 16.5.1. Problem
XML: 22.4.1. Problem
FindBin module: 12.8.3. Discussion
finddepth( ): 9.8.2. Solution
finding
fresh hyperlinks: 20.8.1. Problem
most common anything: 5.15.1. Problem
patterns (see regular expressions)
text and elements in XML documents: 22.6.1. Problem
versions and descriptions of modules: 12.23. Program: Finding Versions and Descriptions of Installed Modules
findnodes( ) vs. getElementsByTagName( ): 22.6.3. Discussion
FIONREAD call: 7.21.2. Solution
firewalls, fetching web pages through: 17.21. Program: fwdport
fixed-length records: 8.. Advanced Operations
flat-file index program: 8.27. Program: Flat File Indexes
reading: 8.15.1. Problem
FixNum class: 13.14.5. Example: Overloaded FixNum Class
fixstyle program: 1.23. Program: fixstyle
flat file index program: 8.27. Program: Flat File Indexes
flattened lists: 4.. Introduction
floating-point numbers: 2.. Introduction
comparing: 2.3.1. Problem
rounding: 2.2.1. Problem
flock( ): 7.18.2. Solution
compared to SysV lockf( ): 7.18.3. Discussion
floor( ): 2.2.3. Discussion
flushing output: 7.19.1. Problem
fmt program: 1.17.3. Discussion
fnctl( ), locking files: 7.18.3. Discussion
folded_demo program: 13.15.6. Tie Example: Case-Insensitive Hash
fonts, Unicode, support for: 8.21.3. Discussion
foodfind program: 5.9.3. Discussion
=for escape pod directive: 12.20.3. Discussion
ForceArray option: 22.1.3. Discussion
foreach loop: 4.13.2. Solution
printing to multiple filehandles: 7.8.2. Solution
renaming files: 9.9.2. Solution
traversing hashes: 5.5.2. Solution
fork( ): 16.10.2. Solution
16.10.3. Discussion
(see also processes)
avoiding zombie processes: 16.19.1. Problem
closing sockets after: 17.9.1. Problem
forking servers: 17.11.1. Problem
non-forking servers: 17.13.1. Problem
preforking servers: 17.12.1. Problem
shell escapes: 19.5.3. Discussion
format_string( ): 20.5.3. Discussion
forms, HTML: 19.. HTML and Forms
saving and emailing: 19.12.1. Problem
sticky widgets: 19.10.1. Problem
submitting: 20.2.1. Problem
forward slash (/)
/e substitution modifier: 1.12.3. Discussion
6.. Pattern-Matching Modifiers
/g pattern-matching modifier: 6.. Pattern-Matching Modifiers
finding Nth matches: 6.5.2. Solution
where last pattern ended: 6.14.3. Discussion
/i pattern-matching modifier: 6.. Pattern-Matching Modifiers
/m pattern-matching modifier: 6.. Pattern-Matching Modifiers
multiple lines: 6.6.2. Solution
/o pattern-matching modifier: 6.10.2. Solution
root directory: 9.. Introduction
/s pattern-matching modifier: 6.. Pattern-Matching Modifiers
multiple lines: 6.6.2. Solution
/x pattern modifier: 1.12.3. Discussion
comments in regular expressions: 6.4.3. Discussion
Frame widget, Tk: 15.14.2. Solution
FTP clients: 18.2.1. Problem
full-screen mode: 15.. Introduction
functions
interpolating within strings: 1.15.1. Problem
vs. methods: 13.10.3. Discussion
private for variables: 12.5.1. Problem
references to: 11.4.1. Problem
types of: 1.1.3. Discussion
fuzzy matching: 6.13.1. Problem
fwdport program: 17.21. Program: fwdport

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

\G anchor: 6.14.3. Discussion
/g pattern-matching modifier: 6.. Pattern-Matching Modifiers
finding Nth matches: 6.5.2. Solution
where last pattern ended: 6.14.3. Discussion
garbage collection: 13.2.3. Discussion
circular data structures and: 13.13.1. Problem
gaussian_rand( ): 2.9.2. Solution
GD module: 15.20.2. Solution
GDBM files: 14.. Introduction
db2gdbm program: 14.3.2. Solution
GDBM_File module: 11.14.2. Solution
GD::Graph modules: 15.18.2. Solution
GD::Graph::Bars module: 15.23. Program: graphbox
generic classes: 13.. Some Notes on Object Terminology
get( ), fetching URLs from Perl scripts: 20.1.2. Solution
GET request: 19.. Behind the Scenes
19.1.3. Discussion
resuming: 20.17.1. Problem
using HTTP 1.1 Range header: 20.17.2. Solution
getElementsByTagName( )
vs. findnodes( ): 22.6.3. Discussion
returning a list of elements by nodes: 22.2.3. Discussion
gethostbyaddr( ): 17.7.3. Discussion
gethostbyname( ): 17.7.3. Discussion
finding IP addresses: 18.1.2. Solution
getitimer( ): 3.9.3. Discussion
getline( ): 7.5.3. Discussion
getopt( ): 15.1.3. Discussion
GetOptions( ): 15.1.3. Discussion
Getopt::Long module: 15.1.2. Solution
getopts( ): 15.1.3. Discussion
Getopt::Std module: 15.1.2. Solution
getpeername( ): 17.16.3. Discussion
17.20. Program: backsniff
getprotobyname( ): 17.. Introduction
get_request( ): 22.7.3. Discussion
getsockname( ): 17.16.2. Solution
17.20. Program: backsniff
GetTerminalSize( ): 15.4.3. Discussion
gettimeofday( ): 3.9.3. Discussion
get_token( ), parsing HTML: 20.18.3. Discussion
ggh program: 14.19. Program: ggh—Grep Netscape Global History
glob( ): 7.3.2. Solution
9.6.2. Solution
global values, saving: 10.13.1. Problem
globbing (see regular expressions)
gmtime( ): 3.. Introduction
3.3.2. Solution
3.8.2. Solution
Time::localtime and Time::gmtime: 3.. Introduction
today's date: 3.1.3. Discussion
graphbox program: 15.23. Program: graphbox
graphical user interfaces (GUIs): 15.. Introduction
greedy pattern matching: 6.. The Tricky Bits
vs. non-greedy pattern matching: 6.15.1. Problem
grep operator: 4.14.2. Solution
grep program (Unix), Perl rewrite of: 6.22. Program: tcgrep
group( ), Usenet news messages: 18.4.3. Discussion
GUIs (graphical user interfaces): 15.. Introduction

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

handlers
Apache: 21.. Handlers
sharing information between: 21.13.1. Problem
handlers for signals (see signal handlers)
handles (see filehandles)
hard links: 9.. Introduction
hash-list equivalence: 5.. Introduction
hashes: 4.7.3. Discussion
5.. Introduction
adding elements to: 5.1.1. Problem
10.11.3.2. Mimicking built-ins
anonymous: 11.. Anonymous Data
of arrays: 11.2.1. Problem
arrays and: 5.. Introduction
comparing keys of: 5.12.1. Problem
counting how often something appears: 5.15.3. Discussion
deleting elements of: 5.4.1. Problem
dutree program: 5.17. Program: dutree
finding most common anything: 5.15.1. Problem
initializing: 5.. Introduction
inverting: 5.9.1. Problem
for list unions, intersections, differences: 4.8.3. Discussion
lookups by key or value: 13.15.7. Tie Example: Hash That Allows Lookups by Key or Value
merging: 5.11.1. Problem
multiple values per key: 5.8.1. Problem
presizing: 5.14.1. Problem
printing: 5.6.1. Problem
reading and writing records to file: 11.10.1. Problem
as records: 11.. Records
references as elements: 5.13.2. Solution
references to: 11.3.1. Problem
representing data relationships: 5.16.1. Problem
representing relationships between data: 5.16.2. Solution
retrieving in insertion order: 5.7.1. Problem
slices of: 4.8.3. Discussion
sorting elements: 5.10.1. Problem
testing for keys: 5.2.1. Problem
ties for: 13.15.5. Tie Example: Make a Hash That Always Appends
traversing: 5.5.1. Problem
head( ), finding stale hyperlinks: 20.7.2. Solution
HEAD method: 19.. Behind the Scenes
headers, interrogating with mod_perl: 21.5.1. Problem
here documents: 1.. Introduction
indenting: 1.16.1. Problem
hex( ): 2.15.2. Solution
hexadecimal numbers, converting: 2.15.1. Problem
hidden( ), generating sticky hidden fields: 19.11.3. Discussion
high-resolution timers: 3.9.1. Problem
history.db file, grepping: 14.19. Program: ggh—Grep Netscape Global History
hopdelta program: 3.11. Program: hopdelta
hostnames
identifying at socket end: 17.7.2. Solution
obtaining your own: 17.8.1. Problem
HotKey module: 15.8.3. Description
hours (see date and time values)
h2ph tool, translating C header files: 12.17.1. Problem
hpush( ): 10.11.3.2. Mimicking built-ins
HREF fields, substitutions for: 20.21. Program: hrefsub
hrefsub program: 20.21. Program: hrefsub
HTML
converting ASCII to and from: 20.4.1. Problem
extracting tags: 20.6.1. Problem
extracting URLs from: 20.3.1. Problem
finding stale or fresh links: 20.7.1. Problem
parsing: 20.18.1. Problem
putting links around URLs: 6.21. Program: urlify
shortcuts, formatting lists and tables with: 19.6.1. Problem
tables in, extracting data from: 20.19.1. Problem
templates: 20.9.1. Problem
text substitutions: 20.20. Program: htmlsub
XML and: 22.. Introduction
HTML forms: 19.. HTML and Forms
accessing parameters with mod_perl: 21.6.1. Problem
automating submission: 20.2.1. Problem
Boolean connectives in patterns: 6.18.1. Problem
saving and mailing: 19.12.1. Problem
sticky widgets: 19.10.1. Problem
HTML::FormatText module: 20.5.3. Discussion
HTML::LinkExtor module: 20.3.2. Solution
HTML::Mason module: 21.16.1. Problem
autohandlers: 21.16.3.4. Autohandlers
configuration: 21.16.3.1. Configuration
dhandlers: 21.16.3.5. Dhandlers
21.16.3.5. Dhandlers
Mason syntax: 21.16.3.2. Basic Mason syntax
objects: 21.16.3.3. Objects
htmlsub program: 20.20. Program: htmlsub
HTML::TableContentParser module: 20.19.2. Solution
HTML::TextToHTML module: 20.4.3. Discussion
HTML::TokeParser module: 20.18.3. Discussion
HTTP methods: 19.. Behind the Scenes
19.1.3. Discussion
HTTP::Cookies module: 20.14.3. Discussion
HTTP::Response module: 20.1.3. Discussion
h2xs tool: 12.9.2. Solution
making a module with C code: 12.18.1. Problem
hyperlinks
clearing link list: 20.3.3. Discussion
extracting from HTML: 20.3.1. Problem
finding stale or fresh: 20.7.1. Problem
hyphen (-)
-0 command-line option: 8.. Basic Operations
-a command-line option, writing filters: 7.14.3.2. Command-line options
-e command-line option, writing filters: 7.14.3.2. Command-line options
-> (arrow) operator: 11.. References
13.. Methods
-> (infix) notation: 11.. References
-i command-line option
modifying files with: 7.16.2. Solution
writing filters: 7.14.3.2. Command-line options
-I command-line switch: 12.8.2. Solution
-n command-line option, writing filters: 7.14.3.2. Command-line options
-p command-line option
modifying files with: 7.16.2. Solution
writing filters: 7.14.3.2. Command-line options
-t command-line option: 15.2.2. Solution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

-i command-line option
modifying files with: 7.16.2. Solution
writing filters: 7.14.3.2. Command-line options
-I command-line switch: 12.8.2. Solution
/i pattern-matching modifier: 6.. Pattern-Matching Modifiers
idempotency: 19.. Behind the Scenes
If-Modified-Since header: 20.10.3. Discussion
Image::Magick module: 15.19.2. Solution
images
adding text to: 15.20.1. Problem
thumbnailing: 15.19.1. Problem
imaginary numbers: 2.14.1. Problem
implementing sparse arrays: 4.4.1. Problem
importing from modules: 10.14.3. Discussion
12.. Modules
INADDR_ANY: 17.1.3. Discussion
17.16.2. Solution
@INC array: 12.8.3. Discussion
indents (see whitespace)
indices
fixed-length records program: 8.27. Program: Flat File Indexes
of hash elements: 5.. Introduction
indirect notation: 13.. A Warning on Indirect Object Notation
indirect object notation: 7.5.3. Discussion
inet_ntoa( ): 17.. Introduction
18.1.2. Solution
infix (->) notation: 11.. References
inheritance: 13.. Inheritance
13.10.1. Problem
initializers (see constructors)
initializing
arrays and lists: 4.1.1. Problem
hashes: 5.. Introduction
modules: 12.7.1. Problem
Inline::C module: 12.19.2. Solution
inner( ): 10.16.3. Discussion
inode structure: 9.. Introduction
input
comma-separated, parsing: 1.20.1. Problem
controlling for other programs: 16.8.1. Problem
16.9.1. Problem
editing: 15.11.1. Problem
executing shell commands from: 19.5.1. Problem
expanding variables in: 1.12.1. Problem
Expect-controlled programs and: 15.13.3. Discussion
extracting variable-length fields: 8.9.1. Problem
from HTML forms [input
HTML forms (see CGI programming)
line input operator: 7.. I/O Operations
8.. Basic Operations
managing multiple streams: 17.19.1. Problem
parsing command-line arguments: 15.1.1. Problem
preprocessing: 16.6.1. Problem
random-access I/O: 8.12.1. Problem
reading
from keyboard: 15.6.1. Problem
from other programs: 16.4.1. Problem
passwords: 15.10.1. Problem
records with pattern separators: 6.7.1. Problem
STDERR from programs: 16.7.1. Problem
waiting, checking for: 15.9.1. Problem
installing
modules from CPAN: 12.21.1. Problem
signal handlers: 16.15.1. Problem
instance data
circular data structures: 13.13.1. Problem
managing: 13.3.1. Problem
instance methods: 13.. Methods
13.. Some Notes on Object Terminology
int( ): 2.2.3. Discussion
integers
(see also numbers)
integer truncation: 2.2.3. Discussion
interactivity, testing for: 15.2.1. Problem
internal redirection: 21.4.3. Discussion
internationalization
localization, first week of the year: 3.6.3. Discussion
Unicode: 1.. Unicode Support in Perl
Internet
domain sockets: 17.. Introduction
protocols: 18.. Introduction
Internet services: 18.. Introduction
accessing LDAP server: 18.8.1. Problem
DNS lookups: 18.1.1. Problem
expn and vrfy programs: 18.16. Program: expn and vrfy
FTP client: 18.2.1. Problem
mail (see email)
pinging machines: 18.7.1. Problem
remote procedure calls: 18.. Introduction
simulating telnet connection: 18.6.1. Problem
SOAP client: 18.14.1. Problem
SOAP server: 18.13.1. Problem
Usenet news: 18.4.1. Problem
XML-RPC client: 18.12.1. Problem
XML-RPC server: 18.11.1. Problem
intersections on lists: 4.8.1. Problem
4.9.1. Problem
inverting hashes: 5.9.1. Problem
invocant: 13.. Methods
I/O layers: 7.. I/O Operations
7.19.3. Discussion
8.. I/O Layers
bytes: 8.. I/O Layers
crlf: 8.. I/O Layers
8.. I/O Layers
8.11.3. Discussion
raw: 8.. I/O Layers
8.11.3. Discussion
reading and writing Unicode from filehandles: 8.20.2. Solution
scalars: 8.23.3. Discussion
setting default: 8.19.1. Problem
stdio: 7.. I/O Operations
7.10.3. Discussion
unix: 7.. I/O Operations
7.19.3. Discussion
utf8: 8.. I/O Layers
I/O operations
access modes: 7.. I/O Operations
buffering: 7.. I/O Operations
7.19.3. Discussion
8.. Advanced Operations
17.3.3. Discussion
controlling for other programs: 16.8.1. Problem
flushing output: 7.19.1. Problem
non-blocking: 7.20.1. Problem
preprocessing input: 16.6.1. Problem
random-access I/O: 8.12.1. Problem
reading and writing to other programs: 16.4.1. Problem
ioctl( ): 7.21.2. Solution
12.17.3. Discussion
return values: 10.10.3. Discussion
IO::File module: 7.. Getting a Handle on the File
IO::Handle module: 7.5.3. Discussion
7.9.2. Solution
7.23.2. Solution
8.5.3. Discussion
IO::Multiplex module: 17.19.2. Solution
IO::Pty module: 15.13.3. Discussion
IO::Select module: 7.22.2. Solution
16.9.2. Solution
16.9.3. Discussion
IO::Socket module: 17.1.2. Solution
closing socket after forking: 17.9.2. Solution
TCP, communicating over: 17.3.2. Solution
UDP clients/servers: 17.4.2. Solution
IO::Socket::INET class: 17.1.2. Solution
IO::Socket::SSL module: 20.16.3. Discussion
IO::Socket::UNIX module: 17.6.2. Solution
IO::Stty module: 15.13.3. Discussion
IO::Tee module: 7.8.3. Discussion
IP addresses
determining your own: 17.8.1. Problem
DNS lookups: 18.1.1. Problem
expn and vrfy programs: 18.16. Program: expn and vrfy
identifying socket ends: 17.7.1. Problem
multihomed servers: 17.16.1. Problem
packed, converting to ASCII strings: 17.. Introduction
IPC::Open2 module: 16.8.2. Solution
IPC::Shareable module: 16.12.3. Discussion
isa( ): 13.9.3. Discussion
is_numeric( ): 2.1.3. Discussion
is_safe( ): 8.17.3. Discussion
iterations (see arrays lists)
iterator variables: 4.5.3. Discussion

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

join( ), using reverse( ) with: 1.7.2. Solution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

keyboard input
15.11.1. Problem
(see also input)
checking for: 15.9.1. Problem
keys( ): 5.5.2. Solution
5.12.2. Solution
hashes
ordering elements: 5.7.1. Problem
presizing: 5.14.2. Solution
sorting: 5.10.2. Solution
traversing: 5.5.3. Discussion
kill command: 16.13.2. Solution
listing available signals: 16.13.1. Problem
sending signals: 16.14.1. Problem

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

\L string escape: 1.13.2. Solution
labels, menu: 15.14.3. Discussion
last( ): 4.13.2. Solution
laston program: 8.26. Program: laston
lc( ): 1.13.2. Solution
lcfirst( ): 1.13.2. Solution
LDAP (Lightweight Directory Access Protocol): 18.8.1. Problem
server: 18.8.1. Problem
modify( ) and: 18.8.3. Discussion
search( ) and: 18.8.3. Discussion
leading whitespace, removing: 1.19.1. Problem
left angle bracket (<)
file-access modes: 7.. I/O Operations
7.1.3. Discussion
<&= and <& open modes: 7.9.2. Solution
<FH> line input operator: 7.. I/O Operations
<=> numerical comparison operator: 4.15.2. Solution
lexical scope: 10.2.3. Discussion
libraries: 12.. Other Kinds of Library Files
DBM: 14.. Introduction
libxml2: 22.. History of Perl and XML
22.5.3. Discussion
OpenSSL: 20.16.3. Discussion
permissions: 19.3.3.3. Is the script valid Perl?
libwww-perl modules: 20.. Introduction
libxml2 library: 22.. History of Perl and XML
22.5.3. Discussion
Lightweight Directory Access Protocol (see LDAP)
line breaks
extracting ranges of lines: 6.8.1. Problem
lines in files
counting: 8.2.1. Problem
deleting last: 8.10.1. Problem
randomizing order: 8.7.1. Problem
selecting random: 8.6.1. Problem
matching within multiple lines: 6.6.1. Problem
reading files backwards: 8.4.1. Problem
reading with continuation characters: 8.1.1. Problem
LINE: (implicit loop label): 7.14.3.2. Command-line options
line input operator: 7.. I/O Operations
8.. Basic Operations
line mode interfaces: 15.. Introduction
__LINE__ symbol: 10.4.3. Discussion
lines
counting in files: 8.2.1. Problem
reading files backward by: 8.4.1. Problem
single, extracting from file: 8.8.1. Problem
Lingua::EN::Inflect module: 2.17.2. Solution
links (see hyperlinks)
links( ), extracting URLs: 20.3.3. Discussion
list assignment: 1.3.2. Solution
list context, detecting: 10.6.1. Problem
lists: 4.. Introduction
vs. arrays: 4.. Introduction
circular: 4.17.1. Problem
4.17.2. Solution
extracting
elements: 4.7.1. Problem
subsets: 4.14.1. Problem
flattened: 4.. Introduction
formatting with HTML shortcuts: 19.6.1. Problem
initializing: 4.1.1. Problem
iterating through elements: 4.5.1. Problem
4.13.1. Problem
permute programs: 4.20. Program: permute
printing with commas: 4.2.1. Problem
processing multiple elements: 4.12.1. Problem
randomizing element order: 4.18.1. Problem
reversing elements of: 4.11.1. Problem
sorting by computable field: 4.16.1. Problem
unions, intersections, differences: 4.8.1. Problem
4.9.1. Problem
words program: 4.19. Program: words
List::Util module: 4.13.3. Discussion
4.18.2. Solution
8.7.2. Solution
loading modules: 12.10.1. Problem
with mod_perl: 21.14.1. Problem
local( )
global values: 10.13.3.1. Using local( ) for temporary values for globals
overriding signal handlers: 16.16.2. Solution
redefining functions: 10.14.2. Solution
local operator: 10.13.2. Solution
locale settings: 6.12.1. Problem
localizing functions: 10.14.1. Problem
localtime( ): 3.. Introduction
3.8.2. Solution
calculating days: 3.6.2. Solution
Time::localtime/Time::gmtime: 3.. Introduction
today's date: 3.1.2. Solution
lockarea program: 7.25. Program: lockarea
locking
blocking signals: 16.20.1. Problem
files: 7.18.1. Problem
advisory locking: 7.18.2. Solution
netlock program: 7.24. Program: netlock
region-specific locks: 7.25. Program: lockarea
log( ): 2.12.2. Solution
log files
(see also logging)
web server: 20.12.1. Problem
processing: 20.13.1. Problem
logarithms: 2.12.1. Problem
log_base( ): 2.12.3. Discussion
Logfile::Apache module: 20.13.3. Discussion
logging
customizing Apache logging requests: 21.9.1. Problem
port connection attempts: 17.20. Program: backsniff
server logs, processing: 20.13.3. Discussion
logical functionality in patterns: 6.18.1. Problem
login( ), POP3 server: 18.5.3. Discussion
login sessions: 15.. Introduction
looks_like_number( ): 2.1.3. Discussion
loop variables: 4.5.3. Discussion
lowercase, converting to uppercase: 1.13.1. Problem
lst program: 9.13. Program: lst
lvaluable functions: 1.1.3. Discussion
LWP modules: 20.. Introduction
extracting HTML tags: 20.6.1. Problem
LWP::RobotUA module: 20.11.2. Solution
LWP::Simple module: 20.1.2. Solution
automating HTML forms: 20.2.3. Discussion
finding stale hyperlinks: 20.7.2. Solution
mirroring web pages: 20.10.2. Solution
LWP::UserAgent module: 20.1.3. Discussion
automating HTML forms: 20.2.2. Solution
using cookies: 20.14.2. Solution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

m// operator: 1.1.3. Discussion
8.3.2. Solution
/m pattern-matching modifier: 6.. Pattern-Matching Modifiers
multiple lines: 6.6.2. Solution
magic ARGV: 8.25. Program: tctee
16.6.3. Discussion
magic open: 8.25. Program: tctee
16.6.3. Discussion
magic variables, creating: 13.15.1. Problem
Mail Transport Agent (MTA): 18.5.3. Discussion
Mail User Agents (MUAs): 18.3.3. Discussion
Mail::Mailer module: 18.3.2. Solution
map( ): 4.16.3. Discussion
building SQL queries programmatically: 14.13.3. Discussion
printing hashes: 5.6.2. Solution
matching: 1.22.1. Problem
(see also regular expressions)
Soundex matching: 1.22.1. Problem
Math::BigInt module: 2.18. Program: Calculating Prime Factors
Math::Complex module: 2.12.3. Discussion
2.14.2. Solution
Math::Random module: 2.8.2. Solution
Math::Trig module: 2.10.2. Solution
2.14.3. Discussion
Math::TrulyRandom module: 2.8.2. Solution
matrix multiplication: 2.13.1. Problem
maximal matching
Boolean connectives in patterns: 6.18.3. Discussion
quantifiers: 6.15.3. Discussion
memoizing technique: 4.20. Program: permute
memory
deallocation: 11.. Anonymous Data
encodings and: 8.20.3. Discussion
event-based XML parsing: 22.3.1. Problem
garbage collection: 13.2.3. Discussion
circular data structures and: 13.13.1. Problem
preallocating for hashes: 5.14.1. Problem
requirements for hash merging technique: 5.11.3. Discussion
Menubutton widget, Tk: 15.14.2. Solution
merging
DBM files: 14.4.1. Problem
hashes: 5.11.1. Problem
methods: 13.. Under the Hood
13.. Methods
13.3.3. Discussion
vs. functions: 13.10.3. Discussion
generating with AUTOLOAD: 13.. Methods
13.12.1. Problem
HTTP: 19.. Behind the Scenes
19.1.3. Discussion
indirect notation: 13.. A Warning on Indirect Object Notation
invoking indirectly: 13.8.1. Problem
overridden: 13.11.1. Problem
private and public: 13.. Methods
references to: 11.8.1. Problem
remote: 18.12.3. Discussion
XML::SAX::Base: 22.3.3. Discussion
MHCONTEXTFD environment variable: 7.9.3. Discussion
MIME (Multimedia Internet Mail Extensions): 18.9.3. Discussion
18.10.3. Discussion
MIME-Tools module: 18.10.2. Solution
MIME::Lite module: 18.9.2. Solution
minimal matching
Boolean connectives in patterns: 6.18.3. Discussion
quantifiers: 6.15.3. Discussion
minus sign (-), modifiers and: 6.18.3. Discussion
minutes (see date and time values)
mirror( ): 20.10.2. Solution
MLDBM module: 11.14.2. Solution
14.. Introduction
14.6.2. Solution
persistent data: 14.7.2. Solution
modify( ), LDAP server: 18.8.3. Discussion
modifying files (see file contents)
mod_perl: 21.. Introduction
accessing form parameters: 21.6.1. Problem
Apache handlers
receiving uploaded files: 21.7.1. Problem
sharing information between: 21.13.1. Problem
Apache logging requests, customizing: 21.9.1. Problem
applications, benchmarking: 21.15.1. Problem
authentication: 21.1.1. Problem
communicating with PHP: 21.11.1. Problem
cookies
accessing values: 21.3.1. Problem
setting: 21.2.1. Problem
documentation: 21.. More Documentation
interrogating headers: 21.5.1. Problem
migrating from CGI: 21.12.1. Problem
redirecting browsers: 21.4.1. Problem
reloading changed modules: 21.14.1. Problem
speeding database access: 21.8.1. Problem
templating with HTML::Mason: 21.16.1. Problem
autohandlers: 21.16.3.4. Autohandlers
configuration: 21.16.3.1. Configuration
dhandlers: 21.16.3.5. Dhandlers
Mason syntax: 21.16.3.2. Basic Mason syntax
objects: 21.16.3.3. Objects
templating with Template Toolkit: 21.17.1. Problem
configuration: 21.17.3.1. Configuration
data structures: 21.17.3.4. Data structures
other templates: 21.17.3.6. Including other templates
parameters: 21.17.3.7. Parameters
Perl code: 21.17.3.3. Perl code
plug-ins: 21.17.3.8. Plug-ins
subroutines: 21.17.3.5. Subroutines
syntax: 21.17.3.2. Syntax
URLs, transparently storing information in: 21.10.1. Problem
mod_perl 2: 21.. mod_perl 2
modules: 12.. Modules
automatic setup and cleanup: 12.7.1. Problem
CPAN (see CPAN)
designing interface for: 12.1.1. Problem
directories of: 12.8.1. Problem
documenting with pod: 12.20.1. Problem
sorting =head1 sections: 15.22. Program: tkshufflepod
errors
reporting like built-ins: 12.14.1. Problem
trapping in use and require statements: 12.2.1. Problem
finding versions and descriptions of: 12.23. Program: Finding Versions and Descriptions of Installed Modules
importing from: 10.14.3. Discussion
loading: 12.10.1. Problem
reloading changed modules with mod_perl: 21.14.1. Problem
at runtime: 12.3.1. Problem
mod_perl: 21.. More Documentation
overriding built-in functions: 12.12.1. Problem
preparing for distribution: 12.9.1. Problem
private variables: 12.4.1. Problem
template for: 12.22. Example: Module Template
writing in C: 12.18.1. Problem
months (see date and time values)
move( ): 9.3.3. Discussion
MTA (Mail Transport Agent): 18.5.3. Discussion
mtime field, inode structure: 9.. Introduction
MUAs (Mail User Agents): 18.3.3. Discussion
multidimensional
arrays: 4.. Introduction
associative array emulation syntax: 9.4.3. Discussion
multihomed servers: 17.16.1. Problem
Multimedia Internet Mail Extensions (see MIME)
multiple inheritance: 13.. Inheritance
multiplication
of matrices: 2.13.1. Problem
x operator: 2.13.3. Discussion
mux_input( ): 17.19.2. Solution
my operator: 10.2.3. Discussion

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

-n command-line option, writing filters: 7.14.3.2. Command-line options
Nagle Algorithm: 17.3.3. Discussion
name-value pairs, passing subroutines by named parameter: 10.7.3. Discussion
named pipes: 16.11.1. Problem
sigrand program: 16.23. Program: sigrand
names of current subroutines. determining: 10.4.1. Problem
namespaces, XML: 22.. Namespaces
natural logarithms: 2.12.2. Solution
navigating Web with robots: 20.11.1. Problem
NDBM files: 14.. Introduction
nested
elements, XML: 22.. Namespaces
HTML tags: 20.6.3. Discussion
pattern matching: 6.17.1. Problem
subroutines: 10.16.1. Problem
Net::DNS module: 18.1.3. Discussion
18.16. Program: expn and vrfy
Net::FTP module: 18.2.2. Solution
Net::hostent module: 13.5.3. Discussion
Net::LDAP module: 18.8.2. Solution
netlock program: 7.24. Program: netlock
Net::NNTP module: 18.4.2. Solution
Net::Ping module: 18.7.2. Solution
Net::POP3 module: 18.5.2. Solution
Netscape history.db file: 14.19. Program: ggh—Grep Netscape Global History
Net::SMTP module: 18.9.3. Discussion
expn and vrfy programs: 18.16. Program: expn and vrfy
Net::Telnet module: 18.6.2. Solution
new( ): 7.22.3. Discussion
new_from_fd( ): 7.9.2. Solution
newlines (see line breaks whitespace)
NFA (non-deterministic finite automata): 6.. The Tricky Bits
NFC( ): 1.9.3. Discussion
NFD( ): 1.9.2. Solution
NFKC( ): 1.9.3. Discussion
NFKD( ): 1.9.3. Discussion
noecho input mode: 15.10.2. Solution
NOFILE constant: 7.7.3. Discussion
non-blocking I/O: 7.20.1. Problem
non-deterministic finite automata (NFA): 6.. The Tricky Bits
non-greedy pattern matching: 6.. The Tricky Bits
vs. greedy pattern matching: 6.15.1. Problem
non-numeric strings, converting to numbers: 2.. Introduction
NOT functionality in regular expressions: 6.18.1. Problem
notes, Apache requests: 21.11.3. Discussion
nounder_demo program: 13.15.4. Tie Example: Outlaw $_
n2perm( ): 4.20. Program: permute
nstore( ): 11.13.3. Discussion
numbers: 1.4.1. Problem
2.. Introduction
adding commas to: 2.16.1. Problem
complex (imaginary): 2.14.1. Problem
converting between characters and values: 1.4.1. Problem
converting binary, octal, and hexadecimal: 2.15.1. Problem
decimal places, controlling: 13.14.5. Example: Overloaded FixNum Class
floating-point: 2.. Introduction
comparing: 2.3.1. Problem
rounding: 2.2.1. Problem
logarithms: 2.12.1. Problem
matrix multiplication: 2.13.1. Problem
operating on integer series: 2.4.1. Problem
plural words based on: 2.17.1. Problem
primes, calculating: 2.18. Program: Calculating Prime Factors
random: 2.. Introduction
biasing: 2.9.1. Problem
generating: 2.6.1. Problem
Roman numerals: 2.5.1. Problem
scalars as: 2.. Introduction
strings as valid numbers: 2.1.1. Problem
trigonometry: 2.10.1. Problem
numerical comparison (<=>) operator: 4.15.2. Solution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

O_ flags: 7.1.3. Discussion
7.20.2. Solution
/o pattern-matching modifier: 6.10.2. Solution
OASIS group: 22.. Schemas
object attributes: 13.3.1. Problem
object methods: 13.. Some Notes on Object Terminology
object-oriented programming: 13.. Under the Hood
13.. Some Notes on Object Terminology
objects: 13.. Under the Hood
cloning parent objects: 13.6.1. Problem
closures as: 11.7.1. Problem
constructing: 13.. Methods
13.1.1. Problem
destroying: 13.. Methods
13.2.1. Problem
determining subclass membership: 13.9.1. Problem
managing class data: 13.4.1. Problem
managing instance data: 13.3.1. Problem
tied objects: 13.15.1. Problem
oct( ): 2.15.2. Solution
octal
numbers, converting: 2.15.1. Problem
values, working with symbolic file permissions instead: 9.11.1. Problem
octets: 1.. The Universal Character Code
treating Unicode strings as: 1.10.1. Problem
O_NONBLOCK option: 7.20.2. Solution
open( ): 16.10.3. Discussion
(see also processes)
caching open filehandles: 7.7.2. Solution
creating temporary files: 7.11.3. Discussion
file access modes: 7.. I/O Operations
file descriptors, creating aliases for: 7.10.3. Discussion
filehandles: 7.1.2. Solution
storing in variables: 7.5.2. Solution
filtering output: 16.5.2. Solution
magic open: 8.25. Program: tctee
reading from other programs: 16.4.2. Solution
unusual filenames: 7.2.2. Solution
open pragma: 8.19.2. Solution
opendir( ): 9.5.2. Solution
globbing: 9.6.3. Discussion
readdir( ): 9.. Introduction
opening
file descriptors: 7.9.1. Problem
files: 7.1.1. Problem
OpenSSL libraries: 20.16.3. Discussion
operators
line input: 7.. I/O Operations
8.. Basic Operations
overloading: 13.14.1. Problem
OR functionality in regular expressions: 6.18.1. Problem
or operator, vs. || operator: 1.2.3. Discussion
ord( ): 1.4.3. Discussion
outer( ): 10.16.3. Discussion
outlaw $_ program: 13.15.4. Tie Example: Outlaw $_
outline programs: 11.16. Program: Outlines
output
controlling decimal places: 13.14.5. Example: Overloaded FixNum Class
controlling for other programs: 16.8.1. Problem
filtering: 16.5.1. Problem
flushing: 7.19.1. Problem
gathering from programs: 16.1.1. Problem
random access I/O: 8.12.1. Problem
writing to other programs: 16.4.1. Problem
output( ): 5.17. Program: dutree
output_fh( ): 22.7.3. Discussion
output_file( ): 22.7.3. Discussion
overloading operators: 13.14.1. Problem
overridden methods: 13.11.1. Problem
overriding
built-in functions: 12.12.1. Problem
signal handlers: 16.16.1. Problem

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

-p command-line option
modifying files with: 7.16.2. Solution
writing filters: 7.14.3.2. Command-line options
pack( ): 1.4.3. Discussion
8.13.2. Solution
with Tk resize events: 15.16.2. Solution
package statement: 12.. Introduction
__PACKAGE__ symbol: 10.4.3. Discussion
12.6.3. Discussion
packages: 12.. Introduction
determining current calling: 12.6.1. Problem
overriding built-in functions: 12.12.1. Problem
private variables: 12.4.1. Problem
referring to indirectly: 12.16.1. Problem
paragraphs
counting in files: 8.2.1. Problem
in pod documentation: 12.20.3. Discussion
reading files backwards by: 8.4.1. Problem
reformatting: 1.17.1. Problem
param( ): 19.1.3. Discussion
parent classes
accessing overridden methods: 13.11.1. Problem
cloning objects: 13.6.1. Problem
parentheses ( ): 1.. Introduction
autouse pragma: 12.3.3. Discussion
prototyping functions: 10.11.3.1. Omitting parentheses
substitution: 6.1.3. Discussion
parse( ), HTML tables, extracting data: 20.19.3. Discussion
parse_csv subroutines: 1.20.3. Discussion
ParseDate( ): 3.7.2. Solution
3.11. Program: hopdelta
parsing
comma-separated data: 1.20.1. Problem
command-line arguments: 15.1.1. Problem
commas into numbers: 2.16.1. Problem
date and time from strings: 3.7.1. Problem
filenames: 9.10.1. Problem
HTML: 20.18.1. Problem
HTML tags: 20.6.1. Problem
web server log file: 20.12.1. Problem
XML
into data structures: 22.1.1. Problem
into DOM tree: 22.2.1. Problem
into SAX events: 22.3.1. Problem
passing
arrays and hashes by reference: 10.5.1. Problem
by named parameter: 10.7.1. Problem
passwords
randomly generating: 2.6.3. Discussion
reading without echo: 15.10.1. Problem
15.10.1. Problem
paths, XML: 22.. Paths
pattern matching (see regular expressions)
pattern separators, reading data with: 6.7.1. Problem
PDL (Perl Data Language): 2.13.2. Solution
modules, matrix multiplication: 2.13.2. Solution
percent sign (%)
hashes: 5.. Introduction
%SIG hash: 16.15.2. Solution
performance
backreferences and: 1.11.3. Discussion
database access, speeding with mod_perl: 21.8.1. Problem
event-based XML parsing: 22.3.1. Problem
presizing hashes: 5.14.3. Discussion
web server, improving: 21.12.1. Problem
Perl Data Language (see PDL)
PERL5LIB environment variable: 12.8.3. Discussion
perlmenu module: 15.12.3. Description
PERL_UNICODE environment variable: 8.21.3. Discussion
permissions
CGI scripts: 19.3.3.2. Make sure the script has permissions to do what it's trying to do
libraries: 19.3.3.3. Is the script valid Perl?
symbolic file, instead of octal values: 9.11.1. Problem
testing files for trustworthiness: 8.17.1. Problem
permutations, generating all possible: 4.20. Program: permute
permute program: 4.20. Program: permute
persistent
data structures: 11.14.1. Problem
database data: 14.7.1. Problem
private subroutine variables: 10.3.1. Problem
personal identification number (PIN): 6.19.3. Discussion
PF_ constants: 17.. Introduction
.ph filename extension: 12.17.3. Discussion
PHP, communicating with mod_perl: 21.11.1. Problem
PIN (personal identification number): 6.19.3. Discussion
pinging machines: 18.7.1. Problem
pipe( ): 16.. Process Creation
16.10.2. Solution
places( ): 13.14.5. Example: Overloaded FixNum Class
pluralizing words: 2.17.1. Problem
plus sign (+), file-access modes: 7.1.3. Discussion
.pm filename extension: 12.. Modules
pnotes
Apache requests, sharing information between handlers: 21.13.2. Solution
URLs, storing information in: 21.10.2. Solution
pod
converting into other languages: 12.20.3. Discussion
documentation: 12.20.1. Problem
sorting =head1 sections: 15.22. Program: tkshufflepod
pod2html: 12.20.3. Discussion
pod2man: 12.20.3. Discussion
pod2text tools: 12.20.3. Discussion
POE framework, writing multitasking server with: 17.15.1. Problem
POE::Component::Server::TCP module: 17.15.2. Solution
pop( ), circular lists: 4.17.2. Solution
POP (Post Office Protocol): 18.5.3. Discussion
servers
(see also POP3 servers)
fetching and summarizing messages: 18.15. Program: rfrm
logging in: 18.5.3. Discussion
POP3 servers: 18.5.1. Problem
port connection attempts, logging: 17.20. Program: backsniff
portability
closing filehandles: 7.. I/O Operations
encodings in XML: 22.. XML Declaration
Portable Operating System Interface (see POSIX)
pos( ): 6.14.3. Discussion
POSIX module
blocking signals: 16.20.2. Solution
today's date: 3.1.3. Discussion
trigonometric functions: 2.11.2. Solution
POSIX (Portable Operating System Interface): 0.3. Platform Notes
termios interface: 15.8.1. Problem
time( ): 3.. Introduction
POSIX::close( ): 7.9.2. Solution
7.9.3. Discussion
POSIX::setsid( ): 17.17.3. Discussion
POSIX::strtod( ): 2.1.3. Discussion
POSIX::uname( ): 17.8.2. Solution
POST method: 19.. Behind the Scenes
19.1.3. Discussion
20.2.2. Solution
Post Office Protocol (see POP)
posting Usenet messages: 18.4.1. Problem
pound sign (#), with printf( ): 2.15.3. Discussion
pragmas: 12.. Modules
preallocating memory for hashes: 5.14.1. Problem
prime numbers, calculating: 2.18. Program: Calculating Prime Factors
print( )
email attachments: 18.9.3. Discussion
filehandles
outputting to multiple: 7.8.3. Discussion
storing in variables: 7.5.3. Discussion
printf( ): 1.4.3. Discussion
floating-point numbers, rounding: 2.2.2. Solution
storing filehandles in variables: 7.5.3. Discussion
printing
; printf( ))
(see also print( ))
data structures: 11.11.1. Problem
date and time information: 3.8.1. Problem
hashes: 5.6.1. Problem
lists with commas: 4.2.1. Problem
to multiple filehandles simultaneously: 7.8.1. Problem
private
function to variable: 12.5.1. Problem
methods: 13.. Methods
module variables: 12.4.1. Problem
subroutine variables: 10.2.1. Problem
processes: 16.. Introduction
catching Ctrl-C: 16.18.1. Problem
communicating between: 16.10.1. Problem
controlling input/output: 16.8.1. Problem
creating: 16.. Process Creation
filtering output: 16.5.1. Problem
gathering output: 16.1.1. Problem
groups: 7.25. Program: lockarea
16.14.3. Discussion
imitating files with named pipes: 16.11.1. Problem
large XML files, processing: 22.8.1. Problem
multitasking servers, writing: 17.14.1. Problem
with POE: 17.15.1. Problem
preprocessing input: 16.6.1. Problem
programs
reading from and writing to: 16.4.1. Problem
reading STDERR from: 16.7.1. Problem
replacing: 16.3.1. Problem
running multiple: 16.2.1. Problem
recursively processing files in directories: 9.7.1. Problem
sharing variables among: 16.12.1. Problem
signal handlers: 16.15.1. Problem
overriding: 16.16.1. Problem
writing: 16.17.1. Problem
signals: 16.. Signals
blocking: 16.20.1. Problem
listing available: 16.13.1. Problem
sending: 16.14.1. Problem
turning into errors: 16.22.1. Problem
timing out operations: 16.21.1. Problem
XML processing instructions: 22.. Processing Instructions
XSLT, processing: 22.7.1. Problem
zombies: 16.. Process Creation
avoiding: 16.19.1. Problem
programs
CGI (see CGI programming)
command-line arguments, parsing: 15.1.1. Problem
controlling input/output of: 16.8.1. Problem
controlling with Expect: 15.13.1. Problem
filtering output: 16.5.1. Problem
gathering output from: 16.1.1. Problem
preprocessing input: 16.6.1. Problem
reading from and writing to: 16.4.1. Problem
reading STDERR from: 16.7.1. Problem
replacing: 16.3.1. Problem
running multiple: 16.2.1. Problem
simulating telnet from: 18.6.1. Problem
testing if running interactively: 15.2.1. Problem
progressive matching: 6.5.3. Discussion
protocols
Internet: 18.. Introduction
socket: 17.. Introduction
prototypes: 10.11.1. Problem
13.. Methods
proxy, submitting forms through: 20.2.3. Discussion
psgrep program: 1.24. Program: psgrep
public methods: 13.. Methods
push( ): 4.10.2. Solution
11.2.2. Solution
circular lists: 4.17.2. Solution
Tie::IxHash module and: 5.7.3. Discussion

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

q// operator: 1.. Introduction
` string metacharacter: 1.18.3. Discussion
qq// operator: 1.. Introduction
qr// operator
comments in regular expressions: 6.4.3. Discussion
interpolated matches: 6.10.3. Discussion
qualify_to_ref( ): 7.6.2. Solution
query_form( ): 20.2.3. Discussion
quote( ): 14.10.2. Solution
quotemeta( ): 1.18.3. Discussion
quotewords( ): 1.20.3. Discussion
qw( ): 4.1.2. Solution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

race conditions: 19.4.3. Discussion
rad2deg( ): 2.10.3. Discussion
radians, vs. degrees: 2.10.1. Problem
radiobuttons: 15.14.3. Discussion
rand( ): 2.6.2. Solution
8.6.2. Solution
random
email signatures: 16.23. Program: sigrand
lines in files
ordering of: 8.7.1. Problem
selecting: 8.6.1. Problem
numbers: 2.. Introduction
biasing: 2.9.1. Problem
generating: 2.6.1. Problem
random-access files, updating: 8.13.1. Problem
random-access I/O: 8.12.1. Problem
randomizing arrays: 4.18.1. Problem
Range header: 20.17.2. Solution
raw I/O layer: 8.. I/O Layers
8.11.3. Discussion
read( )
fixed-length records: 8.. Advanced Operations
8.15.2. Solution
I/O layers: 8.. Advanced Operations
random-access files: 8.12.4. See Also
readdir( ): 9.5.2. Solution
globbing: 9.6.3. Discussion
reading
files (see file access file contents)
records: 7.. I/O Operations
with pattern separators: 6.7.1. Problem
Usenet messages: 18.4.1. Problem
reading and writing
determining whether data can be read or written: 17.3.2. Solution
hash records to text files: 11.10.1. Problem
RSS files: 22.9.1. Problem
records: 11.. Records
binary tree structures: 11.17. Program: Binary Trees
closures as objects: 11.7.1. Problem
comma-separated (see CSV)
constructing: 11.9.1. Problem
counting in files: 8.2.1. Problem
fixed-length: 8.. Advanced Operations
reading: 8.15.1. Problem
lastlog file: 8.26. Program: laston
random-access I/O: 8.12.1. Problem
reading: 7.. I/O Operations
with pattern separators: 6.7.1. Problem
reading and writing to text files: 11.10.1. Problem
variable-length: 8.9.1. Problem
wtmp file: 8.24. Program: tailwtmp
recursively processing files in directories: 9.7.1. Problem
recv( ), TCP, communicating over: 17.3.2. Solution
redirect( ): 19.7.3. Discussion
ref( ): 11.. References
13.. Under the Hood
references: 11.. References
anonymous data: 11.. Anonymous Data
to arrays: 11.1.1. Problem
arrays of scalar references: 11.6.1. Problem
autovivification: 11.. Anonymous Data
closures as objects: 11.7.1. Problem
to functions: 11.4.1. Problem
as hash keys: 13.15.7. Tie Example: Hash That Allows Lookups by Key or Value
as hash values: 5.13.2. Solution
to hashes: 11.3.1. Problem
hashes of arrays: 11.2.1. Problem
11.2.1. Problem
iterating over arrays by: 4.6.1. Problem
to methods: 11.8.1. Problem
to packages, indirect: 12.16.1. Problem
passing arrays and hashes by: 10.5.1. Problem
reference count: 11.. References
returning subroutines by: 10.9.1. Problem
to scalars: 11.5.1. Problem
self-referential structures: 13.13.1. Problem
symbolic: 1.12.2. Solution
12.16.2. Solution
typed: 11.. References
weak, coping with circular data structures using: 11.15.1. Problem
Regexp::Common module: 2.1.3. Discussion
6.17.3. Discussion
register_function( ): 22.7.3. Discussion
regular expressions: 6.. Introduction
backtracking: 6.. The Tricky Bits
6.16.3. Discussion
checking strings for valid numbers: 2.1.1. Problem
commas in numbers: 2.16.3. Discussion
commenting: 6.4.1. Problem
copying and substituting: 6.1.1. Problem
doubled words: 6.16.1. Problem
eager matching: 6.. The Tricky Bits
email addresses: 6.19.1. Problem
extracting ranges of lines: 6.8.1. Problem
fuzzy matching: 6.13.1. Problem
\G anchor: 6.14.3. Discussion
globbing filenames: 9.6.1. Problem
greedy vs. non-greedy matching: 6.. The Tricky Bits
6.15.1. Problem
honoring locale settings: 6.12.1. Problem
logical functionality in: 6.18.1. Problem
matching
abbreviations: 6.20.1. Problem
letters: 6.2.1. Problem
within multiple lines: 6.6.1. Problem
nested patterns: 6.17.1. Problem
Nth occurrence: 6.5.1. Problem
shell globs as: 6.9.1. Problem
from where last pattern ended: 6.14.1. Problem
words: 6.3.1. Problem
parsing HTML: 20.18.2. Solution
pattern-matching modifiers: 6.. Pattern-Matching Modifiers
Boolean connectives: 6.18.3. Discussion
progressive matching: 6.5.3. Discussion
tcgrep program: 6.22. Program: tcgrep
testing for invalid patterns: 6.11.1. Problem
urlify program: 6.21. Program: urlify
useful, list of: 6.23. Regular Expression Grab Bag
RelaxNG schema: 22.. Schemas
rename( ): 9.9.2. Solution
modifying files with temporary files: 7.15.2. Solution
rename script, example: 9.9.3. Discussion
rep program: 15.12.3. Description
report( ), processing server logs: 20.13.3. Discussion
Representational State Transfer (REST): 18.. Introduction
require operator: 10.. Introduction
12.. Modules
trapping errors in: 12.2.1. Problem
Resize( ), thumbnailing images: 15.19.3. Discussion
REST (Representational State Transfer): 18.. Introduction
restarting servers on demand: 17.18.1. Problem
retrieve( ): 11.13.2. Solution
return context, subroutines: 10.6.1. Problem
return statement: 10.10.2. Solution
return values, subroutines
returning by reference: 10.9.1. Problem
returning failure: 10.10.1. Problem
skipping selected: 10.8.1. Problem
reverse( ): 1.7.2. Solution
4.11.2. Solution
inverting hashes: 5.9.2. Solution
reversing
array elements: 4.11.1. Problem
hashes: 5.9.2. Solution
words or characters in strings: 1.7.1. Problem
revhash_demo program: 13.15.7. Tie Example: Hash That Allows Lookups by Key or Value
revnum( ): 4.15.3. Discussion
rewinddir( ): 9.5.3. Discussion
rfrm program: 18.15. Program: rfrm
Rich Site Summary (see RSS)
right angle bracket (>), file-access modes: 7.. I/O Operations
7.1.3. Discussion
rmdir( ): 9.8.3. Discussion
rmtree( ): 9.8.2. Solution
robots for Web traversal: 20.11.1. Problem
rollback( ): 14.15.2. Solution
roman( ): 2.5.3. Discussion
Roman module: 2.5.2. Solution
Roman numerals: 2.5.1. Problem
rounding floating-point numbers: 2.2.1. Problem
RSS (Rich Site Summary): 22.9.1. Problem
files, reading and writing: 22.9.1. Problem
runtime
loading modules at: 12.3.1. Problem
scoping: 10.13.3.3. Using local( ) on parts of aggregates

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

s/// operator: 1.1.3. Discussion
stripping whitespace with: 1.16.2. Solution
/s pattern-matching modifier: 6.. Pattern-Matching Modifiers
multiple lines: 6.6.2. Solution
save( ), HTML forms: 19.12.2. Solution
save_parameters( ), HTML forms: 19.12.2. Solution
SAX (Simple API for XML): 22.3.1. Problem
events, parsing XML into: 22.3.1. Problem
scalar multiplication operator: 2.13.3. Discussion
scalar operator, list version: 10.8.3. Discussion
scalars: 1.. Introduction
arrays of scalar references: 11.6.1. Problem
detecting scalar context: 10.6.1. Problem
exchanging values between: 1.3.1. Problem
as numbers: 2.. Introduction
references to: 11.5.1. Problem
Scalar::Util module: 2.1.3. Discussion
11.15.3. Description
schemas, XML: 22.. Schemas
schemes, URLs: 19.. Architecture
scope of subroutine variables: 10.2.3. Discussion
screen (see user interfaces)
scripts, CGI (see CGI programming)
SDBM files: 14.. Introduction
search( ), LDAP server: 18.8.3. Discussion
searching for patterns (see regular expressions)
seconds (see date and time values)
Secure Sockets Layer (SSL): 20.16.1. Problem
security
CGI scripts: 19.. Security
19.4.1. Problem
executing user commands: 19.5.1. Problem
connecting through firewalls: 17.21. Program: fwdport
fetching secure web pages: 20.16.1. Problem
reading passwords without echo: 15.10.1. Problem
testing files for trustworthiness: 8.17.1. Problem
seek( ): 8.. Advanced Operations
8.5.3. Discussion
seek offset, filehandles: 7.. I/O Operations
seekdir( ): 9.5.3. Discussion
select( ): 3.10.2. Solution
determining whether data can be read or written: 17.3.2. Solution
reading from multiple filehandles: 7.22.2. Solution
17.3.3. Discussion
self-referential data structures: 13.13.1. Problem
SelfLoader module: 12.10.2. Solution
send( ), communicating over TCP: 17.3.2. Solution
sendmail program: 18.3.2. Solution
servers
daemon servers: 17.17.1. Problem
database, using SQL without: 14.18.1. Problem
forking: 17.11.1. Problem
LDAP: 18.8.1. Problem
18.8.3. Discussion
search( ): 18.8.3. Discussion
multihomed: 17.16.1. Problem
multitasking, writing: 17.14.1. Problem
with POE: 17.15.1. Problem
non-forking: 17.13.1. Problem
POP3: 18.5.1. Problem
preforking: 17.12.1. Problem
processing logs: 20.13.3. Discussion
restarting on demand: 17.18.1. Problem
SMTP: 18.16. Program: expn and vrfy
SOAP: 18.13.1. Problem
TCP, writing: 17.2.1. Problem
UDP, setting up: 17.5.1. Problem
web
common log format fields: 20.12.3. Discussion
performance, improving: 21.12.1. Problem
set theory: 4.8.1. Problem
setitimer( ): 3.9.3. Discussion
setting default I/O layers: 8.19.1. Problem
SGML (Standard Generalized Markup Language): 22.. Introduction
shallow copies: 11.12.3. Discussion
shared locks: 7.18.3. Discussion
sharing variables among processes: 16.12.1. Problem
shell escapes, executing commands without: 19.5.1. Problem
shell wildcards for regular expression matching: 6.9.1. Problem
shift( ), circular lists: 4.17.2. Solution
shopping cart applications: 19.11.1. Problem
shuffle( )
arrays: 4.18.2. Solution
lines: 8.7.2. Solution
shutdown( ): 17.9.2. Solution
%SIG hash: 16.15.2. Solution
SIGALRM signal: 16.. Signals
16.21.2. Solution
SIGCHLD signal: 16.. Signals
16.19.2. Solution
SIGHUP signal: 16.. Signals
17.18.2. Solution
SIGINT signal: 16.. Signals
16.18.2. Solution
signal handlers: 16.15.1. Problem
overriding: 16.16.1. Problem
writing: 16.17.1. Problem
signals: 16.. Signals
blocking: 16.20.1. Problem
handlers for (see signal handlers)
listing available: 16.13.1. Problem
process groups: 7.25. Program: lockarea
16.14.3. Discussion
sending: 16.14.1. Problem
turning into fatal errors: 16.22.1. Problem
signatures, randomized: 16.23. Program: sigrand
SIGPIPE signal: 16.. Signals
16.4.3. Discussion
sigprocmask syscall: 16.20.2. Solution
SIGQUIT signal: 16.. Signals
sigrand program: 16.23. Program: sigrand
SIGTERM signal: 16.. Signals
sigtrap pragma: 16.22.2. Solution
SIGUSR1/SIGUSR2 signals: 16.. Signals
Simple API for XML (SAX): 22.3.1. Problem
simple difference: 4.9.3. Discussion
Simple Mail Transfer Protocol (SMTP): 18.3.3. Discussion
Simple Object Access Protocol (see SOAP)
sin( ): 2.11.2. Solution
single inheritance: 13.. Inheritance
single quote ('): 1.. Introduction
escaping: 14.10.1. Problem
size
arrays, changing: 4.3.1. Problem
hashes, preallocating for: 5.14.1. Problem
Tk window resize events: 15.16.1. Problem
window or terminal, determining: 15.4.1. Problem
sleep( ): 3.9.3. Discussion
3.10.1. Problem
SMTP (Simple Mail Transfer Protocol): 18.3.3. Discussion
server: 18.16. Program: expn and vrfy
SOAP (Simple Object Access Protocol): 18.. Introduction
client: 18.14.1. Problem
server: 18.13.1. Problem
SOAP::Lite module: 18.11.3. Discussion
18.13.2. Solution
SOCK_ constants: 17.. Introduction
sockaddr_in( ): 17.. Introduction
17.4.3. Discussion
sockaddr_un( ): 17.. Introduction
Unix domain sockets: 17.6.2. Solution
socket( ): 17.. Introduction
sockets: 17.. Introduction
bidirectional clients: 17.10.1. Problem
closing after forking: 17.9.1. Problem
connecting through firewalls: 17.21. Program: fwdport
daemon servers: 17.17.1. Problem
finding own name and address: 17.8.1. Problem
forking servers: 17.11.1. Problem
identifying machine at end: 17.7.1. Problem
logging port connection attempts: 17.20. Program: backsniff
managing multiple input streams: 17.19.1. Problem
multihomed servers: 17.16.1. Problem
non-blocking: 17.2.3. Discussion
non-forking servers: 17.13.1. Problem
preforking servers: 17.12.1. Problem
protocol associated with: 17.. Introduction
restarting servers on demand: 17.18.1. Problem
TCP protocol
communicating over: 17.3.1. Problem
writing clients: 17.1.1. Problem
writing servers: 17.2.1. Problem
UDP protocol
writing clients for: 17.4.1. Problem
writing servers for: 17.5.1. Problem
Unix domain: 17.. Introduction
17.6.1. Problem
sort( ): 4.15.2. Solution
by computable field: 4.16.2. Solution
hashes: 5.10.2. Solution
sorting
array elements numerically: 4.15.1. Problem
arrays and lists by computable field: 4.16.1. Problem
DBM files: 14.5.1. Problem
directory contents: 9.. Introduction
9.13. Program: lst
du command output: 5.17. Program: dutree
hash elements: 5.10.1. Problem
mail: 10.18. Program: Sorting Your Mail
pod =head1 sections: 15.22. Program: tkshufflepod
randomizing array element order: 4.18.1. Problem
randomizing file line order: 8.7.1. Problem
text into columns: 4.19. Program: words
soundex( ): 1.22.3. Discussion
Soundex matching: 1.22.1. Problem
splice( ): 4.12.2. Solution
split( ): 1.6.2. Solution
processing all words in file: 8.3.2. Solution
reading records with pattern separators: 6.7.2. Solution
using reverse( ) with: 1.7.2. Solution
variable-length text fields: 8.9.2. Solution
sprintf( ): 1.4.3. Discussion
floating-point numbers
comparing: 2.3.2. Solution
rounding: 2.2.2. Solution
SQL database: 20.9.3. Discussion
SQL queries
building programmatically: 14.13.1. Problem
without database server: 14.18.1. Problem
executing using DBI: 14.9.1. Problem
querying CSV files: 14.17.1. Problem
repeating efficiently: 14.12.1. Problem
saving results to Excel or CSV: 14.8.1. Problem
square brackets ([]): 1.. Introduction
creating anonymous arrays and hashes: 11.. References
srand( ): 2.7.2. Solution
SSL (Secure Sockets Layer): 20.16.1. Problem
standard filehandles: 7.. Standard Filehandles
Standard Generalized Markup Language (SGML): 22.. Introduction
stat( ): 8.17.2. Solution
9.. Introduction
timestamps: 9.1.2. Solution
static data members: 13.4.1. Problem
Stat::lsMode module: 9.11.2. Solution
STDERR filehandle: 7.. Standard Filehandles
controlling for other programs: 16.9.1. Problem
reading from programs: 16.7.1. Problem
STDIN filehandle: 7.. Standard Filehandles
preprocessing input: 16.6.2. Solution
stdio layer: 7.. I/O Operations
7.10.3. Discussion
STDOUT filehandle: 7.. Standard Filehandles
7.. I/O Operations
filtering output: 16.5.3. Discussion
sticky widgets, creating: 19.10.1. Problem
Storable module: 11.12.2. Solution
13.7.2. Solution
store( ): 11.13.2. Solution
stream sockets: 17.. Introduction
17.11.3. Discussion
strftime( ): 3.1.3. Discussion
3.8.2. Solution
String::Approx module: 1.22.3. Discussion
6.13.3. Discussion
strings
1.12.1. Problem
(see also variables)
accessing substrings: 1.1.1. Problem
canonicalizing with Unicode combined characters: 1.9.1. Problem
checking if valid numbers: 2.1.1. Problem
converting
ASCII to and from HTML: 20.4.1. Problem
case: 1.13.1. Problem
characters and values: 1.4.1. Problem
non-numeric: 2.. Introduction
copying and substituting: 6.1.1. Problem
doubled words, finding: 6.16.1. Problem
escaping characters: 1.18.1. Problem
hash element indices: 5.. Introduction
headlines and titles, capitalizing: 1.14.1. Problem
HTML text substitutions: 20.20. Program: htmlsub
interpolating functions and expressions within: 1.15.1. Problem
matching
letters: 6.2.1. Problem
words: 6.3.1. Problem
null-terminated, reading from binary files: 8.14.1. Problem
numeric operators with: 13.14.4. Example: Overloaded StrNum Class
parsing date and time information in: 3.7.1. Problem
plurals based on numbers: 2.17.1. Problem
processing characters individually: 1.6.1. Problem
psgrep program: 1.24. Program: psgrep
reformatting paragraphs: 1.17.1. Problem
removing leading or trailing spaces: 1.19.1. Problem
removing or extracting HTML tags: 20.6.1. Problem
reversing elements of: 1.7.1. Problem
substituting specific words: 1.23. Program: fixstyle
text color, changing: 15.5.1. Problem
treating as files: 8.23.1. Problem
Unicode
support in Perl: 1.. Unicode Support in Perl
treating as octets: 1.10.1. Problem
treating as single characters: 1.8.1. Problem
universal character code: 1.. The Universal Character Code
StrNum class (example): 13.14.4. Example: Overloaded StrNum Class
struct( ): 13.5.3. Discussion
struct_flock( ), lockarea program: 7.25. Program: lockarea
structs, classes as: 13.5.1. Problem
sub keyword: 10.. Introduction
subclasses, determining membership: 13.9.1. Problem
subject, sorting mail by: 10.18. Program: Sorting Your Mail
subroutines: 10.. Introduction
access arguments: 10.1.1. Problem
built-in, overriding: 12.12.1. Problem
currently running, name of: 10.4.1. Problem
email sorter: 10.18. Program: Sorting Your Mail
exception handling: 10.12.1. Problem
localizing: 10.14.1. Problem
nesting: 10.16.1. Problem
passing arrays and hashes by reference: 10.5.1. Problem
passing by named parameter: 10.7.1. Problem
persistent private variables: 10.3.1. Problem
private for modules: 12.4.1. Problem
private variables: 10.2.1. Problem
prototypes for functions: 10.11.1. Problem
return context, detecting: 10.6.1. Problem
return values
returning by reference: 10.9.1. Problem
returning failure: 10.10.1. Problem
skipping selected: 10.8.1. Problem
saving global values: 10.13.1. Problem
trapping undefined function calls: 10.15.1. Problem
writing switch statement: 10.17.1. Problem
substitution
expanding filenames: 7.3.2. Solution
within strings: 6.1.1. Problem
substr( ): 1.1.2. Solution
operators to use with: 1.1.3. Discussion
pattern matching variables: 6.. Special Variables
substrings: 1.1.1. Problem
SUPER pseudoclass: 13.11.2. Solution
superclasses: 13.. Inheritance
13.. Some Notes on Object Terminology
accessing overridden methods: 13.11.1. Problem
surface copies: 11.12.3. Discussion
surl script: 20.8.3. Discussion
switch construct: 10.17.3. Discussion
Switch module: 10.17.2. Solution
switch statement: 19.7.3. Discussion
19.11.3. Discussion
writing: 10.17.1. Problem
Symbol module: 7.6.2. Solution
symbolic links: 9.. Introduction
duplicating directory trees: 9.12. Program: symirror
to packages: 12.16.1. Problem
symbolic references: 12.16.2. Solution
Symbol::qualify( ): 12.6.3. Discussion
symirror program: 9.12. Program: symirror
symmetric difference: 4.9.3. Discussion
syscalls: 7.. I/O Operations
Sys::Hostname module: 17.8.2. Solution
sysopen( )
filehandles: 7.1.2. Solution
non-blocking I/O: 7.20.2. Solution
unusual filenames: 7.2.2. Solution
sysread( ): 8.. Advanced Operations
sysreadline( ): 7.23.2. Solution
sysseek( ): 8.. Advanced Operations
Sys::Syslog module: 17.20. Program: backsniff
system( )
running multiple programs: 16.2.2. Solution
shell escapes: 19.5.2. Solution
system calls: 7.. I/O Operations
SysV IPC: 16.12.2. Solution
syswrite( ): 8.. Advanced Operations

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

-t command-line option: 15.2.2. Solution
tables, formatting with HTML shortcuts: 19.6.1. Problem
tabs (see whitespace)
tags, HTML (see HTML)
tailwtmp program: 8.24. Program: tailwtmp
taint mode: 19.4.3. Discussion
tan( ): 2.11.2. Solution
tc( ): 1.14.2. Solution
tcapdemo program: 15.21.1. Description
tcgrep program: 6.22. Program: tcgrep
TCP protocol
communicating over: 17.3.1. Problem
writing clients for: 17.1.1. Problem
writing servers for: 17.2.1. Problem
TCP_NODELAY socket option: 17.3.3. Discussion
tctee program: 8.25. Program: tctee
tear-off menus: 15.14.3. Discussion
tell( ): 8.. Advanced Operations
telnet, simulating from programs: 18.6.1. Problem
tempfile( ): 7.11.2. Solution
template( ): 20.9.2. Solution
Template Toolkit: 21.17.1. Problem
configuration: 21.17.3.1. Configuration
data structures: 21.17.3.4. Data structures
other templates: 21.17.3.6. Including other templates
parameters: 21.17.3.7. Parameters
Perl code: 21.17.3.3. Perl code
plug-ins: 21.17.3.8. Plug-ins
subroutines: 21.17.3.5. Subroutines
syntax: 21.17.3.2. Syntax
templates
HTML: 20.9.1. Problem
HTML::Mason: 21.16.1. Problem
autohandlers: 21.16.3.4. Autohandlers
configuration: 21.16.3.1. Configuration
dhandlers: 21.16.3.5. Dhandlers
Mason syntax: 21.16.3.2. Basic Mason syntax
objects: 21.16.3.3. Objects
for modules: 12.22. Example: Module Template
Template Toolkit: 21.17.1. Problem
configuration: 21.17.3.1. Configuration
data structures: 21.17.3.4. Data structures
other templates: 21.17.3.6. Including other templates
parameters: 21.17.3.7. Parameters
Perl code: 21.17.3.3. Perl code
plug-ins: 21.17.3.8. Plug-ins
subroutines: 21.17.3.5. Subroutines
syntax: 21.17.3.2. Syntax
temporary files, modifying files
with: 7.15.1. Problem
without: 7.17.1. Problem
Term::ANSIColor module: 15.5.2. Solution
Term::Cap module: 15.3.2. Solution
15.21.1. Description
terminal (see user interfaces)
termios interface: 15.8.1. Problem
Term::ReadKey module: 1.17.3. Discussion
checking for waiting input: 15.9.2. Solution
determining window size: 15.4.2. Solution
reading from keyboard: 15.6.2. Solution
reading passwords: 15.10.2. Solution
Term::ReadLine module: 15.11.2. Solution
Term::ReadLine::Gnu module: 15.11.2. Solution
text
(see also strings)
adding to images: 15.20.1. Problem
changing color: 15.5.1. Problem
editors, support for Unicode fonts: 8.21.3. Discussion
XML as: 22.. Introduction
Text::Abbrev module: 6.20.2. Solution
6.20.3. Discussion
Text::Balanced module: 6.17.2. Solution
6.17.3. Discussion
Text::CSV module: 1.20.3. Discussion
Text::CSV_File module: 1.20.3. Discussion
Text::Diff module: 8.22.3. Discussion
Text::Metaphone module: 1.22.2. Solution
Text::ParseWords module: 1.20.3. Discussion
Text::Soundex module: 1.22.2. Solution
Text::Tabs module: 1.11.3. Discussion
Text::Template module: 20.9.2. Solution
Text::Wrap module: 1.17.1. Problem
threads.pm: 17.14.2. Solution
tie( ): 13.15.2. Solution
DBM files
emptying: 14.2.2. Solution
making and using: 14.1.2. Solution
TIEARRAY( ): 13.15.3. Discussion
Tie::Array module: 13.15.3. Discussion
Tie::File module: 8.4.2. Solution
8.8.2. Solution
8.10.3. Discussion
files as arrays: 8.18.2. Solution
TIEHANDLE( ): 13.15.3. Discussion
Tie::Handle module: 13.15.3. Discussion
TIEHASH( ): 13.15.3. Discussion
Tie::Hash module: 13.15.3. Discussion
Tie::IxHash module: 5.7.2. Solution
Tie::RefHash module: 5.13.2. Solution
TIESCALAR( ): 13.15.3. Discussion
Tie::Scalar module: 13.15.3. Discussion
tilde (~), in filenames, expanding: 7.3.1. Problem
time (see date and time values)
time( ): 3.. Introduction
high-res timers: 3.9.3. Discussion
time zones (see date and time values)
timegm( ): 3.. Introduction
3.2.2. Solution
Time::gmtime module: 3.. Introduction
3.3.2. Solution
Time::HiRes module: 3.9.2. Solution
3.10.2. Solution
timelocal( ): 3.. Introduction
3.2.2. Solution
Time::Local module: 3.. Introduction
3.2.2. Solution
Time::localtime module: 3.. Introduction
timers, high-resolution: 3.9.1. Problem
timestamps: 9.1.1. Problem
Time::timelocal module: 3.3.2. Solution
Time::tm module: 3.. Introduction
timing out operations: 16.21.1. Problem
Tk toolkit: 15.. Introduction
dialog boxes: 15.15.1. Problem
DOS shell window, removing: 15.17.1. Problem
menus: 15.14.1. Problem
resize events: 15.16.1. Problem
tkshufflepod program: 15.22. Program: tkshufflepod
tkshufflepod program: 15.22. Program: tkshufflepod
toString( ), XML documents: 22.2.3. Discussion
tr/// operator: 1.1.3. Discussion
converting case with: 1.13.3. Discussion
trailing
growing files: 8.5.1. Problem
whitespace, removing: 1.19.1. Problem
transformations, XML: 22.. Transformations
trapping undefined function calls: 10.15.1. Problem
traversing hashes: 5.5.1. Problem
tree structures: 11.17. Program: Binary Trees
trigonometry: 2.11.1. Problem
operating in degrees vs. radians: 2.10.1. Problem
trim( ): 2.1.3. Discussion
truncate( ): 8.. Advanced Operations
tty devices, testing for: 15.2.3. Discussion
typed referents: 11.. References
typeglobs: 1.24. Program: psgrep
7.5.3. Discussion
assigning references to: 12.16.3. Discussion
filehandles with, creating alias for: 7.10.3. Discussion
global values: 10.13.3.3. Using local( ) on parts of aggregates

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

\U string escape: 1.13.2. Solution
ualarm( ): 3.9.3. Discussion
uc( ): 1.13.2. Solution
ucfirst( ): 1.13.2. Solution
UDP (User Datagram Protocol)
writing clients for: 17.4.1. Problem
writing servers for: 17.5.1. Problem
umask values: 7.1.3. Discussion
uname( ): 17.8.2. Solution
unbuffered input/output: 7.. I/O Operations
7.19.3. Discussion
8.. Advanced Operations
15.6.1. Problem
undef( ), compared to delete( ): 5.4.3. Discussion
undefined values: 1.. Introduction
underscore (_), file stat cache: 9.. Introduction
Unicode: 1.. Unicode Support in Perl
character database: 1.5.3. Discussion
combined characters, canonicalizing strings with: 1.9.1. Problem
converting Microsoft files to: 8.21.1. Problem
encodings, XML and: 22.. XML Declaration
named characters, using: 1.5.1. Problem
reading and writing from filehandles: 8.20.1. Problem
strings
treating as octets: 1.10.1. Problem
treating as single characters: 1.8.1. Problem
Uniform Resource Locators (see URLs)
unimport( ): 13.15.4. Tie Example: Outlaw $_
unions of lists: 4.8.1. Problem
computing: 4.9.1. Problem
unique list elements, extracting: 4.7.1. Problem
universal character code: 1.. The Universal Character Code
UNIVERSAL module: 13.8.3. Discussion
Unix
domain sockets: 17.. Introduction
17.6.1. Problem
I/O layers: 7.19.3. Discussion
unix layer: 7.. I/O Operations
7.19.3. Discussion
UnixDate( ): 3.7.3. Discussion
unlink( ), removing directories and contents: 9.8.3. Discussion
unpack( ): 1.1.2. Solution
1.4.3. Discussion
fixed-length records: 8.15.2. Solution
unread bytes, determining number: 7.21.1. Problem
unshift( ), circular lists: 4.17.2. Solution
updating random-access files: 8.13.1. Problem
uppercase, converting to lowercase: 1.13.1. Problem
uri_escape( ): 20.2.3. Discussion
URI::Escape module: 20.2.3. Discussion
URI::Heuristic module: 20.1.3. Discussion
20.7.3. Discussion
urlify program: 6.21. Program: urlify
URLs (Uniform Resource Locators): 19.. Architecture
expanding tildes in filenames: 7.3.3. Discussion
external redirection: 21.4.3. Discussion
extracting from HTML: 20.3.1. Problem
fetching from Perl scripts: 20.1.1. Problem
putting HTML links around: 6.21. Program: urlify
transparently storing information in: 21.10.1. Problem
use autouse pragma: 12.3.1. Problem
use bytes pragma: 1.10.2. Solution
use charnames pragma: 1.5.3. Discussion
use constant pragma: 1.21.2. Solution
use lib pragma: 12.8.3. Discussion
use locale pragma: 6.12.2. Solution
use operator: 10.. Introduction
use overload pragma: 13.14.1. Problem
use pragmas: 6.12.2. Solution
12.. Modules
trapping errors in: 12.2.1. Problem
Usenet news messages: 18.4.1. Problem
User Datagram Protocol (see UDP)
user interfaces: 15.. Introduction
adding text to images: 15.20.1. Problem
checking for waiting input: 15.9.1. Problem
clearing the screen: 15.3.1. Problem
controlling programs with Expect: 15.13.1. Problem
determining window size: 15.4.1. Problem
dialog boxes, creating with Tk: 15.15.1. Problem
DOS shell window, removing: 15.17.1. Problem
editing input: 15.11.1. Problem
full-screen mode: 15.. Introduction
graphing data: 15.18.1. Problem
15.23. Program: graphbox
managing screen: 15.12.1. Problem
manipulating terminal directly: 15.8.1. Problem
menus, creating with Tk: 15.14.1. Problem
multiscreen CGI scripts: 19.11.1. Problem
reading from keyboard: 15.6.1. Problem
reading passwords without echo: 15.10.1. Problem
ringing terminal bell: 15.7.1. Problem
tcapdemo program: 15.21.1. Description
testing programs if running interactively: 15.2.1. Problem
text color: 15.5.1. Problem
thumbnailing images: 15.19.1. Problem
Tk resize events: 15.16.1. Problem
User::pwent module: 4.16.3. Discussion
userstats program: 14.1.3. Discussion
usleep( ): 3.9.3. Discussion
UTF-8: 1.. Unicode Support in Perl
8.20.3. Discussion
utf8 I/O layer: 8.. I/O Layers
utime( ), timestamps: 9.1.2. Solution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

validation( ): 22.5.3. Discussion
values
(see also numbers strings variables)
comma-separated
initializing arrays with: 4.1.2. Solution
parsing: 1.20.1. Problem
converting strings between: 1.4.1. Problem
definedness: 1.. Introduction
1.2.3. Discussion
exchanging between scalar variables: 1.3.1. Problem
false: 1.. Introduction
values( ), traversing hashes: 5.5.3. Discussion
variable-length text fields: 8.9.1. Problem
variables
constants: 1.21.1. Problem
default values for: 1.2.1. Problem
expanding in user input: 1.12.1. Problem
filehandles in: 7.5.1. Problem
functions private for: 12.5.1. Problem
loop (iterator) variables: 4.5.3. Discussion
magic, creating: 13.15.1. Problem
persistent private, for subroutines: 10.3.1. Problem
private, for modules: 12.4.1. Problem
private, for subroutines: 10.2.1. Problem
scalars (see scalars)
sharing among different processes: 16.12.1. Problem
strings (see strings)
VERSION( ): 13.9.3. Discussion
$VERSION variable (use pragma): 12.1.3. Discussion
vertical bar (|)
||= (assignment) operator: 1.2.2. Solution
|| operator
vs. or operator: 1.2.3. Discussion
separating multiple comparisons: 4.16.3. Discussion
visual bell: 15.7.3. Discussion
VRFY command: 18.16. Program: expn and vrfy
vrfy program: 18.16. Program: expn and vrfy

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

wait( ): 16.19.3. Discussion
waitpid( ): 16.19.3. Discussion
wantarray( ): 10.6.2. Solution
warn( ), dialog box for: 15.15.3. Discussion
__WARN__ signal: 16.15.3. Discussion
warnings
customizing: 12.15.1. Problem
reporting like built-ins: 12.14.1. Problem
warnings::enabled( ): 12.15.2. Solution
warnings::register pragma: 12.15.3. Discussion
wc program: 8.2.2. Solution
W3C (World Wide Web Consortium): 22.. Schemas
weaken( ): 11.15.3. Description
WeakRef module: 11.15.3. Description
web architecture: 19.. Architecture
web automation: 20.. Introduction
converting ASCII to and from HTML: 20.4.1. Problem
extracting
table data: 20.19.1. Problem
URLs from HTML: 20.3.1. Problem
fetching
https:// web pages: 20.16.1. Problem
password-protected pages: 20.15.1. Problem
URLs: 20.1.1. Problem
finding stale or fresh links: 20.7.1. Problem
HTML
forms, submitting: 20.2.1. Problem
parsing: 20.18.1. Problem
removing or extracting tags: 20.6.1. Problem
templates: 20.9.1. Problem
text substitutions: 20.20. Program: htmlsub
htmlsub program: 20.20. Program: htmlsub
mirroring web pages: 20.10.1. Problem
resuming HTTP GET: 20.17.1. Problem
robots: 20.11.1. Problem
server logs
parsing: 20.12.1. Problem
processing: 20.13.1. Problem
using cookies: 20.14.1. Problem
web browsers (see browsers)
web pages
https://: 20.16.1. Problem
modified, links in: 20.8.1. Problem
password-protected: 20.15.1. Problem
web, references on: 19.. Web-Related Resources
web servers
log files, Common Log Format: 20.12.3. Discussion
logs
parsing: 20.12.1. Problem
processing: 20.13.1. Problem
performance, improving: 21.12.1. Problem
web services
SOAP client: 18.14.1. Problem
SOAP server: 18.13.1. Problem
XML-RPC server: 18.11.1. Problem
weekearly program: 8.13.3. Discussion
Week_Number( ): 3.6.2. Solution
weeks (see date and time values)
weighted_rand( ): 2.9.2. Solution
while loop, traversing hashes: 5.5.2. Solution
whitespace
deleting leading or trailing: 1.19.1. Problem
expanding and compressing tabs: 1.11.1. Problem
extracting ranges of lines: 6.8.1. Problem
in pod documentation: 12.20.3. Discussion
indenting here documents: 1.16.1. Problem
matching
within multiple lines: 6.6.1. Problem
words: 6.3.1. Problem
sorted text in columns and: 4.19. Program: words
sorting du command output: 5.17. Program: dutree
whoami( ): 10.4.3. Discussion
whowasi( ): 10.4.3. Discussion
wildcards (shell) for regular expression matching: 6.9.1. Problem
Win32::Console module: 15.17.3. Description
windows
dialog boxes, creating with Tk: 15.15.1. Problem
DOS shell, removing: 15.17.1. Problem
size of, determining: 12.17.3. Discussion
15.4.1. Problem
words
double, finding: 6.16.1. Problem
fuzzy matching: 6.13.1. Problem
matching abbreviations: 6.20.1. Problem
pattern matching: 6.3.1. Problem
pluralizing, based on numbers: 2.17.1. Problem
processing all in file: 8.3.1. Problem
reversing: 1.7.1. Problem
sorting into columns: 4.19. Program: words
substitutions for specific: 1.23. Program: fixstyle
text color, changing: 15.5.1. Problem
wrapping paragraph text: 1.17.1. Problem
words program: 4.19. Program: words
World Wide Web Consortium (W3C): 22.. Schemas
wrapping paragraph text: 1.17.1. Problem
write( ): 16.4.2. Solution
writing
signal handlers: 16.17.1. Problem
XML: 22.10.1. Problem
wtmp file, adding records to: 8.24. Program: tailwtmp

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x command (Perl debugger): 11.11.2. Solution
\X metacharacter: 1.8.3. Discussion
x operator: 2.13.3. Discussion
/x pattern modifier: 1.12.3. Discussion
comments in regular expressions: 6.4.3. Discussion
XML declaration: 22.. XML Declaration
XML documents
changing elements or text: 22.4.1. Problem
finding elements and text: 22.6.1. Problem
validating against schemas: 22.. Schemas
XML (Extensible Markup Language): 22.. Introduction
CDATA: 22.. CDATA
comments: 22.. Comments
declaration: 22.. XML Declaration
documents (see XML documents)
files, larger than available memory, processing: 22.8.1. Problem
filtering: 22.4.1. Problem
namespaces: 22.. Namespaces
nested elements: 22.. Namespaces
parsing
into data structures: 22.1.1. Problem
into DOM tree: 22.2.1. Problem
into SAX events: 22.3.1. Problem
paths: 22.. Paths
Perl and, history of: 22.. History of Perl and XML
processing instructions: 22.. Processing Instructions
reasons for success of: 22.. Introduction
schemas: 22.. Schemas
syntax: 22.. Syntax
transformations: 22.. Transformations
Unicode encodings: 22.. XML Declaration
validating: 22.5.1. Problem
documents against schemas: 22.. Schemas
well-formed documents: 22.. Well-Formed XML
writing: 22.10.1. Problem
XML-RPC: 18.. Introduction
client: 18.12.1. Problem
server: 18.11.1. Problem
XML Schema: 22.. Schemas
XML Stylesheet Language for Transformations (see XSLT)
XMLin( ): 22.1.3. Discussion
XML::LibXML module: 22.. History of Perl and XML
22.3.3. Discussion
finding elements and text in XML documents: 22.6.2. Solution
parsing XML into a DOM tree: 22.2.2. Solution
validating XML against DTD: 22.5.2. Solution
XML::LibXSLT module: 22.. Transformations
22.7.2. Solution
XMLout( ), writing XML: 22.10.2. Solution
XML::Parser module: 22.3.3. Discussion
caution against using directly: 22.. History of Perl and XML
XMLRPC::Lite module: 18.. Introduction
18.12.2. Solution
XML::RSS module: 22.9.2. Solution
XML::Sablotron module, XSLT: 22.. Transformations
XML::SAX module: 22.3.3. Discussion
parsing XML into SAX events: 22.3.2. Solution
XML::SAX modules, parsing XML: 22.. History of Perl and XML
XML::SAX::Base module: 22.3.3. Discussion
XML::SAX::Machines module, filtering XML: 22.4.2. Solution
XML::SAX::ParserFactory module: 22.3.3. Discussion
XML::SAX::PurePerl module: 22.3.3. Discussion
XML::Simple module: 22.1.2. Solution
writing XML: 22.10.2. Solution
XML::Twig module, processing large XML files: 22.8.2. Solution
XML::Xerces module, validating XML against W3C Schema: 22.5.2. Solution
XML::XSLT module: 22.. Transformations
XPath: 22.. Paths
expressions: 22.6.3. Discussion
XS interface: 12.9.3. Discussion
12.18.3. Discussion
XSLT (XML Stylesheet Language for Transformations): 22.. Transformations
processing: 22.7.1. Problem

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

years (see date and time values)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

zombies: 16.. Process Creation
avoiding: 16.19.1. Problem

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal featured on the cover of Perl Cookbook, Second Edition is a bighorn sheep. Bighorn sheep (Ovis canadensis) are wild sheep noted, not surprisingly, for their large, curved horns. Male bighorns grow to approximately 5 feet long and 40 inches tall to the shoulder and weigh up to 350 pounds. Their horns measure up to 18 inches in circumference and 4 feet long and can weigh up to 30 pounds. Despite their bulk, bighorns are adept at negotiating mountainous terrains. With their sharp, cloven hooves they can walk on ledges as thin as two inches. They have excellent eyesight that enables them to locate footholds and to accurately judge distances between ledges. They can jump as far as 20 feet from ledge to ledge.

Competition for ewes is intense and often leads to fierce battles that can continue for a full day. During the battle two rams race at each other at speeds of up to 20 miles an hour, clashing their horns together. The skull of the bighorn sheep is double-layered to provide protection from these blows. Horn size is a significant factor in determining rank, and rams will only fight other rams with an equivalently sized horn. Mature males usually stay apart from the females and young. In these "bachelor flocks" the lower-ranking males often play the part of ewes and behave in a submissive manner toward the dominant males. The dominant male, in turn, behaves like a courting ram and mounts the lower-ranking male. This behavior is believed to enable the rams to live together without rank disputes that might otherwise drive the lower-ranking males out of the flock.

Bighorns can be found in the Rocky Mountains from Canada to Colorado and in the desert from California to west Texas and Mexico. They are threatened with extinction as a result of disease, habitat reduction, and hunting.

Genevieve d'Entremont was the production editor and copyeditor for Perl Cookbook, Second Edition. Phil Dangler, Emily Quill, Matt Hutchinson, and Colleen Gorman provided quality control. Mary Agner and Jamie Peppard provided production assistance. Nancy Crumpton wrote the index.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

David Futato designed the interior layout. This book was converted by Julie Hawks and Andrew Savikas from Pod to FrameMaker 5.5.6 with a format conversion tool created by Erik Ray, Jason McIntosh, Neil Walls, and Mike Sierra that uses Perl and XML technologies. The text font is Linotype Birka; the heading font is Adobe Myriad Condensed; and the code font is LucasFont's TheSans Mono Condensed. The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand 9 and Adobe Photoshop 6. The warning icon was drawn by Christopher Bing. This colophon was written by Clairemarie Fisher O'Leary.

Previous | Home
 | Book Index
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Table of Contents

Copyright Page
Preface
Chapter 1: Introduction
Chapter 2: Scalar Data
Chapter 3: Lists and Arrays
Chapter 4: Subroutines
Chapter 5: Hashes
Chapter 6: I/O Basics
Chapter 7: Concepts of Regular Expressions
Chapter 8: More About Regular Expressions
Chapter 9: Using Regular Expressions
Chapter 10: More Control Structures
Chapter 11: Filehandles and File Tests
Chapter 12: Directory Operations
Chapter 13: Manipulating Files and Directories
Chapter 14: Process Management
Chapter 15: Strings and Sorting
Chapter 16: Simple Databases
Chapter 17: Some Advanced Perl Techniques
Appendix A: Exercise Answers
Appendix B: Beyond the Llama
Index
Colophon

Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


(Learning Perl, 3rd Edition)

 Learning Perl, 3rd Edition
Previous Next

Copyright © 2001, 1997, 1993 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com). For more information contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com.

Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The association between the image of a llama and Perl is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Preface

Welcome to the third edition of Learning Perl.

If you're looking for the best way to spend your first 30 to 45 hours with the Perl programming language, look no further. In the pages that follow, you'll find a carefully paced introduction to the language that remains the workhorse of the Internet, as well as the language of choice for system administrators, web hackers, and casual programmers around the world.

We can't give you all of Perl in just a few hours. The books that promise that are probably fibbing a bit. Instead, we've carefully selected a complete and useful subset of Perl for you to learn, good for programs from one to 128 lines long, which end up being about 90% of the programs in use out there. And when you're ready to go on, we've included a number of pointers for further education.

Each chapter is small enough to be read in an hour or two. Each chapter ends with a series of exercises to help you practice what you've just learned, with the answers in Appendix A, "Exercise Answers" for your reference. Thus, this book is ideally suited for a classroom "introduction to Perl" course. We know this directly, because the material for this book was lifted almost word-for-word from our flagship "Learning Perl" course, delivered to thousands of students around the world. However, we've designed the book for self-study as well.

Although Perl lives as the "toolbox for Unix," you don't have to be a Unix guru, or even a Unix user, to use this book. Unless otherwise noted, everything we're saying applies equally well to Windows ActivePerl from ActiveState, as well as to the later releases of MacPerl for the Macintosh and pretty much every other modern implementation of Perl.

Although you don't need to know a single bit about Perl to begin reading this book, we do recommend that you already have familiarity with basic programming concepts such as variables, loops, subroutines, and arrays, and the all-important "editing a source code file with your favorite text editor." We won't spend any time trying to explain those concepts. Although we're pleased that we've had many reports of people successfully picking up Learning Perl and grasping Perl as their first programming language, of course we can't promise the same results for everyone.

0.1. Typographical Conventions

The following font conventions are used in this book:

Constant width
is used for method names, function names, variables, and attributes. It is also used for code examples.

Constant width bold
is used to indicate user input.

Constant width italic
is used to indicate a replaceable item in code (e.g., filename, where you are supposed to substitute an actual filename).

Italic
is used for filenames, URLs, hostnames, commands in text, important words on first mention, and emphasis.

Footnotes
are used to attach parenthetical notes that you should not read on your first (or perhaps second or third) reading of this book. Sometimes lies are spoken to simplify the presentation, and the footnotes restore the lie to truth. Often the material in the footnote will be advanced material not even discussed anywhere else in the book.

Previous | Home | Next
Copyright Page | Book Index | 0.2. How to Contact Us
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.2. How to Contact Us

We have tested and verified all the information in this book to the best of our abilities, but you may find that features have changed or that we have let errors slip through the production of the book. Please let us know of any errors that you find, as well as suggestions for future editions, by writing to:

O'Reilly & Associates, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
1-800-998-9938 (in the U.S. or Canada)
1-707-829-0515 (international/local)
1-707-829-0104 (fax)

You can also send messages electronically. To be put on our mailing list or to request a catalog, send email to:

info@oreilly.com

To ask technical questions or to comment on the book, send email to:

bookquestions@oreilly.com

We have a web site for the book, where we'll list examples, errata, and any plans for future editions. It also offers a downloadable set of text files (and a couple of Perl programs) which are useful, but not required, when doing some of the exercises. You can access this page at:

http://www.oreilly.com/catalog/lperl3/

For more information about this book and others, see the O'Reilly web site:

http://www.oreilly.com

Previous | Home | Next
0. Preface | Book Index | 0.3. Code Examples
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.3. Code Examples

You are invited to copy the code in the book and adapt it for your own needs. Rather than copying by hand, however, we encourage you to download the code from http://www.oreilly.com/catalog/lperl3/.

Previous | Home | Next
0.2. How to Contact Us | Book Index | 0.4. History of This Book
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.4. History of This Book

For the curious, here's how Randal tells the story of how this book came about:

After I had finished the first Programming Perl book with Larry Wall (in 1991), I was approached by Taos Mountain Software in Silicon Valley to produce a training course. This included having me deliver the first dozen or so courses and train their staff to continue offering the course. I wrote the course for them[1] and delivered it for them as promised.

[1]In the contract, I retained the rights to the exercises, hoping someday to reuse them in some other way, like in the magazine columns I was writing at the time. The exercises are the only things that lept from the Taos course to the book.

On the third or fourth delivery of that course (in late 1991), someone came up to me and said, "you know, I really like Programming Perl, but the way the material is presented in this course is so much easier to follow -- you oughta write a book like this course." It sounded like an opportunity to me, so I started thinking about it.

I wrote to Tim O'Reilly with a proposal based on an outline that was similar to the course I was presenting for Taos -- although I had rearranged and modified a few of the chapters based on observations in the classroom. I think that was my fastest proposal acceptance in history -- I got a message from Tim within fifteen minutes saying "we've been waiting for you to pitch a second book -- Programming Perl is selling like gangbusters." That started the effort over the next eighteen months to finish the first edition of Learning Perl.

During that time, I was starting to see an opportunity to teach Perl classes outside Silicon Valley[2], so I created a class based on the text I was writing for Learning Perl. I gave a dozen classes for various clients (including my primary contractor, Intel Oregon), and used the feedback to fine-tune the book draft even further.

[2]My Taos contract had a no-compete clause, so I had to stay out of Silicon Valley with any similar courses, which I respected for many years.

The first edition hit the streets on the first day of November, 1993[3] and became a smashing success, frequently even outpacing Programming Perl book sales.

[3]I remember that date very well, because it was also the day I was arrested at my home for computer-related-activities around my Intel contract, a series of felony charges for which I was later convicted. The appeals battle continues -- see http://www.lightlink.com/fors/for details.

The back-cover jacket of the first book said "written by a leading Perl trainer." Well, that became a self-fulfilling prophesy. Within a few months, I was starting to get email from all over the United States from people asking to have me teach at their site. In the following seven years, my company became the leading worldwide on-site Perl training company, and I had personally racked up (literally) a million frequent-flier miles. It didn't hurt that the Web started taking off about then, and the webmasters and webmistresses picked Perl as the language of choice for content management, interaction through CGI, and maintenance.

For the past two years, I've been working closely with Tom Phoenix in his role as lead trainer and content manager for Stonehenge, giving him charter to experiment with the "Llama" course by moving things around and breaking things up. When we had come up with what we thought was the best major revision of the course, I contacted O'Reilly and said "it's time for a new book!" And now you're reading it.

Some of the differences you may notice from prior editions:

  • The text is completely new. Rather than simply copy-and-paste from previous editions, we have derived the text from our Stonehenge "Learning Perl" courseware and the instructor notes we've created and road-tested. (Some of the exercises are similar to the originals simply because we were using the prior editions as our textbook until recently. But even those have mutated during the rewrites.)

  • We've broken the hard-to-swallow-all-at-once regular expressions section into three easily digestible sections.

  • We've created exercises with both Unix and Windows in mind.

  • We got rid of the artificial "control structures" chapter, moving the while and if statement earlier, and the foreach and for loops later. This gives us more useful examples and exercises for the scalars chapter, for example.

  • We moved subroutines much earlier to permit subsequent exercises to use subroutines for the questions and answers.

  • We now teach element syntax before the aggregate syntax for both arrays and hashes. This has worked a bit of a miracle in the classrooms, since it nearly always keeps beginners from the all-too-common mistake of writing a slice where they mean an element. At the risk of hubris, we'll admit that we expect other Perl instructors and books to follow our lead here.

  • The exercises are more real-world and better paced.

  • We've included information on use strict, warnings, and modules, although mostly as pointers for further information.

  • We've made the book much less addressed to the Unix system administrator, and much more to the general programmer. The phrase "like C" has been nearly completely eliminated.

  • The jokes are better. (We're constantly improvising jokes in the classroom, and some of these end up as part of the standard Stonehenge script. The best of those ended up here. You should see what didn't make the cut!)

  • We deeply regret that this edition lacks the wonderfully witty Foreword, written by Larry Wall, who was busy defining Perl 6 as we went to press. Larry is always supportive of our efforts, and we know that he's still part of the book in spirit, if not in word, to wish you the best as you start your holiday in the lustrous land of Perl.

Previous | Home | Next
0.3. Code Examples | Book Index | 0.5. Acknowledgments
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.5. Acknowledgments

From Randal. I want to thank the Stonehenge trainers past and present (Joseph Hall, Tom Phoenix, Chip Salzenberg, brian d foy, and Tad McClellan) for their willingness to go out and teach in front of classrooms week after week and to come back with their notes about what's working (and what's not) so we could fine-tune the material for this book. I especially want to single out my co-author and business associate, Tom Phoenix, for having spent many, many hours working to improve Stonehenge's Llama course and to provide the wonderful core text for most of this book.

I also want to thank everyone at O'Reilly, especially our very encouraging and patient editor, Linda Mui, and Tim O'Reilly himself for taking a chance on me in the first place with the Camel and Llama books.

I am also absolutely indebted to the thousands of people who have purchased the past editions of the Llama so that I could use the money to stay "off the streets and out of jail," and to those students in my classrooms who have trained me to be a better trainer, and to the stunning array of Fortune 1000 clients who have purchased our classes in the past and will continue to do so into the future.

As always, a special thanks to Lyle and Jack, for teaching me nearly everything I know about writing. I won't ever forget you guys.

From Tom. I've got to echo Randal's thanks to our editor, Linda Mui, for her patience in pointing out which jokes and footnotes were most excessive, while pointing out that she is in no way to blame for the ones that remain. Both she and Randal have guided me through the process of writing, and I am grateful.

And another echo with regard to Randal and the other Stonehenge trainers, who hardly ever complained when I unexpectedly updated the course materials to try out a new teaching technique. You folks have contributed many different viewpoints on teaching methods that I would never have seen.

For many years, I worked at the Oregon Museum of Science and Industry (OMSI), and I'd like to thank the folks there for letting me hone my teaching skills as I learned to build a joke or two into every activity, explosion, or dissection.

To the many folks on Usenet who have given me your appreciation and encouragement for my contributions there, thanks. As always, I hope this helps.

Of course, deep thanks are due especially to my co-author, Randal, for giving me the freedom to try various ways of presenting the material both in the classroom and here in the book, as well as for the push to make this material into a book in the first place. And without fail, I must say that I am indeed inspired by your on-going work to ensure that no one else becomes ensnared by the legal troubles that have stolen so much of your time and energy; you're a fine example.

From Both of Us. Thanks to our reviewers (Elaine Ashton, Kevin Bingham, Jarkko Hietaniemi, Joe Johnston, and Ben Tilly) for providing comments on the draft of this book.

Thanks also to our many students who have let us know what parts of the course material have needed improvement over the years. It's because of you that we're both so proud of it today.

Thanks to the many Perl Mongers who have made us feel at home as we've visited your cities. Let's do it again sometime.

And finally, our sincerest thanks to our friend Larry Wall, for having the wisdom to share his really cool and powerful toys with the rest of the world so that we can all get our work done just a little bit faster, easier, and with more fun.

Previous | Home | Next
0.4. History of This Book | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 1. Introduction

Contents:

Questions and Answers
What Does "Perl" Stand For?
How Can I Get Perl?
How Do I Make a Perl Program?
A Whirlwind Tour of Perl
Exercises

Welcome to the Llama book!

This is the third edition of a book that has been enjoyed by half a million readers since 1993. At least, we hope they've enjoyed it. It's a sure thing that we've enjoyed writing it.[4]

[4]To be sure, the first edition was written by Randal L. Schwartz, the second by Randal L. Schwartz and Tom Christiansen, and this one by Randal L. Schwartz and Tom Phoenix. So, whenever we say "we" in this edition, we mean those last two. Now, if you're wondering how we can say that we've enjoyed writing it (in the past tense) when we're still on the first page, that's easy: we started at the end, and worked our way backwards. It sounds like a strange way to do it, we know. But, honestly, once we finished writing the index, the rest was hardly any trouble at all.

1.1. Questions and Answers

You probably have some questions about Perl, and maybe even some about this book; especially if you've already flipped through the book to see what's coming. So we'll use this chapter to answer them.

1.1.1. Is This the Right Book for You?

If you're anything like us, you're probably standing in a bookstore right now,[5] wondering whether you should get this Llama book and learn Perl, or maybe that book over there and learn some language named after a snake, or a beverage, or a letter of the alphabet.[6] You've got about two minutes before the bookstore manager comes over to tell you that this isn't a library,[7] and you need to buy something or get out. Maybe you want to use these two minutes to see a quick Perl program, so you'll know something about how powerful Perl is and what it can do. In that case, you should check out the whirlwind tour of Perl, later in this chapter.

[5]Actually, if you're like us, you're standing in a library, not a bookstore. But we're tightwads.

[6]Before you write to tell us that it's a comedy troupe, not a snake, we should really explain that we're dyslexically thinking of CORBA.

[7]Unless it is.

1.1.2. Why Are There So Many Footnotes?

Thank you for noticing. There are a lot of footnotes in this book. Ignore them. They're needed because Perl is chock-full of exceptions to its rules. This is a good thing, as real life is chock-full of exceptions to rules.

But it means that we can't honestly say, "The fizzbin operator frobnicates the hoozistatic variables" without a footnote giving the exceptions.[8] We're pretty honest, so we have to write the footnotes. But you can be honest without reading them. (It's funny how that works out.)

[8]Except on Tuesdays, during a power outage, when you hold your elbow at a funny angle during the equinox, or when use integer is in effect inside a loop block being called by a prototyped subroutine prior to Perl version 5.6.

Many of the exceptions have to do with portability. Perl began on Unix systems, and it still has deep roots in Unix. But wherever possible, we've tried to show when something may behave unexpectedly, whether that's because it's running on a non-Unix system, or for another reason. We hope that readers who know nothing about Unix will nevertheless find this book a good introduction to Perl. (And they'll learn a little about Unix along the way, at no extra charge.)

And many of the other exceptions have to do with the old "80/20" rule. By that we mean that 80% of the behavior of Perl can be described in 20% of the documentation, and the other 20 percent of the behavior takes up the other 80% of the documentation. So to keep this book small, we'll talk about the most common, easy-to-talk-about behavior in the main text, and hint in the direction of the other stuff in the footnotes (which are in a smaller font, so we can say more in the same space).[9]

[9]We even discussed doing the entire book as a footnote to save the pagecount, but footnotes on footnotes started to get a bit crazy.

Once you've read the book all the way through without reading the footnotes, you'll probably want to look back at some sections for reference. At that point, or if you become unbearably curious along the way, go ahead and read the notes. A lot of them are just computer jokes anyway.

1.1.3. What About the Exercises and Their Answers?

The exercises are at the end of each chapter because, between the two of us, we've presented this same course material to several thousand students.[10] We have carefully crafted these exercises to give you the chance to make mistakes as well.

[10]Not all at once.

It's not that we want you to make mistakes, but you need to have the chance. That's because you are going to make most of these mistakes during your Perl programming career, and it may as well be now. Any mistake that you make while reading this book you won't make again when you're writing a program on a deadline. And we're always here to help you out if something goes wrong, in the form of Appendix A, "Exercise Answers", which has our answer for each exercise and a little text to go with it, explaining the mistakes you made and a few you didn't. Check out the answers when you're done with the exercises.

Try not to peek at the answer until you've given the problem a good try, though. You'll learn better if you figure it out rather than if you read about it.

Even if you never make any mistakes, you should look at the answers when you're done; the accompanying text will point out some details of the program that might not be obvious at first.

1.1.4. What Do Those Numbers Mean at the Start of the Exercise?

Each exercise has a number in square brackets in front of the exercise text, looking something like this:

  1. [2] What does the number 2 inside square brackets mean, when it appears at the start of an exercise's text?

That number is our (very rough) estimate of how many minutes you can expect to spend on that particular exercise. It's rough, so don't be too surprised if you're all done (with writing, testing, and debugging) in half that time, or not done in twice that long. On the other hand, if you're really stuck, we won't tell anyone that you peeked at Appendix A, "Exercise Answers" to see what our answer looked like.

1.1.5. What If I'm a Perl Course Instructor?

If you're a Perl instructor who has decided to use this as your textbook (as many have over the years), you should know that we've tried to make each set of exercises short enough that most students could do the whole set in 45 minutes to an hour, with a little time left over for a break. Some chapters' exercises should be quicker, and some may take longer. That's because, once we had written all of those little numbers in square brackets, we discovered that we don't know how to add.

Previous | Home | Next
0.5. Acknowledgments | Book Index | 1.2. What Does "Perl" Stand For?
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.2. What Does "Perl" Stand For?

Perl is short for " Practical Extraction and Report Language," although it has also been called a "Pathologically Eclectic Rubbish Lister," among other expansions.[11] There's no point in arguing which expansion is correct, because both of those are endorsed by Larry Wall, Perl's creator and chief architect, implementor, and maintainer. He created Perl in the mid-1980s when he was trying to produce some reports from a Usenet-news-like hierarchy of files for a bug-reporting system, and awk ran out of steam. Larry, being the lazy programmer that he is,[12] decided to overkill the problem with a general-purpose tool that he could use in at least one other place. The result was Perl version zero.

[11]It's actually a retronym, not an acronym. That is, Larry came up with the name first, and the expansion later. That's why "Perl" isn't in all caps.

[12]We're not insulting Larry by saying he's lazy; laziness is a virtue. The wheelbarrow was invented by someone who was too lazy to carry things; writing was invented by someone who was too lazy to memorize; Perl was invented by someone who was too lazy to get the job done without inventing a whole new computer language.

1.2.1. Why Didn't Larry Just Use Some Other Language?

There's no shortage of computer languages, is there? But, at the time, Larry didn't see anything that really met his needs. If one of the other languages of today had been available back then, perhaps Larry would have used one of those. He needed something with the quickness of coding available in shell or awk programming, and with some of the power of more advanced tools like grep, cut, sort, and sed,[13] without having to resort to a language like C.

[13]Don't worry if you don't know what these are. All that matters is that they were the programs Larry had in his Unix toolbox, but they weren't up to the tasks at hand.

Perl tries to fill the gap between low-level programming (such as in C or C++ or assembly) and high-level programming (such as "shell" programming). Low-level programming is usually hard to write and ugly, but fast and unlimited; it's hard to beat the speed of a well-written low-level program on a given machine. And there's not much you can't do there. High-level programming, at the other extreme, tends to be slow, hard, ugly, and limited; there are many things you can't do at all with the shell, if there's no command on your system that provides the needed functionality. Perl is easy, nearly unlimited, mostly fast, and kind of ugly.

Let's take another look at those four claims we just made about Perl:

First, Perl is easy. As you'll see, though, this means it's easy to use. It's not especially easy to learn. If you drive a car, you spent many weeks or months learning that, and now it's easy to drive. When you've been programming Perl for about as many hours as it took you to learn to drive, Perl will be easy for you.[14]

[14]But we hope you'll crash less often with the car.

Perl is nearly unlimited. There are very few things you can't do with Perl. You wouldn't want to write a interrupt-microkernel-level device driver in Perl (even though that's been done), but most things that ordinary folks need most of the time are good tasks for Perl, from quick little one-off programs to major industrial-strength applications.

Perl is mostly fast. That's because nobody is developing Perl who doesn't also use it -- so we all want it to be fast. If someone wants to add a feature that would be really cool, but which would slow down other programs, Larry is almost certain to refuse the new feature until we find a way to make it quick enough.

Perl is kind of ugly. This is true. The symbol of Perl has become the camel, from the cover of the venerable Camel book (also known as Programming Perl ), a sister to this one. Camels are kind of ugly, too. But they work hard, even in tough conditions. Camels are there to get the job done despite all difficulties, even when they look bad and smell worse and sometimes spit at you. Perl is a little like that.

1.2.2. Is Perl Easy or Hard?

It's easy to use, but sometimes hard to learn. This is a generalization, of course. But in designing Perl, Larry has had to make many trade-offs. When he's had the chance to make something easier for the programmer at the expense of being more difficult for the student, he's decided in the programmer's favor nearly every time. That's because you'll learn Perl only once, but you'll use it again and again.[15]

[15]If you're going to use a programming language for only a few minutes each week or month, you'd prefer one that is easier to learn, since you'll have forgotten nearly all of it from one use to the next. Perl is for people who are programmers for at least twenty minutes per day, and probably most of that in Perl.

Perl has any number of conveniences that let the programmer save time. For example, most functions will have a default; frequently, the default is the way that you'll want to use the function. So you'll see lines of Perl code like these:[16]

[16]We won't explain it all here, but this example pulls some data from an input file or files in one format and writes some of it out in another format. All of its features are covered in this book.

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

Written out in full, without using Perl's defaults and shortcuts, that snippet would be roughly ten or twelve times longer, so it would take much longer to read and write. It would be harder to maintain and debug, too, with more variables. If you already know some Perl, and you don't see the variables in that code, that's part of the point. They're all being used by default. But to have this ease at the programmer's tasks means paying the price when you're learning; you have to learn those defaults and shortcuts.

Once you become familiar with Perl, you may find yourself spending less time trying to get shell quoting (or C declarations) right, and more time surfing the Web, because Perl is a great tool for leverage. Perl's concise constructs allow you to create (with minimal fuss) some very cool one-up solutions or general tools. Also, you can drag those tools along to your next job, because Perl is highly portable and readily available, so you'll have even more time to surf.

Perl is a very high-level language. That means that the code is quite dense; a Perl program may be around 30% to 70% as long as the corresponding program in C. This makes Perl faster to write, faster to read, faster to debug, and faster to maintain. It doesn't take much programming before you realize that, when the entire subroutine is small enough to fit onscreen all at once, you don't have to keep scrolling back and forth to see what's going on. Also, since the number of bugs in a program is roughly proportional to the length of the source code[17] (rather than being proportional to the program's functionality), the shorter source in Perl will mean fewer bugs on average.

[17]With a sharp jump when any one section of the program exceeds the size of your screen.

Like any language, Perl can be "write-only" -- it's possible to write programs that are impossible to read. But with proper care, you can avoid this common accusation. Yes, sometimes Perl looks like line-noise to the uninitiated, but to the seasoned Perl programmer, it looks like checksummed line-noise with a mission in life. If you follow the guidelines of this book, your programs should be easy to read and easy to maintain, and they probably won't win The Obfuscated Perl Contest.[18]

[18]An actual annual event sponsored by the Perl Journal (at http://www.tpj.com/ ).

1.2.3. How Did Perl Get to Be So Popular?

After playing with Perl a bit, adding stuff here and there, Larry released it to the community of Usenet readers, commonly known as "the Net." The users on this ragtag fugitive fleet of systems around the world (tens of thousands of them) gave him feedback, asking for ways to do this, that, or the other thing, many of which Larry had never envisioned his little Perl handling.

But as a result, Perl grew, and grew, and grew. It grew in features. It grew in portability. What was once a little language available on only a couple of Unix systems has now grown to have thousands of pages of free online documentation, dozens of books, several mainstream Usenet newsgroups (and a dozen newsgroups and mailing lists outside the mainstream) with an uncountable number of readers, and implementations on nearly every system in use today -- and don't forget this Llama book as well.

1.2.4. What's Happening with Perl Now?

Larry is still in charge of Perl, although the Perl development team is now made up of approximately thirty key people and a few hundred others from around the world. And Perl is still growing.

These days, Perl is still free for you to use. In fact, Larry promises that it will always be free. (He's a really nice guy; you'd like him.) So go ahead and write code in Perl today, without worrying that there will be a licensing fee on your program tomorrow.

So, if Perl is free, who pays Larry and the other Perl developers? Well, the majority of us contribute to Perl as a labor of love; Perl helps us, and we help Perl. (If you ever see some way in which you could improve Perl, we encourage you to send in your contributions, too.) In some cases, though, a person or firm has paid someone to do some development work. This may be because they needed some new functionality badly enough to pay for it, or because they wanted to make the world a better place.

Larry doesn't write all of the code these days, but he still guides the development and makes the big decisions. One of the most important rules he's given us is this one: "Common things should be easy; advanced things should at least be possible."

Because of that rule, you can be sure that anything that you need to do frequently will have a shortcut in Perl. In fact, by the end of this book, you'll probably be using at least ten shortcuts in a typical ten-line program. That is the sort of thing that makes Perl easier to use, at the price of being harder to learn.

1.2.5. What's Perl Really Good For?

Perl is good for quick-and-dirty programs that you whip up in three minutes. Perl is also good for long-and-extensive programs that will take a dozen programmers three years to finish. Of course, you'll probably find yourself writing many programs that take you less than an hour to complete, from the initial plan to the fully tested code.

Perl is optimized for problems which are about 90% working with text and about 10% everything else. That description seems to fit most programming tasks that pop up these days. In a perfect world, every programmer could know every language; you'd always be able to choose the best language for each project. Most of the time, you'd choose Perl.[19]

[19]Don't just take our word for it, though. If you want to know whether Perl is better than language X, learn them both and try them both, then see which one you use most often. That's the one that's best for you. In the end, you'll understand Perl better because of your study of language X, and vice versa, so it will be time well spent.

Although the Web wasn't even a twinkle in Tim Berners-Lee's eye when Larry created Perl, it was a marriage made on the Net. Some claim that the deployment of Perl in the early 1990s permitted lots of content to be moved into HTML format very rapidly, and the Web couldn't exist without content. Of course, Perl is the darling language for small CGI scripting (programs run by a web server) as well -- so much so that many of the uninformed still make statements like "Isn't CGI just Perl?" or "Why would you use Perl other than for CGI?" We find those statements amusing.

1.2.6. What Is Perl Not Good For?

So, if it's good for so many things, what is Perl not good for? Well, you shouldn't choose Perl if you're trying to make an opaque binary. That's a program that you could give away or sell to someone who then can't see your secret algorithms in the source, and thus can't help you to maintain or debug your code either. When you give someone your Perl program, you'll normally be giving them the source, not an opaque binary.

If you're wishing for an opaque binary, though, we have to tell you that they don't exist. If someone can install and run your program, they can turn it back into source code. Granted, this won't necessarily be the same source that you started with, but it will be some kind of source code. The real way to keep your secret algorithm a secret is, alas, to apply the proper number of attorneys; they can write a license that says "you can do this with the code, but you can't do that. And if you break our rules, we've got the proper number of attorneys to ensure that you'll regret it."

If you think you really want to compile your Perl code to make a binary, though, see Section 1.4.3, "But How Do I Compile Perl?" later in this chapter.

Previous | Home | Next
1. Introduction | Book Index | 1.3. How Can I Get Perl?
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.3. How Can I Get Perl?

You probably already have it. At least, we find Perl wherever we go. It ships with many systems, and system administrators often install it on every machine at their site.[20] But if you can't find it already on your system, you can still get it for free.

[20]Well, each machine that is made for programming, at least.

Perl is distributed under two different licenses. For most people, since you'll merely be using it, either license is as good as the other. If you'll be modifying Perl, however, you'll want to read the licenses more closely, because they put some small restrictions on distributing the modified code. For people who won't modify Perl, the licenses essentially say "it's free -- have fun with it."

In fact, it's not only free, but it runs rather nicely on nearly everything that calls itself Unix and has a C compiler. You download it, type a command or two, and it starts configuring and building itself. Or, better yet, you get your system administrator to type those two commands and install it for you.[21]

[21]If system administrators can't install software, what good are they? If you have trouble convincing your admin to install Perl, offer to buy a pizza. We've never met a sys admin who could say no to a free pizza, or at least counter-offer with something just as easy to get.

Besides Unix and Unix-like systems, people have also been addicted enough to Perl to port it to other systems, like the Macintosh,[22] VMS, OS/2, even MS/DOS and every modern species of Windows -- and probably even more by the time you read this.[23] Many of these ports of Perl come with an installation program that's even easier to use than the process for installing Perl on Unix. Check for links in the "ports" section on CPAN.

[22]MacPerl runs under the "classic" Mac OS. If you have Mac OS X, which is a Unix-based system, you have mainstream Perl.

[23]And no, as we write this, it won't fit in your Palm handheld -- it's just too darn big, even stripped down.

1.3.1. What Is CPAN?

CPAN is the Comprehensive Perl Archive Network, your one-stop shopping for Perl. It has the source code for Perl itself, ready-to-install ports of Perl to all sorts of non-Unix systems,[24] examples, documentation, extensions to Perl, and archives of messages about Perl. In short, CPAN is comprehensive.

[24]It's nearly always better to compile Perl from the source on Unix systems. Other systems may not have a C compiler and other tools needed for compilation, so CPAN has binaries for these.

CPAN is replicated on hundreds of mirror machines around the world; start at http://www.cpan.org/ to find one near you. Most of the time, you can also simply visit http://COUNTRYCODE.cpan.org/ where COUNTRYCODE is your two-letter official country code (like on the end of your national domain names). Or, if you don't have access to the Net, you might find a CD-ROM or DVD-ROM with all of the useful parts of CPAN on it; check with your local technical bookstore. Look for a recently minted archive, though; since CPAN changes daily, an archive from two years ago is an antique. (Better yet, get a kind friend with Net access to burn you one with today's CPAN.)

CPAN is pretty-well organized; most of the time, you should find what you want with just a few clicks of the mouse. But there's also a couple of nice search interfaces on the Web at http://search.cpan.org/ and http://kobesearch.cpan.org/,which are especially helpful when you're looking for an extension to Perl.

1.3.2. How Can I Get Support for Perl?

Well, you get the complete source -- so you get to fix the bugs yourself!

That doesn't sound so good, does it? But it really is a good thing. Since there's no "source code escrow" on Perl, anyone can fix a bug -- in fact, by the time you've found and verified a bug, someone else has probably already got a fix for it. There are thousands of people around the world who help to maintain Perl.

Now, we're not saying that Perl has a lot of bugs. But it's a program, and every program has at least one bug.[25]

[25]Programmers also know that every program has at least one line of unnecessary source code. By combining these two rules and using logical induction, it's a simple matter to prove that any program could be reduced to a single line of code with a bug.

To see why it's so useful to have the source to Perl, imagine that instead of using Perl, you licensed a programming language called Forehead from a giant, powerful corporation owned by a zillionaire with a bad haircut. (This is all hypothetical. Everyone knows there's no such programming language as Forehead.) Now think of what you can do when you find a bug in Forehead. First, you can report it; second, you can hope -- hope that they fix the bug, hope that they fix it soon, hope that they won't charge too much for the new version. You can hope that the new version doesn't add new features with new bugs, and hope that the giant company doesn't get broken up in an anti-trust lawsuit.

But with Perl, you've got the source. In the rare and unlikely event that you can't get a bug fixed any other way, you can hire a programmer or ten and get to work. For that matter, if you buy a new machine that Perl doesn't yet run on, you can port it yourself. Or if you need a feature that doesn't yet exist, well, you know what to do.

1.3.3. Are There Any Other Kinds of Support?

Sure; one of our favorites is the Perl Mongers. This is a worldwide association of Perl users' groups; see http://www.pm.org/ for more information. There's probably a group near you with an expert or someone who knows an expert. If there's no group, you can easily start one.

Of course, for the first line of support, you shouldn't neglect the documentation. Besides the manpages[26] themselves, Perl's documentation includes the voluminous FAQ (Frequently Asked Questions) and many tutorials.

[26]The term manpages is a Unix-ism meaning documentation. If you're not on a Unix system, the manpages for Perl should be available via your system's native documentation system. If you can't find them anywhere else, the manpages are available directly on CPAN.

Another authoritative source is the book Programming Perl, commonly known as "the Camel book" because of its cover animal (just as this book has come to be known as "the Llama book"). The Camel book contains the complete reference information, some tutorial stuff, and a bunch of miscellaneous information about Perl. There's also a separate pocket-sized quick reference to Perl (by Johan Vromans) that's handy to keep at hand (or in your pocket).

If you need to ask a question of someone, there are newsgroups on Usenet and any number of mailing lists.[27] At any hour of the day or night, there's a Perl expert awake in some timezone answering questions on Usenet's Perl newsgroups -- the sun never sets on the Perl empire. This means that if you ask a question, you'll often get an answer within minutes. If you didn't check the documentation and FAQ first, you'll get flamed within minutes.

[27]Many mailing lists are listed at http://lists.perl.org.

We generally recommend the newsgroup comp.lang.perl.moderated, where (as the name implies) a moderator will check over your question before posting it. If there's something wrong with your question, you'll still get flamed of course, but it's a small, private flame in email rather than a big public one in a newsgroup.[28] But for most questions, you'll get an answer back within the hour. Just try getting that level of support from your favorite software vendor for free!

[28]Of course, we're joking here. Unless you've done something amazingly boneheaded, the moderators are all kind, polite, helpful folks, who will gently point you in the direction of the information you need, with just enough flame to remind you to be more careful next time. Don't be afraid to ask.

The official Perl newsgroups on Usenet are located in the comp.lang.perl.* part of the hierarchy. As of this writing, there are five of them, but they change from time to time. You (or whoever is in charge of Perl at your site) should generally subscribe to comp.lang.perl.announce, which is a low-volume newsgroup just for important announcements about Perl, including especially any security-related announcements. Ask your local expert if you need help with Usenet.

Also, a few web communities have sprung up around Perl discussions. One very popular one, known as The Perl Monastery (http://www.perlmonks.org) has seen quite a bit of participation from many Perl book and column authors, including at least one of the authors of this book.

If you find yourself needing a support contract for Perl, there are a number of firms who are willing to charge as much as you'd like. In most cases, these other support avenues will take care of you for free.

1.3.4. What If I Find a Bug in Perl?

The first thing to do when you find a bug is to check the documentation[29] again.[30] Perl has so many special features and exceptions to rules that you may have discovered a feature, not a bug. Also, check that you don't have an older version of Perl; maybe you found something that's been fixed in a more recent version.

[29]Even Larry admits to consulting the documentation from time to time.

[30]Maybe even twice or three times. Many times, we've gone into the documentation looking to explain a particular unexpected behavior and found some new little nuance that ends up on a slide or in a column.

Once you're 99% certain that you've found a real bug, ask around. Ask someone at work, at your local Perl Mongers' meeting, or at a Perl conference. Chances are, it's still a feature, not a bug.

Once you're 100% certain that you've found a real bug, cook up a test case (if you haven't done so already). The ideal test case is a tiny self-contained program that any Perl user could run to see the same (mis-)behavior as you've found. Once you've got a test case that clearly shows the bug, use the perlbug utility (which comes with Perl) to report the bug. That will normally send email from you to the Perl developers, so don't use perlbug until you've got your test case ready.

Once you've sent off your bug report, if you've done everything right, it's not unusual to get a response within minutes. Typically, you can apply a simple patch and get right back to work. Of course, you may (at worst) get no response at all; the Perl developers are under no obligation to even read your bug reports. But all of us love Perl, so nobody likes to let a bug escape our notice.

Previous | Home | Next
1.2. What Does "Perl" Stand For? | Book Index | 1.4. How Do I Make a Perl Program?
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.4. How Do I Make a Perl Program?

It's about time you asked (even if you didn't). Perl programs are text files; you can create and edit them with your favorite text editor. (You don't need any special development environment, although there are some commercial ones available from various vendors. We've never used any of these enough to recommend them.)

You should generally use a programmers' text editor, rather than an ordinary editor. What's the difference? Well, a programmers' text editor will let you do things that programmers need, like to indent or unindent a block of code, or to find the matching closing curly brace for a given opening curly brace. On Unix systems, the two most popular programmers' editors are emacs and vi (and their variants and clones). Both of these have been ported to several non-Unix systems, and many systems today offer a graphical editor (which uses a pointing device like a mouse). In fact, there are even versions of vi and emacs that offer a graphical interface. Ask your local expert about text editors on your system.

For the simple programs you'll be writing for the exercises in this book, none of which will need to be more than about twenty or thirty lines of code, any text editor will be fine.

A few beginners try to use a word processor instead of a text editor. We recommend against this -- it's inconvenient at best and impossible at worst. But we won't try to stop you. Be sure to tell the word processor to save your file as "text only"; the word processor's own format will almost certainly be unusable.

In some cases, you may need to compose the program on one machine, then transfer it to another to be run. If you do this, be sure that the transfer uses "text" or "ASCII" mode, and not "binary" mode. This step is needed because of the different text formats on different machines. Without that, you may get inconsistent results -- some versions of Perl actually abort when they detect a mismatch in the line endings.

1.4.1. A Simple Program

According to the oldest rule in the book, any book about a computer language that has Unix-like roots has to start with showing the "Hello, world" program. So, here it is in Perl:

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

Let's imagine that you've typed that into your text editor. (Don't worry yet about what the parts mean and how it works. We'll see about those in a moment.) You can generally save that program under any name you wish. Perl doesn't require any special kind of filename or extension, and it's better to use no extension at all.[31] But some non-Unix systems may require an extension like .plx (meaning PerL eXecutable); see your system's release notes for more information.

[31]Why is it better to have no extension? Imagine that you've written a program to calculate bowling scores and you've told all of your friends that it's called bowling.plx. One day you decide to rewrite it in C. Do you still call it by the same name, implying that it's still written in Perl? Or do you tell everyone that it has a new name? (And don't call it bowling.c, please!) The answer is that it's none of their business what language it's written in, if they're merely using it. So it should have simply been called bowling in the first place.

You will also need to do something so that your system knows that it's an executable program (that is, a command). What you'll do depends upon your system; maybe you won't have to do anything more than to save the program in a certain place. (Your current directory will generally be fine.) On Unix systems, you mark a program as being executable by using the chmod command, perhaps like this:

$ chmod a+x my_program

The dollar sign (and space) at the start of the line represents the shell prompt, which will probably look different on your system. If you're used to using chmod with a number like 755 instead of a symbolic parameter like a+x, that's fine too, of course. Either way, it tells the system that this file is now a program.

Now you're ready to run it:

$ ./my_program

The dot and slash at the start of this command mean to find the program in the current working directory. That's not needed in all cases, but you should use it at the start of each command invocation until you fully understand what it's doing.[32]

[32]In short, it's preventing your shell from running another program (or shell builtin) of the same name. A common mistake among beginners is to name their first program test. Many systems already have a program (or shell builtin) with that name; that's what the beginners run instead of their program.

If everything worked, it's a miracle. More often, you'll find that your program has a bug. Edit and try again -- but you don't need to use chmod each time, since that should "stick" to the file. (Of course, if the bug is that you didn't use chmod correctly, you'll probably get a "permission denied" message from your shell.)

1.4.2. What's Inside That Program?

Like other "free-form" languages, Perl generally lets you use insignificant whitespace (like spaces, tabs, and newlines) at will to make your program easier to read. Most Perl programs use a fairly standard format, though, much like most of what we show here. We strongly encourage you to properly indent your programs, since that makes your program easier to read; a good text editor will do most of the work for you. Good comments also make a program easier to read. In Perl, comments run from a pound sign (#) to the end of the line. (There are no "block comments" in Perl.[33]) We don't use many comments in the programs in this book, because the surrounding text explains their workings, but you should use comments as needed in your own programs.

[33]But there are a number of ways to fake them. See the FAQ (accessible with perldocperlfaq on most installations).

So another way (a very strange way, it must be said) to write that same "Hello, world" program might be like this:

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

That first line is actually a very special comment. On Unix systems,[34] if the very first two characters on the first line of a text file are "#!", then what follows is the name of the program that actually executes the rest of the file. In this case, the program is stored in the file /usr/bin/perl.

[34]Most modern ones, anyway. The "sh-bang" mechanism was introduced somewhere in the mid-1980s, and that's pretty ancient, even on the extensively long Unix timeline.

This #! line is actually the least portable part of a Perl program, because you'll need to find out what goes there for each machine. Fortunately, it's almost always either /usr/bin/perl or /usr/local/bin/perl. If you find that it's not, you can cast a magic spell on your system administrator to fix things. Just say "You know, I read in a book that both /usr/bin/perl and /usr/local/bin/perl should be symbolic links to the true Perl binary," and under the influence of your spell the admin will make everything work. All of the example programs you're likely to find on the Net and elsewhere will begin with one of those two forms.

On non-Unix systems, it's traditional (and even useful) to make the first line say #!perl. If nothing else, it tells your maintenance programmer as soon as he or she gets ready to fix it that it's a Perl program.

If that #! line is wrong, you'll generally get an error from your shell. This may be something unexpected, like "file not found." It's not your program that's not found, though; it's /usr/bin/perl that wasn't where it should have been. We'd make the message clearer, but it's not coming from Perl; it's the shell that's complaining. (By the way, you should be careful to spell it usr and not user -- the folks who invented Unix were lazy typists, so they omitted a lot of letters.)

Another problem you could have is if your system doesn't support the #! line at all. In that case, your shell (or whatever your system uses) will probably try to run your program all by itself, with results that may disappoint or astonish you. If you can't figure out what some strange error message is telling you, search for it in the perldiag manpage.

The "main" program consists of all of the ordinary Perl statements (not including anything in subroutines, which we'll see later). There's no "main" routine, as there is in languages like C or Java. In fact, many programs don't even have routines (in the form of subroutines).

There's also no required variable declaration section, as there is in some other languages. If you've always had to declare your variables, you may be startled or unsettled by this at first. But it allows us to write "quick-and-dirty" Perl programs. If your program is only two lines long, you don't want to have to use one of those lines just to declare your variables. If you really want to declare your variables, that's a good thing; we'll see how to do that in Chapter 4, "Subroutines".

Most statements are an expression followed by a semicolon. Here's the one we've seen a few times so far:

print "Hello, world!\n";

As you may have guessed by now, this line prints the message Hello, world! At the end of that message is the shortcut \n, which is probably familiar to you if you've used another language like C, C++, or Java; it means a newline character. When that's printed after the message, the print position drops down to the start of the next line, allowing the following shell prompt to appear on a line of its own, rather than being attached to the message. Every line of output should end with a newline character. We'll see more about the newline shortcut and other so-called backslash escapes in the next chapter.

1.4.3. But How Do I Compile Perl?

You may be surprised to learn that all you have to do to compile Perl is to run it. When you run your program, Perl's internal compiler first runs through your entire source, turning it into internal bytecodes (an internal data structure representing the program); then Perl's bytecode engine actually runs them.[35]

[35]As usual, there's more to the story than what we say here. But this should be close enough for all but the technically advanced folks, and they already know about this.

So, if there's a syntax error on line 200, you'll get that error message before you start running line two.[36] If you have a loop that runs 5000 times, it's compiled just once; the actual loop can then run at top speed. And there's no runtime penalty for using as many comments and as much whitespace as you need to make your program easy to understand. You can even use calculations involving only constants, and the result is a constant computed once as the program is beginning -- not each time through a loop.

[36]Unless line two happens to be a compile-time operation, like a BEGIN block or a use invocation.

To be sure, this compilation does take time -- it's inefficient to have a voluminous Perl program that does one small quick task (out of many potential tasks, say) and then exits, because the runtime for the program will be dwarfed by the compile time. But the compiler is very fast; normally the compilation will be a tiny percentage of the runtime.

An exception might be if you were writing a program to be run over the Web, where it may be called hundreds or thousands of times every minute. (This is a very high usage rate. If it were called a few hundreds or thousands of times per day, like most programs on the Web, we probably wouldn't worry too much about it.) Many of these programs have very short runtimes, so the issue of recompilation may become significant. If this is an issue for you, you'll want to find a way to keep your program resident in memory between invocations (whether it's written in Perl or not); see the documentation for your web server and ask your local expert for help with this.[37]

[37]Point your local expert to http://perl.apache.orgfor one possible solution.

What if you could save the compiled bytecodes to avoid the overhead of compilation? Or, even better, what if you could turn the bytecodes into another language, like C, and then compile that? Well, both of these things are possible (although beyond the scope of this book), although they won't make most programs any easier to use, maintain, debug, or install, and they may (for somewhat technical reasons) make your program even slower.[38] We don't know anyone who has ever needed to compile a Perl program (except for experimental purposes), and we doubt you ever will ever meet one, either.

[38]On many (perhaps most) systems where you might want to compile a Perl program, the perl binary (the program that executes your Perl programs) is always in use by some process, so it's always resident in memory. A "compiled Perl" program will take time to load into memory. If it's a small program, it would probably compile at least as fast as it takes to load a compiled executable. If it's a large one, compilation is probably an insignificant part of its runtime anyway.

Previous | Home | Next
1.3. How Can I Get Perl? | Book Index | 1.5. A Whirlwind Tour of Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.5. A Whirlwind Tour of Perl

So, you want to see a real Perl program with some meat? (If you don't, just play along for now.) Here you are:

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

Now, the first time you see Perl code like this, it can seem pretty strange. (In fact, every time you see Perl code like this, it can seem pretty strange.) But let's take it line by line, and see what this example does. (These explanations are very brief; this is a whirlwind tour, after all. We'll see all of this program's features in more detail during the rest of this book. You're not really supposed to understand the whole thing until later.)

The first line is the #! line, as we saw before. You might need to change that line for your system, as we discussed earlier.

The second line runs an external command, named within backquotes ("` `"). (The backquote key is often found next to the number 1 on full-sized American keyboards. Be sure not to confuse the backquote with the single quote, "'".) The command we're using is perldoc -u -f atan2; try typing that at your command line to see what its output looks like. The perldoc command is used on most systems to read and display the documentation for Perl and its associated extensions and utilities, so it should normally be available.[39] This command tells you something about the trigonometric function atan2; we're using it here just as an example of an external command whose output we wish to process.

[39]If perldoc is not available, that probably means that your system doesn't have a command-line interface, and your Perl can't run commands (like perldoc) in backticks or via the piped-open, which we'll see in Chapter 14, "Process Management". In that case, you should simply skip the exercises that use perldoc.

The output of that command in the backticks is saved in an array variable called @lines. The next line of code starts a loop that will process each one of those lines. Inside the loop, the statements are indented. Although Perl doesn't require this, good programmers do.

The first line inside the loop body is the scariest one; it says s/\w<([^>]+)>/\U$1/g;. Without going into too much detail, we'll just say that this can change any line that has a special marker made with angle brackets (< >), and there should be at least one of those in the output of the perldoc command.

The next line, in a surprise move, prints out each (possibly modified) line. The resulting output should be similar to what perldoc -u -f atan2 would do on its own, but there will be a change where any of those markers appears.

Thus, in the span of a few lines, we've run another program, saved its output in memory, updated the memory items, and printed them out. This kind of program is a fairly common use of Perl, where one type of data is converted to another.

Previous | Home | Next
1.4. How Do I Make a Perl Program? | Book Index | 1.6. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.6. Exercises

Normally, each chapter will end with some exercises, with the answers in Appendix A, "Exercise Answers". But in this chapter, the answers were already provided.

If you can't get these exercises to work on your machine, double-check your work and then consult your local expert. Remember that you may need to change each program a little, as described in the text.

  1. [7] Type in the "Hello, world" program and get it to work! (You may name it anything you wish, but a good name might be ex1-1, for simplicity, since it's exercise 1 in Chapter 1, "Introduction".)

  2. [5] Type the command perldoc -u -f atan2 at a command prompt and note its output. If you can't get that to work, then find out from a local administrator or the documentation for your version of Perl about how to invoke perldoc or its equivalent. (You'll need this for the next exercise anyway.)

  3. [6] Type in the second example program (from the previous section) and see what it prints. (Hint: Be careful to type those punctuation marks exactly as shown!) Do you see how it changed the output of the command?

Previous | Home | Next
1.5. A Whirlwind Tour of Perl | Book Index | 2. Scalar Data
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 2. Scalar Data

Contents:

What Is Scalar Data?
Numbers
Strings
Perl's Built-in Warnings
Scalar Variables
Output with print
The if Control Structure
Getting User Input
The chomp Operator
The while Control Structure
The undef Value
The defined Function
Exercises

2.1. What Is Scalar Data?

In English, as in many other spoken languages, we're used to distinguishing between singular and plural. As a computer language designed by a human linguist, Perl is similar. As a general rule, when Perl has just one of something, that's a scalar.[40]

[40]This has little to do with the similar term from mathematics or physics in that a scalar is a single thing; there are no "vectors" in Perl.

A scalar is the simplest kind of data that Perl manipulates. Most scalars are either a number (like 255 or 3.25e20) or a string of characters (like hello [41] or the Gettysburg Address). Although you may think of numbers and strings as very different things, Perl uses them nearly interchangeably.

[41]If you have been using other programming languages, you may think of hello as a collection of five characters, rather than as a single thing. But in Perl, a string is a single scalar value. Of course, we can access the individual characters when we need to; we'll see how to do that in later chapters.

A scalar value can be acted upon with operators (like addition or concatenate), generally yielding a scalar result. A scalar value can be stored into a scalar variable. Scalars can be read from files and devices, and can be written out as well.

Previous | Home | Next
1.6. Exercises | Book Index | 2.2. Numbers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.2. Numbers

Although a scalar is most often either a number or a string, it's useful to look at numbers and strings separately for the moment. We'll cover numbers first, and then move on to strings.

2.2.1. All Numbers Are the Same Format Internally

As you'll see in the next few paragraphs, you can specify both integers (whole numbers, like 255 or 2001) and floating-point numbers (real numbers with decimal points, like 3.14159, or 1.35 x 1025). But internally, Perl computes with double-precision floating-point values.[42] This means that there are no integer values internal to Perl -- an integer constant in the program is treated as the equivalent floating-point value.[43] You probably won't notice the conversion (or care much), but you should stop looking for distinct integer operations (as opposed to floating-point operations), because there aren't any.[44]

[42]A double-precision floating-point value is whatever the C compiler that compiled Perl used for a double declaration. While the size may vary from machine to machine, most modern systems use IEEE floating-point formats, which suggest 15 digits of precision and a range of at least 1e-100 to 1e100.

[43]Well, Perl will sometimes use internal integers in ways that are not visible to the programmer. That is, the only difference you should generally be able to see is that your program runs faster. And who could complain about that?

[44]Okay, there is the integer pragma. But using that is beyond the scope of this book. And yes, some operations force an integer to be computed from a given floating-point number, as we'll see later. But that's not what we're talking about here.

2.2.2. Floating-Point Literals

A literal is the way a value is represented in the source code of the Perl program. A literal is not the result of a calculation or an I/O operation; it's data written directly into the source code.

Perl's floating-point literals should look familiar to you. Numbers with and without decimal points are allowed (including an optional plus or minus prefix), as well as tacking on a power-of-10 indicator (exponential notation) with E notation. For example:

1.25
255.000
255.0
7.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

2.2.3. Integer Literals

Integer literals are also straightforward, as in:

0
2001
-40
255
61298040283768

That last one is a little hard to read. Perl allows underscores for clarity within integer literals, so we can also write that number like this:

61_298_040_283_768

It's the same value; it merely looks different to us human beings. You might have thought that commas should be used for this purpose, but commas are already used for a more-important purpose in Perl (as we'll see in the next chapter).

2.2.4. Nondecimal Integer Literals

Like many other programming languages, Perl allows you to specify numbers in other than base 10 (decimal). Octal (base 8) literals start with a leading 0, hexadecimal (base 16) literals start with a leading 0x, and binary (base 2) literals start with a leading 0b.[45] The hex digits A through F (or a through f) represent the conventional digit values of ten through fifteen. For example:

[45]The "leading zero" indicator works only for literals -- not for automatic string-to-number conversion, which we'll see later in this chapter. You can convert a data string that looks like an octal or hex value into a number with oct( )or hex( ). Although there's no "bin" function for converting binary values, oct( )can do that for strings beginning with 0b.

0377       # 377 octal, same as 255 decimal
0xff       # FF hex, also 255 decimal
0b11111111 # also 255 decimal (available in version 5.6 and later)

Although these values look different to us humans, they're all three the same number to Perl. It makes no difference to Perl whether you write 0xFF or 255.000, so choose the representation that makes the most sense to you and your maintenance programmer (by which we mean the poor chap who gets stuck trying to figure out what you meant when you wrote your code. Most often, this poor chap is you, and you can't recall whay you did what you did three months ago).

When a non-decimal literal is more than about four characters long, it may be hard to read. For this reason, starting in version 5.6, Perl allows underscores for clarity within these literals:

0x1377_0b77
0x50_65_72_7C

2.2.5. Numeric Operators

Perl provides the typical ordinary addition, subtraction, multiplication, and division operators, and so on. For example:

2 + 3      # 2 plus 3, or 5
5.1 - 2.4  # 5.1 minus 2.4, or 2.7
3 * 12     # 3 times 12 = 36
14 / 2     # 14 divided by 2, or 7
10.2 / 0.3 # 10.2 divided by 0.3, or 34
10 / 3     # always floating-point divide, so 3.3333333...

Perl also supports a modulus operator (%). The value of the expression 10 % 3 is the remainder when ten is divided by three, which is one. Both values are first reduced to their integer values, so 10.5 % 3.2 is computed as 10 % 3.[46]

[46]The result of a modulus operator when a negative number (or two) is involved can vary between Perl implementations. Beware.

Additionally, Perl provides the FORTRAN-like exponentiation operator, which many have yearned for in Pascal and C. The operator is represented by the double asterisk, such as 2**3, which is two to the third power, or eight.[47]

[47]You can't normally raise a negative number to a noninteger exponent. Math geeks know that the result would be a complex number. To make that possible, you'll need the help of the Math::Complex module.

In addition, there are other numeric operators, which we'll introduce as we need them.

Previous | Home | Next
2. Scalar Data | Book Index | 2.3. Strings
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.3. Strings

Strings are sequences of characters (like hello). Strings may contain any combination of any characters.[48]

[48]Unlike C or C++, there's nothing special about the NUL character in Perl, because Perl uses length counting, not a null byte, to determine the end of the string.

The shortest possible string has no characters. The longest string fills all of your available memory (although you wouldn't be able to do much with that). This is in accordance with the principle of "no built-in limits" that Perl follows at every opportunity. Typical strings are printable sequences of letters and digits and punctuation in the ASCII 32 to ASCII 126 range. However, the ability to have any character in a string means you can create, scan, and manipulate raw binary data as strings -- something with which many other utilities would have great difficulty. For example, you could update a graphical image or compiled program by reading it into a Perl string, making the change, and writing the result back out.

Like numbers, strings have a literal representation, which is the way you represent the string in a Perl program. Literal strings come in two different flavors: single-quoted string literals and double-quoted string literals.

2.3.1. Single-Quoted String Literals

A single-quoted string literal is a sequence of characters enclosed in single quotes. The single quotes are not part of the string itself -- they're just there to let Perl identify the beginning and the ending of the string. Any character other than a single quote or a backslash between the quote marks (including newline characters, if the string continues onto successive lines) stands for itself inside a string. To get a backslash, put two backslashes in a row, and to get a single quote, put a backslash followed by a single quote. In other words:

'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
'hello
there'    # hello, newline, there (11 characters total)
'\'\\'    # single quote followed by backslash

Note that the \n within a single-quoted string is not interpreted as a newline, but as the two characters backslash and n. Only when the backslash is followed by another backslash or a single quote does it have special meaning.

2.3.2. Double-Quoted String Literals

A double-quoted string literal is similar to the strings you may have seen in other languages. Once again, it's a sequence of characters, although this time enclosed in double quotes. But now the backslash takes on its full power to specify certain control characters, or even any character at all through octal and hex representations. Here are some double-quoted strings:

"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

Note that the double-quoted literal string "barney" means the same six-character string to Perl as does the single-quoted literal string 'barney'. It's like what we saw with numeric literals, where we saw that 0377 was another way to write 255.0. Perl lets you write the literal in the way that makes more sense to you. Of course, if you wish to use a backslash escape (like \n to mean a newline character), you'll need to use the double quotes.

The backslash can precede many different characters to mean different things (generally called a backslash escape). The nearly complete[49] list of double-quoted string escapes is given in Table 2-1.

[49]Recent versions of Perl have introduced "Unicode" escapes, which we aren't going to be talking about here.

Table 2-1. Double-quoted string backslash escapes

Construct

Meaning

\n

Newline

\r

Return

\t

Tab

\f

Formfeed

\b

Backspace

\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, Ctrl-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 non-word characters by adding a backslash until \E

\E

Terminate \L, \U, or \Q

Another feature of double-quoted strings is that they are variable interpolated, meaning that some variable names within the string are replaced with their current values when the strings are used. We haven't formally been introduced to what a variable looks like yet, so we'll get back to this later in this chapter.

2.3.3. String Operators

String values can be concatenated with the . operator. (Yes, that's a single period.) This does not alter either string, any more than 2+3 alters either 2 or 3. The resulting (longer) string is then available for further computation or to be stored into a variable. For example:

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

Note that the concatenation must be explicitly requested with the . operator, unlike in some other languages where you merely have to stick the two values next to each other.

A special string operator is the string repetition operator, consisting of the single lowercase letter x. This operator takes its left operand (a string) and makes as many concatenated copies of that string as indicated by its right operand (a number). For example:

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

That last example is worth spelling out slowly. The string repetition operator wants a string for a left operand, so the number 5 is converted to the string "5" (using rules described in detail later), giving a one-character string. This new string is then copied four times, yielding the four-character string 5555. Note that if we had reversed the order of the operands, as 4 x 5, we would have made five copies of the string 4, yielding 44444. This shows that string repetition is not commutative.

The copy count (the right operand) is first truncated to an integer value (4.8 becomes 4) before being used. A copy count of less than one results in an empty (zero-length) string.

2.3.4. Automatic Conversion Between Numbers and Strings

For the most part, Perl automatically converts between numbers to strings as needed. How does it know whether a number or a string is needed? It all depends upon the operator being used on the scalar value. If an operator expects a number (like + does), Perl will see the value as a number. If an operator expects a string (like . does), Perl will see the value as a string. So you don't need to worry about the difference between numbers and strings; just use the proper operators, and Perl will make it all work.

When a string value is used where an operator needs a number (say, for multiplication), Perl automatically converts the string to its equivalent numeric value, as if it had been entered as a decimal floating-point value.[50] So "12" * "3" gives the value 36. Trailing nonnumber stuff and leading whitespace are discarded, so "12fred34" * " 3" will also give 36 without any complaints.[51] At the extreme end of this, something that isn't a number at all converts to zero. This would happen if you used the string "fred" as a number.

[50]The trick of using a leading zero to mean a nondecimal value works for literals, but never for automatic conversion. Use hex( )or oct( )to convert those kinds of strings.

[51]Unless you request warnings, which we'll discuss in a moment.

Likewise, if a numeric value is given when a string value is needed (say, for string concatenation), the numeric value is expanded into whatever string would have been printed for that number. For example, if you want to concatenate the string Z followed by the result of 5 multiplied by 7,[52] you can say this simply as:

[52]We'll see about precedence and parentheses shortly.

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

In other words, you don't really have to worry about whether you have a number or a string (most of the time). Perl performs all the conversions for you.[53] And if you're worried about efficiency, don't be. Perl generally remembers the result of a conversion so that it's done only once.

[53]It's usually not an issue, but these conversions can cause small round-off errors. That is, if you start with a number, convert it to a string, then convert that string back to a number, the result may not be the same number as you started with. It's not just Perl that does this; it's a consequence of the conversion process, so it happens to any powerful programming language.

Previous | Home | Next
2.2. Numbers | Book Index | 2.4. Perl's Built-in Warnings
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.4. Perl's Built-in Warnings

Perl can be told to warn you when it sees something suspicious going on in your program. To run your program with warnings turned on, use the -w option on the command line:

$ perl -w my_program

Or, if you always want warnings, you may request them on the #! line:

#!/usr/bin/perl -w

That works even on non-Unix systems, where it's traditional to write something like this, since the path to Perl doesn't generally matter:

#!perl -w

Now, Perl will warn you if you use '12fred34' as if it were a number:

Argument "12fred34" isn't numeric

Of course, warnings are generally meant for programmers, not for end-users. If the warning won't be seen by a programmer, it probably won't do any good. And warnings won't change the behavior of your program, except that now it will emit gripes once in a while. If you get a warning message you don't understand, look for its explanation in the perldiag manpage.

Warnings change from one version of Perl to the next. This may mean that your well-tuned program runs silently when warnings are on today, but not when it's used with a newer (or older) version of Perl. To help with this situation, version 5.6 of Perl introduces lexical warnings. These are warnings that may be turned on or off in different sections of code, providing more detailed control than the single -w switch could. See the perllexwarn manpage for more information on these warnings.

As we run across situations in which Perl will usually be able to warn you about a mistake in your code, we'll point them out. But you shouldn't count on the text or behavior of any warning staying exactly the same in future Perl releases.

Previous | Home | Next
2.3. Strings | Book Index | 2.5. Scalar Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.5. Scalar Variables

A variable is a name for a container that holds one or more values.[54] The name of the variable stays the same throughout the program, but the value or values contained in that variable typically change over and over again throughout the execution of the program.

[54]As we'll see, a scalar variable can hold only one value. But other types of variables, such as arrays and hashes, may hold many values.

A scalar variable holds a single scalar value, as you'd expect. Scalar variable names begin with a dollar sign followed by what we'll call a Perl identifier: a letter or underscore, and then possibly more letters, or digits, or underscores. Another way to think of it is that it's made up of alphanumerics and underscores, but can't start with a digit. Uppercase and lowercase letters are distinct: the variable $Fred is a different variable from $fred. And all of the letters, digits, and underscores are significant, so:

$a_very_long_variable_that_ends_in_1

is different from:

$a_very_long_variable_that_ends_in_2

Scalar variables in Perl are always referenced with the leading $. In the shell, you use $ to get the value, but leave the $ off to assign a new value. In awk or C, you leave the $ off entirely. If you bounce back and forth a lot, you'll find yourself typing the wrong things occasionally. This is expected. (Most Perl programmers would recommend that you stop writing shell, awk, and C programs, but that may not work for you.)

2.5.1. Choosing Good Variable Names

You should generally select variable names that mean something regarding the purpose of the variable. For example, $r is probably not very descriptive but $line_length is. A variable used for only two or three lines close together may be called something simple, like $n, but a variable used throughout a program should probably have a more descriptive name.

Similarly, properly placed underscores can make a name easier to read and understand, especially if your maintenance programmer has a different spoken language background than you have. For example, $super_bowl is a better name than $superbowl, since that last one might look like $superb_owl. Does $stopid mean $sto_pid (storing a process-ID of some kind?) or $s_to_pid (converting something to a process-ID?) or $stop_id (the ID for some kind of "stop" object?) or is it just a stopid mispelling?

Most variable names in our Perl programs are all lowercase, like most of the ones we'll see in this book. In a few special cases, capitalization is used. Using all-caps (like $ARGV) generally indicates that there's something special about that variable. (But you can get into an all-out brawl if you choose sides on the $underscores_are_cool versus the $giveMeInitialCaps argument. So be careful.)

Of course, choosing good or poor names makes no difference to Perl. You could name your program's three most-important variables $OOO000OOO, $OO00OO00, and $O0O0O0O0O and Perl wouldn't be bothered -- but in that case, please, don't ask us to maintain your code.

2.5.2. Scalar Assignment

The most common operation on a scalar variable is assignment, which is the way to give a value to a variable. The Perl assignment operator is the equals sign (much like other languages), which takes a variable name on the left side, and gives it the value of the expression on the right. For example:

$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)

Notice that last line uses the $barney variable twice: once to get its value (on the right side of the equals sign), and once to define where to put the computed expression (on the left side of the equals sign). This is legal, safe, and in fact, rather common. In fact, it's so common that we can write it using a convenient shorthand, as we'll see in the next section.

2.5.3. Binary Assignment Operators

Expressions like $fred = $fred + 5 (where the same variable appears on both sides of an assignment) occur frequently enough that Perl (like C and Java) has a shorthand for the operation of altering a variable -- the binary assignment operator. Nearly all binary operators that compute a value have a corresponding binary assignment form with an appended equals sign. For example, the following two lines are equivalent:

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

These are also equivalent:

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

In each case, the operator causes the existing value of the variable to be altered in some way, rather than simply overwriting the value with the result of some new expression.

Another common assignment operator is the string concatenate operator ( . ); this gives us an append operator ( .= ):

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

Nearly all binary operators are valid this way. For example, a raise to the power of operator is written as **=. So, $fred **= 3 means "raise the number in $fred to the third power, placing the result back in $fred".

Previous | Home | Next
2.4. Perl's Built-in Warnings | Book Index | 2.6. Output with print
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.6. Output with print

It's generally a good idea to have your program produce some output; otherwise, someone may think it didn't do anything. The print( ) operator makes this possible. It takes a scalar argument and puts it out without any embellishment onto standard output. Unless you've done something odd, this will be your terminal display. For example:

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

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

You can actually give print a series of values, separated by commas.

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

This is actually a list, but we haven't talked about lists yet, so we'll put that off for later.

2.6.1. Interpolation of Scalar Variables into Strings

When a string literal is double-quoted, it is subject to variable interpolation[55] (besides being checked for backslash escapes). This means that any scalar variable[56] name in the string is replaced with its current value. For example:

[55]This has nothing to do with mathematical or statistical interpolation.

[56]And some other variable types, but we won't see those until later.

$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

As you see on the last line above, you can get the same results without the double quotes. But the double-quoted string is often the more convenient way to write it.

If the scalar variable has never been given a value,[57] the empty string is used instead:

[57]This is actually the special undefined value, undef, which we'll see a little later in this chapter. If warnings are turned on, Perl will complain about interpolating the undefined value.

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

Don't bother with interpolating if you have just the one lone variable:

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

There's nothing really wrong with putting quote marks around a lone variable, but the other programmers will laugh at you behind your back.[58]

[58]Well, it may force a value to be interpreted as a string, rather than a number. In a few rare cases that may be needed, but nearly always it's just a waste of typing.

Variable interpolation is also known as double-quote interpolation, because it happens when double-quote marks (but not single quotes) are used. It happens for some other strings in Perl, which we'll mention as we get to them.

To put a real dollar sign into a double-quoted string, precede the dollar sign with a backslash, which turns off the dollar sign's special significance:

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

The variable name will be the longest possible variable name that makes sense at that part of the string. This can be a problem if you want to follow the replaced value immediately with some constant text that begins with a letter, digit, or underscore.[59] As Perl scans for variable names, it would consider those characters to be additional name characters, which is not what you want. Perl provides a delimiter for the variable name in a manner similar to the shell. Simply enclose the name of the variable in a pair of curly braces. Or, you can end that part of the string and start another part of the string with a concatenation operator:

[59]There are some other characters that may be a problem as well. If you need a left square bracket or a left curly brace just after a scalar variable's name, precede it with a backslash. You may also do that if the variable's name is followed by an apostrophe or a pair of colons, or you could use the curly-brace method described in the main text

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

2.6.2. Operator Precedence and Associativity

Operator precedence determines which operations in a complex group of operations happen first. For example, in the expression 2+3*4, do we perform the addition first or the multiplication first? If we did the addition first, we'd get 5*4, or 20. But if we did the multiplication first (as we were taught in math class), we'd get 2+12, or 14. Fortunately, Perl chooses the common mathematical definition, performing the multiplication first. Because of this, we say multiplication has a higher precedence than addition.

You can override the default precedence order by using parentheses. Anything in parentheses is completely computed before the operator outside of the parentheses is applied (just like you learned in math class). So if I really want the addition before the multiplication, I can say (2+3)*4, yielding 20. Also, if I wanted to demonstrate that multiplication is performed before addition, I could add a decorative but unnecessary set of parentheses, as in 2+(3*4).

While precedence is simple for addition and multiplication, we start running into problems when faced with, say, string concatenation compared with exponentiation. The proper way to resolve this is to consult the official, accept-no-substitutes Perl operator precedence chart, shown in Table 2-1.[60] (Note that some of the operators have not yet been described, and in fact, may not even appear anywhere in this book, but don't let that scare you from reading about them in the perlop manpage.)

[60]C programmers: Rejoice! The operators that are available in both Perl and C have the same precedence and associativity in both.

Table 2-2. Associativity and precedence of operators (highest to lowest)

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 | &
left | | ^
left | &&
left | ||
 | .. ...
right | ?: (ternary)
right | = += -= .= (and similar assignment operators)
left | , =>
 | list operators (rightward)
right | not
left | and
left | or xor

In the chart, any given operator has higher precedence than all of the operators listed below it, and lower precedence than all of the operators listed above it. Operators at the same precedence level resolve according to rules of associativity instead.

Just like precedence, associativity resolves the order of operations when two operators of the same precedence compete for three operands:

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

In the first case, the ** operator has right associativity, so the parentheses are implied on the right. Comparatively, the * and / operators have left associativity, yielding a set of implied parentheses on the left.

So should you just memorize the precedence chart? No! Nobody actually does that. Instead, just use parentheses when you don't remember the order of operations, or when you're too busy to look in the chart. After all, if you can't remember it without the parentheses, your maintenance programmer is going to have the same trouble. So be nice to your maintenance programmer.

2.6.3. Comparison Operators

For comparing numbers, Perl has the logical comparison operators that remind you of algebra: < <= == >= > !=. Each of these returns a true or false value. We'll find out more about those return values in the next section. Some of these may be different than you'd use in other languages. For example, == is used for equality, not a single = sign, because that's used for another purpose in Perl. And != is used for inequality testing, because <> is used for another purpose in Perl. And you'll need >= and not => for "greater than or equal to", because the latter is used for another purpose in Perl. In fact, nearly every sequence of punctuation is used for something in Perl.

For comparing strings, Perl has an equivalent set of string comparison operators which look like funny little words: lt le eq ge gt ne. These compare two strings character by character to see whether they're the same, or whether one comes first in standard string sorting order. (In ASCII, the capital letters come before the lowercase letters, so beware.)

The comparison operators (for both numbers and strings) are given in Table 2-3.

Table 2-3. Numeric and string comparison operators

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

Here are some example expressions using these comparison operators:

35 != 30 + 5         # false
35 == 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
Previous | Home | Next
2.5. Scalar Variables | Book Index | 2.7. The if Control Structure
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.7. The if Control Structure

Once you can compare two values, you'll probably want your program to make decisions based upon that comparison. Like all similar languages, Perl has an if control structure:

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

If you need an alternative choice, the else keyword provides that as well:

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";
}

Unlike in C, those block curly braces are required around the conditional code. It's a good idea to indent the contents of the blocks of code as we show here; that makes it easier to see what's going on. If you're using a programmers' text editor (as discussed in Chapter 1, "Introduction"), it'll do most of the work for you.

2.7.1. Boolean Values

You may actually use any scalar value as the conditional of the if control structure. That's handy if you want to store a true or false value into a variable, like this:

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

But how does Perl decide whether a given value is true or false? Perl doesn't have a separate Boolean data type, like some languages have. Instead, it uses a few simple rules:

  1. The special value undef is false. (We'll see this a little later in this section.)

  2. Zero is false; all other numbers are true.

  3. The empty string ('') is false; all other strings are normally true.

  4. The one exception: since numbers and strings are equivalent, the string form of zero, '0', has the same value as its numeric form: false.

So, if your scalar value is undef, 0, '', or '0', it's false. All other scalars are true -- including all of the types of scalars that we haven't told you about yet.

If you need to get the opposite of any Boolean value, use the unary not operator, !. If what follows it is a true value, it returns false; if what follows is false, it returns true:

if (! $is_bigger) {
  # Do something when $is_bigger is not true
}
Previous | Home | Next
2.6. Output with print | Book Index | 2.8. Getting User Input
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.8. Getting User Input

At this point, you're probably wondering how to get a value from the keyboard into a Perl program. Here's the simplest way: use the line-input operator, <STDIN> .[61] Each time you use <STDIN> in a place where a scalar value is expected, Perl reads the next complete text line from standard input (up to the first newline), and uses that string as the value of <STDIN>. Standard input can mean many things, but unless you do something uncommon, it means the keyboard of the user who invoked your program (probably you). If there's nothing waiting to be read (typically the case, unless you type ahead a complete line), the Perl program will stop and wait for you to enter some characters followed by a newline (return).[62]

[61]This is actually a line-input operator working on the filehandle STDIN, but we can't tell you about that until we get to filehandles (in Chapter 11, "Filehandles and File Tests").

[62]To be honest, it's normally your system that waits for the input; Perl waits for your system. Although the details depend upon your system and its configuration, you can generally correct your mistyping with a backspace key before you press return -- your system handles that, not Perl itself. If you need more control over the input, get the Term::ReadLine module from CPAN.

The string value of <STDIN> typically has a newline character on the end of it.[63] So you could do something like this:

[63]The exception is if the standard input stream somehow runs out in the middle of a line. But that's not a proper text file, of course!

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

But in practice, you don't often want to keep the newline, so you need the chomp operator.

Previous | Home | Next
2.7. The if Control Structure | Book Index | 2.9. The chomp Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.9. The chomp Operator

The first time you read about the chomp operator, it seems terribly overspecialized. It works on a variable. The variable has to hold a string. And if the string ends in a newline character, chomp can get rid of the newline. That's (nearly) all it does. For example:

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

But it turns out to be so useful, you'll put it into nearly every program you write. As you see, it's the best way to remove a trailing newline from a string in a variable. In fact, there's an easier way to use chomp, because of a simple rule: any time that you need a variable in Perl, you can use an assignment instead. First, Perl does the assignment. Then it uses the variable in whatever way you requested. So the most common use of chomp looks like this:

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

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

At first glance, the combined chomp may not seem to be the easy way, especially if it seems more complex! If you think of it as two operations -- read a line, then chomp it -- then it's more natural to write it as two statements. But if you think of it as one operation -- read just the text, not the newline -- it's more natural to write the one statement. And since most other Perl programmers are going to write it that way, you may as well get used to it now.

chomp is actually a function. As a function, it has a return value, which is the number of characters removed. This number is hardly ever useful:

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

As you see, you may write chomp with or without the parentheses. This is another general rule in Perl: except in cases where it changes the meaning to remove them, parentheses are always optional.

If a line ends with two or more newlines,[64] chomp removes only one. If there's no newline, it does nothing, and returns zero.

[64]This situation can't arise if we're reading a line at a time, but it certainly can when we have set the input separator ($/) to something other than newline, or use the read function, or perhaps have glued some strings together ourselves.

If you work with older Perl programs, you may run across the chop operator. It's similar, but removes any trailing character, not just a trailing newline. Since that could accidentally turn pebbles into pebble, it's usually not what you want.

Previous | Home | Next
2.8. Getting User Input | Book Index | 2.10. The while Control Structure
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.10. The while Control Structure

Like most algorithmic programming languages, Perl has a number of looping structures.[65] The while loop repeats a block of code as long as a condition is true:

[65]Every programmer eventually creates an infinite loop by accident. If your program keeps running and running, though, you can generally stop it in the same way you'd stop any other program on your system. Often, typing Control-C will stop a runaway program; check with your system's documentation to be sure.

$count = 0;
while ($count < 10) {
  $count += 1;
  print "count is now $count\n"; # Gives values from 1 to 10
}

As always in Perl, the truth value here works like the truth value in the if test. Also like the if control structure, the block curly braces are required. The conditional expression is evaluated before the first iteration, so the loop may be skipped completely, if the condition is initially false.

Previous | Home | Next
2.9. The chomp Operator | Book Index | 2.11. The undef Value
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.11. The undef Value

What happens if you use a scalar variable before you give it a value? Nothing serious, and definitely nothing fatal. Variables have the special undef value before they are first assigned, which is just Perl's way of saying "nothing here to look at -- move along, move along." If you try to use this "nothing" as a "numeric something," it acts like 0. If you try to use it as a "string something," it acts like the empty string. But undef is neither a number nor a string; it's an entirely separate kind of scalar value.

Because undef automatically acts like zero when used as a number, it's easy to make an numeric accumulator that starts out empty:

# 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";

This works properly when $sum was undef before the loop started. The first time through the loop, $n is one, so the first line inside the loop adds one to $sum. That's like adding one to a variable that already holds zero (because we're using undef as if it were a number). So now it has the value 1. After that, since it's been initialized, adding works in the traditional way.

Similarly, you could have a string accumulator that starts out empty:

$string .= "more text\n";

If $string is undef, this will act as if it already held the empty string, putting "more text\n" into that variable. But if it already holds a string, the new text is simply appended.

Perl programmers frequently use a new variable in this way, letting it act as either zero or the empty string as needed.

Many operators return undef when the arguments are out of range or don't make sense. If you don't do anything special, you'll get a zero or a null string without major consequences. In practice, this is hardly a problem. In fact, most programmers will rely upon this behavior. But you should know that when warnings are turned on, Perl will typically warn about unusual uses of the undefined value, since that may indicate a bug. For example, simply copying undef from one variable into another isn't a problem, but trying to print it would generally cause a warning.

Previous | Home | Next
2.10. The while Control Structure | Book Index | 2.12. The defined Function
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.12. The defined Function

One operator that can return undef is the line-input operator, <STDIN>. Normally, it will return a line of text. But if there is no more input, such as at end-of-file, it returns undef to signal this.[66] To tell whether a value is undef and not the empty string, use the defined function, which returns false for undef, and true for everything else:

[66]Normally, there's no "end-of-file" when the input comes from the keyboard, but input may have been redirected to come from a file. Or the user may have pressed the key that the system recognizes to indicate end-of-file.

$madonna = <STDIN>;
if ( defined($madonna) ) {
  print "The input was $madonna";
} else {
  print "No input available!\n";
}

If you'd like to make your own undef values, you can use the obscurely named undef operator:

$madonna = undef; # As if it had never been touched
Previous | Home | Next
2.11. The undef Value | Book Index | 2.13. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.13. Exercises

See Section A.1, "Answers to Chapter 2 Exercises " for answers to the following exercises:

  1. [5] Write a program that computes the circumference of a circle with a radius of 12.5. Circumference is 2 [image] times the radius (approximately 2 times 3.141592654). The answer you get should be about 78.5.

  2. [4] Modify the program from the previous exercise to prompt for and accept a radius from the person running the program. So, if the user enters 12.5 for the radius, she should get the same number as in the previous exercise.

  3. [4] Modify the program from the previous exercise so that, if the user enters a number less than zero, the reported circumference will be zero, rather than negative.

  4. [8] Write a program that prompts for and reads two numbers (on separate lines of input) and prints out the product of the two numbers multiplied together.

  5. [8] Write a program that prompts for and reads a string and a number (on separate lines of input) and prints out the string the number of times indicated by the number on separate lines. (Hint: Use the "x" operator.) If the user enters "fred" and "3," the output should be three lines, each saying "fred". If the user enters "fred" and "299792," there may be a lot of output.

Previous | Home | Next
2.12. The defined Function | Book Index | 3. Lists and Arrays
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 3. Lists and Arrays

Contents:

Accessing Elements of an Array
Special Array Indices
List Literals
List Assignment
Interpolating Arrays into Strings
The foreach Control Structure
Perl's Favorite Default: $_
Scalar and List Context
<STDIN> in List Context
Exercises

If a scalar was the "singular" in Perl, as we described them at the beginning of Chapter 2, "Scalar Data", the "plural" in Perl is represented by lists and arrays.

A list is an ordered collection of scalars. An array is a variable that contains a list. In Perl, the two terms are often used as if they're interchangeable. But, to be accurate, the list is the data, and the array is the variable. You can have a list value that isn't in an array, but every array variable holds a list (although that list may be empty). Figure 3-1 represents a list, whether it's stored in an array or not.

Figure 3-1. A list with five elements

Each element of an array or list is a separate scalar variable with an independent scalar value. These values are ordered -- that is, they have a particular sequence from the first to the last element. The elements of an array or list are indexed by small integers starting at zero[67] and counting by ones, so the first element of any array or list is always element zero.

[67]Array and list indices always start at zero in Perl, unlike in some other languages. In early Perl, it was possible to change the starting number of array and list indexing (not for just one array or list, but for all of them at once!). Larry later realized that this was a misfeature, and its (ab)use is now strongly discouraged. But, if you're terminally curious, look up the $[variable in the perlvarmanpage.

Since each element is an independent scalar value, a list or array may hold numbers, strings, undef values, or any mixture of different scalar values. Nevertheless, it's most common to have all elements of the same type, such as a list of book titles (all strings) or a list of cosines (all numbers).

Arrays and lists can have any number of elements. The smallest one has no elements, while the largest can fill all of available memory. Once again, this is in keeping with Perl's philosophy of "no unnecessary limits."

3.1. Accessing Elements of an Array

If you've used arrays in another language, you won't be surprised to find that Perl provides a way to subscript an array in order to refer to an element by a numeric index.

The array elements are numbered using sequential integers, beginning at zero and increasing by one for each element, like this:

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

The array name itself (in this case, "fred") is from a completely separate namespace than scalars use; you could have a scalar variable named $fred in the same program, and Perl will treat them as different things, and wouldn't be confused.[68] (Your maintenance programmer might be confused, though, so don't capriciously make all of your variable names the same!)

[68]The syntax is always unambiguous -- tricky perhaps, but unambiguous.

You can use an array element like $fred[2] in every place[69] where you could use any other scalar variable like $fred. For example, you can get the value from an array element or change that value by the same sorts of expressions we used in the previous chapter:

[69]Well, almost. The most notable exception is that the control variable of a foreach loop, which we'll see later in this chapter, must be a simple scalar. And there are others, like the "indirect object slot" and "indirect filehandle slot" for print and printf.

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

Of course, the subscript may be any expression that gives a numeric value. If it's not an integer already, it'll automatically be truncated to the next lower integer:

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

If the subscript indicates an element that would be beyond the end of the array, the corresponding value will be undef. This is just as with ordinary scalars; if you've never stored a value into the variable, it's undef.

$blank = $fred[ 142_857 ]; # unused array element gives undef
$blanc = $mel;             # unused scalar $mel also gives undef
Previous | Home | Next
2.13. Exercises | Book Index | 3.2. Special Array Indices
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.2. Special Array Indices

If you store into an array element that is beyond the end of the array, the array is automatically extended as needed -- there's no limit on its length, as long as there's available memory for Perl to use. If intervening elements need to be created, they'll be created as undef values.

$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

Sometimes, you need to find out the last element index in an array. For the array of rocks that we've just been using, the last element index is $#rocks.[70] That's not the same as the number of elements, though, because there's an element number zero. As seen in the code snippet below, it's actually possible to assign to this value to change the size of the array, although this is rare in practice.[71]

[70]Blame this ugly syntax on the C shell. Fortunately, we don't have to look at this very often in the real world.

[71]This is very infrequently done to "pre-size" an array, so that Perl won't need to allocate memory in many small chunks as an array grows. See the Perl documentation for more information, in the unlikely case that you need this.

$end = $#rocks;                  # 99, which is the last element's index
$number_of_rocks = $end + 1;     # okay, but we'll see a better way later
$#rocks = 2;                     # Forget all rocks after 'lava'
$#rocks = 99;                    # add 97 undef elements (the forgotten rocks are
                                 # gone forever)
$rocks[ $#rocks ] = 'hard rock'; # the last rock

Using the $#name value as an index, like that last example, happens often enough that Larry has provided a shortcut: negative array indices count from the end of the array. But don't get the idea that these indices "wrap around." If you've got three elements in the array, the valid negative indices are -1 (the last element), -2 (the middle element), and -3 (the first element). In the real world, nobody seems to use any of these except -1, though.

$rocks[ -1 ] = 'hard rock'; # easier way to do that last example above
$dead_rock = $rocks[-100];  # gets 'bedrock'
$rocks[ -200 ] = 'crystal'; # fatal error!
Previous | Home | Next
3. Lists and Arrays | Book Index | 3.3. List Literals
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.3. List Literals

A list literal (the way you represent a list value within your program) is a list of comma-separated values enclosed in parentheses. These values form the elements of the list. For example:

(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

That last one uses the .. range operator, which is seen here for the first time. That operator creates a list of values by counting from the left scalar up to the right scalar by ones. For example:

(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)
($a..$b)          # range determined by current values of $a and $b
(0..$#rocks)      # the indices of the rocks array from the previous section

As you can see from those last two items, the elements of an array are not necessarily constants -- they can be expressions that will be newly evaluated each time the literal is used. For example:

($a, 17)       # two values: the current value of $a, and 17
($b+$c, $d+$e) # two values

Of course, a list may have any scalar values, like this typical list of strings:

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

3.3.1. The qw Shortcut

It turns out that lists of simple words (like the previous example) are frequently needed in Perl programs. The qw shortcut makes it easy to generate them without typing a lot of extra quote marks:

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

qw stands for "quoted words" or "quoted by whitespace," depending upon whom you ask. Either way, Perl treats it like a single-quoted string (so, you can't use \n or $fred inside a qw list as you would in a double-quoted string). The whitespace (characters like spaces, tabs, and newlines) will be discarded, and whatever is left becomes the list of items. Since whitespace is discarded, here's another (but unusual) way to write that same list:

qw/fred
  barney     betty
wilma dino/   # same as above, but pretty strange whitespace

Since qw is a form of quoting, though, you can't put comments inside a qw list.

The previous two examples have used forward slashes as the delimiter, but Perl actually lets you choose any punctuation character as the delimiter. Here are some of the common ones:

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 >

As those last four show, sometimes the two delimiters can be different. If the opening delimiter is one of those "left" characters, the corresponding "right" character is the proper closing delimiter. Other delimiters use the same character for start and finish.

If you need to include the closing delimiter within the string as one of the characters, you probably picked the wrong delimeter. But even if you can't or don't want to change the delimiter, you can still include the character using the backslash:

qw! yahoo\! google excite lycos ! # include yahoo! as an element

As in single-quoted strings, two consecutive backslashes contribute one single backslash to the item.

Now, although the Perl motto is "There's More Than One Way To Do It," you may well wonder why anyone would need all of those different ways! Well, we'll see later that there are other kinds of quoting where Perl uses this same rule, and it can come in handy in many of those. But even here, it could be useful if you were to need a list of Unix filenames:

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

That list would be quite inconvenient to read, write, and maintain if the slash were the only delimiter available.

Previous | Home | Next
3.2. Special Array Indices | Book Index | 3.4. List Assignment
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.4. List Assignment

In much the same way as scalar values may be assigned to variables, list values may also be assigned to variables:

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

All three variables in the list on the left get new values, just as if we did three separate assignments. Since the list is built up before the assignment starts, this makes it easy to swap two variables' values in Perl:[72]

[72]As opposed to in languages like C, which has no easy way to do this in general. C programmers usually resort to some kind of macro to do this, or use a variable to temporarily hold the value.

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

But what happens if the number of variables (on the left side of the equals sign) isn't the same as the number of values (from the right side)? In a list assignment, extra values are silently ignored -- Perl figures that if you wanted those values stored somewhere, you would have told it where to store them. Alternatively, if you have too many variables, the extras get the value undef.[73]

[73]Well, that's true for scalar variables. Array variables get an empty list, as we'll see in a moment.

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

Now that we can assign lists, you could build up an array of strings with a line of code like this:[74]

[74]We're cheating by assuming that the rocks array is empty before this statement. If there were a value in $rocks[7], say, this assignment wouldn't affect that element.

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

But when you wish to refer to an entire array, Perl has a simpler notation. Just use the at-sign (@) before the name of the array (and no index brackets after it) to refer to the entire array at once. You can read this as "all of the," so @rocks is "all of the rocks."[75] This works on either side of the assignment operator:

[75]Larry claims that he chose the dollar and at-sign because they can be read as $calar (scalar) and @rray (array). If you don't get that, or remember it that way, no big deal.

@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);

That last assignment gives @quarry the five-element list (bedrock, slate, lava, crushed rock, granite), since @tiny contributes zero elements to the list. (In particular, it doesn't put an undef item into the list -- but we could do that explicitly, as we did with @stuff earlier.) It's also worth noting that an array name is replaced by the list it contains. An array doesn't become an element in the list, because these arrays can contain only scalars, not other arrays.[76]

[76]But when you get into more advanced Perl, you'll learn about a special kind of scalar called a reference. That lets us make what are informally called "lists of lists", among other interesting and useful structures. But in that case, you're still not really storing a list into a list; you're storing a reference to an array.

The value of an array variable that has not yet been assigned is ( ), the empty list. Just as new, empty scalars start out with undef, new, empty arrays start out with the empty list.

It's worth noting that when an array is copied to another array, it's still a list assignment. The lists are simply stored in arrays. For example:

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

3.4.1. The pop and push Operators

You could add new items to the end of an array by simply storing them into elements with new, larger indices. But real Perl programmers don't use indices.[77] So in the next few sections, we'll present some ways to work with an array without using indices.

[77]Of course, we're joking. But there's a kernel of truth in this joke. Indexing into arrays is not using Perl's strengths. If you use the pop, push, and similar operators that avoid using indexing, your code will generally be faster than if you use many indices, as well as being more likely to avoid "off-by-one" errors, often called "fencepost" errors. Occasionally, a beginning Perl programmer (wanting to see how Perl's speed compares to C's) will take, say, a sorting algorithm optimized for C (with many array index operations), rewrite it straightforward in Perl (again, with many index operations) and wonder why it's so slow. The answer is that using a Stradivarius violin to pound nails should not be considered a sound construction technique.

One common use of an array is as a stack of information, where new values are added to and removed from the right-hand side of the list. (This is the end with the "last" items in the array, the end with the highest index values.) These operations occur often enough to have their own special functions.

The pop operator takes the last element off of an array, and returns it:

@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.)

That last example uses pop "in a void context," which is merely a fancy way of saying the return value isn't going anywhere. There's nothing wrong with using pop in this way, if that's what you want.

If the array is empty, pop will leave it alone (since there is no element to remove), and it will return undef.

You may have noticed that pop may be used with or without parentheses. This is a general rule in Perl: as long as the meaning isn't changed by removing the parentheses, they're optional.[78]

[78]A reader from the educated class will recognize that this is a tautology.

The converse operation is push, which adds an element (or a list of elements) to the end of an array:

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)

Note that the first argument to push or the only argument for pop must be an array variable -- pushing and popping would not make sense on a literal list.

3.4.2. The shift and unshift Operators

The push and pop operators do things to the end of an array (or the right side of an array, or the portion with the highest subscripts, depending upon how you like to think of it). Similarly, the unshift and shift operators perform the corresponding actions on the "start" of the array (or the "left" side of an array, or the portion with the lowest subscripts). Here are a few examples:

@array = qw# dino fred barney #;
$a = shift(@array);      # $a gets "dino", @array now has ("fred", "barney")
$b = shift @array;       # $b gets "fred", @array now has ("barney")
shift @array;            # @array is now empty
$c = shift @array;       # $c gets undef, @array is still empty
unshift(@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)

Analogous to pop, shift returns undef if given an empty array variable.

Previous | Home | Next
3.3. List Literals | Book Index | 3.5. Interpolating Arrays into Strings
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.5. Interpolating Arrays into Strings

Like scalars, array values may be interpolated into a double-quoted string. Elements of an array are automatically separated by spaces[79] upon interpolation:

[79]Actually, the separator is the value of the special $"variable, which is a space by default.

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

There are no extra spaces added before or after an interpolated array; if you want those, you'll have to put them in yourself:

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

If you forget that arrays interpolate like this, you'll be surprised when you put an email address into a double-quoted string. For historical reasons,[80] this is a fatal error at compile time:

[80]Since you asked: Before version 5, Perl would silently leave uninterpolated an unused array's name in a double-quoted string. So, "fred@bedrock.edu" might be a string containing an email address. This attempt to Do What I Mean will backfire when someone adds a variable named @bedrockto the program -- now the string becomes "fred.edu" or worse.

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

A single element of an array will be replaced by its value, just as you'd expect:

@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

Note that the index expression is evaluated as an ordinary expression, as if it were outside a string. It is not variable-interpolated first. In other words, if $y contains the string "2*4", we're still talking about element 1, not element 7, because "2*4" as a number (the value of $y used in a numeric expression) is just plain 2.[81]

[81]Of course, if you've got warnings turned on, Perl is likely to remind you that "2*4"is a pretty funny-looking number.

If you want to follow a simple scalar variable with a left square bracket, you need to delimit the square bracket so that it isn't considered part of an array reference, as follows:

@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)
Previous | Home | Next
3.4. List Assignment | Book Index | 3.6. The foreach Control Structure
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.6. The foreach Control Structure

It's handy to be able to process an entire array or list, so Perl provides a control structure to do just that. The foreach loop steps through a list of values, executing one iteration (time through the loop) for each value:

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

The control variable ($rock in that example) takes on a new value from the list for each iteration. The first time through the loop, it's "bedrock"; the third time, it's "lava".

The control variable is not a copy of the list element -- it actually is the list element. That is, if you modify the control variable inside the loop, you'll be modifying the element itself, as shown in the following code snippet. This is useful, and supported, but it would surprise you if you weren't expecting it.

@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

What is the value of the control variable after the loop has finished? It's the same as it was before the loop started. The value of the control variable of a foreach loop is automatically saved and restored by Perl. While the loop is running, there's no way to access or alter that saved value. So after the loop is done, the variable has the value it had before the loop, or undef if it hadn't had a value. That means that if you want to name your loop control variable "$rock", you don't have to worry that maybe you've already used that name for another variable.[82]

[82]Unless the variable name has been declared as a lexical in the current scope, in which case you get a lexically local variable instead of a package local variable -- more on this in Chapter 4, "Subroutines".

Previous | Home | Next
3.5. Interpolating Arrays into Strings | Book Index | 3.7. Perl's Favorite Default: $_
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.7. Perl's Favorite Default: $_

If you omit the control variable from the beginning of the foreach loop, Perl uses its favorite default variable, $_. This is (mostly) just like any other scalar variable, except for its unusual name. For example:

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

Although this isn't Perl's only default by a long shot, it's Perl's most common default. We'll see many other cases in which Perl will automatically use $_ when you don't tell it to use some other variable or value, thereby saving the programmer from the heavy labor of having to think up and type a new variable name. So as not to keep you in suspense, one of those cases is print, which will print $_ if given no other argument:

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

3.7.1. The reverse Operator

The reverse operator takes a list of values (which may come from an array) and returns the list in the opposite order. So if you were disappointed that the range operator, .., only counts upwards, this is the way to fix it:

@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

The last line is noteworthy because it uses @fred twice. Perl always calculates the value being assigned (on the right) before it begins the actual assignment.

Remember that reverse returns the reversed list; it doesn't affect its arguments. If the return value isn't assigned anywhere, it's useless:

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

3.7.2. The sort Operator

The sort operator takes a list of values (which may come from an array) and sorts them in the internal character ordering. For ASCII strings, that would be ASCIIbetical order. Of course, ASCII is a strange place where all of the capital letters come before all of the lowercase letters, where the numbers come before the letters, and the punctuation marks -- well, those are here, there, and everywhere. But sorting in ASCII order is just the default behavior; we'll see in Chapter 15, "Strings and Sorting", Strings and Sorting, how to sort in whatever order you'd like:

@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

As you can see from that last example, sorting numbers as if they were strings may not give useful results. But, of course, any string that starts with 1 has to sort before any string that starts with 9, according to the default sorting rules. And like what happened with reverse, the arguments themselves aren't affected. If you want to sort an array, you must store the result back into that array:

sort @rocks;          # WRONG, doesn't modify @rocks
@rocks = sort @rocks; # Now the rock collection is in order
Previous | Home | Next
3.6. The foreach Control Structure | Book Index | 3.8. Scalar and List Context
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.8. Scalar and List Context

This is the most important section in this chapter. In fact, it's the most important section in the entire book. In fact, it wouldn't be an exaggeration to say that your entire career in using Perl will depend upon understanding this section. So if you've gotten away with skimming the text up to this point, this is where you should really pay attention.

That's not to say that this section is in any way difficult to understand. It's actually a simple idea: a given expression may mean different things depending upon where it appears. This is nothing new to you; it happens all the time in natural languages. For example, in English,[83] suppose someone asked you what the word "read"[84] means. It has different meanings depending on how it's used. You can't identify the meaning, until you know the context.

[83]If you aren't a native speaker of English, this analogy may not be obvious to you. But context sensitivity happens in every spoken language, so you may be able to think of an example in your own language.

[84]Or maybe they were asking what the word "red" means, if they were speaking rather than writing a book. It's ambiguous either way. As Douglas Hofstadter said, no language can express every thought unambiguously, especially this one.

The context refers to where an expression is found. As Perl is parsing your expressions, it always expects either a scalar value or a list value.[85] What Perl expects is called the context of the expression.[86]

[85]Unless, of course, Perl is expecting something else entirely. There are other contexts that aren't covered here. In fact, nobody knows how many contexts Perl uses; the biggest brains in all of Perl haven't agreed on an answer to that yet.

[86]This is no different than what you're used to in human languages. If I make a grammatical mistake, you notice it right away, because you expect certain words in places certain. Eventually, you'll read Perl this way, too, but at first you have to think about it.

5 + something  # The something must be a scalar
sort something # The something must be a list

Even if something is the exact same sequence of characters, in one case it may give a single, scalar value, while in the other, it may give a list.[87]

[87]The list may be just one element long, of course. It could also be empty, or it could have any number of elements.

Expressions in Perl always return the appropriate value for their context. For example, how about the "name"[88] of an array. In a list context, it gives the list of elements. But in a scalar context, it returns the number of elements in the array:

[88]Well, the true name of the array @peopleis just people. The @-sign is just a qualifier.

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

Even ordinary assignment (to a scalar or a list) causes different contexts:

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

But please don't jump to the conclusion that scalar context always gives the number of elements that would have been returned in list context. Most list-producing expressions[89] return something much more interesting than that.

[89]But with regard to the point of this section, there's no difference between a "list-producing" expression and a "scalar-producing" one; any expression can produce a list or a scalar, depending upon context. So when we say "list-producing expressions," we mean expressions that are typically used in a list context and that therefore might surprise you when they're used unexpectedly in a scalar context (like reverse or @fred).

3.8.1. Using List-Producing Expressions in Scalar Context

There are many expressions that would typically be used to produce a list. If you use one in a scalar context, what do you get? See what the author of that operation says about it. Usually, that person is Larry, and usually the documentation gives the whole story. In fact, a big part of learning Perl is actually learning how Larry thinks.[90] Therefore, once you can think like Larry does, you know what Perl should do. But while you're learning, you'll probably need to look into the documentation.

[90]This is only fair, since while writing Perl he tried to think like you do to predict what you would want!

Some expressions don't have a scalar-context value at all. For example, what should sort return in a scalar context? You wouldn't need to sort a list to count its elements, so until someone implements something else, sort in a scalar context always returns undef.

Another example is reverse. In a list context, it gives a reversed list. In a scalar context, it returns a reversed string (or reversing the result of concatenating all the strings of a list, if given one):

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

At first, it's not always obvious whether an expression is being used in a scalar or a list context. But, trust us, it will get to be second nature for you eventually.

Here are some common contexts to start you off:

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

Don't be fooled by the one-element list; that last one is a list context, not a scalar one. If you're assigning to a list (no matter the number of elements), it's a list context. If you're assigning to an array, it's a list context.

Here are some other expressions we've seen, and the contexts they provide. First, some that provide scalar context to something:

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

And here are some that provide a list context:

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

3.8.2. Using Scalar-Producing Expressions in List Context

Going this direction is straightforward: if an expression doesn't normally have a list value, the scalar value is automatically promoted to make a one-element list:

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

Well, there's one possible catch:

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

Since undef is a scalar value, assigning undef to an array doesn't clear the array. The better way to do that is to assign an empty list.[91]

[91]Well, in most real-world algorithms, if the variable is declared in the proper scope, it will never need to be explicitly emptied. So this type of assignment is rare in well-written Perl programs. We'll learn about scoping in the next chapter.

3.8.3. Forcing Scalar Context

On occasion, you may need to force scalar context where Perl is expecting a list. In that case, you can use the fake function scalar. It's not a true function, because it just tells Perl to provide a scalar context:

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

Oddly enough, there's no corresponding function to force list context. It turns out never to be needed. Trust us on this, too.

Previous | Home | Next
3.7. Perl's Favorite Default: $_ | Book Index | 3.9. <STDIN> in List Context
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.9. <STDIN> in List Context

One previously seen operator that returns a different value in an array context is the line-input operator, <STDIN>. As described earlier, <STDIN> returns the next line of input in a scalar context. Now, in list context, this operator returns all of the remaining lines up to the end of file. Each line is returned as a separate element of the list. For example:

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

When the input is coming from a file, this will read the rest of the file. But how can there be an end-of-file when the input comes from the keyboard? On Unix and similar systems, including Linux and Mac OS X, you'll normally type a Control-D[92] to indicate to the system that there's no more input; the special character itself is never seen by Perl,[93] even though it may be echoed to the screen. On DOS/Windows systems, use Ctrl-Z instead.[94] You'll need to check the documentation for your system or ask your local expert, if it's different from these.

[92]This is merely the default; it can be changed by the sttycommand. But it's pretty dependable -- we've never seen a Unix system where a different character was used to mean end-of-file from the keyboard.

[93]It's the OS that "sees" the control key and reports "end of file" to the application.

[94]There's a bug affecting some ports of Perl for DOS/Windows where the first line of output to the terminal following the use of Control-Z is obscured. On these systems, you can work around this problem by simply printing a blank line ("\n")after reading the input.

If the person running the program types three lines, then presses the proper keys needed to indicate end-of-file, the array ends up with three elements. Each element will be a string that ends in a newline, corresponding to the three newline-terminated lines entered.

Wouldn't it be nice if, having read those lines, you could chomp the newlines all at once? It turns out that if you give chomp a list of lines, it will remove the newlines from each item in the list. For example:

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

But the more common way to write that is with code similar to what we used earlier:

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

Although you're welcome to write your code either way in the privacy of your own cubicle, most Perl programmers will expect the second, more compact, notation.

It may be obvious to you (but it's not obvious to everyone) that once these lines of input have been read, they can't be re-read.[95] Once you've reached end-of-file, there's no more input out there to read.

[95]Well, yes, if the input is from a source upon which you can seek, then you'll be able to go back and read again. But that's not what we're talking about here.

And what happens if the input is coming from a 400MB log file? The line input operator reads all of the lines, gobbling up lots of memory.[96] Perl tries not to limit you in what you can do, but the other users of your system (not to mention your system administrator) are likely to object. If the input data is large, you should generally find a way to deal with it without reading it all into memory at once.

[96]Typically, that's much more memory than the size of the file, too. That is, a 400MB file will typically take up at least a full gigabyte of memory when read into an array. This is because Perl will generally waste memory to save time. This is a good tradeoff; if you're short of memory, you can buy more; if you're short on time, you're hosed.

Previous | Home | Next
3.8. Scalar and List Context | Book Index | 3.10. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.10. Exercises

See Section A.2, "Answers to Chapter 3 Exercises" for answers to the following exercises:

  1. [6] Write a program that reads a list of strings on separate lines until end-of-input and prints out the list in reverse order. If the input comes from the keyboard, you'll probably need to signal the end of the input by pressing Control-D on Unix, or Control-Z on Windows.

  2. [12] Write a program that reads a list of numbers (on separate lines) until end-of-input and then prints for each number the corresponding person's name from the list shown below. (Hardcode this list of names into your program. That is, it should appear in your program's source code.) For example, if the input numbers were 1, 2, 4, and 2, the output names would be fred, betty, dino, and betty.

    fred betty barney dino wilma pebbles bamm-bamm

  3. [8] Write a program that reads a list of strings (on separate lines) until end-of-input. Then it should print the strings in ASCIIbetical order. That is, if you enter the strings fred, barney, wilma, betty, the output should show barney betty fred wilma. Are all of the strings on one line in the output, or on separate lines? Could you make the output appear in either style?

Previous | Home | Next
3.9. <STDIN> in List Context | Book Index | 4. Subroutines
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 4. Subroutines

Contents:

System and User Functions
Defining a Subroutine
Invoking a Subroutine
Return Values
Arguments
Private Variables in Subroutines
The local Operator
Variable-length Parameter Lists
Notes on Lexical (my) Variables
The use strict Pragma
The return Operator
Exercises

4.1. System and User Functions

We've already seen and used some of the builtin system functions, such as chomp, reverse, print, and so on. But, as other languages do, Perl has the ability to make subroutines, which are user-defined functions.[97] These let us recycle one chunk of code many times in one program.[98]

[97]In Perl, we don't generally make the distinction that Pascal programmers are used to, between functions, which return a value, and procedures, which don't. But a subroutine is always user-defined, while a function may or may not be. That is, the word function may be used as a synonym for subroutine, or it may mean one of Perl's builtin functions. That's why this chapter is titled Subroutines, because it's about the ones you can define, not the builtins. Mostly.

[98]The code examples used in this book are recycled from at least 40% post-consumer programming, and are at least 75% recyclable into your programs when properly decomposed.

The name of a subroutine is another Perl identifier (letters, digits, and underscores, but can't start with a digit) with a sometimes-optional ampersand (&) in front. There's a rule about when you can omit the ampersand and when you cannot; we'll see that rule by the end of the chapter. For now, we'll just use it every time that it's not forbidden, which is always a safe rule. And we'll tell you every place where it's forbidden, of course.

That subroutine name comes from a separate namespace, so Perl won't be confused if you have a subroutine called &fred and a scalar called $fred in the same program -- although there's no reason to do that under normal circumstances.

Previous | Home | Next
3.10. Exercises | Book Index | 4.2. Defining a Subroutine
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.2. Defining a Subroutine

To define your own subroutine, use the keyword sub, the name of the subroutine (without the ampersand), then the indented[99] block of code (in curly braces) which makes up the body of the subroutine, something like this:

[99]Okay, purists, we admit it: the curly braces are part of the block, properly speaking. And Perl doesn't require the indentation of the block -- but your maintenance programmer will. So please be stylish.

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

Subroutine definitions can be anywhere in your program text, but programmers who come from a background of languages like C or Pascal like to put them at the start of the file. Others may prefer to put them at the end of the file, so that the main part of the program appears at the beginning. It's up to you. In any case, you don't normally need any kind of forward declaration.[100]

[100]Unless your subroutine is being particularly tricky and declares a "prototype," which dictates how a compiler will parse and interpret its invocation arguments. This is rare -- see the perlsubmanpage for more information.

Subroutine definitions are global; without some powerful trickiness, there are no private subroutines.[101] If you have two subroutine definitions with the same name, the later one overwrites the earlier one.[102] That's generally considered bad form, or the sign of a confused maintenance programmer.

[101]If you wish to be powerfully tricky, read the Perl documentation about coderefs stored in private (lexical) variables.

[102]A warnable offense, however.

As you may have noticed in the previous example, you may use any global variables within the subroutine body. In fact, all of the variables we've seen so far are globals; that is, they are accessible from every part of your program. This horrifies linguistic purists, but the Perl development team formed an angry mob with torches and ran them out of town years ago. We'll see how to make private variables in the section "Private Variables in Subroutines" later in this chapter.

Previous | Home | Next
4. Subroutines | Book Index | 4.3. Invoking a Subroutine
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.3. Invoking a Subroutine

Invoke a subroutine from within any expression by using the subroutine name (with the ampersand):[103]

[103]And frequently a pair of parentheses, even if empty. As written, the subroutine inherits the caller's @_ value, which we'll be discussing shortly. So don't stop reading here, or you'll be writing code with unintended effects!

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

Sometimes, we refer to the invocation as calling the subroutine.

Previous | Home | Next
4.2. Defining a Subroutine | Book Index | 4.4. Return Values
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.4. Return Values

The subroutine is always invoked as part of an expression, even if the result of the expression isn't being used. When we invoked &marine earlier, we were calculating the value of the expression containing the invocation, but then throwing away the result.

Many times, we'll call a subroutine and actually do something with the result. This means that we'll be paying attention to the return value of the subroutine. All Perl subroutines have a return value -- there's no distinction between those that return values and those that don't. Not all Perl subroutines have a useful return value, however.

Since all Perl subroutines can be called in a way that needs a return value, it'd be a bit wasteful to have to declare special syntax to "return" a particular value for the majority of the cases. So Larry made it simple. Every subroutine is chugging along, calculating values as part of its series of actions. Whatever calculation is last performed in a subroutine is automatically also the return value.

For example, let's define this subroutine:

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
}

The last expression evaluated in the body of this subroutine is the sum of $fred and $barney, so the sum of $fred and $barney will be the return value. Here's that in action:

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

That code will produce this output:

Hey, you called the sum_of_fred_and_barney subroutine!
$c is 7.
Hey, you called the sum_of_fred_and_barney subroutine!
$d is 21.

That print statement is just a debugging aid, so that we can see that we called the subroutine. You'd take it out when the program is finished. But suppose you added another line to the end of the code, like this:

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!
}

In this example, the last expression evaluated is not the addition; it's the print statement. Its return value will normally be 1, meaning "printing was successful,"[104] but that's not the return value we actually wanted. So be careful when adding additional code to a subroutine to ensure that the last expression evaluated will be the desired return value.

[104]The return value of print is true for a successful operation and false for a failure. We'll see how to determine the kind of failure later in Chapter 11, "Filehandles and File Tests".

So, what happened to the sum of $fred and $barney in that subroutine? We didn't put it anywhere, so Perl discarded it. If you had requested warnings, Perl (noticing that there's nothing useful about adding two variables and discarding the result) would likely warn you about something like "a useless use of addition in a void context." The term void context is just a fancy of saying that the answer isn't being stored in a variable or used by another function.

"The last expression evaluated" really means the last expression evaluated, rather than the last line of text. For example, this subroutine returns the larger value of $fred or $barney:

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

The last expression evaluated is the single $fred or $barney, which becomes the return value. We won't know whether the return value will be $fred or $barney until we see what those variables hold at runtime.

A subroutine can also return a list of values when evaluated in a list context.[105] Suppose you wanted to get a range of numbers (as from the range operator, ..), except that you want to be able to count down as well as up. The range operator only counts upwards, but that's easily fixed:

[105]You can detect whether a subroutine is being evaluated in a scalar or list context using the wantarray function, which lets you easily write subroutines with specific list or scalar context values.

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)

In this case, the range operator gives us the list from 6 to 11, then reverse reverses the list, so that it goes from $fred (11) to $barney (6), just as we wanted.

These are all rather trivial examples. It gets better when we can pass values that are different for each invocation into a subroutine instead of relying on global variables. In fact, that's coming right up.

Previous | Home | Next
4.3. Invoking a Subroutine | Book Index | 4.5. Arguments
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.5. Arguments

That subroutine called larger_of_fred_or_barney would be much more useful if it didn't force us to use the global variables $fred and $barney. That's because, if we wanted to get the larger value from $wilma and $betty, we currently have to copy those into $fred and $barney before we can use larger_of_fred_or_barney. And if we had something useful in those variables, we'd have to first copy those to other variables, say $save_fred and $save_barney. And then, when we're done with the subroutine, we'd have to copy those back to $fred and $barney again.

Luckily, Perl has subroutine arguments. To pass an argument list to the subroutine, simply place the list expression, in parentheses, after the subroutine invocation, like this:

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

That list is passed to the subroutine; that is, it's made available for the subroutine to use however it needs to. Of course, this list has to be stored into a variable, so the parameter list (another name for the argument list) is automatically assigned to a special array variable named @_ for the duration of the subroutine. The subroutine can access this variable to determine both the number of arguments and the value of those arguments.

So, that means that the first subroutine parameter is stored in $_[0], the second one is stored in $_[1], and so on. But -- and here's an important note -- these variables have nothing whatsoever to do with the $_ variable, any more than $dino[3] (an element of the @dino array) has to do with $dino (a completely distinct scalar variable). It's just that the parameter list must be stored into some array variable for the subroutine to use it, and Perl uses the array @_ for this purpose.

Now, you could write the subroutine &max to look a little like the subroutine &larger_of_fred_or_barney, but instead of using $a you could use the first subroutine parameter ($_[0]), and instead of using $b, you could use the second subroutine parameter ($_[1]). And so you could end up with code something like this:

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

Well, as we said, you could do that. But it's pretty ugly with all of those subscripts, and hard to read, write, check, and debug, too. We'll see a better way in a moment.

There's another problem with this subroutine. The name &max is nice and short, but it doesn't remind us that this subroutine works properly only if called with exactly two parameters:

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

Excess parameters are ignored -- since the subroutine never looks at $_[2], Perl doesn't care whether there's something in there or not. And insufficient parameters are also ignored -- you simply get undef if you look beyond the end of the @_ array, as with any other array. We'll see how to make a better &max, which works with any number of parameters, later in this chapter.

The @_ variable is local to the subroutine;[106] if there's a global value in @_, it is saved away before the subroutine is invoked and restored to its previous value upon return from the subroutine.[107] This also means that a subroutine can pass arguments to another subroutine without fear of losing its own @_ variable -- the nested subroutine invocation gets its own @_ in the same way. Even if the subroutine calls itself recursively, each invocation gets a new @_, so @_ is always the parameter list for the current subroutine invocation.

[106]Unless there's an ampersand in front of the name for the invocation, and no parentheses (or arguments) afterward, in which case the @_ array is inherited from the caller's context. That's generally a bad idea, but is occasionally useful.

[107]You might recognize that this is the same mechanism as used with the control variable of the foreach loop, as seen in the previous chapter. In either case, the variable's value is saved and automatically restored by Perl. We'll see this again with the local operator later in this chapter.

Previous | Home | Next
4.4. Return Values | Book Index | 4.6. Private Variables in Subroutines
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.6. Private Variables in Subroutines

But if Perl can give us a new @_ for every invocation, can't it give us variables for our own use as well? Of course it can.

By default, all variables in Perl are global variables; that is, they are accessable from every part of the program. But you can create private variables called lexical variables at any time with the my operator:

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

These variables are private (or scoped) to the enclosing block; any other $a or $b is totally unaffected by these two. And that goes the other way, too -- no other code can access or modify these private variables, by accident or design.[108] So, we could drop this subroutine into any Perl program in the world and know that we wouldn't mess up that program's $a and $b (if any).[109]

[108]Advanced programmers will realize that a lexical variable may be accessible by reference from outside its scope, but never by name.

[109]Of course, if that program already had a subroutine called &max, we'd mess that up.

It's also worth pointing out that, inside the if's blocks, there's no semicolon needed after the return value expression. Although Perl allows for the last semicolon in a block to be omitted, in practice that's omitted only when the code is so simple that the block is written in a single line, like the previous ones.

The subroutine in the previous example could be made even simpler. Did you notice that the list ($a, $b) was written twice? That my operator can also be applied to a list of variables enclosed in parentheses, so it's more customary to combine those first two statements in the subroutine:

my($a, $b) = @_;  # Name the subroutine parameters

That one statement creates the private variables and sets their values, so the first parameter now has the easier-to-use name $a and the second has $b. Nearly every subroutine will start with a line much like that one, naming its parameters. When you see that line, you'll know that the subroutine expects two scalar parameters, which we'll call $a and $b inside the subroutine.

Previous | Home | Next
4.5. Arguments | Book Index | 4.7. The local Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.7. The local Operator

You might consider this next section a giant footnote, but then we couldn't have footnotes on footnotes, so we decided to put it up in the main text. Skip over this text on first reading, and pop right on down to Section 4.8, "Variable-length Parameter Lists". You won't need any of it to do the exercises or write Perl code for a long time. But someone invariably asks us in class something like "What is that local thing I see in some programs?" so we're including what we normally say as an aside in class for your enjoyment and edification.

Occasionally, mostly in older code or older Perl books, you'll see the local operator used instead of my. It often looks much the same as my:

sub max {
  local($a, $b) = @_;  # looks a lot like my
  if ($a > $b) { $a } else { $b }
}

But local is misnamed, or at least misleadingly named. Our friend Chip Salzenberg says that if he ever gets a chance to go back in a time machine to 1986 and give Larry one piece of advice, he'd tell Larry to call local by the name "save" instead.[110] That's because local actually will save the given global variable's value away, so it will later automatically be restored to the global variable. (That's right: these so-called "local" variables are actually globals!) This save-and-restore mechanism is the same one we've already seen twice now, in the control variable of a foreach loop, and in the @_ array of subroutine parameters.

[110]We would tell Larry to buy stock in Yahoo!, but Chip is more idealistic than we are.

What local actually does, then, is to save away a copy of the variable's value in a secret place (called the stack). That value can't be accessed, modified, or deleted[111] while it is saved. Then local sets the variable to an empty value (undef for scalars, or empty list for arrays), or to whatever value is being assigned. When Perl returns from the subroutine,[112] the variable is automatically restored to its original value. In effect, the variable was borrowed for a time and given back (hopefully) before anyone noticed that it was borrowed.

[111]Or damaged, defiled, read, checked, touched, seen, changed, or printed, for that matter. There's no way from within Perl to get at the saved value.

[112]Or when it finishes execution of the smallest enclosing block or file, to be more precise.

4.7.1. The Difference Between local and my

But what if the subroutine called another subroutine, one that did notice that the variable was being borrowed by local? For example:

$office = "global";  # Global $office
&say( );                                # says "global", accessing $office directly

&fred( );                               # says "fred", dynamic scope,
    # because fred's local $office hides the global

&barney( );                             # says "global", lexical scope;
    # barney's $office is visible only in that block

sub say { print "$office\n"; }         # print the currently visible $office
sub fred { local($office) = "fred"; &say( ); }
sub barney { my($office) = "barney"; &say( ); }

First, we call the subroutine &say, which tells us which $office it sees -- the global $office. That's normal.

But then we call Fred's subroutine. Fred has made his own local $office, so he has actually changed the behavior of the &say subroutine; now it tells us what's in Fred's $office. We can't tell whether that's what Fred wanted to do or not without understanding the meaning of his code. But it's a little odd.

Barney, however, is a little smarter, as well as being shorter, so he uses the shorter (and smarter) operator, my. Barney's variable $office is private, and Barney's private $office can't be accessed from outside his subroutine, so the &say subroutine is back to normal; it can see only the global $office. Barney didn't change the way &say works, which is more like what most programmers would want and expect.

Now, if you're confused about these two operators at this point, that's to be expected. But any time that you see local, think "save," and that may help. In any new code, just use my, since my variables (lexical variables) are faster than globals -- remember, so-called local variables are really globals -- and they'll work more like the traditional variables in other modern programming languages. But when you're maintaining someone else's old code, you can't necessarily change every local to my without checking upon whether the programmer was using that save-and-restore functionality.

Previous | Home | Next
4.6. Private Variables in Subroutines | Book Index | 4.8. Variable-length Parameter Lists
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.8. Variable-length Parameter Lists

In real-world Perl code, subroutines are often given parameter lists of arbitrary length. That's because of Perl's "no unnecessary limits" philosophy that we've already seen. Of course, this is unlike many traditional programming languages, which require every subroutine to be strictly typed; that is, to permit only a certain, predefined number of parameters of predefined types. It's nice that Perl is so flexible, but (as we saw with the &max routine earlier) that may cause problems when a subroutine is called with a different number of arguments than the author expected.

Of course, the subroutine can easily check that it has the right number of arguments by examining the @_ array. For example, we could have written &max to check its argument list like this:[113]

[113]As soon as you learn about warn (in Chapter 11, "Filehandles and File Tests"), you'll see that you can use it to turn improper usage like this into a proper warning. Or perhaps you'll decide that this case is severe enough to warrant using die, described in the same chapter.

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

That if-test uses the "name" of the array in a scalar context to find out the number of array elements, as we saw in Chapter 3, "Lists and Arrays ".

But in real-world Perl programming, this sort of check is hardly ever used; it's better to make the subroutine adapt to the parameters.

4.8.1. A Better &max Routine

So let's rewrite &max to allow for any number of arguments:

$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;
}

This code uses what has often been called the "high-water mark" algorithm; after a flood, when the waters have surged and receded for the last time, the high-water mark shows where the highest water was seen. In this routine, $max_so_far keeps track of our high-water mark, the largest number yet seen.

The first line sets $max_so_far to 3 (the first parameter in the example code) by shifting that parameter from the parameter array, @_. So @_ now holds (5, 10, 4, 6), since the 3 has been shifted off. And the largest number yet seen is the only one yet seen: 3, the first parameter.

Now, the foreach loop will step through the remaining values in the parameter list, from @_. The control variable of the loop is, by default, $_. (But, remember, there's no automatic connection between @_ and $_; it's just a coincidence that they have such similar names.) The first time through the loop, $_ is 5. The if test sees that it is larger than $max_so_far, so $max_so_far is set to 5 -- the new high-water mark.

The next time through the loop, $_ is 10. That's a new record high, so it's stored in $max_so_far as well.

The next time, $_ is 4. The if test fails, since that's no larger than $max_so_far, which is 10, so the body of the if is skipped.

The next time, $_ is 6, and the body of the if is skipped again. And that was the last time through the loop, so the loop is done.

Now, $max_so_far becomes the return value. It's the largest number we've seen, and we've seen them all, so it must be the largest from the list: 10.

4.8.2. Empty Parameter Lists

That improved &max algorithm works fine now, even if there are more than two parameters. But what happens if there are none?

At first, it may seem too esoteric to worry about. After all, why would someone call &max without giving it any parameters? But maybe someone wrote a line like this one:

$maximum = &max(@numbers);

And the array @numbers might sometimes be an empty list; perhaps it was read in from a file that turned out to be empty, for example. So what does &max do in that case?

The first line of the subroutine sets $max_so_far by using shift on @_, the (now empty) parameter array. That's harmless; the array is left empty, and shift returns undef to $max_so_far.

Now the foreach loop wants to iterate over @_, but since that's empty, the loop body is executed zero times.

So in short order, Perl returns the value of $max_so_far -- undef -- as the return value of the subroutine. In some sense, that's the right answer, because there is no largest value in an empty list.

Of course, whoever is calling this subroutine should be aware that the return value may be undef -- or they could simply ensure that the parameter list is never empty.

Previous | Home | Next
4.7. The local Operator | Book Index | 4.9. Notes on Lexical (my) Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.9. Notes on Lexical (my) Variables

Those lexical variables can actually be used in any block, not merely in a subroutine's block. For example, they can be used in the block of an if, while, or foreach:

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

The variable $square is private to the enclosing block; in this case, that's the block of the foreach loop. If there's no block, the variable is private to the entire source file. For now, your programs aren't going to use more than one source file, so this isn't an issue. But the important concept is that the scope of a lexical variable's name is limited to the smallest enclosing block or file. The only code that can say $square and mean that variable is the code inside that textual scope. This is a big win for maintainability -- if the wrong value is found in $square, the culprit will be found within a limited amount of source code. As experienced programmers have learned (often the hard way), limiting the scope of a variable to a page of code, or even to a few lines of code, really speeds along the development and testing cycle.

Note also that the my operator doesn't change the context of an assignment:

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

In the first one, $num gets the first parameter, as a list-context assignment; in the second, it gets the number of parameters, in a scalar context. Either line of code could be what the programmer wanted; we can't tell from that one line alone, and so Perl can't warn you if you use the wrong one. (Of course, you wouldn't have both of those lines in the same subroutine, since you can't have two lexical variables with the same name declared in the same scope; this is just an example.) So, when reading code like this, you can always tell the context of the assignment by seeing what the context would be without the word my.

Of course, you can use my to create new, private arrays as well:[114]

[114]Or hashes, which we'll see in the next chapter.

my @phone_number;

Any new variable will start out empty -- undef for scalars, or the empty list for arrays.

Previous | Home | Next
4.8. Variable-length Parameter Lists | Book Index | 4.10. The use strict Pragma
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.10. The use strict Pragma

Perl tends to be a pretty permissive language. But maybe you want Perl to impose a little discipline; that can be arranged with the use strict pragma.

A pragma is a hint to a compiler, telling it something about the code. In this case, the use strict pragma tells Perl's internal compiler that it should enforce some good programming rules for the rest of this block or source file.

Why would this be important? Well, imagine that you're composing your program, and you type a line like this one:

$bamm_bamm = 3;  # Perl creates that variable automatically

Now, you keep typing for a while. After that line has scrolled off the top of the screen, you type this line to increment the variable:

$bammbamm += 1;  # Oops!

Since Perl sees a new variable name (the underscore is significant in a variable name), it creates a new variable and increments that one. If you're lucky and smart, you've turned on warnings, and Perl can tell you that you used one or both of those global variable names only once in your program. But if you're merely smart, you used each name more than once, and Perl won't be able to warn you.

To tell Perl that you're ready to be more restrictive, put the use strict pragma at the top of your program (or in any block or file where you want to enforce these rules):

use strict;  # Enforce some good programming rules

Now, among other restrictions,[115] Perl will insist that you declare every new variable with my:[116]

[115]To learn about the other restrictions, see the documentation for strict. The documentation for any pragma is filed under that pragma's name, so the command perldoc strict(or your system's native documentation method) should find it for you. In brief, the other restrictions require that strings be quoted in most cases, and that references be true (hard) references. Neither of these restrictions should affect beginners in Perl.

[116]There are some other ways to declare variables, too.

my $bamm_bamm = 3;  # New lexical variable

Now if you try to spell it the other way, Perl can complain that you haven't declared any variable called $bammbamm, so your mistake is automatically caught at compile time.

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

Of course, this applies only to new variables; Perl's builtin variables, such as $_ and @_ never need to be declared.[117]

[117]And, at least in some circumstances, $a and $b won't need to be declared, because they're used internally by sort. So if you're testing this feature, use other variable names than those two. The fact that use strict doesn't forbid these two is one of the most frequently reported non-bugs in Perl.

If you add use strict to an already-written program, you'll generally get a flood of warning messages, so it's better to use it from the start, when it's needed.

Most people recommend that programs that are longer than a screenful of text generally need use strict. And we agree.

From here on, most (but not all) of our examples will be written as if use strict is in effect, even where we don't show it. That is, we'll generally declare variables with my where it's appropriate. But, even though we don't always do so here, we encourage you to include use strict in your programs as often as possible.

Previous | Home | Next
4.9. Notes on Lexical (my) Variables | Book Index | 4.11. The return Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.11. The return Operator

The return operator immediately returns a value from a subroutine:

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

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

This subroutine is being used to find the index of "dino" in the array @names. First, the my declaration names the parameters: there's $what, which is what we're searching for, and @list, a list of values to search within. That's a copy of the array @names, in this case. The foreach loop steps through the indices of @list (the first index is 0, and the last one is $#list, as we saw in Chapter 3, "Lists and Arrays ").

Each time through the foreach loop, we check to see whether the string in $what is equal[118] to the element from @list at the current index. If it's equal, we return that index at once. This is the most common use of the keyword return in Perl -- to return a value immediately, without executing the rest of the subroutine.

[118]You noticed that we used the string equality test, eq, instead of the numeric equality test, ==, didn't you?

But what if we never found that element? In that case, the author of this subroutine has chosen to return -1 as a "value not found" code. It would be more Perlish, perhaps, to return undef in that case, but this programmer used -1. Saying return -1 on that last line would be correct, but the word return isn't really needed.

Some programmers like to use return every time there's a return value, as a means of documenting that it is a return value. For example, you might use return when the return value is not the last line of the subroutine, such as in the subroutine &list_from_fred_to_barney, earlier in this chapter. It's not really needed, but it doesn't hurt anything. However, many Perl programmers believe it's just an extra seven characters of typing. So you'll need to be able to read code written by both kinds of programmers.

If return is used with no expression, that will return an empty value -- undef in a scalar context, or an empty list in a list context. return ( ) does the same, in case you want to be explicit.

4.11.1. Omitting the Ampersand

As promised, now we'll tell you the rule for when a subroutine call can omit the ampersand. If the compiler sees the subroutine definition before invocation, or if Perl can tell from the syntax that it's a subroutine call, the subroutine can be called without an ampersand, just like a builtin function. (But there's a catch hidden in that rule, as we'll see in a moment.)

This means that if Perl can see that it's a subroutine call without the ampersand, from the syntax alone, that's generally fine. That is, if you've got the parameter list in parentheses, it's got to be a function[119] call:

[119]In this case, the function is the subroutine &shuffle. But it may be a built-in function, as we'll see in a moment.

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

Or if Perl's internal compiler has already seen the subroutine definition, that's generally okay, too; in that case, you can even omit the parentheses around the argument list:

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

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

This works because of the rule that parentheses may always be omitted, except when doing so would change the meaning of the code.

But don't put that subroutine declaration after the invocation, or the compiler won't know what the attempted invocation of division is all about. The compiler has to see the definition before the invocation in order to use the subroutine call as if it were a builtin.

That's not the catch, though. The catch is this: if the subroutine has the same name as a Perl builtin, you must use the ampersand to call it. With an ampersand, you're sure to call the subroutine; without it, you can get the subroutine only if there's no builtin with the same name:

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

&chomp;  # That ampersand is not optional!

Without the ampersand, we'd be calling the builtin chomp, even though we've defined the subroutine &chomp. So, the real rule to use is this one: until you know the names of all of Perl's builtin functions, always use the ampersand on function calls. That means that you will use it for your first hundred programs or so. But when you see someone else has omitted the ampersand in their own code, it's not necessarily a mistake; perhaps they simply know that Perl has no builtin with that name.[120]

[120]Then again, maybe it is a mistake; you can search the perlfunc and perlop manpages for that name, though, to see whether it's the same as a builtin. And Perl will usually be able to warn you about this, when you have warnings turned on.

When programmers plan to call their subroutines as if they were calling Perl's builtins, often when writing modules, they often use prototypes to tell Perl about the parameters to expect. Making modules is an advanced topic, though; when you're ready for that, see Perl's documentation (in particular, the perlmod and perlsub documents) for more information about subroutine prototypes and making modules.

Previous | Home | Next
4.10. The use strict Pragma | Book Index | 4.12. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.12. Exercises

See Section A.3, "Answers to Chapter 4 Exercises" for answers to the following exercises:

  1. [12] Write a subroutine, called &total, which returns the total of a list of numbers. Hint: the subroutine should not perform any I/O; it should simply process its parameters and return a value to its caller. Try it out in this sample program, which merely exercises the subroutine to see that it works. The first group of numbers should add up to 25.

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

  2. [5] Using the subroutine from the previous problem, make a program to calculate the sum of the numbers from 1 to 1000.

Previous | Home | Next
4.11. The return Operator | Book Index | 5. Hashes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 5. Hashes

Contents:

What Is a Hash?
Hash Element Access
Hash Functions
Typical Use of a Hash
Exercises

In this chapter, we will see one of Perl's features that makes Perl one of the world's truly great programming languages -- hashes. [121] Although hashes are a powerful and useful feature, you may have used other powerful languages for years without ever hearing of hashes. But you'll use hashes in nearly every Perl program you'll write from now on; they're that important.

[121]In the olden days, we called these "associative arrays." But the Perl community decided in about 1995 this was too many letters to type and too many syllables to say, so we changed the name to "hashes."

5.1. What Is a Hash?

A hash is a data structure, not unlike an array in that it can hold any number of values and retrieve them at will. But instead of indexing the values by number, as we did with arrays, we'll look up the values by name. That is, the indices (here, we'll call them keys ) aren't numbers, but instead they are arbitrary unique strings (see Figure 5-1).

Figure 5-1. Hash keys and values

The keys are strings, first of all, so instead of getting element number 3 from an array, we'll be accessing the hash element named wilma.

These keys are arbitrary strings -- you can use any string expression for a hash key. And they are unique strings -- just as there's only one array element numbered 3, there's only one hash element named wilma.

Another way to think of a hash is that it's like a barrel of data, where each piece of data has a tag attached. You can reach into the barrel and pull out any tag and see what piece of data is attached. But there's no "first" item in the barrel; it's just a jumble. In an array, we'd start with element 0, then element 1, then element 2, and so on. But in a hash, there's no fixed order, no first element. It's just a collection of key-value pairs.

The keys and values are both arbitrary scalars, but the keys are always converted to strings. So, if you used the numeric expression 50/20 as the key,[122] it would be turned into the three-character string "2.5", which is one of the keys shown in the diagram above.

[122]That's a numeric expression, not the five-character string "50/20". If we used that five-character string as a hash key, it would stay the same five-character string, of course.

As usual, Perl's no-unnecessary-limits philosophy applies: a hash may be of any size, from an empty hash with zero key-value pairs, up to whatever fills up your memory.

Some implementations of hashes (such as in the original awk language, from where Larry borrowed the idea) slow down as the hashes get larger and larger. This is not the case in Perl -- it has a good, efficient, scalable algorithm.[123] So, if a hash has only three key-value pairs, it's very quick to "reach into the barrel" and pull out any one of those. If the hash has three million key-value pairs, it should be just about as quick to pull out any one of those. A big hash is nothing to fear.

[123]Technically, Perl rebuilds the hash table as needed for larger hashes. In fact, the term "hashes" comes from the fact that a hash table is used for implementing them.

It's worth mentioning again that the keys are always unique, although the values may be duplicated. The values of a hash may be all numbers, all strings, undef values, or a mixture.[124] But the keys are all arbitrary, unique strings.

[124]Or, in fact, any scalar values, including other scalar types than the ones we'll see in this book.

5.1.1. Why Use a Hash?

When you first hear about hashes, especially if you've lived a long and productive life as a programmer using other languages that don't have hashes, you may wonder why anyone would want one of these strange beasts. Well, the general idea is that you'll have one set of data "related to" another set of data. For example, here are some hashes you might find in typical applications of Perl:

Given name, family name
The given name (first name) is the key, and the family name is the value. This requires unique given names, of course; if there were two people named randal, this wouldn't work. With this hash, you can look up anyone's given name, and find the corresponding family name. If you use the key tom, you get the value phoenix.

Host name, IP address
You may know that each computer on the Internet has both a host name (like www.stonehenge.com) and an IP address number (like 123.45.67.89). That's because machines like working with the numbers, but we humans have an easier time remembering the names. The host names are unique strings, so they can be used to make this hash. With this hash, you could look up a host name and find the corresponding IP address number.

IP address, host name
Or you could go in the opposite direction. We generally think of the IP address as a number, but it can also be a unique string, so it's suitable for use as a hash key. In this hash, we can look up the IP address number to determine the corresponding host name. Note that this is not the same hash as the previous example: hashes are a one-way street, running from key to value; there's no way to look up a value in a hash and find the corresponding key! So these two are a pair of hashes, one for storing IP addresses, one for host names. It's easy enough to create one of these given the other, though, as we'll see below.

Word, count of number of times that word appears[125]
The idea here is that you want to know how often each word appears in a given document. Perhaps you're building an index to a number of documents, so that when a user searches for fred, you'll know that a certain document mentions fred five times, another mentions fred seven times, and yet another doesn't mention fred at all -- so you'll know which documents the user is likely to want. As the index-making program reads through a given document, each time it sees a mention of fred, it adds one to the value filed under the key of fred. That is, if we had seen fred twice already in this document, the value would be 2, but now we'll increment it to 3. If we had never seen fred before, we'd change the value from undef (the implicit, default value) to 1.

Username, number of disk blocks they are using [wasting]
System administrators like this one: the usernames on a given system are all unique strings, so they can be used as keys in a hash to look up information about that user.

Driver's license number, name
There may be many, many people named John Smith, but we hope that each one has a different driver's license number. That number makes for a unique key, and the person's name is the value.

So, yet another way to think of a hash is as a very simple database, in which just one piece of data may be filed under each key. In fact, if your task description includes phrases like "finding duplicates," "unique," "cross-reference," or "lookup table," it's likely that a hash will be useful in the implementation.

Previous | Home | Next
4.12. Exercises | Book Index | 5.2. Hash Element Access
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.2. Hash Element Access

To access an element of a hash, use syntax that looks like this:

$hash{$some_key}

This is similar to what we used for array access, but here we use curly braces instead of square brackets around the subscript (key).[126] And that key expression is now a string, rather than a number:

[126]Here's a peek into the mind of Larry Wall: Larry says that we use curly braces instead of square brackets because we're doing something fancier than ordinary array access, so we should use fancier punctuation.

$family_name{"fred"} = "flintstone";
$family_name{"barney"} = "rubble";

Figure 5-2 shows how the resulting hash keys are assigned.

Figure 5-2. Assigned hash keys

This lets us use code like this:

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

The name of the hash is like any other Perl identifier (letters, digits, and underscores, but can't start with a digit). And it's from a separate namespace; that is, there's no connection between the hash element $family_name{"fred"} and a subroutine &family_name, for example. Of course, there's no reason to confuse everyone by giving everything the same name. But Perl won't mind if you also have a scalar called $family_name and array elements like $family_name[5]. We humans will have to do as Perl does; that is, we'll have to look to see what punctuation appears before and after the identifier to see what it means. When there is a dollar sign in front of the name and curly braces afterwards, it's a hash element that's being accessed.

When choosing the name of a hash, it's often nice to think of the word "of" between the name of the hash and the key. As in, "the family_name of fred is flintstone". So the hash is named family_name. Then it becomes clear what the relationship is between the keys and their values.

Of course, the hash key may be any expression, not just the literal strings and simple scalar variables that we're showing here:

$foo = "bar";
print $family_name{ $foo . "ney" };  # prints "rubble"

When you store something into an existing hash element, that overwrites the previous value:

$family_name{"fred"} = "astaire";  # gives new value to existing element
$bedrock = $family_name{"fred"};   # gets "astaire"; old value is lost

That's analogous to what happens with arrays and scalars; if you store something new into $pebbles[17] or $dino, the old value is replaced. If you store something new into $family_name{"fred"}, the old value is replaced as well.

Hash elements will spring into existence by assignment:

$family_name{"wilma"} = "flintstone";             # adds a new key (and value)
$family_name{"betty"} .= $family_name{"barney"};  # creates the element if needed

That's also just like what happens with arrays and scalars; if you didn't have $pebbles[17] or $dino before, you will have it after you assign to it. If you didn't have $family_name{"betty"} before, you do now.

And accessing outside the hash gives undef:

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

Once again, this is just like what happens with arrays and scalars; if there's nothing yet stored in $pebbles[17] or $dino, accessing them will yield undef. If there's nothing yet stored in $family_name{"larry"}, accessing it will yield undef.

5.2.1. The Hash as a Whole

To refer to the entire hash, use the percent sign ("%") as a prefix. So, the hash we've been using for the last few pages is actually called %family_name.

For convenience, a hash may be converted into a list, and back again. Assigning to a hash (in this case, the one from Figure 5-1) is a list-context assignment, where the list is made of key-value pairs:[127]

[127]Although any list expression may be used, it must have an even number of elements, because the hash is made of key-value pairs. An odd element will likely do something unreliable, although it's a warnable offense.

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

The value of the hash (in a list context) is a simple list of key-value pairs:

@any_array = %some_hash;

We call this unwinding the hash; turning it back into a list of key-value pairs. Of course, the pairs won't necessarily be in the same order as the original list:

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

The order is jumbled because Perl keeps the key-value pairs in an order that's convenient for Perl, so that it can look up any item quickly. So you'd normally use a hash either when you don't care what order the items are in, or when you have an easy way to put them into the order you want.

Of course, even though the order of the key-value pairs is jumbled, each key "sticks" with its corresponding value in the resulting list. So, even though we don't know where the key foo will appear in the list, we know that its value, 35, will be right after it.

5.2.2. Hash Assignment

It's rare to do so, but a hash may be copied using the obvious syntax:

%new_hash = %old_hash;

This is actually more work for Perl than meets the eye. Unlike what happens in languages like Pascal or C, where such an operation would be a simple matter of copying a block of memory, Perl's data structures are more complex. So, that line of code tells Perl to unwind the %old_hash into a list of key-value pairs, then assign those to %new_hash, building it up one key-value pair at a time.

It's more common to transform the hash in some way, though. For example, we could make an inverse hash:

%inverse_hash = reverse %any_hash;

This takes %any_hash and unwinds it into a list of key-value pairs, making a list like (key, value, key, value, key, value, ...). Then reverse turns that list end-for-end, making a list like (value, key, value, key, value, key, ...). Now the keys are where the values used to be, and the values are where the keys used to be. When that's stored into %inverse_hash, we'll be able to look up a string that was a value in %any_hash -- it's now a key of %inverse_hash. And the value we'll find is one that was one of the keys from %any_hash. So, we have a way to look up a "value" (now a key), and find a "key" (now a value).

Of course, you might guess (or determine from scientific principles, if you're clever) that this will work properly only if the values in the original hash were unique -- otherwise we'd have duplicate keys in the new hash, and keys are always unique. Here's the rule that Perl uses: the last one in wins. That is, the later items in the list overwrite any earlier ones. Of course, we don't know what order the key-value pairs will have in this list, so there's no telling which ones would win. You'd use this technique only if you know there are no duplicates among the original values.[128] But that's the case for the IP address and host name examples given earlier:

[128]Or if you don't care that there are duplicates. For example, we could invert the %family_name hash (in which the keys are people's given names and values are their family names) to make it easy to determine whether there is or is not anyone with a given family name in the group. Thus, in the inverted hash, if there's no key of slate, we'd know that there's no one with that name in the original hash.

%ip_address = reverse %host_name;

Now we can look up a host name or IP address with equal ease, to find the corresponding IP address or host name.

5.2.3. The Big Arrow

When assigning a list to a hash, sometimes it's not obvious which elements are keys and which are values. For example, in this assignment (which we saw earlier), we humans have to count through the list, saying, "key, value, key, value...", in order to determine whether 2.5 is a key or a value:

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

Wouldn't it be nice if Perl gave us a way to pair up keys and values in that kind of a list, so that it would be easy to see which ones were which? Larry thought so, too, which is why he invented the big arrow, (=>).[129] To Perl, it's just a different way to "spell" a comma. That is, in the Perl grammar, any time that you need a comma ( , ), you can use the big arrow instead; it's all the same to Perl.[130] So here's another way to set up the hash of last names:

[129]Yes, there's also a little arrow, (->). It's used with references, which are an advanced topic; see the perlreftutand perlrefmanpage when you're ready for that.

[130]Well, there's one technical difference: any bareword (a sequence of nothing but letters, digits, and underscores not starting with a digit) to the left of the big arrow is implicitly quoted. So you can leave off the quote marks on a bareword to the left of the big arrow. You may also omit the quote marks if there's nothing but a bareword as a key inside the curly braces of a hash.

my %last_name = (  # a hash may be a lexical variable
  "fred" => "flintstone",
  "dino" => undef,
  "barney" => "rubble",
  "betty" => "rubble",
);

Here, it's easy (or perhaps at least easier) to see whose name pairs with which value, even if we end up putting many pairs on one line. And notice that there's an extra comma at the end of the list. As we saw earlier, this is harmless, but convenient; if we need to add additional people to this hash, we'll simply make sure that each line has a key-value pair and a trailing comma. Perl will see that there is a comma between each item and the next, and one extra (harmless) comma at the end of the list.

Previous | Home | Next
5. Hashes | Book Index | 5.3. Hash Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.3. Hash Functions

Naturally, there are some useful functions that can work on an entire hash at once.

5.3.1. The keys and values Functions

The keys function yields a list of all the current keys in a hash, while the values function gives the corresponding values. If there are no elements to the hash, then either function returns an empty list:

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

So, @k will contain "a", "b", and "c", and @v will contain 1, 2, and 3 -- in some order. Remember, Perl doesn't maintain the order of elements in a hash. But, whatever order the keys are in, the values will be in the corresponding order: If "b" is last in the keys, 2 will be last in the values; if "c" is the first key, 3 will be the first value. That's true as long as you don't modify the hash between the request for the keys and the one for the values. If you add elements to the hash, Perl reserves the right to rearrange it as needed, to keep the access quick.[131]

[131]Of course, if you started adding elements to the hash between keys and values, your list of values (or keys, whichever you did second) would have additional items, which would be tough to match up with the first list. So no normal programmer would do that.

In a scalar context, these functions give the number of elements (key-value pairs) in the hash. They do this quite efficiently, without having to visit each element of the hash:

my $count = keys %hash;  # gets 3, meaning three key-value pairs

Once in a long while, you'll see that someone has used a hash as a Boolean (true/false) expression, something like this:

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

That will be true if (and only if) the hash has at least one key-value pair.[132] So, it's just saying, "if the hash is not empty...". But this is a pretty rare construct, as such things go.

[132]The actual result is an internal debugging string useful to the people who maintain Perl. It looks something like "4/16", but the value is guaranteed to be true when the hash is non-empty, and false when it's empty, so the rest of us can still use it for that.

5.3.2. The each Function

If you wish to iterate over (that is, examine every element of) an entire hash, one of the usual ways is to use the each function, which returns a key-value pair as a two-element list.[133] On each evaluation of this function for the same array, the next successive key-value pair is returned, until all the elements have been accessed. When there are no more pairs, each returns an empty list.

[133]The other usual way to iterate over an entire hash is to use foreach on a list of keys from the hash; we'll see that by the end of this section.

In practice, the only way to use each is in a while loop, something like this:

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

There's a lot going on here. First, each %hash returns a key-value pair from the hash, as a two-element list; let's say that the key is "c" and the value is 3, so the list is ("c", 3). That list is assigned to the list ($key, $value), so $key becomes "c", and $value becomes 3.

But that list assignment is happening in the conditional expression of the while loop, which is a scalar context. (Specifically, it's a Boolean context, looking for a true/false value; and a Boolean context is a particular kind of scalar context.) The value of a list assignment in a scalar context is the number of elements in the source list -- 2, in this case. Since 2 is a true value, we enter the body of the loop and print the message c => 3.

The next time through the loop, each %hash gives a new key-value pair; let's say it's ("a", 1) this time. (It knows to return a different pair than previously because it keeps track of where it is; in technical jargon, there's an iterator stored in with each hash.[134]) Those two items are stored into ($key, $value). Since the number of elements in the source list was again 2, a true value, the while condition is true, and the loop body runs again, telling us a => 1.

[134]Since each hash has its own private iterator, loops using each may be nested, as long as they are iterating over different hashes. And, as long as we're already in a footnote, we may as well tell you: it's unlikely you'll ever need to do so, but you may reset the iterator of a hash by using the keys or values function on the hash. The iterator is also automatically reset if a new list is stored into the entire hash, or if each has iterated through all of the items to the "end" of the hash. On the other hand, adding new key-value pairs to the hash while iterating over it is generally a bad idea, since that won't necessarily reset the iterator. That's likely to confuse you, your maintenance programmer, and each as well.

We go one more time through the loop, and by now we know what to expect, so it's no surprise to see b => 2 appear in the output.

But we knew it couldn't go on forever. Now, when Perl evaluates each %hash, there are no more key-value pairs available. So, each has to return an empty list.[135] The empty list is assigned to ($key, $value), so $key gets undef, and $value also gets undef.

[135]It's being used in list context, so it can't return undef to signal failure; that would be the one-element list (undef)instead of the empty (zero-element) list ( ).

But that hardly matters, because the whole thing is being evaluated in the conditional expression of the while loop. The value of a list assignment in a scalar context is the number of elements in the source list -- in this case, that's 0. Since 0 is a false value, the while loop is done, and execution continues with the rest of the program.

Of course, each returns the key-value pairs in a jumbled order. (It's the same order as keys and values would give, incidentally; the "natural" order of the hash.) If you need to go through the hash in order, simply sort the keys, perhaps something like this:

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";
}

We'll see more about sorting hashes in Chapter 15, "Strings and Sorting".

Previous | Home | Next
5.2. Hash Element Access | Book Index | 5.4. Typical Use of a Hash
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.4. Typical Use of a Hash

At this point, you may find it helpful to see a more concrete example.

The Bedrock library uses a Perl program in which a hash keeps track of how many books each person has checked out, among other information:

$books{"fred"} = 3;
$books{"wilma"} = 1;

It's easy to see whether an element of the hash is true or false, do this:

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

But there are some elements of the hash that aren't true:

$books{"barney"} = 0;       # no books currently checked out
$books{"pebbles"} = undef;  # no books EVER checked out - a new library card

Since Pebbles has never checked out any books, her entry has the value of undef, rather than 0.

There's a key in the hash for everyone who has a library card. For each key (that is, for each library patron), there's a value that is either a number of books checked out, or undef if that person's library card has never been used.

5.4.1. The exists Function

To see whether a key exists in the hash, (that is, whether someone has a library card or not), use the exists function, which returns a true value if the given key exists in the hash, whether the corresponding value is true or not:

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

That is to say, exists $books{"dino"} will return a true value if (and only if) dino is found in the list of keys from keys %books.

5.4.2. The delete Function

The delete function removes the given key (and its corresponding value) from the hash. (If there's no such key, its work is done; there's no warning or error in that case.)

my $person = "betty";
delete $books{$person};  # Revoke the library card for $person

Note that this is not the same as storing undef into that hash element -- in fact, it's precisely the opposite! Checking exists($books{"betty"}) will give opposite results in these two cases; after a delete, the key can't exist in the hash, but after storing undef, the key must exist.

5.4.3. Hash Element Interpolation

You can interpolate a single hash element into a double-quoted string just as you'd expect:

foreach $person (sort keys %books) {            # for each library patron,in order
  if ($books{$person}) {
    print "$person has $books{$person} items\n";# fred has 3 items
  }
}

But there's no support for entire hash interpolation; "%books" is just the six chararcters of (literally) %books.[136] So we've seen all of the magical characters that need backslashing in double quotes: $ and @, because they introduce a variable to be interpolated; ", since that's the quoting character that would otherwise end the double-quoted string; and \, the backslash itself. Any other characters in a double-quoted string are non-magical and should simply stand for themselves.[137]

[136]Well, it couldn't really be anything else; if we tried to print out the entire hash, as a series of key-value pairs, that would be nearly useless. And, as we'll see in Chapter 6, "I/O Basics", the percent sign is frequently used in printf format strings; giving it another meaning here would be terribly inconvenient.

[137]But do beware of the apostrophe ('), left square bracket ([), left curly brace ({), the small arrow (->), or double-colon (::) following a variable name in a double-quoted string, as they could perhaps mean something you didn't intend.

Previous | Home | Next
5.3. Hash Functions | Book Index | 5.5. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.5. Exercises

See Section A.4, "Answers to Chapter 5 Exercises" for answers to the following exercises:

  1. [7] Write a program that will ask the user for a given name and report the corresponding family name. Use the names of people you know, or (if you spend so much time on the computer that you don't know any actual people) use the following table:

    Input

    Output

    fred

    flintstone

    barney

    rubble

    wilma

    flintstone

  2. [15] Write a program that reads a series of words (with one word per line[138]) until end-of-input, then prints a summary of how many times each word was seen. (Hint: remember that when an undefined value is used as if it were a number, Perl automatically converts it to 0. It may help to look back at the earlier exercise that kept a running total.) So, if the input words were fred, barney, fred, dino, wilma, fred (all on separate lines), the output should tell us that fred was seen 3 times. For extra credit, sort the summary words in ASCII order in the output.

    [138]It has to be one word per line, because we still haven't shown you how to extract individual words from a line of input.

Previous | Home | Next
5.4. Typical Use of a Hash | Book Index | 6. I/O Basics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 6. I/O Basics

Contents:

Input from Standard Input
Input from the Diamond Operator
The Invocation Arguments
Output to Standard Output
Formatted Output with printf
Exercises

We've already seen how to do some input/output (I/O), in order to make some of the earlier exercises possible. But now we'll learn a little more about those operations. As the title of this chapter implies, there will be more about Perl's I/O operations in Chapter 11, "Filehandles and File Tests".

6.1. Input from Standard Input

Reading from the standard input stream is easy.[139] We've been doing it already with the <STDIN> operator.[140] Evaluating this operator in a scalar context gives you the next line of input:

[139]If you're already familiar with the workings of standard input, output, and error streams, you're ahead of the game. If not, we'll get you caught up when we get to Chapter 14, "Process Management". For now, just think of "standard input" as being "the keyboard," and "standard output" as being "the display screen."

[140]What we're calling the line-input operator here, <STDIN>, is actually a line-input operator (represented by the angle brackets) around a filehandle. We'll learn about filehandles in Chapter 11, "Filehandles and File Tests".

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

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

Since the line-input operator will return undef when you reach end-of-file, this is handy for dropping out of loops:

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

There's a lot going on in that first line: we're reading the input into a variable, checking that it's defined, and if it is (meaning that we haven't reached the end of the input) we're running the body of the while loop. So, inside the body of the loop, we'll see each line, one after another, in $line.[141] This is something you'll want to do fairly often, so naturally Perl has a shortcut for it. The shortcut looks like this:

[141]You probably noticed that we never chomped that input. In this kind of a loop, you can't really put chomp into the conditional expression, so it's often the first item in the loop body, when it's needed. We'll see examples of that in the next section.

while (<STDIN>) {
  print "I saw $_";
}

Now, to make this shortcut, Larry chose some useless syntax. That is, this is literally saying, "Read a line of input, and see if it's true. (Normally it is.) And if it is true, enter the while loop, but throw away that line of input!" Larry knew that it was a useless thing to do; nobody should ever need to do that in a real Perl program. So, Larry took this useless syntax and made it useful.

What this is actually saying is that Perl should do the same thing as we saw in our earlier loop: it tells Perl to read the input into a variable, and (as long as the result was defined, so we haven't reached end-of file) then enter the while loop. However, instead of storing the input into $line, Perl will use its favorite default variable, $_, just as if you had written this:

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

Now, before we go any further, we must be very clear about something: this shortcut works only if you write it just as we did. If you put a line-input operator anywhere else (in particular, as a statement all on its own) it won't read a line into $_ by default. It works only if there's nothing but the line-input operator in the conditional of a while loop.[142] If you put anything else into the conditional expression, this shortcut won't apply.

[142]Well, okay, the conditional of a for loop is just a while conditional in disguise, so it works there, too.

There's no connection between the line-input operator (<STDIN>) and Perl's favorite default variable ($_). In this case, though, it just happens that the input is being stored in that variable.

On the other hand, evaluating the line-input operator in a list context gives you all of the (remaining) lines of input as a list -- each element of the list is one line:

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

Once again, there's no connection between the line-input operator and Perl's favorite default variable. In this case, though, the default control variable for foreach is $_. So in this loop, we'll see each line of input in $_, one after the other.

That may sound familiar, and for good reason: That's the same behavior as the while loop would do. Isn't it?

The difference is under the hood. In the while loop, Perl reads a line of input, puts it into a variable, and runs the body of the loop. Then, it goes back to find another line of input. But in the foreach loop, the line-input operator is being used in a list context (since foreach needs a list to iterate through). So it has to read all of the input before the loop can start running. That difference will become apparent when the input is coming from your 400MB web server log file! It's generally best to use code like the while loop's shortcut, which will process input a line at a time, whenever possible.

Previous | Home | Next
5.5. Exercises | Book Index | 6.2. Input from the Diamond Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.2. Input from the Diamond Operator

Another way to read input is with the diamond[143] operator: <>. This is useful for making programs that work like standard Unix[144] utilities, with respect to the invocation arguments (which we'll see in a moment). If you want to make a Perl program that can be used like the utilities cat, sed, awk, sort, grep, lpr, and many others, the diamond operator will be your friend. If you want to make anything else, the diamond operator probably won't help.

[143]The diamond operator was named by Larry's daughter, Heidi, when Randal went over to Larry's house one day to show off the new training materials he'd been writing, and complained that there was no spoken name for "that thing". Larry didn't have a name for it, either. Heidi (eight years old at the time) quickly chimed in, "That's a diamond, Daddy." So the name stuck. Thanks, Heidi!

[144]But not just on Unix systems. Many other systems have adopted this way of using invocation arguments.

The invocation arguments to a program are normally a number of "words" on the command line after the name of the program.[145] In this case, they give the names of a number of files to be processed in sequence:

[145]Whenever a program is started, it has a list of zero or more invocation arguments, supplied by whatever program is starting it. Often this is the shell, which makes up the list depending upon what you type on the command line. But we'll see in a later chapter that you can invoke a program with pretty much any strings as the invocation arguments. Because they often come from the shell's command line, they are sometimes called "command-line arguments" as well.

$ ./my_program fred barney betty

That command means to run the command my_program (which will be found in the current directory), and that it should process file fred, followed by file barney, followed by file betty.

If you give no invocation arguments, the program should process the standard input stream. Or, as a special case, if you give just a hyphen as one of the arguments, that means standard input as well.[146] So, if the invocation arguments had been fred - betty, that would have meant that the program should process file fred, followed by the standard input stream, followed by file betty.

[146]Here's a possibly unfamilar Unix fact: most of those standard utilities, like cat and sed use this same convention, where a hyphen stands for the standard input stream.

The benefit of making your programs work like this is that you may choose where the program gets its input at run time; for example, you won't have to rewrite the program to use it in a pipeline (which we'll discuss more later). Larry put this feature into Perl because he wanted to make it easy for you to write your own programs that work like standard Unix utilities -- even on non-Unix machines. Actually, he did it so he could make his own programs work like standard Unix utilities; since some vendors' utilities don't work just like others', Larry could make his own utilities, deploy them on a number of machines, and know that they'd all have the same behavior. Of course, this meant porting Perl to every machine he could find.

The diamond operator is actually a special kind of line-input operator. But instead of getting the input from the keyboard, it comes from the user's choice of input:[147]

[147]Which may or may not include getting input from the keyboard.

while (defined($line = <>)) {
  chomp($line);
  print "It was $line that I saw!\n";
}

So, if we run this program with the invocation arguments fred, barney, and betty, it will say something like: "It was [a line from file fred] that I saw!", "It was [another line from file fred] that I saw!", on and on until it reaches the end of file fred. Then, it will automatically go on to file barney, printing out one line after another, and then on to file betty. Note that there's no break when we go from one file to another; when you use the diamond, it's as if the input files have been merged into one big file.[148] The diamond will return undef (and we'll drop out of the while loop) only at the end of all of the input.

[148]If it matters to you, or even if it doesn't, the current file's name is kept in Perl's special variable $ARGV. This name may be "-" instead of a real filename if the input is coming from the standard input stream, though.

In fact, since this is just a special kind of line-input operator, we may use the same shortcut we saw earlier, to read the input into $_ by default:

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

This works like the loop above, but with less typing. And you may have noticed that we're using the default for chomp; without an argument, chomp will work on $_. Every little bit of saved typing helps!

Since the diamond operator is generally being used to process all of the input, it's typically a mistake to use it in more than one place in your program. If you find yourself putting two diamonds into the same program, especially using the second diamond inside the while loop that is reading from the first one, it's almost certainly not going to do what you would like.[149] In our experience, when beginners put a second diamond into a program, they meant to use $_ instead. Remember, the diamond operator reads the input, but the input itself is (generally, by default) found in $_.

[149]If you re-initialize @ARGV before using the second diamond, then you're on solid ground. We'll see @ARGV in the next section.

If the diamond operator can't open one of the files and read from it, it'll print an allegedly helpful diagnostic message, such as:

can't open wimla: No such file or directory

The diamond operator will then go on to the next file automatically, much like what you'd expect from cat or another standard utility.

Previous | Home | Next
6. I/O Basics | Book Index | 6.3. The Invocation Arguments
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.3. The Invocation Arguments

Technically, the diamond operator isn't looking literally at the invocation arguments -- it works from the @ARGV array. This array is a special array that is preset by the Perl interpreter to be a list of the invocation arguments. In other words, this is just like any other array, (except for its funny, all-caps name), but when your program starts, @ARGV is already stuffed full of the list of invocation arguments.[150]

[150]C programmers may be wondering about argc (there isn't one in Perl), and what happened to the program's own name (that's found in Perl's special variable $0, not @ARGV). Also, depending upon how you've invoked your program, there may be a little more happening than we say here. See the perlrun manpage for the full details.

You can use @ARGV just like any other array; you could shift items off of it, perhaps, or use foreach to iterate over it. You could even check to see if any arguments start with a hyphen, so that you could process them as invocation options (like Perl does with its own -w option).[151]

[151]If you need more than just one or two such options, you should almost certainly use a module to process them in a standard way. See the documentation for the Getopt::Long and Getopt::Std modules, which are part of the standard distribution.

This is how the diamond operator knows what filenames it should use: it looks in @ARGV. If it finds an empty list, it uses the standard input stream; otherwise it uses the list of files that it finds. This means that after your program starts and before you start using the diamond, you've got a chance to tinker with @ARGV. For example, here we can process three specific files, regardless of what the user chose on the command line:

@ARGV = qw# larry moe curly #;  # force these three files to be read
while (<>) {
  chomp;
  print "It was $_ that I saw in some stooge-like file!\n";
}

In Chapter 11, "Filehandles and File Tests", we'll see how to open and close specific filenames at specific times. But this technique will suffice for the next few chapters.

Previous | Home | Next
6.2. Input from the Diamond Operator | Book Index | 6.4. Output to Standard Output
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.4. Output to Standard Output

The print operator takes a list of values and sends each item (as a string, of course) to standard output in turn, one after another. It doesn't add any extra characters before, after, or in between the items;[152] if you want spaces between items and a newline at the end, you have to say so:

[152]Well, it doesn't add anything extra by default, but this default (like so many others in Perl) may be changed. Changing these defaults will likely confuse your maintenance programmer, though, so avoid doing so except in small, quick-and-dirty programs, or (rarely) in a small section of a normal program. See the perlvarmanpage to learn about changing the defaults.

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

Of course, that means that there's a difference between printing an array and interpolating an array:

print @array;     # print a list of items
print "@array";   # print a string (containing an interpolated array)

That first print statement will print a list of items, one after another, with no spaces in between. The second one will print exactly one item, which is the string you get by interpolating @array into the empty string -- that is, it prints the contents of @array, separated by spaces.[153] So, if @array holds qw/ fred barney betty /,[154] the first one prints fredbarneybetty, while the second prints fred barney betty separated by spaces.

[153]Yes, the spaces are another default; see the perlvarmanpage again.

[154]You know that we mean a three-element list here, right? This is just Perl notation.

But before you decide to always use the second form, imagine that @array is a list of unchomped lines of input. That is, imagine that each of its strings has a trailing newline character. Now, the first print statement prints fred, barney, and betty on three separate lines. But the second one prints this:

fred
 barney
 betty

Do you see where the spaces come from? Perl is interpolating an array, so it puts spaces between the elements. So, we get the first element of the array (fred and a newline character), then a space, then the next element of the array (barney and a newline character), then a space, then the last element of the array (betty and a newline character). The result is that the lines seem to have become indented, except for the first one. Every week or two, a message appears on the newsgroup comp.lang.perl.misc with a subject line something like:

Perl indents everything after the first line

Without even reading the message, we can immediately see that the program used double quotes around an array containing unchomped strings. "Did you perhaps put an array of unchomped strings inside double quotes?" we ask, and the answer is always yes.

Generally, if your strings contain newlines, you simply want to print them, after all:

print @array;

But if they don't contain newlines, you'll generally want to add one at the end:

print "@array\n";

So, if you're using the quote marks, you'll be (generally) adding the \n at the end of the string anyway; this should help you to remember which is which.

It's normal for your program's output to be buffered . That is, instead of sending out every little bit of output at once, it'll be saved until there's enough to bother with. That's because if (for example) the output were going to be saved on disk, it would be (relatively) slow and inefficient to spin the disk every time that one or two characters need to be added to the file. Generally, then, the output will go into a buffer that is flushed (that is, actually written to disk, or wherever) only when the buffer gets full, or when the output is otherwise finished (such as at the end of runtime). Usually, that's what you want.

But if you (or a program) may be waiting impatiently for the output, you may wish to take that performance hit and flush the output buffer each time you print. See the Perl manpages for more information on controlling buffering in that case.

Since print is looking for a list of strings to print, its arguments are evaluated in list context. Since the diamond operator (as a special kind of line-input operator) will return a list of lines in a list context, these can work well together:

print <>;          # source code for 'cat'

print sort <>;  # source code for 'sort'

Well, to be fair, the standard Unix commands cat and sort do have some additional functionality that these replacements lack. But you can't beat them for the price! You can now re-implement all of your standard Unix utilities in Perl, and painlessly port them to any machine that has Perl, whether that machine is running Unix or not. And you can be sure that the programs on every different type of machine will nevertheless have the same behavior.[155]

[155]In fact, there was even an endeavor started, called the PPT (Perl Power Tools) project, whose goal is to implement all of the classic Unix utilities in Perl. They actually completed nearly all the utilities (and most of the games!), but got bogged down when they got to reimplementing the shell. The PPT project has been helpful because it has made these standard utilities available on many non-Unix machines.

What might not be obvious is that print has optional parentheses, which can sometimes cause confusion. Remember the rule that parentheses in Perl may always be omitted, except when doing so would change the meaning of a statement. So, here are two ways to print the same thing:

print("Hello, world!\n");
print "Hello, world!\n";

So far, so good. But another rule in Perl is that if the invocation of print looks like a function call, then it is a function call. It's a simple rule, but what does it mean for something to look like a function call?

In a function call, there's a function name immediately[156] followed by parentheses around the function's arguments, like this:

[156]We say "immediately" here because Perl won't permit a newline character between the function name and the opening parenthesis in this kind of function call. If there is a newline there, Perl sees your code as making a list operator, rather than a function call. This is the kind of piddling technical detail that we mention only for completeness. If you're terminally curious, see the full story in the manpages.

print (2+3);

That looks like a function call, so it is a function call. It prints 5, but then it returns a value like any other function. The return value of print is a true or false value, indicating the success of the print. It nearly always succeeds, unless you get some I/O error, so the $result in the following statement will normally be 1:

$result = print("hello world!\n");

But what if you used the result in some other way? Let's suppose you decide to multiply the return value times four:

print (2+3)*4;  # Oops!

When Perl sees this line of code, it prints 5, just as you asked. Then it takes the return value from print, which is 1, and multiplies that times 4. It then throws away the product, wondering why you didn't tell it to do something else with it. And at this point, someone looking over your shoulder says, "Hey, Perl can't do math! That should have printed 20, rather than 5!"

This is the problem with allowing the parentheses to be optional; sometimes we humans forget where the parentheses really belong. When there are no parentheses, print is a list operator, printing all of the items in the following list; that's generally what you'd expect. But when the first thing after print is a left parenthesis, print is a function call, and it will print only what's found inside the parentheses. Since that line had parentheses, it's the same to Perl as if you'd said this:

( print(2+3) ) * 4;  # Oops!

Fortunately, Perl itself can almost always help you with this, if you ask for warnings -- so use -w, at least during program development and debugging.

Actually, this rule -- "If it looks like a function call, it is a function call" -- applies to all list functions[157] in Perl, not just to print. It's just that you're most likely to notice it with print. If print (or another function name) is followed by an open parenthesis, make sure that the corresponding close parenthesis comes after all of the arguments to that function.

[157]Functions that take zero or one arguments don't suffer from this problem.

Previous | Home | Next
6.3. The Invocation Arguments | Book Index | 6.5. Formatted Output with printf
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.5. Formatted Output with printf

You may wish to have a little more control with your output than print provides. In fact, you may be accustomed to the formatted output of C's printf function. Fear not -- Perl provides a comparable operation with the same name.

The printf operator takes a format string followed by a list of things to print. The format[158] string is a fill-in-the-blanks template showing the desired form of the output:

[158]Here, we're using "format" in the generic sense. Perl has a report-generating feature called "formats" that we won't even be mentioning (except in this footnote) until Appendix B, "Beyond the Llama", and then only to say that we really aren't going to talk about them. So, you're on your own there. Just wanted to keep you from getting lost.

printf "Hello, %s; your password expires in %d days!\n",
  $user, $days_to_die;

The format string holds a number of so-called conversions ; each conversion begins with a percent sign (%) and ends with a letter. (As we'll see in a moment, there may be significant extra characters between these two symbols.) There should be the same number of items in the following list as there are conversions; if these don't match up, it won't work correctly. In the example above, there are two items and two conversions, so the output might look something like this:

Hello, merlyn; your password expires in 3 days!

There are many possible printf conversions, so we'll take time here to describe just the most common ones. Of course, the full details are available in the perlfunc manpage.

To print a number in what's generally a good way, use %g ,[159] which automatically chooses floating-point, integer, or even exponential notation as needed:

[159]"General" numeric conversion. Or maybe a "Good conversion for this number" or "Guess what I want the output to look like."

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

The %d format means a decimal[160] integer, truncated as needed:

[160]There's also %x for hexadecimal and %o for octal, if you need those. But we really say "decimal" here as a memory aid: %d for Decimal integer.

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

Note that this is truncated, not rounded; we'll see how to round off a number in a moment.

In Perl, printf is most often used for columnar data, since most formats accept a field width. If the data won't fit, the field will generally be expanded as needed:

printf "%6d\n", 42;  # output like ‘‘‘‘42 (the ‘ symbol stands for a space)
printf "%2d\n", 2e3 + 1.95;  # 2001

The %s conversion means a string, so it effectively interpolates the given value as a string, but with a given field width:

printf "%10s\n", "wilma";  # looks like ‘‘‘‘‘wilma

A negative field width is left-justified (in any of these conversions):

printf "%-15s\n", "flintstone";  # looks like flintstone ‘‘‘‘‘

The %f conversion (floating-point) rounds off its output as needed, and even lets you request a certain number of digits after the decimal point:

printf "%12f\n", 6 * 7 + 2/3;    # looks like ‘‘‘42.666667
printf "%12.3f\n", 6 * 7 + 2/3;  # looks like ‘‘‘‘‘‘42.667
printf "%12.0f\n", 6 * 7 + 2/3;  # looks like ‘‘‘‘‘‘‘‘‘‘43

To print a real percent sign, use %%, which is special in that it uses no element from the list:[161]

[161]Maybe you thought you could simply put a backslash in front of the percent sign. Nice try, but no. The reason that won't work is that the format is an expression, and the expression "\%" means the one-character string '%'. Even if we got a backslash into the format string, printf wouldn't know what to do with it. Besides, C programmers are used to printf working like this.

printf "Monthly interest rate: %.2f%%\n",
  5.25/12;  # the value looks like "0.44%"

6.5.1. Arrays and printf

Generally, you won't use an array as an argument to printf. That's because an array may hold any number of items, and a given format string will work with only a certain fixed number of items: if there are three conversions in the format, there must be exactly three items.

But there's no reason you can't whip up a format string on the fly, since it may be any expression. This can be tricky to get right, though, so it may be handy (especially when debugging) to store the format into a variable:

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

This uses the x operator (which we learned about in Chapter 2, "Scalar Data") to replicate the given string a number of times given by @items (which is being used in a scalar context). In this case, that's 3, since there are three items, so the resulting format string is the same as if we had written it as "The items are:\n%10s\n%10s\n%10s\n." And the output prints each item on its own line, right-justified in a ten-character column, under a heading line. Pretty cool, huh? But not cool enough, because you can even combine these:

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

Note that here we have @items being used once in a scalar context, to get its length, and once in a list context, to get its contents. Context is important.

Previous | Home | Next
6.4. Output to Standard Output | Book Index | 6.6. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.6. Exercises

See Section A.5, "Answers to Chapter 6 Exercises" for answers to the following exercises:

  1. [7] Write a program that acts like cat, but reverses the order of the output lines. (Some systems have a utility like this named tac.) If you run yours as ./tac fred barney betty, the output should be all of file betty from last line to first, then barney and then fred, also from last line to first. (Be sure to use the ./ in your program's invocation if you call it tac, so that you don't get the system's utility instead!)

  2. [8] Write a program that asks the user to enter a list of strings on separate lines, printing each string in a right-justified 20-character column. To be certain that the output is in the proper columns, print a "ruler line" of digits as well. (This is simply a debugging aid.) Make sure that you're not using a 19-character column by mistake! For example, entering hello, good-bye should give output something like this:

    123456789012345678901234567890123456789012345678901234567890
               hello
            good-bye

  3. [8] Modify the previous program to let the user choose the column width, so that entering 30, hello, good-bye (on separate lines) would put the strings at the 30th column. (Hint: see the section Section 2.6.1, "Interpolation of Scalar Variables into Strings" in Chapter 2, "Scalar Data" about controlling variable interpolation.) For extra credit, make the ruler line longer when the selected width is larger.

Previous | Home | Next
6.5. Formatted Output with printf | Book Index | 7. Concepts of Regular Expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 7. Concepts of Regular Expressions

Contents:

What Are Regular Expressions?
Using Simple Patterns
A Pattern Test Program
Exercises

Perl has many features that set it apart from other languages. Of all those features, one of the most important is its strong support for regular expressions. These allow fast, flexible, and reliable string handling.

But that power comes at a price. Regular expressions are actually tiny programs in their own special language, built inside Perl. (Yes, you're about to learn another programming language![162] Fortunately it's a simple one.) So for the next two chapters, we'll be learning that language; then we'll take what we've learned back to the world of Perl in Chapter 9, "Using Regular Expressions".

[162]Some might argue that regular expressions are not a complete programming language. We won't argue.

Regular expressions aren't merely part of Perl; they're also found in sed and awk, procmail, grep, most programmers' text editors like vi and emacs, and even in more esoteric places. If you've seen some of these already, you're ahead of the game. Keep watching, and you'll see many more tools that use or support regular expressions, such as search engines on the Web (often written in Perl), email clients, and others.

7.1. What Are Regular Expressions?

A regular expression, often called a pattern in Perl, is a template that either matches or doesn't match a given string.[163] That is, there are an infinite number of possible text strings; a given pattern divides that infinite set into two groups: the ones that match, and the ones that don't. There's never any kinda-sorta-almost-up-to-here wishy-washy matching: either it matches or it doesn't. A pattern may match just one possible string, or just two or three, or a dozen, or a hundred, or an infinite number. Or it may match all strings except for one, or except for some, or except for an infinite number.[164]

[163]Purists would ask for a more rigorous definition. But then again, purists say that Perl's patterns aren't really regular expressions. If you're serious about regular expressions, we highly recommend the book Mastering Regular Expressions by Jeffrey Friedl (O'Reilly & Associates, Inc.).

[164]And as we'll see, you could have a pattern that always matches or that never does. In rare cases, even these may be useful. Generally, though, they're mistakes.

We already referred to regular expressions as being little programs in their own simple programming language. It's a simple language because the programs have just one task: to look at a string and say "it matches" or "it doesn't match".[165] That's all they do.

[165]The programs also pass back some information that Perl can use later. One such piece of information is the "regular expressions memories" that we'll learn about a little later.

One of the places you're likely to have seen regular expressions is in the Unix grep command, which prints out text lines matching a given pattern. For example, if you wanted to see which lines in a given file mention flint and, somewhere later on the same line, stone, you might do something like this, with the Unix grep command:

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

Now, if you've used regular expressions somewhere else, that's good, because you have a head start on these three chapters. But Perl's regular expressions have somewhat different syntax than most other implementations; in fact, everybody's regular expressions are a little different. So, if you needed to use a backslash to do something in another implementation, maybe you'll need to leave it off in Perl, or maybe vice versa.

Don't confuse regular expressions with shell filename-matching patterns, called globs. A typical glob is what you use when you type *.pm to the Unix shell to match all filenames that end in .pm. Globs use a lot of the same characters that we use in regular expressions, but those characters are used in totally different ways.[166] We'll visit globs later, in Chapter 12, "Directory Operations", but for now try to put them totally out of your mind.

[166]Globs are also (alas) sometimes called patterns. What's worse, though, is that some bad Unix books for beginners (and possibly written by beginners) have taken to calling globs "regular expressions", which they certainly are not. This confuses many folks at the start of their work with Unix.

Previous | Home | Next
6.6. Exercises | Book Index | 7.2. Using Simple Patterns
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.2. Using Simple Patterns

To compare a pattern (regular expression) to the contents of $_, simply put the pattern between a pair of forward slashes (/), like we do here:

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

The expression /abba/ looks for that four-letter string in $_; if it finds it, it returns a true value. In this case, it's found more than once, but that doesn't make any difference. If it's found at all, it's a match; if it's not in there at all, it fails.

Because the pattern match is generally being used to return a true or false value, it is almost always found in the conditional expression of if or while.

All of the usual backslash escapes that you can put into double-quoted strings are available in patterns, so you could use the pattern /coke\tsprite/ to match the eleven characters of coke, a tab, and sprite.

7.2.1. About Metacharacters

Of course, if patterns matched only simple literal strings, they wouldn't be very useful. That's why there are a number of special characters, called metacharacters, that have special meanings in regular expressions.

For example, the dot (.) is a wildcard character -- it matches any single character except a newline (which is represented by "\n"). So, the pattern /bet.y/ would match betty. Or it would match betsy, or bet=y, or bet.y, or any other string that has bet, followed by any one character (except a newline), followed by y. It wouldn't match bety or betsey, though, since those don't have exactly one character between the t and the y. The dot always matches exactly one character.

So, if you wanted to match a period in the string, you could use the dot. But that would match any possible character (except a newline), which might be more than you wanted. If you wanted the dot to match just a period, you can simply backslash it. In fact, that rule goes for all of Perl's regular expression metacharacters: a backslash in front of any metacharacter makes it nonspecial. So, the pattern /3\.14159/ doesn't have a wildcard character.

So the backslash is our second metacharacter. If you mean a real backslash, just use a pair of them -- a rule that applies just as well everywhere else in Perl.

7.2.2. Simple Quantifiers

It often happens that you'll need to repeat something in a pattern. The star (*) means to match the preceding item zero or more times. So, /fred\t*barney/ matches any number of tab characters between fred and barney. That is, it matches "fred\tbarney" with one tab, or "fred\t\tbarney" with two tabs, or "fred\t\t\tbarney" with three tabs, or even "fredbarney" with nothing in between at all. That's because the star means "zero or more" -- so you could even have hundreds of tab characters in between, but nothing other than tabs. You may find it helpful to think of star as saying, "that previous thing, any number of times, even zero times."

What if you wanted to allow something besides tab characters? The dot matches any character[167], so .* will match any character, any number of times. That means that the pattern /fred.*barney/ matches "any old junk" between fred and barney. Any line that mentions fred and (somewhere later) barney will match that pattern. We often call .* the "any old junk" pattern, because it can match any old junk in your strings.

[167]Except newline. But we're going to stop reminding you of that so often, because you know it by now. Most of the time it doesn't matter, anyway, because your strings will most-often not have newlines. But don't forget this detail, because someday a newline will sneak into your string and you'll need to remember that the dot doesn't match newline.

The star is formally called a quantifier, meaning that it specifies a quantity of the preceding item. But it's not the only quantifier; the plus ("+") is another. The plus means to match the preceding item one or more times: /fred +barney/ matches if fred and barney are separated by spaces and only spaces. (The space is not a metacharacter.) This won't match fredbarney, since the plus means that there must be one or more spaces between the two names, so at least one space is required. It may be helpful to think of the plus as saying, "that last thing, plus any number more of the same thing."

There's a third quantifier like the star and plus, but more limited. It's the question mark ("?"), which means that the preceding item is optional. That is, the preceding item may occur once or not at all. Like the other two quantifiers, the question mark means that the preceding item appears a certain number of times. It's just that in this case the item may match one time (if it's there) or zero times (if it's not). There aren't any other possibilities. So, /bamm-?bamm/ matches either spelling: bamm-bamm or bammbamm. This is easy to remember, since it's saying "that last thing, maybe? Or maybe not?"

All three of these quantifiers must follow something, since they tell how many times the previous item may repeat.

7.2.3. Grouping in Patterns

As in mathematics, parentheses ("( )") may be used for grouping. So, parentheses are also metacharacters. As an example, the pattern /fred+/ matches strings like freddddddddd, but strings like that don't show up often in real life. But the pattern /(fred)+/ matches strings like fredfredfred, which is more likely to be what you wanted. And what about the pattern /(fred)*/? That matches strings like hello, world.[168]

[168]The star means to match zero or more repetitions of fred. When you're willing to settle for zero, it's hard to be disappointed! That pattern will match any string, even the empty string.

7.2.4. Alternatives

The vertical bar (|), often pronounced "or" in this usage, means that either the left side may match, or the right side. That is, if the part of the pattern on the left of the bar fails, the part on the right gets a chance to match. So, /fred|barney|betty/ will match any string that mentions fred, or barney, or betty.

Now we can make patterns like /fred( |\t)+barney/, which matches if fred and barney are separated by spaces, tabs, or a mixture of the two. The plus means to repeat one or more times; each time it repeats, the ( |\t) has the chance to match either a space or a tab.[169] There must be at least one character between the two names.

[169]This particular match would normally be done more efficiently with a character class, as we'll see in the next chapter.

If you wanted the characters between fred and barney to all be the same, you could rewrite that pattern as /fred( +|\t+)barney/. In this case, the separators must be all spaces, or all tabs.

The pattern /fred (and|or) barney/ matches any string containing either of the two possible strings: fred and barney, or fred or barney.[170] We could match the same two strings with the pattern /fred and barney|fred or barney/, but that would be too much typing. It would probably also be less efficient, depending upon what optimizations are built into the regular expression engine.

[170]Note that the words and and or are not operators in regular expressions! They are shown here in a fixed-width typeface because they're part of the strings.

Previous | Home | Next
7. Concepts of Regular Expressions | Book Index | 7.3. A Pattern Test Program
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.3. A Pattern Test Program

When in the course of Perl events it becomes necessary for a programmer to write a regular expression, it may be difficult to tell just what the pattern will do. It's normal to find that a pattern matches more than you expected, or less. Or it may match earlier in the string than you expected, or later, or not at all.

This program is useful to test out a pattern on some strings and see just what it matches, and where:

#!/usr/bin/perl
while (<>) {                        # take one input line at a time
  chomp;
  if (/YOUR_PATTERN_GOES_HERE/) {
    print "Matched: |$`<$&>$'|\n";  # Mystery code! See the text.
  } else {
    print "No match.\n";
  }
}

This pattern test program is written for programmers to use, not endusers; you can tell because it doesn't have any prompts or usage information. It will take any number of input lines and check each one against the pattern that you'll put in place of the string saying YOUR_PATTERN_GOES_HERE. For each line that matches, the line with "mystery code" will be run. We'll learn about what that line is really doing in Chapter 9, "Using Regular Expressions". But what you'll see is this: if the pattern is /match/ and the input is beforematchafter, the output will say "|before<match>after|", using angle brackets to show you just what part of the string was matched by your pattern. Try it and see! If you pattern matches something you didn't expect, you'll be able to see that right away.

Previous | Home | Next
7.2. Using Simple Patterns | Book Index | 7.4. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.4. Exercises

See Section A.6, "Answers to Chapter 7 Exercises" for answers to the following exercises:

Remember, it's normal to be surprised by some of the things that regular expressions do; that's one reason that the exercises in this chapter are even more important than the others. Expect the unexpected.

Several of these exercises ask you to use the test program from this chapter. You could manually type up this program, taking great care to get all of the odd punctuation marks correct.[171] But you'll probably find it faster and easier to simply download the program and some other goodies from the O'Reilly website, as we mentioned in the Preface. You'll find this program under the name pattern_test.[172]

[171]If you do type it up on your own, remember that the backtick character (`) is not the same as the apostrophe ('). On most full-sized computer keyboards these days (in the U.S., at least), the backtick is found on a key immediately to the left of the 1 key. Try out the program with the pattern /match/and the string beforematchafter, as the text describes, and see that it works correctly before you do the exercises.

[172]Don't be surprised if the program you download is a little fancier than what we have in the book. The commented-out extra features you see will come in handy in later exercises.

  1. [6] Use the test program to make and test a pattern that matches any string containing fred. Does it match if your string is Fred, frederick, or Alfred?

  2. [6] Use the test program to make and test a pattern that matches any string containing at least one a followed by any number of b's. Remember that "any number" might be zero. Does it match if your string is barney, fred, abba, or dinosaur?

  3. [5] Use the test program to make and test a pattern that matches any string containing any number of backslashes followed by any number of asterisks. Does it match if your string is \\**, fred, barney \\\***, or *wilma\? (Note the typography; those are four separate test strings.)

  4. [6] Write a new program (not the test program) that prints out any input line that mentions wilma. (Any other lines should simply be skipped.) For extra credit, allow it to match Wilma with a capital W as well.

  5. [8] Extra credit exercise: write a program that prints out any input line that mentions both wilma and fred.

Previous | Home | Next
7.3. A Pattern Test Program | Book Index | 8. More About Regular Expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 8. More About Regular Expressions

Contents:

Character Classes
General Quantifiers
Anchors
Memory Parentheses
Precedence
Exercises

In the previous chapter, we saw the beginnings of what regular expressions can do. Here we'll see some of their other common features.

8.1. Character Classes

A character class, a list of possible characters inside square brackets ([]), matches any single character from within the class. It matches just one single character, but that one character may be any of the ones listed.

For example, the character class [abcwxyz] may match any one of those seven characters. For convenience, you may specify a range of characters with a hyphen (-), so that class may also be written as [a-cw-z]. That didn't save much typing, but it's more usual to make a character class like [a-zA-Z], to match any one letter out of that set of 52.[173] You may use the same character shortcuts as in any double-quotish string to define a character, so the class [\000-\177] matches any seven-bit ASCII character.[174]

[173]Notice that those 52 don't include letters like Å and É and Î and Ø and Ü. But when Unicode processing is available, that particular character range is noticed and enhanced to automatically do the right thing.

[174]At least, if you use ASCII and not EBCDIC.

Of course, a character class will be just part of a full pattern; it will never stand on its own in Perl. For example, you might see code that says something like this:

$_ = "The HAL-9000 requires authorization to continue.";
if (/HAL-[0-9]+/) {
  print "The string mentions some model of HAL computer.\n";
}

Sometimes, it's easier to specify the characters left out, rather than the ones within the character class. A caret ("^") at the start of the character class negates it. That is, [^def] will match any single character except one of those three. And [^n\-z] matches any character except for n, hyphen, or z. (Note that the hyphen is backslashed, because it's special inside a character class. But the first hyphen in /HAL-[0-9]+/ doesn't need a backslash, because hyphens aren't special outside a character class.)

8.1.1. Character Class Shortcuts

Some character classes appear so frequently that they have shortcuts. For example, the character class for any digit, [0-9], may be abbreviated as \d . Thus, the pattern from the example about HAL could be written /HAL-\d+/ instead.

The shortcut \w is a so-called "word" character: [A-Za-z0-9_]. If your "words" are made up of ordinary letters, digits, and underscores, you'll be happy with this. Most of the rest of us have words made up of ordinary letters, hyphens, and apostrophes,[175] and we'd like to change this. As of this writing, the Perl developers are working on it, but it's not available yet.[176] So use this one only when you want ordinary letters, digits, and underscores.

[175]At least, in usual English we do. In other languages, you may have different components of words. And when looking at ASCII-encoded English text, we have the problem that the single quote and the apostrophe are the same character, so it's not possible in isolation to tell whether cats' is a word with an apostrophe or a word at the end of a quotation. This is probably one reason that computers haven't been able to take over the world yet.

[176]Except to a limited (but nevertheless useful) extent in connection with locales; see the perllocale manpage.

Of course, \w doesn't match a "word"; it merely matches a single "word" character. To match an entire word, though, the plus modifier is handy. A pattern like /fred \w+ barney/ will match fred and a space, then a "word", then a space and barney. That is, it'll match if there's one word[177] between fred and barney, set off by single spaces.

[177]We're going to stop saying "word" in quotes so much; you know by now that these letter-digit-underscore words are the ones we mean.

As you may have noticed in that previous example, it might be handy to be able to match spaces more flexibly. The \s shortcut is good for whitespace; it's the same as [\f\t\n\r ]. That is, it's the same as a class containing the five whitespace characters form-feed, tab, newline, carriage return, and the space character itself. These are the characters that merely move the printing position around; they don't use any ink. Still, like the other shortcuts we've just seen, \s matches just a single character from the class, so it's usual to use either \s* for any amount of whitespace (including none at all), or \s+ for one or more whitespace characters. (In fact, it's rare to see \s without one of those quantifiers.) Since all of those whitespace characters look about the same to us humans, we can treat them all in the same way with this shortcut.

8.1.2. Negating the Shortcuts

Sometimes you may want the opposite of one of these three shortcuts. That is, you may want [^\d], [^\w], or [^\s], meaning a nondigit character, a nonword character, or a nonwhitespace character. That's easy enough to accomplish by using their uppercase counterparts: \D, \W, or \S. These match any character that their counterpart would not match.

Any of these shortcuts will work either in place of a character class (standing on their own in a pattern), or inside the square brackets of a larger character class. That means that you could now use /[\dA-Fa-f]+/ to match hexadecimal (base 16) numbers, which use letters ABCDEF (or the same letters in lowercase) as additional digits.

Another compound character class is [\d\D], which means any digit, or any non-digit. That is to say, any character at all! This is a common way to match any character, even a newline. (As opposed to ., which matches any character except a newline.) And then there's the totally useless [^\d\D], which matches anything that's not either a digit or a non-digit. Right -- nothing!

Previous | Home | Next
7.4. Exercises | Book Index | 8.2. General Quantifiers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.2. General Quantifiers

A quantifier in a pattern means to repeat the preceding item a certain number of times. We've already seen three quantifiers: *, +, and ?. But if none of those three suits your needs, just use a comma-separated pair of numbers inside curly braces ({}) to specify exactly how few and how many repetitions are allowed.

So the pattern /a{5,15}/ will match from five to fifteen repetitions of the letter a. If the a appears three times, that's too few, so it won't match. If it appears five times, it's a match. If it appears ten times, that's still a match. If it appears twenty times, just the first fifteen will match, since that's the upper limit.

If you omit the second number (but include the comma), there's no upper limit to the number of times the item will match. So, /(fred){3,}/ will match if there are three or more instances of fred in a row (with no extra characters, like spaces, allowed between each fred and the next). There's no upper limit, so that would match eighty-eight instances of fred, if you had a string with that many.

If you omit the comma as well as the upper bound, the number given is an exact count: /\w{8}/ will match exactly eight word characters (occuring as part of a larger string, perhaps).

In fact, the three quantifier characters that we saw earlier are just common shortcuts. The star is the same as the quantifier {0,}, meaning zero or more. The plus is the same as {1,}, meaning one or more. And the question mark could be written as {0,1}. In practice, it's unusual to need any curly-brace quantifiers, since the three shortcut characters are nearly always the only ones needed.

Previous | Home | Next
8. More About Regular Expressions | Book Index | 8.3. Anchors
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.3. Anchors

By default, if a pattern doesn't match at the start of the string, it can "float" on down the string, trying to match somewhere else. But there are a number of anchors that may be used to hold the pattern at a particular point in a string.

The caret[178] anchor (^) marks the beginning of the string, while the dollar sign ($) marks the end.[179] So the pattern /^fred/ will match fred only at the start of the string; it wouldn't match manfred mann. And /rock$/ will match rock only at the end of the string; it wouldn't match knute rockne.

[178]Yes, you've seen that caret is already used in another way in patterns. As the first character of a character class, it negates the class. But outside of a character class, it's a metacharacter in a different way, being the start-of-string anchor. There are only so many characters, so we have to use some of them twice.

[179]Actually, it matches either the end of the string, or at a newline at the end of the string. That's so that you can match the end of the string whether it has a trailing newline or not. Most folks don't worry about this distinction much, but once in a long while it's important to remember that /^fred$/will match either "fred" or "fred\n" with equal ease.

Sometimes, you'll want to use both of these anchors, to ensure that the pattern matches an entire string. A common example is /^\s*$/, which matches a blank line. But this "blank" line may include some whitespace characters, like tabs and spaces, which are invisible to you and me. Any line that matches that pattern looks just like any other one on paper, so this pattern treats all blank lines as equivalent. Without the anchors, it would match nonblank lines as well.

8.3.1. Word Anchors

Anchors aren't just at the ends of the string. The word-boundary anchor, \b, matches at either end of a word.[180] So we can use /\bfred\b/ to match the word fred but not frederick or alfred or manfred mann. This is similar to the feature often called something like "match whole words only" in a word processor's search command.

[180]Some regular expression implementations have one anchor for start-of-word and another for end-of-word, but Perl uses \b for both.

Alas, these aren't words as you and I are likely to think of them; they're those \w-type words made up of ordinary letters, digits, and underscores. The \b anchor matches at the start or end of a group of \w characters.

In Figure 8-1, there's a grey underline under each "word," and the arrows show the corresponding places where \b could match. There are always an even number of word boundaries in a given string, since there's an end-of-word for every start-of-word.

The "words" are sequences of letters, digits, and underscores; that is, a word in this sense is what's matched by /\w+/. There are five words in that sentence: That, s, a, word, and boundary.[181] Notice that the quote marks around word don't change the word boundaries; these words are made of \w characters.

[181]You can see why we wish that we could change the definition of "word"; That's should be one word, not two words with an apostrophe in-between. And even in text that may be mostly ordinary English, it's normal to find a soupçon of other characters spicing things up.

Each arrow points to the beginning or the end of one of the grey underlines, since the word boundary anchor \b matches only at the beginning or the end of a group of word characters.

Figure 8-1. Word-boundary matches with \b

The word-boundary anchor is useful to ensure that we don't accidentally find cat in delicatessen, dog in boondoggle, or fish in selfishness. Sometimes you'll want just one word-boundary anchor, as when using /\bhunt/ to match words like hunt or hunting or hunter, but not shunt, or when using /stone\b/ to match words like sandstone or flintstone but not capstones.

The nonword-boundary anchor is \B; it matches at any point where \b would not match. So the pattern /\bsearch\B/ will match searches, searching, and searched, but not search or researching.

Previous | Home | Next
8.2. General Quantifiers | Book Index | 8.4. Memory Parentheses
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.4. Memory Parentheses

You remember that parentheses ("( )") may be used for grouping together parts of a pattern. They also have a second function: they tell the regular expression engine to remember what was in the substring matched by the pattern in the parentheses. That is to say, it doesn't remember what was in the pattern itself; it remembers what was in the corresponding part of the string. Whenever you use parentheses for grouping, they automatically work as memory parentheses as well.

So, if you use /./, you'll match any single character (except newline); if you use /(.)/, you'll still match any single character, but now it will be kept in a regular expression memory. For each pair of parentheses in the pattern, you'll have one regular expression memory.

8.4.1. Backreferences

A backreference refers back to a memory that was saved earlier in the current pattern's processing. Backreferences are made with a backslash, which is easy to remember. For example, \1 contains the first regular expression memory (that is, the part of the string matched by the first pair of parentheses).

Backreferences are used to go back and match the exact same[182] string that was matched earlier in the pattern. So, /(.)\1/ means to match any one character, remember it as memory one, then match memory one again. In other words, match any character, followed by the same character. So, this pattern will match strings with doubled-letters, as in bamm-bamm and betty. Of course, the dot will match characters other than letters, so if a string has two spaces in a row, two tabs in a row, or two asterisks in a row, it will match.

[182]Well, if the pattern is case-insensitive, as we'll learn in the next chapter, the capitalization doesn't have to match. Other than that, though, the string must be the same.

That's not the same as the pattern /../, which will match any character followed by any character -- those two could be the same, or they could be different. /(.)\1/ means to match any character followed by the same character.

A typical usage of these memories might be if you have some HTML-like[183] text to process. For example, maybe you want to match a tag like these two, which may use either single quotes or double quotes:

[183]These examples are intentionally not HTML, because there are too many tricky things that crop up in real HTML, or any similar markup language like XML or SGML. If you need to work with HTML, don't use simple patterns like these. Get a robust module from CPAN, so that you can start with code that's already written and debugged. If you don't, we promise that you'll be sorry. Don't say we didn't warn you.

<image source='fred.png'>
<image source="fred's-birthday.png">

The tag may have either single quotes or double quotes, since the quoted data may include the other kind of mark (as with the apostrophe in the second example tag). So the pattern might look like this: /<image source=(['"]).*\1>/. That says that the opening quote mark may be of either type, but there must be a matching mark at the end of the quote.[184]

[184]If you realize that there may be problems with using this pattern on a markup language like HTML, that's okay. There are lots of problems with that! This is just an example to illustrate a use of a backreference. You shouldn't use simple patterns to parse anything as complex as HTML anyway.

If you have more sets of parentheses, you can have more backreferences. As you might guess, \17 is the contents of the seventeenth regular expression memory, if you have at least that many sets of parentheses.[185]

[185]If you don't have that many sets of parentheses before that point in the pattern, backreferences \10 and beyond will be treated as octal character escapes. To keep an octal character escape like \12 from accidentally meaning a backreference, just use a leading zero: \012 is always a character, never a backreference.

In numbering backreferences, you can just count the left (opening) parentheses. The pattern/((fred|wilma) (flintstone)) \1/ says to match strings like fred flintstone fred flintstone, since the first opening parenthesis and its corresponding closing parenthesis hold a pattern that matches fred flintstone.[186]

[186]This pattern would also match wilma flintstone wilma flintstone.

If we wrote /((fred|wilma) (flintstone)) \2/ instead, we would match strings like fred flintstone fred; memory two is the choice of fred or wilma. (Notice that it wouldn't match fred flintsone wilma, since the backreference can match only the same name that was matched earlier: either fred or wilma. But it could match wilma flintstone wilma, since that one uses the same name.) And the pattern /((fred|wilma) (flintstone)) \3/ would match strings like fred flintstone flintstone. It's uncommon to have a literal string like flintstone in memory parentheses, though; we did that one just to have a third example.

8.4.2. Memory Variables

When we get to the next chapter and back into the world of Perl, we'll see that the contents of these regular expression memories are available to us in special variables like $1 after the pattern match is done. We mention this here just so you'll know that the memories aren't merely used for backreferences; if you see what seem to be unnecessary parentheses in a pattern, they may actually be setting up those memories.

Previous | Home | Next
8.3. Anchors | Book Index | 8.5. Precedence
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.5. Precedence

With all of these metacharacters in regular expressions, you may feel that you can't keep track of the players without a scorecard. That's the precedence chart, which shows us which parts of the pattern "stick together" the most tightly. Unlike the precedence chart for operators, the regular expression precedence chart is simple, with only four levels. As a bonus, this section will review all of the metacharacters that Perl uses in patterns.

  1. At the top of the precedence chart are the parentheses, ("( )"), used for grouping and memory. Anything in parentheses will "stick together" more tightly than anything else.

  2. The second level is the quantifiers. These are the repeat operators -- star (*), plus (+), and question mark (?) -- as well as the quantifiers made with curly braces, like {5,15}, {3,}, and {5}. These always stick to the item they're following.

  3. The third level of the precedence chart holds anchors and sequence. The anchors are the caret (^) start-of-string anchor, the dollar-sign ($) end-of-string anchor, the \b word-boundary anchor, and the \B nonword-boundary anchor. Sequence (putting one item after another) is actually an operator, even though it doesn't use a metacharacter. That means that letters in a word will stick together just as tightly as the anchors stick to the letters.

  4. The lowest level of precedence is the vertical bar (|) of alternation. Since this is at the bottom of the chart, it effectively cuts the pattern into pieces. It's at the bottom of the chart because we want the letters in the words in /fred|barney/ to stick together more tightly than the alternation. If alternation were higher priority than sequence, that pattern would mean to match fre, followed by a choice of d or b, followed by arney. So, alternation is at the bottom of the chart, and the letters within the names stick together.

Besides the precedence chart, there are the so-called atoms that make up the most basic pieces of the pattern. These are the individual characters, character classes, and backreferences.

8.5.1. Examples of Precedence

When you need to decipher a complex regular expression, you'll need to do as Perl does, and use the precedence chart to see what's really going on.

For example, /^fred|barney$/ is probably not what the programmer intended. That's because the vertical bar of alternation is very low precedence; it cuts the pattern in two. That pattern matches either fred at the beginning of the string or barney at the end. It's much more likely that the programmer wanted /^(fred|barney)$/, which will match if the whole line has nothing but fred, or nothing but barney.[187]

[187]And, perhaps, a newline at the end of the string, as we mentioned earlier in connection with the $ anchor.

And what will /(wilma|pebbles?)/ match? The question mark applies to the previous character,[188] so that will match either wilma or pebbles or pebble, perhaps as part of a larger string (since there are no anchors).

[188]Because a quantifier sticks to the letter s more tightly than the s sticks to the other letters in pebbles.

The pattern /^(\w+)\s+(\w+)$/ matches lines that have a "word," some required whitespace, and another "word," with nothing else before or after. That might be used to match lines like fred flintstone, for example. The parentheses around the words aren't needed for grouping, so they may be intended to save those substrings into the regular expression memories, which we'll see more about in the next chapter.

When you're trying to understand a complex pattern, it may be helpful to add parentheses to clarify the precedence. That's okay, but remember that grouping parentheses are also automatically memory parentheses; you may need to change the numbering of other memories when you add the parentheses.[189]

[189]But look in the perlre manpage for information about nonmemory parentheses, which are used for grouping without memory.

8.5.2. And There's More

Although we've covered all of the regular expression features that most people are likely to need for everyday programming, there are more features being added all the time. Check the perlre, perlrequick, and perlretut manpages for the latest news about what patterns in Perl can do.[190]

[190]And check out YAPE::Regexp::Explain in CPAN as a regular-expression-to-English translator.

Previous | Home | Next
8.4. Memory Parentheses | Book Index | 8.6. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.6. Exercises

See Section A.7, "Answers to Chapter 8 Exercises" for answers to the following exercises. These exercises are among the most challenging in the entire book. But don't get too discouraged! The following chapters will actually be easier, partly because you'll have the power of regular expressions to help you.

  1. [4] Using the test program from the previous chapter, make a pattern that matches only lines containing either the word fred or wilma, followed by some whitespace, and then the word flintstone. So it should match the string I am fred flintstone (with one or more spaces or tabs between the names).

  2. [10] Here, we give you the answer; you decide what problem it's trying to solve. What do these real-world patterns match? What might they be used for?

    /"([^"]*)"/
/^0?[0-3]?[0-7]{1,2}$/
/^\b[\w.]{1,12}\b$/

    Try each of them in the test program. It may help to find some strings that match (and that fail to match) each one.

  3. [8] Make a pattern that will match a string containing nothing but a scalar variable's name (not its value!), like $fred, $barney, or $_ (but you shouldn't match special variables like $0). That is, if the line of input has the six characters $wilma, the pattern should match. If the input says wilma, it should not match.

  4. [12] Make a pattern that matches any line of input that has the same word repeated two or more times in a row. Words in this problem can be considered to be sequences of letters a to z or A to Z, digits, and underscores. Whitespace between words may differ. For example, the classic observation-test string Paris in the the spring should match, since it has a doubled word. Also, I thought that that was the problem should match, even though that may be a correct use of a doubled word. Does your pattern match all three words in I thought that that that was the problem (with extra spaces between only some of the words)? Does it match This is a test? How about This shouldn't match, according to the theory of regular expressions?

Previous | Home | Next
8.5. Precedence | Book Index | 9. Using Regular Expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 9. Using Regular Expressions

Contents:

Matches with m//
Option Modifiers
The Binding Operator, =~
Interpolating into Patterns
The Match Variables
Substitutions with s///
The split Operator
The join Function
Exercises

Now that we've seen what goes inside a regular expression, let's take what we've learned back into Perl.

9.1. Matches with m//

We've been writing patterns in pairs of forward slashes, like /fred/. But this is actually a shortcut for the m// (pattern match) operator. As we saw with the qw// operator, you may choose any pair of delimiters to quote the contents. So, we could write that same expression as m(fred), m<fred>, m{fred}, or m[fred] using those paired delimiters, or as m,fred,, m!fred!, m^fred^, or many other ways using nonpaired delimiters.[191]

[191]Nonpaired delimiters are the ones that don't have a different "left" and "right" variety; the same punctuation mark is used for both ends.

The shortcut is that if you choose the forward slash as the delimiter, you may omit the initial m. Since Perl folks love to avoid typing extra characters, you'll see most pattern matches written using slashes, as in /fred/.

Of course, you should wisely choose a delimiter that doesn't appear in your pattern.[192] If you wanted to make a pattern to match the beginning of an ordinary web URL, you might start to write /^http:\/\// to match the initial "http://". But that's easier to read, write, maintain, and debug if you use a better choice of delimiter: m%^http://%.[193]

[192]If you're using paired delimiters, you shouldn't generally have to worry about using the delimiter inside the pattern, since that delimiter will generally be paired inside your pattern. That is, m(fred(.*)barney) and m{\w{2,}} and m[wilma[\n \t]+betty] are all fine, even though the pattern contains the quoting character, since each "left" has a corresponding "right". But the angle brackets ("<" and ">") aren't regular expression metacharacters, so they may not be paired; if the pattern were m{(\d+)\s*>=?\s*(\d+)}, quoting it with angle brackets would mean having to backslash the greater-than sign so that it wouldn't prematurely end the pattern.

[193]Remember, the forward slash is not a metacharacter, so it doesn't need to be backslashed when it's not the delimiter.

It's common to use curly braces as the delimiter. If you use a programmers' text editor, it probably has the ability to jump from an opening curly brace to the corresponding closing one, which can be handy in maintaining code.

Previous | Home | Next
8.6. Exercises | Book Index | 9.2. Option Modifiers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.2. Option Modifiers

There are several option modifier letters, sometimes called flags, which may be appended as a group right after the ending delimiter of a regular expression to change its behavior from the default.

9.2.1. Case-insensitive Matching with /i

To make a case-insensitive pattern match, so that you can match FRED as easily as fred or Fred, use the /i modifier:

print "Would you like to play a game? ";
chomp($_ = <STDIN>);
if (/\byes\b/i) {  # case-insensitive match
  print "In that case, I recommend that you go bowling.\n";
}

9.2.2. Matching Any Character with /s

Do you ever feel frustrated that the dot (.) won't match newline? If you might have newlines in your strings, and you want the dot to be able to match them, the /s modifier will do the job. It changes every dot[194] in the pattern to act like the character class [\d\D] does, which is to match any character, even if it is a newline. Of course, you have to have a string with newlines for this to make a difference:

[194]If you wish to change just some of them, and not all, you'll probably want to replace just those few with [\d\D].

$_ = "I saw Barney\ndown at the bowling alley\nwith Fred\nlast night.\n";
if (/\bBarney\b.*\bFred\b/s) {
  print "That string mentions Fred after Barney!\n";
}

Without the /s modifier, that match would fail, since the two names aren't on the same line.

9.2.3. Combining Option Modifiers

If you have more than one option modifier to use on the same pattern, they may be used one after the other; their order isn't significant:

if (/\bbarney\b.*\bfred\b/si) {  # both /s and /i
  print "That string mentions Fred after Barney!\n";
}

9.2.4. Other Options

There are many other option modifiers available. We'll cover those as we get to them, or you can read about them in the perlop manpage and in the descriptions of m// and the other regular expression operators that we'll see later in this chapter.

Previous | Home | Next
9. Using Regular Expressions | Book Index | 9.3. The Binding Operator, =~
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.3. The Binding Operator, =~

Matching against $_ is merely the default; the binding operator (=~) tells Perl to match the pattern on the right against the string on the left, instead of matching against $_.[195] For example:

[195]The binding operator is also used with some other operations besides the pattern match, as we'll see later.

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

The first time you see it, the binding operator looks like some kind of assignment operator. But it's no such thing! It is simply saying, "this pattern match which would attach to $_ by default -- make it work with this string on the left instead." If there's no binding operator, the expression is using $_ by default.

In the (somewhat unusual) example below, $likes_perl is set to a Boolean value according to what the user typed at the prompt. This is a little on the quick-and-dirty side, because the line of input itself is discarded. This code reads the line of input, tests that string against the pattern, then discards the line of input.[196] It doesn't use or change $_ at all.

[196]Remember, the line of input is not automatically stored into $_unless the line-input operator (<STDIN>) is all alone in the conditional expression of a while loop.

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";
  ...
}

The parentheses around the pattern-test expression aren't required, so the following line does the same thing as the one above -- it stores the result of the test (and not the line of input) into the variable:

my $likes_perl = <STDIN> =~ /\byes\b/i;
Previous | Home | Next
9.2. Option Modifiers | Book Index | 9.4. Interpolating into Patterns
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.4. Interpolating into Patterns

The regular expression is double-quote interpolated, just as if it were a double-quoted string. This allows us to write a quick grep-like program like this:

#!/usr/bin/perl -w
my $what = "larry";

while (<>) {
  if (/^($what)/) {  # pattern is anchored at beginning of string
    print "We saw $what in beginning of $_";
  }
}

The pattern will be built up out of whatever's in $what when we run the pattern match. In this case, it's the same as if we had written /^(larry)/, looking for larry at the start of each line.

But we didn't have to get the value of $what from a literal string; we could have gotten it instead from the command-line arguments in @ARGV:

my $what = shift @ARGV;

Now, if the first command-line argument were fred|barney, the pattern becomes /^(fred|barney)/, looking for fred or barney at the start of each line.[197] The parentheses (which weren't really necessary when searching for larry) are important, now, because without them we'd be matching fred at the start or barney anywhere in the string.

[197]The astute reader will know that you can't generally type fred|barney as an argument at the command line because the vertical bar is a shell metacharacter. See the documentation to your shell to learn about how to quote command-line arguments.

With that line changed to get the pattern from @ARGV, this program resembles the Unix grep command. But we have to watch out for metacharacters in the string. If $what contains 'fred(barney', the pattern would look like /^(fred(barney)/, and you know that can't work right -- it'll crash your program with an invalid regular expression error. With some advanced techniques,[198] you can trap this kind of error (or prevent the magic of the metacharacters in the first place) so that it won't crash your program. But for now, just know that if you give your users the power of regular expressions, they'll also need the responsibility to use them correctly.

[198]In this case, you would use an eval block to trap the error, or you would quote the interpolated text using quotemeta (or its \Q equivalent form) so that it's no longer treated as a regular expression.

Previous | Home | Next
9.3. The Binding Operator, =~ | Book Index | 9.5. The Match Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.5. The Match Variables

Do you remember the regular expression memories, which we used with backreferences in the previous chapter? Those memories are also available after the pattern match is done, after we return to Perl. They're strings, so they are kept in scalar variables with names like $1 and $2. There are as many of these variables as there are pairs of memory parentheses in the pattern. As you'd expect, $4 means the string matched by the fourth set of parentheses. This is the same string that \4 referred to inside the pattern match.

Why are there two different ways to refer to that same string? They're not really referring to the same string at the same time; $4 means the fourth memory of an already completed pattern match, while \4 is a backreference referring back to the fourth memory of the currently matching regular expression. Besides, backreferences work inside regular expressions only; once we're back in the world of Perl, we'll use $4.

These match variables are a big part of the power of regular expressions, because they let us pull out the parts of a string:

$_ = "Hello there, neighbor";
if (/\s(\w+),/) {             # memorize the word between space and comma
  print "the word was $1\n";  # the word was there
}

Or you could use more than one memory at once:

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

That tells us that the words were Hello there neighbor. Notice that there's no comma in the output (because the comma is outside of the memory parentheses). That leaves the comma out of memory two. Using this technique, we can choose exactly what we want in the memories, as well as what we want to leave out.

You could even have an empty match variable,[199] if that part of the pattern might be empty. That is, a match variable may contain the empty string:

[199]As opposed to an undefined one. If you have three or fewer sets of parentheses in the pattern, $4 will be undef.

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
}

9.5.1. The Persistence of Memory

These match variables generally stay around until the next successful pattern match.[200] That is, an unsuccessful match leaves the previous memories intact, but a successful one resets them all. But this correctly implies that you shouldn't use these match variables unless the match succeeded; otherwise, you could be seeing a memory from some previous pattern. The following (bad) example is supposed to print a word matched from $_. But if the match fails, it's using whatever leftover string happens to be found in $1:

[200]The actual scoping rule is much more complex (see the documentation if you need it), but as long as you don't expect the match variables to be untouched many lines after a pattern match, you shouldn't have problems.

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

This is another reason that a pattern match is almost always found in the conditional expression of an if or while:

if ($wilma =~ /(\w+)/) {
  print "Wilma's word was $1.\n";
} else {
  print "Wilma doesn't have a word.\n";
}

Since these memories don't stay around forever, you shouldn't use a match variable like $1 more than a few lines after its pattern match. If your maintenance programmer adds a new regular expression between your regular expression and your use of $1, you'll be getting the value of $1 for the second match, rather than the first. For this reason, if you need a memory for more than a few lines, it's generally best to copy it into an ordinary variable. Doing this helps make the code more readable at the same time:

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

Later, in Chapter 14, "Process Management", we'll see how to get the memory value directly into the variable at the same time as the pattern match happens, without having to use $1 explicitly.

9.5.2. The Automatic Match Variables

There are three more match variables that you get for free,[201] whether the pattern has memory parentheses or not. That's the good news; the bad news is that these variables have weird names.

[201]Yeah, right. There's no such thing as a free match. These are "free" only in the sense that they don't require match parentheses. Don't worry; we'll mention their real cost a little later, though.

Now, Larry probably would have been happy enough to call these by slightly-less-weird names, like perhaps $gazoo or $ozmodiar. But those are names that you just might want to use in your own code. To keep ordinary Perl programmers from having to memorize the names of all of Perl's special variables before choosing their first variable names in their first programs,[202] Larry has given strange names to many of Perl's builtin variables, names that "break the rules." In this case, the names are punctuation marks: $&, $`, and $'. They're strange, ugly, and weird, but those are their names.[203]

[202]You should still avoid a few classical variable names like $ARGV, but these few are all in all-caps. All of Perl's builtin variables are documented in the perlvar manpage.

[203]If you really can't stand these names, check out the English module, which attempts to give all of Perl's strangest variables nearly normal names. But the use of this module has never really caught on; instead, Perl programmers have grown to love the punctuation-mark variable names, strange as they are.

The part of the string that actually matched the pattern is automatically stored in $&:

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

That tells us that the part that matched was " there," (with a space, a word, and a comma). Memory one, in $1, has just the five-letter word there, but $& has the entire matched section.

Whatever came before the matched section is in $`, and whatever was after it is in $'. Another way to say that is that $` holds whatever the regular expression engine had to skip over before it found the match, and $' has the remainder of the string that the pattern never got to. If you glue these three strings together in order, you'll always get back the original string:

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

The message shows the string as (Hello)( there,)( neighbor), showing the three automatic match variables in action. This may seem familiar, and for good reason: These automatic memory variables are what the pattern test program (from Chapter 7, "Concepts of Regular Expressions") was using in its line of "mystery" code, to show what part of the string was being matched by the pattern:

print "Matched: |$`<$&>$'|\n";  # The three automatic match variables

Any or all of these three automatic match variables may be empty, of course, just like the numbered match variables. And they have the same scope as the numbered match variables. Generally, that means that they'll stay around until the next successful pattern match.

Now, we said earlier that these three are "free." Well, freedom has its price. In this case, the price is that once you use any one of these automatic match variables anywhere in your entire program, other regular expressions will run a little more slowly. Now, this isn't a giant slowdown, but it's enough of a worry that many Perl programmers will simply never use these automatic match variables.[204] Instead, they'll use a workaround. For example, if the only one you need is $&, just put parentheses around the whole pattern and use $1 instead (you may need to renumber the pattern's memories, of course).

[204]Most of these folks haven't actually benchmarked their programs to see whether their workarounds actually save time, though; it's as though these variables were poisonous or something. But we can't blame them for not benchmarking -- many programs that could benefit from these three variables take up only a few minutes of CPU time in a week, so benchmarking and optimizing would be a waste of time. But in that case, why fear a possible extra millisecond? By the way, the Perl developers are working on this problem, but there will probably be no solution before Perl 6.

Match variables (both the automatic ones and the numbered ones) are most often used in substitutions, which are the topic of the next section.

Previous | Home | Next
9.4. Interpolating into Patterns | Book Index | 9.6. Substitutions with s///
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.6. Substitutions with s///

If you think of the m// pattern match as being like your word processor's "search" feature, the "search and replace" feature would have to be Perl's s/// substitution operator. This simply replaces whatever part of a variable[205] matches a pattern with a replacement string:

[205]Unlike m//, which can match against any string expression, s/// is modifying data that must therefore be contained in what's known as an lvalue. This is nearly always a variable, although it could actually be anything that could be used on the left side of an assignment operator.

$_ = "He's out bowling with Barney tonight.";
s/Barney/Fred/;  # Replace Barney with Fred
print "$_\n";

If the match fails, nothing happens, and the variable is untouched:

# Continuing from above; $_ has "He's out bowling with Fred tonight."
s/Wilma/Betty/;  # Replace Wilma with Betty (fails)

Of course, both the pattern and the replacement string could be more complex. Here, the replacement string uses the first memory variable, which is set by the pattern match:

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

Here are some other possible substitutions. (These are here only as samples; in the real world, it would not be typical to do so many unrelated substitutions in a row.)

$_ = "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"

There's a return value from s///; it's true if a substitution was successful; otherwise it's false:

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

9.6.1. Global Replacements with /g

As you may have noticed in a previous example, s/// will make just one replacement, even if others are possible. Of course, that's just the default. The /g modifier tells s/// to make all possible nonoverlapping[206] replacements:

[206]It's nonoverlapping because each new match starts looking just beyond the latest replacement.

$_ = "home, sweet home!";
s/home/cave/g;
print "$_\n";  # "cave, sweet cave!"

A fairly common use of a global replacement is to collapse whitespace; that is, to turn any arbitrary whitespace into a single space:

$_ = "Input  data\t may have    extra whitespace.";
s/\s+/ /g;  # Now it says "Input data may have extra whitespace."

Once we show collapsing whitespace, everyone wants to know about stripping leading and trailing whitespace. That's easy enough, in two steps:[207]

[207]It could be done in one step, but this way is better.

s/^\s+//;  # Replace leading whitespace with nothing
s/\s+$//;  # Replace trailing whitespace with nothing

9.6.2. Different Delimiters

Just as we did with m// and qw//, we can change the delimiters for s///. But the substitution uses three delimiter characters, so things are a little different.

With ordinary (non-paired) characters, which don't have a left and right variety, just use three of them, as we did with the forward slash. Here, we've chosen the pound sign[208] aSs the delimiter:

[208]With apologies to our British friends, to whom the pound sign is something else! Although the pound sign is generally the start of a comment in Perl, it won't start a comment when the parser knows to expect a delimiter -- in this case, immediately after the s that starts the substitution.

s#^https://#http://#;

But if you use paired characters, which have a left and right variety, you have to use two pairs: one to hold the pattern and one to hold the replacement string. In this case, the delimiters don't have to be the same kind around the string as they are around the pattern. In fact, the delimiters of the string could even be non-paired. These are all the same:

s{fred}{barney};
s[fred](barney);
s<fred>#barney#;

9.6.3. Option Modifiers

In addition to the /g modifier,[209] substitutions may use the /i and /s modifiers that we saw in ordinary pattern matching. The order of modifiers isn't significant.

[209]We speak of the modifiers with names like "/i" , even if the delimiter is something different than a slash.

s#wilma#Wilma#gi;  # replace every WiLmA or WILMA with Wilma
s{__END_  _.*}{}s;   # chop off the end marker and all following lines

9.6.4. The Binding Operator

Just as we saw with m//, we can choose a different target for s/// by using the binding operator:

$file_name =~ s#^.*/##s;  # In $file_name, remove any Unix-style path

9.6.5. Case Shifting

It often happens in a substitution that you'll want to make sure that a replacement word is properly capitalized (or not, as the case may be). That's easy to accomplish with Perl, by using some backslash escapes. The \U escape forces what follows to all uppercase:

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

Similarly, the \L escape forces lowercase. Continuing from the previous code:

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

By default, these affect the rest of the (replacement) string; or you can turn off case shifting with \E:

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

When written in lowercase (\l and \u), they affect only the next character:

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

You can even stack them up. Using \u with \L means "all lower case, but capitalize the first letter":[210]

[210]The \L and \u may appear together in either order. Larry realized that people would sometimes get those two backwards, so he made Perl figure out that you want just the first letter capitalized and the rest lowercase. Larry is a pretty nice guy.

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

As it happens, although we're covering case shifting in relation to substitutions, it's available in any double-quotish string:

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

Previous | Home | Next
9.5. The Match Variables | Book Index | 9.7. The split Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.7. The split Operator

Another operator that uses regular expressions is split, which breaks up a string according to a separator. This is useful for tab-separated data, or colon-separated, whitespace-separated, or anything-separated data, really.[211] So long as you can specify the separator with a regular expression (and generally, it's a simple regular expression), you can use split. It looks like this:

[211]Except "comma-separated values," normally called CSV files. Those are a pain to do with split; you're better off getting the Text::CSV module from CPAN.

@fields = split /separator/, $string;

The split operator[212] drags the pattern through a string and returns a list of fields (substrings) that were separated by the separators. Whenever the pattern matches, that's the end of one field and the start of the next. So, anything that matches the pattern will never show up in the returned fields. Here's a typical split pattern, splitting on colons:

[212]It's an operator, even though it acts a lot like a function, and everyone generally calls it a function. But the technical details of the difference are beyond the scope of this book.

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

You could even have an empty field, if there were two delimiters together:

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

Here's a rule that seems odd at first, but it rarely causes problems: Leading empty fields are always returned, but trailing empty fields are discarded:[213]

[213]This is merely the default. It's this way for efficiency. If you worry about losing trailing empty fields, use -1 as a third argument to split and they'll be kept; see the perlfunc manpage.

@fields = split /:/, ":::a:b:c:::";  # gives ("", "", "", "a", "b", "c")

It's also common to split on whitespace, using /\s+/ as the pattern. Under that pattern, all whitespace runs are equivalent to a single space:

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

The default for split is to break up $_ on whitespace:

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

This is almost the same as using /\s+/ as the pattern, except that a leading empty field is suppressed -- so, if the line starts with whitespace, you won't see an empty field at the start of the list. (If you'd like to get the same behavior when splitting another string on whitespace, just use a single space in place of the pattern: split ' ', $other_string. Using a space instead of the pattern is a special kind of split.)

Generally, the patterns used for split are as simple as the ones you see here. But if the pattern becomes more complex, be sure to avoid using memory parentheses in the pattern; see the perlfunc manpage for more information.[214]

[214]And you might want to check out the nonmemory grouping-only parenthesis notation as well, in the perlre manpage.

Previous | Home | Next
9.6. Substitutions with s/// | Book Index | 9.8. The join Function
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.8. The join Function

The join function doesn't use patterns. So why is it in this chapter? It's here because, in a sense, join performs the opposite function of split: split breaks up a string into a number of pieces, and join glues together a bunch of pieces to make a single string. The join function looks like this:

my $result = join $glue, @pieces;

The first argument to join is the glue, which may be any string. The remaining arguments are a list of pieces. join puts the glue string between the pieces and returns the resulting string:

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

In that example, we had five items, so there are only four colons. That is, there are four pieces of glue. The glue shows up only between the pieces, never before or after them. So, there will be one fewer piece of glue than the number of items in the list.

This means that there may be no glue at all, if the list doesn't have at least two elements:

my $y = join "foo", "bar";       # gives just "bar", since no fooglue is needed
my @empty;                       # empty array
my $empty = join "baz", @empty;  # no items, so it's an empty string

Using $x from above, we can break up a string and put it back together with a different delimiter:

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

Although split and join work well together, don't forget that the first argument to join is always a string, not a pattern.

Previous | Home | Next
9.7. The split Operator | Book Index | 9.9. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.9. Exercises

See Section A.8, "Answers to Chapter 9 Exercises" for answers to the following exercises:

  1. [7] Make a pattern that will match three consecutive copies of whatever is currently contained in $what. That is, if $what is fred, your pattern should match fredfredfred. If $what is fred|barney, your pattern should match fredfredbarney or barneyfredfred or barneybarneybarney or many other variations. (Hint: You should set $what at the top of the pattern test program with a statement like my $what = 'fred|barney';.)

  2. [15] Write a program that looks through the perlfunc.pod file for lines that start with =item and some whitespace, followed by a Perl identifier name (made of letters, digits, and underscores, but never starting with a digit), like the lines below. (There may be more text on the line after the identifier name; just ignore it.) You can locate the perlfunc.pod file on your system with the command perldoc -l perlfunc, or ask your local expert. (Hint: You'll need the diamond operator to open this file. How will it get the filename?) Have the program print each identifier name as it finds it; there will be hundreds of them, and many will appear more than once in the file.

    As an example, the following lines of input resemble what you'll find in perlfunc.pod. For the first line, the program should print wilma. For the second, it should print fred (ignoring the word flintstone, since we're interested only in the identifier name):

    =item wilma
=item fred flintstone

  3. [10] Modify the previous program to list only the identifier names that appear more than twice on those =item lines, and tell how many times each one appeared. (That is, we want to know which identifier names appear on at least three separate =item lines in the file.) There should be a couple of dozen, depending upon your version of Perl.

Previous | Home | Next
9.8. The join Function | Book Index | 10. More Control Structures
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 10. More Control Structures

Contents:

The unless Control Structure
The until Control Structure
Expression Modifiers
The Naked Block Control Structure
The elsif Clause
Autoincrement and Autodecrement
The for Control Structure
Loop Controls
Logical Operators
Exercise

In this chapter, we'll see some alternative ways to write Perl code. For the most part, these techniques don't make the language more powerful, but they make it easier or more convenient to get the job done. You don't have to use these techniques in your own code, but don't be tempted to skip this chapter -- you're certain to see these control structures in other people's code, sooner or later (in fact, you're absolutely certain to see these things in use by the time you finish reading this book).

10.1. The unless Control Structure

In an if control structure, the block of code is executed only when the conditional expression is true. If you want a block of code to be executed only when the conditional is false, change if to unless :

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

Using unless says to run the block of code unless this condition is true. It's just like using an if test with the opposite condition. Another way to say it is that it's like having the else clause on its own. That is, whenever you see an unless that you don't understand, you can rewrite it (either in your head or in reality) to be an if test:

if ($fred =~ /^[A-Z_]\w*$/i) {
  # Do nothing
} else {
  print "The value of \$fred doesn't look like a Perl identifier name.\n";
}

It's no more or less efficient, and it should compile to the same internal byte codes. Or, another way to rewrite it would be to negate the conditional expression by using the negation operator (!):

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

Generally, you should pick the way of writing code that makes the most sense to you, since that will probably make the most sense to your maintenance programmer. If it makes the most sense to write if with a negation, do that. More often, however, you'll probably find it natural to use unless.

10.1.1. The else Clause with unless

You could even have an else clause with an unless. While this syntax is supported, it's potentially confusing:

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

Some people may wish to use this, especially when the first clause is very short (perhaps only one line) and the second is several lines of code. But we'd make this one a negated if, or maybe simply swap the clauses to make a normal if:

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

It's important to remember that you're always writing code for two readers: the computer that will run the code and the human being who has to keep the code working. If the human can't understand what you've written, pretty soon the computer won't be doing the right thing either.

Previous | Home | Next
9.9. Exercises | Book Index | 10.2. The until Control Structure
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.2. The until Control Structure

Sometimes you'll want to reverse the condition of a while loop. To do that, just use until:

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

This loop runs until the conditional expression returns true. But it's really just a while loop in disguise, except that this one repeats as long as the conditional is false, rather than true. The conditional expression is evaluated before the first iteration, so this is still a zero-or-more-times loop, just like the while loop.[215]

[215]Pascal programmers, take note: in Pascal, the repeat-until always runs at least one iteration, but an until loop in Perl may not run at all, if the conditional expression is true before the loop starts.

As with if and unless, you could rewrite any until loop to become a while loop by negating the condition. But generally, you'll find it simple and natural to use until from time to time.

Previous | Home | Next
10. More Control Structures | Book Index | 10.3. Expression Modifiers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.3. Expression Modifiers

In order to have a more compact notation, an expression may be followed by a modifier that controls it. For example, the if modifier works in a way analogous to an if block:

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

That gives exactly the same result as if we had used this code, except that we saved some typing by leaving out the parentheses and curly braces:[216]

[216]We also left out the line breaks. But we should mention that the curly-brace form does create a new scope. In the rare case that you need the full details, check the documentation.

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

As we've said, Perl folks generally like to avoid typing. And the shorter form reads like in English: print this message, if $n is less than zero.

Notice that the conditional expression is still evaluated first, even though it's written at the end. This is backwards from the usual left-to-right ordering; in understanding Perl code, we'll have to do as Perl's internal compiler does, and read to the end of the statement before we can tell what it's really doing.

There are other modifiers as well:

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

These all work just as (we hope) you would expect. That is, each one could be rewritten in a similar way to rewriting the if-modifier example earlier. Here is one:

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

The expression in parentheses inside the print argument list is noteworthy because it adds two to $n, storing the result back into $n. Then it returns that new value, which will be printed.

These shorter forms read almost like a natural language: call the &greet subroutine for each @person in the list. Double $i until it's larger than $j.[217]

[217]Well, it helps us to think of them like that.

One of the common uses of these modifiers is in a statement like this one:

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

By writing the code "in reverse" like this, you can put the important part of the statement at the beginning. The point of that statement is to monitor some variables; the point is not to check whether you're curious.[218] Some people prefer to write the whole statement on one line, perhaps with some tab characters before the if, to move it over toward the right margin, as we showed in the previous example, while others put the if modifier indented on a new line:

[218]Of course, we made up the name $I_am_curious; it's not a builtin Perl variable. Generally, folks who use this technique will either call their variable $TRACING, or will use a constant declared with the constant pragma.

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

Although you can rewrite any of these expressions with modifiers as a block (the "old-fashioned" way), the converse isn't necessarily true. Only a single expression is allowed on either side of the modifier. So you can't write something if something while something until something unless something foreach something, which would just be too confusing. And you can't put multiple statements on the left of the modifier. If you need more than just a simple expression on each side, just write the code the old-fashioned way, with the parentheses and curly braces.

As we mentioned in relation to the if modifier, the control expression (on the right) is always evaluated first, just as it would be in the old-fashioned form.

With the foreach modifier, there's no way to choose a different control variable -- it's always $_. Usually, that's no problem, but if you want to use a different variable, you'll need to rewrite it as a traditional foreach loop.

Previous | Home | Next
10.2. The until Control Structure | Book Index | 10.4. The Naked Block Control Structure
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.4. The Naked Block Control Structure

The so-called "naked" block is one without a keyword or condition. That is, suppose you start with a while loop, which looks something like this:

while (condition) {
  body;
  body;
  body;
}

Now, take away the while keyword and the conditional expression, and you'll have a naked block:

{
  body;
  body;
  body;
}

The naked block is like a while or foreach loop, except that it doesn't loop; it just executes the body of the loop once, and it's done. It's an un-loop!

We'll see in a while that there are other uses for the naked block, but one of its features is that it provides a scope for temporary lexical variables:

{
  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";
}

In this block, $n and $root are temporary variables scoped to the block. As a general guideline, all variables should be declared in the smallest scope available. If you need a variable for just a few lines of code, you can put those lines into a naked block and declare the variable inside that block. Of course, if we would need the value of either $n or $root later, we would need to declare them in a larger scope.

You may have noticed the sqrt function in that code and wondered about it -- yes, it's a function we haven't shown before. Perl has many builtin functions that are beyond the scope of this book. When you're ready, check the perlfunc manpage to learn about more of them.

Previous | Home | Next
10.3. Expression Modifiers | Book Index | 10.5. The elsif Clause
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.5. The elsif Clause

Every so often, you may need to check a number of conditional expressions, one after another, to see which one of them is true. This can be done with the if control structure's elsif clause, as in this example:

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";
}

Perl will test the conditional expressions one after another. When one succeeds, the corresponding block of code is executed, and then the whole control structure is done,[219] and execution goes on to the rest of the program. If none has succeeded, the else block at the end is executed. (Of course, the else clause is still optional, although in this case it's often a good idea to include it.)

[219]There's no "fall-through" to the next block, as in the "switch" structure of languages like C.

There's no limit to the number of elsif clauses, but remember that Perl has to evaluate the first ninety-nine tests before it can get to the hundredth. If you'll have more than half a dozen elsifs, you should consider whether there's a more efficient way to write it. The Perl FAQ (see the perlfaq manpage) has a number of suggestions for emulating the "case" or "switch" statements of other languages.

You may have noticed by this point that the keyword is spelled elsif, with only one e. If you write it as "elseif", with a second e, Perl will tell you that it is not the correct spelling. Why not? Because Larry says so.[220]

[220]In fact, he resists any suggestion that it even be permitted as a valid alternative spelling. "If you want to spell it with a second e, it's simple. Step 1 -- Make up your own language. Step 2 -- Make it popular." When you make your own programming language, you can spell the keywords in any way you'd like. We hope that you will decide that yours shouldn't be the first to have an "elseunless".

Previous | Home | Next
10.4. The Naked Block Control Structure | Book Index | 10.6. Autoincrement and Autodecrement
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.6. Autoincrement and Autodecrement

You'll often want a scalar variable to count up or down by one. Since these are frequent constructs, there are shortcuts for them, like nearly everything else we do frequently.

The autoincrement operator ("++") adds one to a scalar variable, like the same operator in C and similar languages:

my $bedrock = 42;
$bedrock++;  # add one to $bedrock; it's now 43

Just like other ways of adding one to a variable, the scalar will be created if necessary:

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

The first time through that foreach loop, $count{$_} is incremented. That's $count{"fred"}, which thus goes from undef (since it didn't previously exist in the hash) up to 1. The next time through the loop, $count{"barney"} becomes 1; after that, $count{"fred"} becomes 2. Each time through the loop, one element in %count is incremented, and possibly created as well. After that loop is done, $count{"fred"} is 3. This provides a quick and easy way to see which items are in a list and how many times each one appears.

Similarly, the autodecrement operator ("--") subtracts one from a scalar variable:

$bedrock--;  # subtract one from $bedrock; it's 42 again

10.6.1. The Value of Autoincrement

You can fetch the value of a variable and change that value at the same time. Put the ++ operator in front of the variable name to increment the variable first and then fetch its value. This is a preincrement:

my $a = 5;
my $b = ++$a;  # increment $a to 6, and put that value into $b

Or put the -- operator in front to decrement the variable first and then fetch its value. This is a predecrement:

my $c = --$a;  # decrement $a to 5, and put that value into $c

Here's the tricky part. Put the variable name first to fetch the value first, and then do the increment or decrement. This is called a postincrement or postdecrement:

my $d = $a++;  # $d gets the old value (5), then increment $a to 6
my $e = $a--;  # $e gets the old value (6), then decrement $a to 5

It's tricky because we're doing two things at once. We're fetching the value, and we're changing it in the same expression. If the operator is first, we increment (or decrement) first, then use the new value. If the variable is first, we return its (old) value first, then do the increment or decrement. Another way to say it is that these operators return a value, but they also have the side effect of modifying the variable's value.

If you write these in an expression of their own,[221] not using the value but only the side effect, there's no difference[222] whether you put the operator before or after the variable:

[221]That is, in a void context.

[222]Programmers who get inside the implementations of languages may expect that postincrement and postdecrement would be less efficient than their counterparts, but Perl's not like that. Perl automatically optimizes the post- forms when they're used in a void context.

$bedrock++;  # adds one to $bedrock
++$bedrock;  # just the same; adds one to $bedrock

A common use of these operators is in connection with a hash, to identify when an item has been seen before:

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{$_}++;
}

When barney shows up for the first time, the value of $seen{$_}++ is false, since it's the value of $seen{$_}, which is $seen{"barney"}, which is undef. But that expression has the side effect of incrementing $seen{"barney"}. When barney shows up again, $seen{"barney"} is now a true value, so the message is printed.

Previous | Home | Next
10.5. The elsif Clause | Book Index | 10.7. The for Control Structure
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.7. The for Control Structure

Perl's for control structure is like the common for control structure you may have seen in other languages such as C. It looks like this:

for (initialization; test; increment) {
  body;
  body;
}

To Perl, though, this kind of loop is really a while loop in disguise, something like this:[223]

[223]Actually, the increment happens in a continue block, which is beyond the scope of this book. See the perlsyn manpage for the truth.

initialization;
while (test) {
  body;
  body;
  increment;
}

The most common use of the for loop, by far, is for making computed iterations:

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

When you've seen these before, you'll know what the first line is saying even before you read the comment. Before the loop starts, the control variable, $i, is set to 1. Then, the loop is really a while loop in disguise, looping while $i is less than or equal to 10. Between each iteration and the next is the increment, which here is a literal increment, adding one to the control variable, which is $i.

So, the first time through this loop, $i is 1. Since that's less than or equal to 10, we see the message. Although the increment is written at the top of the loop, it logically happens at the bottom of the loop, after printing the message. So, $i becomes 2, which is less than or equal to 10, so we print the message again, and $i is incremented to 3, which is less than or equal to 10, and so on.

Eventually, we print the message that our program can count to 9. Then $i is incremented to 10, which is less than or equal to 10, so we run the loop one last time and print that our program can count to 10. Finally, $i is incremented for the last time, to 11, which is not less than or equal to 10. So control drops out of the loop, and we're on to the rest of the program.

All three parts are together at the top of the loop so that it's easy for an experienced programmer to read that first line and say, "Ah, it's a loop that counts $i from one to ten."

Note that after the loop is done, the control variable has a value "after" the loop. That is, in this case, the control variable has gone all the way to 11. [224]

[224]Obligatory This is Spinal Tap outdated pop-culture reference.

This loop is a very versatile loop, since you can make it count in all sorts of ways. This loop counts from -150 to 1000 by threes:[225]

[225]Of course, it never gets to 1000 exactly. The last iteration uses 999, since each value of $i is a multiple of three.

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

In fact, you could make any of the three control parts (initialization, test, or increment) empty, if you wish, but you still need the two semicolons. In this (quite unusual) example, the test is a substitution, and the increment is empty:

for ($_ = "bedrock"; s/(.)//; ) {  # loops while the s/// is successful
  print "One character is: $1\n";
}

The test expression (in the implied while loop) is the substitution, which will return a true value if it succeeded. In this case, the first time through the loop, the substitution will remove the b from bedrock. Each iteration will remove another letter. When the string is empty, the substitution will fail, and the loop is done.

If the test expression (the one between the two semicolons) is empty, it's automatically true, making an infinite loop. But don't make an infinite loop like this until you see how to break out of such a loop, which we'll discuss later in this chapter:

for (;;) {
  print "It's an infinite loop!\n";
}

A more Perl-like way to write an intentional infinite loop, when you really want one,[226] is with while:

[226]If you somehow made an infinite loop that's gotten away from you, see whether Control-C will halt it. It's possible that you'll get a lot of output even after typing Control-C, depending upon your system's I/O and other factors. Hey, we warned you.

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

Although C programmers are familiar with the first way, even a beginning Perl programmer should recognize that 1 is always true, making an intentional infinite loop, so the second is generally a better way to write it. Perl is smart enough to recognize a constant expression like that and optimize it away, so there's no difference in efficiency.

10.7.1. The Secret Connection Between foreach and for

It turns out that, inside the Perl grammar, the keyword foreach is exactly equivalent to the keyword for. That is, any time Perl sees one of them, it's the same as if you had typed the other. Perl can tell which you meant by looking inside the parentheses. If you've got the two semicolons, it's a computed for loop (like we've just been talking about). If you don't have the semicolons, it's really a foreach loop:

for (1..10) {  # Really a foreach loop from 1 to 10
  print "I can count to $_!\n";
}

That's really a foreach loop, but it's written for. Except for that one example, all through this book, we'll spell out foreach wherever it appears. But in the real world, do you think that Perl folks will type those extra four letters?[227] Excepting only beginners' code, it's always written for, and you'll have to do as Perl does and look for the semicolons to tell which kind of loop it is.

[227]If you think that, you haven't been paying attention. Among programmers, especially Perl programmers, laziness is one of the classical virtues. If you don't believe us, ask someone at the next Perl Mongers' meeting.

In Perl, the true foreach loop is almost always a better choice. In the foreach loop (written for) in that previous example, it's easy to see at a glance that the loop will go from 1 to 10. But do you see what's wrong with this computed loop that's trying to do the same thing? Don't peek at the answer in the footnote until you think you've found what's wrong:[228]

[228]There are two and one-half bugs. First, the conditional uses a less-than sign, so the loop will run nine times, instead of ten. It's easy to get a so-called "fencepost" bug with this kind of loop, like what happened when the rancher needed enough fenceposts to make a 30-meter-long fence with a post every three meters. (The answer is not ten fenceposts.) Second, the control variable is $i, but the loop body is using $_. And second and a half, it's a lot more work to read, write, maintain, and debug this type of loop, which is why we say that the true foreach is generally a better choice in Perl.

for ($i = 1; $i < 10; $i++) {  # Oops! Something is wrong here!
  print "I can count to $_!\n";
}
Previous | Home | Next
10.6. Autoincrement and Autodecrement | Book Index | 10.8. Loop Controls
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.8. Loop Controls

As you've surely noticed by now, Perl is one of the so-called "structured" programming languages. In particular, there's just one entrance to any block of code, which is at the top of that block. But there are times when you may need more control or versatility than what we've shown so far. For example, you may need to make a loop like a while loop, but one that always runs at least once. Or maybe you need to occasionally exit a block of code early. Perl has three loop-control operators you can use in loop blocks to make the loop do all sorts of tricks.

10.8.1. The last Operator

The last operator immediately ends execution of the loop. (If you've used the "break" operator in C or a similar language, it's like that.) It's the "emergency exit" for loop blocks. When you hit last, the loop is done. For example:

# Print all input lines mentioning fred, until the __END__ marker
while (<STDIN>) {
  if (/__END__/) {
    # No more input on or after this marker line
    last;
  } elsif (/fred/) {
    print;
  }
}
## last comes here ##

Once an input line has the __END__ marker, that loop is done. Of course, that comment line at the end is merely a comment -- it's not required in any way. We just threw that in to make it clearer what's happening.

There are five kinds of loop blocks in Perl. These are the blocks of for, foreach, while, until, or the naked block.[229] The curly braces of an if block or subroutine[230] don't qualify. As you may have noticed in the example above, the last operator applied to the entire loop block.

[229]Yes, you can use last to jump out of a naked block. Be sure to check your local laws before doing so.

[230]It's probably not a good idea, but you could use these loop control operators from inside a subroutine to control a loop that is outside the subroutine. That is, if a subroutine is called in a loop block, and the subroutine executes last when there's no loop block running inside the subroutine, the flow of control will jump to just after the loop block in the main code. This ability to use loop control from within a subroutine may go away in a future version of Perl, and no one is likely to miss it.

The last operator will apply to the innermost currently running loop block. To jump out of outer blocks, stay tuned; that's coming up in a little bit.

10.8.2. The next Operator

Sometimes you're not ready for the loop to finish, but you're done with the current iteration. That's what the next operator is good for. It jumps to the inside of the bottom of the current loop block.[231] After next, control continues with the next iteration of the loop (much like the "continue" operator in C or a similar language):

[231]This is another of our many lies. In truth, next jumps to the start of the (usually omitted) continue block for the loop. See the perlsyn manpage for the full details.

# Analyze words in the input file or files
while (<>) {
  foreach (split) {  # break $_ into words, assign each to $_ in turn
    $total++;
    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";
}

This one is a little more complex than most of our examples up to this point, so let's take it step by step. The while loop is reading lines of input from the diamond operator, one after another, into $_; we've seen that before. Each time through that loop, another line of input will be in $_.

Inside that loop, the foreach loop is iterating over the return value split. Do you remember the default for split with no arguments?[232] That splits $_ on whitespace, in effect breaking $_ into a list of words. Since the foreach loop doesn't mention some other control variable, the control variable will be $_. So, we'll see one word after another in $_.

[232]If you don't remember it, don't worry too much. Don't waste any brain cells remembering things that you can look up with perldoc.

But didn't we just say that $_ holds one line of input after another? Well, in the outer loop, that's what it is. But inside the foreach loop, it holds one word after another. It's no problem for Perl to reuse $_ for a new purpose; this happens all the time.

Now, inside the foreach loop, we're seeing one word at a time in $_. $total is incremented, so it must be the total number of words. But the next line (which is the point of this example) checks to see whether the word has any nonword characters -- anything but letters, digits, and underscores. So, if the word is Tom's, or if it is full-sized, or if it has an adjoining comma, quote mark, or any other strange character, it will match that pattern and we'll skip the rest of the loop, going on to the next word.

But let's say that it's an ordinary word, like fred. In that case, we count $valid up by one, and also $count{$_}, keeping a count for each different word. So, when we finish the two loops, we've counted every word in every line of input from every file the user wanted us to use.

We're not going to explain the last few lines. By now, we hope you've got stuff like that down already.

Like last, next may be used in any of the five kinds of loop blocks: for, foreach, while, until, or the naked block. Also, if loop blocks are nested, next works with the innermost one. We'll see how to change that at the end of this section.

10.8.3. The redo Operator

The third member of the loop control triad is redo. It says to go back to the top of the current loop block, without testing any conditional expression or advancing to the next iteration. (If you've used C or a similar language, you've never seen this one before. Those languages don't have this kind of operator.) Here's an example:

# Typing test
my @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";

Like the other two operators, redo will work with any of the five kinds of loop blocks, and it will work with the innermost loop block when they're nested.

The big difference between next and redo is that next will advance to the next iteration, but redo will redo the current iteration. Here's an example program that you can play with to get a feel for how these three operators work:[233]

[233]If you've downloaded the example files from the O'Reilly website (as described in the Preface), you'll find this program called lnr-example.

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";

If you just press return without typing anything (try it two or three times), the loop counts along from one number to the next. If you choose last when you get to number four, the loop is done, and you won't go on to number five. If you choose next when you're on four, you're on to number five without printing the "onward" message. And if you choose redo when you're on four, you're back to doing number four all over again.

10.8.4. Labeled Blocks

When you need to work with a loop block that's not the innermost one, use a label. Labels in Perl are like other identifiers -- made of letters, digits, and underscores, but they can't start with a digit -- however, since they have no prefix character, labels could be confused with the names of builtin function names, or even with your own subroutines' names. So, it would be a poor choice to make a label called print or if. Because of that, Larry recommends that they be all uppercase. That not only ensures that the label won't conflict with another identifier but it also makes it easy to spot the label in the code. In any case, labels are rare, only showing up in a small percentage of Perl programs.

To label a loop block, just put the label and a colon in front of the loop. Then, inside the loop, you may use the label after last, next, or redo as needed:

LINE: while (<>) {
  foreach (split) {
    last LINE if /_ _END_  _/;  # bail out of the LINE loop
    ...;
  }
}

For readability, it's generally nice to put the label at the left margin, even if the current code is at a higher indentation. Notice that the label names the entire block; it's not marking a target point in the code.[234]

[234]This isn't goto, after all.

In that previous snippet of sample code, the special __END__ token marks the end of all input. Once that token shows up, the program will ignore any remaining lines (even from other files).

It often makes sense to choose a noun as the name of the loop.[235] That is, the outer loop is processing a line at a time, so we called it LINE. If we had to name the inner loop, we would have called it WORD, since it processes a word at a time. That makes it convenient to say things like "(move on to the) next WORD" or "redo (the current) LINE".

[235]That is, it makes more sense to do that than not to do that. Perl doesn't care if you call your loop labels things like XYZZY or PLUGH. However, unless you were friendly with the Colossal Cave in the 70's, you might not get the reference.

Previous | Home | Next
10.7. The for Control Structure | Book Index | 10.9. Logical Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.9. Logical Operators

As you might expect, Perl has all of the necessary logical operators needed to work with Boolean (true/false) values. For example, it's often useful to combine logical tests by using the logical AND operator (&&) and the logical OR operator (||):

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)
}

There may be a shortcut. If the left side of a logical AND operation is false, the whole thing is false, since logical AND needs both sides to be true in order to return true. In that case, there's no reason to check the right side, so it will not even be evaluated. Consider what happens in this example if $hour is 3:

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

Similarly, if the left side of a logical OR operation is true, the right side will not be evaluated. Consider what happens here if $name is fred:

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

Because of this behavior, these operators are called "short-circuit" logical operators. They take a short circuit to the result whenever they can. In fact, it's fairly common to rely upon this short-circuit behavior. Suppose you need to calculate an average:

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

In that example, the right side will be evaluated only if the left side is true, so we can't accidentally divide by zero and crash the program.

10.9.1. The Value of a Short-Circuit Operator

Unlike what happens in C (and similar languages), the value of a short-circuit logical operator is the last part evaluated, not just a Boolean value. This provides the same result, in that the last part evaluated is always true when the whole thing should be true, and it's always false when the whole thing should be false.

But it's a much more useful return value. Among other things, the logical OR operator is quite handy for selecting a default value:

my $last_name = $last_name{$someone} || '(No last name)';

If $someone is not listed in the hash, the left side will be undef, which is false. So, the logical OR will have to look to the right side for the value, making the right side the default.[236] We'll see other uses for this behavior later.

[236]But do note that in this idiom the default value won't merely replace undef; it would replace any false value equally well. That's fine for most names, but don't forget that zero and the empty string are useful values that are nevertheless false. This idiom should be used only when you're willing to replace any false value with the expression on the right.

10.9.2. The Ternary Operator, ?:

When Larry was deciding which operators to make available in Perl, he didn't want former C programmers to be left wishing for something that C had and Perl didn't, so he brought over all of C's operators to Perl.[237] That meant bringing over C's most confusing operator: the ternary ?: operator. While it may be confusing, it can also be quite useful.

[237]Well, to be sure, he did leave out the ones that have no use in Perl, such as the operator that turns a number into the memory address of a variable. And he added several operators (like the string concatenation operator), which make C folks jealous of Perl.

The ternary operator is like an if-then-else test, all rolled into an expression. It is called a "ternary" operator because it takes three operands. It looks like this:

expression ? if_true_expr : if_false_expr

First, the expression is evaluated to see whether it's true or false. If it's true, the second expression is used; otherwise, the third expression is used. Every time, one of the two expressions on the right is evaluated, and one is ignored. That is, if the first expression is true, then the second expression is evaluated, and the third is ignored. If the first expression is false, then the second is ignored, and the third is evaluated as the value of the whole thing.

In this example, the result of the subroutine &is_weekend determines which string expression will be assigned to the variable:

my $location = &is_weekend($day) ? "home" : "work";

And here, we calculate and print out an average -- or just a placeholder line of hyphens, if there's no average available:

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

You could always rewrite any use of the ?: operator as an if structure, often much less conveniently and less concisely:

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

Here's a trick you might see, used to code up a nice multiway branch:

my $size =
  ($width < 10) ? "small"  :
  ($width < 20) ? "medium" :
  ($width < 50) ? "large"  :
                  "extra-large"; # default

That is really just three nested ?: operators, and it works quite well, once you get the hang of it.

Of course, you're not obliged to use this operator. Beginners may wish to avoid it. But you'll see it in others' code, sooner or later, and we hope that one day you'll find a good reason to use it in your own programs.

10.9.3. Control Structures Using Partial-Evaluation Operators

These three operators that we've just seen -- &&, ||, and ?: -- all share a peculiar property: depending upon whether the value on the left side is true or false, they may or may not evaluate an expression. Sometimes the expression is evaluated, and sometimes it isn't. For that reason, these are sometimes called partial-evaluation operators, since they may not evaluate all of the expressions around them. And partial-evaluation operators are automatically control structures.[238]

[238]Some of you were wondering why these logical operators are being covered in this chapter, weren't you?

It's not as if Larry felt a burning need to add more control structures to Perl. But once he had decided to put these partial-evaluation operators into Perl, they automatically became control structures as well. After all, anything that can activate and deactivate a chunk of code is a control structure.

Fortunately, you'll notice this only when the controlled expression has side effects, like altering a variable's value or causing some output. For example, suppose you ran across this line of code:

($a < $b) && ($a = $b);

Right away, you should notice that the result of the logical AND isn't being assigned anywhere.[239] Why not?

[239]But don't forget to consider that it might be a return value, as the last expression in a subroutine.

If $a is really less than $b, the left side is true, so the right side will be evaluated, thereby doing the assignment. But if $a is not less than $b, the left side will be false, and thus the right side would be skipped. So that line of code would do essentially the same thing as this one, which is easier to understand:

if ($a < $b) { $a = $b; }

Or maybe you'll be maintaining a program, and you'll see a line like this one:

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

If $a is really greater than ten, the left side is true, and the logical OR is done. But if it's not, the left side is false, and this will go on to print the message. Once again, this could (and probably should) be written in the traditional way, probably with if or unless.

If you have a particularly twisted brain, you might even learn to read these lines as if they were written in English. For example: check that $a is less than $b, and if it is, then do the assignment. Check that $a is more than ten, or if it's not, then print the message.

It's generally former C programmers or old-time Perl programmers who most often use these ways of writing control structures. Why do they do it? Some have the mistaken idea that these are more efficient. Some think these tricks make their code cooler. Some are merely copying what they saw someone else do.

In the same way, the ternary operator may be used for control. In this case, we want to assign $c to the smaller of two variables:

($a < $b) ? ($a = $c) : ($b = $c);

If $a is smaller, it gets $c. Otherwise, $b does.

There is another way to write the logical AND and logical OR operators. You may wish to write them out as words: and and or.[240] These word-operators have the same behaviors as the ones written with punctuation, but the words are much lower on the precedence chart. Since the words don't "stick" so tightly to the nearby parts of the expression, they may need fewer parentheses:

[240]There are also the low-precedence not (like the logical-negation operator, "!") and the rare xor.

$a < $b and $a = $b;  # but better written as the corresponding if

Then again, you may need more parentheses. Precedence is a bugaboo. Be sure to use parentheses to say what you mean, unless you're sure of the precedence. Nevertheless, since the word forms are very low precedence, you can generally understand that they cut the expression into big pieces, doing everything on the left first, and then (if needed) everything on the right.

Despite the fact that using logical operators as control structures can be confusing, sometimes they're the accepted way to write code. We'll see a common use of the or operator starting in the next chapter.

So, using these operators as control structures is part of idiomatic Perl -- Perl as she is spoken. Used properly, they can make your code more powerful; otherwise they can make your code unmaintainable. Don't overuse them.[241]

[241]Using these weird forms more than once per month counts as overuse.

Previous | Home | Next
10.8. Loop Controls | Book Index | 10.10. Exercise
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.10. Exercise

See Section A.9, "Answer to Chapter 10 Exercise" for an answer to the following exercise:

  1. [25] Make a program that will repeatedly ask the user to guess a secret number from 1 to 100 until the user guesses the secret number. Your program should pick the number at random by using the magical formula int(1 + rand 100).[242] When the user guesses wrong, the program should respond "Too high" or "Too low". If the user enters the word quit or exit, or if the user enters a blank line, the program should quit. Of course, if the user guesses correctly, the program should quit then as well!

    [242]See what the perlfunc manpage says about int and rand if you're curious about these functions.

Previous | Home | Next
10.9. Logical Operators | Book Index | 11. Filehandles and File Tests
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 11. Filehandles and File Tests

Contents:

What Is a Filehandle?
Opening a Filehandle
Fatal Errors with die
Using Filehandles
Reopening a Standard Filehandle
File Tests
Exercises

11.1. What Is a Filehandle?

A filehandle is the name in a Perl program for an I/O connection between your Perl process and the outside world. That is, it's the name of a connection, not necessarily the name of a file.

Filehandles are named like other Perl identifiers (letters, digits, and underscores, but they can't start with a digit), but since they don't have any prefix character, they might be confused with present or future reserved words, as we saw with labels. Once again, as with labels, the recommendation from Larry is that you use all uppercase letters in the name of your filehandle -- not only will it stand out better, but it will also guarantee that your program won't fail when a future (lowercase) reserved word is introduced.

But there are also six special filehandle names that Perl already uses for its own purposes: STDIN, STDOUT, STDERR, DATA, ARGV, and ARGVOUT.[243] Although you may choose any filehandle name you'd like, you shouldn't choose one of those six unless you intend to use that one's special properties.[244]

[243]Some people hate typing in all-caps, even for a moment, and will try spelling these in lowercase, like stdin. Perl may even let you get away with that from time to time, but not always. The details of when these work and when they fail are beyond the scope of this book. But the important thing is that programs that rely upon this kindness will one day break, so it is best to avoid lowercase here.

[244]In some cases, you could (re-)use these names without a problem. But your maintenance programmer may think that you're using the name for its builtin features, and thus may be confused.

Maybe you recognized some of those names already. When your program starts, STDIN is the filehandle naming the connection between the Perl process and wherever the program should get its input, known as the standard input stream. This is generally the user's keyboard unless the user asked for something else to be the source of input, such as reading the input from a file or reading the output of another program through a pipe.[245]

[245]The defaults we speak of in this chapter for the three main I/O streams are what the Unix shells do by default. But it's not just shells that launch programs, of course. We'll see in Chapter 14, "Process Management" what happens when you launch another program from Perl.

There's also the standard output stream, which is STDOUT. By default, this one goes to the user's display screen, but the user may send the output to a file or to another program, as we'll see shortly. These standard streams come to us from the Unix "standard I/O" library, but they work in much the same way on most modern operating systems.[246] The general idea is that your program should blindly read from STDIN and blindly write to STDOUT, trusting in the user (or generally whichever program is starting your program) to have set those up. In that way, the user can type a command like this one at the shell prompt:

[246]If you're not already familiar with how your non-Unix system provides standard input and output, see the perlport manpage and the documentation for that system's equivalent to the Unix shell (the program that runs programs based upon your keyboard input).

$ ./your_program <dino >wilma

That command tells the shell that the program's input should be read from the file dino, and the output should go to the file wilma. As long as the program blindly reads its input from STDIN, processes it (in whatever way we need), and blindly writes its output to STDOUT, this will work just fine.

And at no extra charge, the program will work in a pipeline. This is another concept from Unix, which lets us write command lines like this one:

$ cat fred barney | sort | ./your_program | grep something | lpr

Now, if you're not familiar with these Unix commands, that's okay. This line says that the cat command should print out all of the lines of file fred followed by all of the lines of file barney. Then that output should be the input of the sort command, which sorts those lines and passes them on to your_program. After it has done its processing, your_program will send the data on to grep, which discards certain lines in the data, sending the others on to the lpr command, which should print everything that it gets on a printer. Whew!

But pipelines like that are common in Unix and many other systems today because they let you put together a powerful, complex command out of simple, standard building blocks.

There's one more standard I/O stream. If (in the previous example) your_program had to emit any warnings or other diagnostic messages, those shouldn't go down the pipeline. The grep command is set to discard anything that it hasn't specifically been told to look for, and so it will most likely discard the warnings. Even if it did keep the warnings, we probably don't want those to be passed downstream to the other programs in the pipeline. So that's why there's also the standard error stream: STDERR. Even if the standard output is going to another program or file, the errors will go to wherever the user desires. By default, the errors will generally go to the user's display screen,[247] but the user may send the errors to a file with a shell command like this one:

[247]Also, generally, errors aren't buffered. That means that if the standard error and standard output streams are both going to the same place (such as the monitor), the errors may appear earlier than the normal output. For example, if your program prints a line of ordinary text, then tries to divide by zero, the output may show the message about dividing by zero first, and the ordinary text second.

$ netstat | ./your_program 2>/tmp/my_errors
Previous | Home | Next
10.10. Exercise | Book Index | 11.2. Opening a Filehandle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.2. Opening a Filehandle

So we see that Perl provides three filehandles -- STDIN, STDOUT, and STDERR -- which are automatically open to files or devices established by the program's parent process (probably the shell). When you need other filehandles, use the open operator to tell Perl to ask the operating system to open the connection between your program and the outside world. Here are some examples:

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

The first one opens a filehandle called CONFIG to a file called dino. That is, the (existing) file dino will be opened and whatever it holds will come into our program through the filehandle named CONFIG. This is similar to the way that data from a file could come in through STDIN if the command line had a shell redirection like <dino. In fact, the second example uses exactly that sequence. The second does the same as the first, but the less-than sign explicitly says "this filename is to be used for input," even though that's the default.[248]

[248]This may be important for security reasons. As we'll see in a moment (and in further detail in Chapter 14, "Process Management"), there are a number of magical characters that may be used in filenames. If $name holds a user-chosen filename, simply opening $name will allow any of these magical characters to come into play. This could be a convenience tn the user, or it could be a security hole. But opening "<$name" is much safer, since it explicitly says to open the given name for input. Still, this doesn't prevent all possible mischief. For more information on different ways of opening files, especially when security may be a concern, see the perlopentut manpage.

Although you don't have to use the less-than sign to open a file for input, we include that because, as you can see in the third example, a greater-than sign means to create a new file for output. This opens the filehandle BEDROCK for output to the new file fred. Just as when the greater-then sign is used in shell redirection, we're sending the output to a new file called fred. If there's already a file of that name, we're asking to wipe it out and replace it with this new one.

The fourth example shows how two greater-than signs may be used (again, as the shell does) to open a file for appending. That is, if the file already exists, we will add new data at the end. If it doesn't exist, it will be created in much the same way as if we had used just one greater-than sign. This is handy for log files; your program could write a few lines to the end of a log file each time it's run. So that's why the fourth example names the filehandle LOG and the file logfile.

You can use any scalar expression in place of the filename specifier, although typically you'll want to be explicit about the direction specification:

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

Note the space after the greater-than. Perl ignores this,[249] but it keeps unexpected things from happening if $selected_output were ">passwd" for example (which would make an append instead of a write).

[249]Yes, this means that if your filename were to have leading whitespace, that would also be ignored by Perl. See perlfunc and perlopentut if you're worried about this.

We'll see how to use these filehandles later in this chapter.

11.2.1. Closing a Filehandle

When you are finished with a filehandle, you may close it with the close operator like this:

close BEDROCK;

Closing a filehandle tells Perl to inform the operating system that we're all done with the given data stream, so any last output data should be written to disk in case someone is waiting for it.[250]

[250]If you know much about I/O systems, you'll know there's more to the story. Generally, though, when a filehandle is closed, here's what happens. If there's input remaining in a file, it's ignored. If there's input remaining in a pipeline, the writing program may get a signal that the pipeline is closed. If there's output going to a file or pipeline, the buffer is flushed (that is, pending output is sent on its way). If the filehandle had a lock, the lock is released. See your system's I/O documentation for further details.

Perl will automatically close a filehandle if you reopen it (that is, if you reuse the filehandle name in a new open) or if you exit the program.[251] Because of this, many simple Perl programs don't bother with close. But it's there if you want to be tidy, with one close for every open. In general, it's best to close each filehandle soon after you're done with it, though the end of the program often arrives soon enough.[252]

[251]Any exit from the program will close all filehandles, but if Perl itself breaks, pending output buffers won't get flushed. That is to say, if you accidentally crash your program by dividing by zero, for example, Perl itself is still running. Perl will ensure that data you've written actually gets output in that case. But if Perl itself can't run (because you ran out of memory or caught an unexpected signal), the last few pieces of output may not be written to disk. Usually, this isn't a big issue.

[252]Closing a filehandle will flush any output buffers and release any locks on the file. Since someone else may be waiting for those things, a long-running program should generally close each filehandle as soon as possible. But many of our programs will take only one or two seconds to run to completion, so this may not matter. Closing a filehandle also releases possibly limited resources, so it's more than just being tidy.

11.2.2. Bad Filehandles

Perl can't actually open a file all by itself. Like any other programming language, Perl can merely ask the operating system to let us open a file. Of course, the operating system may refuse, because of permission settings, an incorrect filename, or other reasons.

If you try to read from a bad filehandle (that is, a filehandle that isn't properly open), you'll see an immediate end-of-file. (With the I/O methods we'll see in this chapter, end-of-file will be indicated by undef in a scalar context or an empty list in a list context.) If you try to write to a bad filehandle, the data is silently discarded.

Fortunately, these dire consequences are easy to avoid. First of all, if we ask for warnings with -w, Perl will generally be able to tell us with a warning when it sees that we're using a bad filehandle. But even before that, open always tells us if it succeeded or failed, by returning true for success or false for failure. So you could write code like this:

my $success = open LOG, ">>logfile";  # capture the return value
unless ($success) {
  # The open failed
  ...
}

Well, you could do it like that, but there's another way that we'll see in the next section.

Previous | Home | Next
11. Filehandles and File Tests | Book Index | 11.3. Fatal Errors with die
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.3. Fatal Errors with die

Let's step aside for a moment. We need some stuff that isn't directly related to (or limited to) filehandles, but is more about getting out of a program earlier than normal.

When a fatal error happens inside Perl (for example, if you divide by zero, use an invalid regular expression, or call a subroutine that hasn't been declared) your program stops with an error message telling why.[253] But this functionality is available to us with the die function, so we can make our own fatal errors.

[253]Well, it does this by default, but errors may be trapped with an eval block, as we'll see in Chapter 17, "Some Advanced Perl Techniques".

The die function prints out the message you give it (to the standard error stream, where such messages should go) and makes sure that your program exits with a nonzero exit status.

You may not have known it, but every program that runs on Unix (and many other modern operating systems) has an exit status, telling whether it was successful or not. Programs that run other programs (like the make utility program) look at that exit status to see that everything is running correctly. The exit status is just a single byte, so it can't say much; traditionally, it is zero for success and a nonzero value for failure. Perhaps one means a syntax error in the command arguments, while two means that something went wrong during processing and three means the configuration file couldn't be found; the details differ from one command to the next. But zero always means that everything worked. When the exit status shows failure, a program like make knows not to go on to the next step.

So we could rewrite the previous example, perhaps something like this:

unless (open LOG, ">>logfile") {
  die "Cannot create logfile: $!";
}

If the open fails, die will terminate the program and tell us that it cannot create the logfile. But what's that $! in the message? That's the human-readable complaint from the system. In general, when the system refuses to do something we've requested (like opening a file), it will give us a reason (perhaps "permission denied" or "file not found," in this case). This is the string that you may have obtained with perror in C or a similar language. This human-readable complaint message will be available in Perl's special variable $!.[254] It's a good idea to include $! in the message when it could help the user to figure out what he or she did wrong. But if you use die to indicate an error that is not the failure of a system request, don't include $!, since it will generally hold an unrelated message left over from something Perl did internally. It will hold a useful value only immediately after a failed system request. A successful request won't leave anything useful there.

[254]On some non-Unix operating systems, $!may say something like error number 7, leaving it up to the user to look that one up in the documentation. On Windows and VMS, the variable $^E may have additional diagnostic information.

There's one more thing that die will do for you: it will automatically append the Perl program name and line number[255] to the end of the message, so you can easily identify which die in your program is responsible for the untimely exit. The error message from the previous code might look like this, if $! contained the message permission denied:

[255]If the error happened while reading from a file, the error message will include the "chunk number" (usually the line number) from the file and the name of the filehandle as well, since those are often useful in tracking down a bug.

Cannot create logfile: permission denied at your_program line 1234.

That's pretty helpful -- in fact, we always seem to want more information in our error messages than we put in the first time around. If you don't want the line number and file revealed, make sure that the dying words have a newline on the end. That is, another way you could use die is in a line like this, with a trailing newline:

die "Not enough arguments\n" if @ARGV < 2;

If there aren't at least two command-line arguments, that program will say so and quit. It won't include the program name and line number, since the line number is of no use to the user; this is the user's error, after all. As a rule of thumb, put the newline on messages that indicate a usage error and leave it off when it the error might be something you want to track down during debugging.[256]

[256]The program's name is in Perl's special variable $0, so you may wish to include that in the string: "$0:Not enough arguments\n". This is useful if the program may be used in a pipeline or shell script, for example, where it's not obvious which command is complaining. $0 can be changed during the execution of the program, however. You might also want to look into the special _ _FILE_ _ and _ _LINE_ _tokens (or the caller function) to get the information that is being left out by adding the newline, so you can print it in your own choice of format.

When opening a file fails, though, there's an easier and more common way instead of the unless block:

open LOG, ">>logfile"
  or die "Cannot create logfile: $!";

This uses the low-precedence short-circuit or operator that we saw in Chapter 10, "More Control Structures". If the open succeeds, it returns true, and the or is done. If the open fails, it returns false, and the short-circuit or goes on to the right side and dies with the message. You can read this as if it were English: "Open this file, or die!" It may not be the battle cry that will win a war, but it's a good way to write code.

You should always check the return value of open, since the rest of the program is relying upon its success. That's why we say that this is really the only way to write open -- with or die after it.[257] Until you're ready to be extra tricky, you should simply think of this as the syntax for open. Typing or die and a message takes only a moment when you're writing the program, but it can save hours, or possibly days of debugging time when something goes wrong.

[257]Older code may use the higher-precedence || operator instead. The only difference is the precedence, but it's a big one! If the open is written without parentheses, the higher-precedence operator will bind to the filename argument, not to the return value -- so the return value of open isn't being checked after all. If you use the ||, be sure to use the parentheses. Better yet, just use the low-precedence or as we've shown here whenever you're writing or die.

11.3.1. Warning Messages with warn

Just as die can indicate a fatal error that acts like one of Perl's builtin errors (like dividing by zero), you can use the warn function to cause a warning that acts like one of Perl's builtin warnings (like using an undef value as if it were defined, when warnings are enabled).

The warn function works just like die does, except for that last step -- it doesn't actually quit the program. But it adds the program name and line number if needed, and it prints the message to standard error, just as die would.[258]

[258]Warnings can't be trapped with an eval block, like fatal errors can. But see the documentation for the _ _WARN_ _ pseudo-signal (in the perlvar manpage) if you need to trap a warning.

And having talked about death and dire warnings, we now return you to your regularly scheduled filehandle instructional material. Read on.

Previous | Home | Next
11.2. Opening a Filehandle | Book Index | 11.4. Using Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.4. Using Filehandles

Once a filehandle is open for reading, you can read lines from it just like you can read from standard input with STDIN. So, for example, to read lines from the Unix password file:

open PASSWD, "/etc/passwd"
  or die "How did you get logged in? ($!)";

while (<PASSWD>) {
  chomp;
  if (/^root:/) {  # found root entry...
    ...;
  }
}

In this example, the die message uses parentheses around $!. Those are merely parentheses around the message in the output. (Sometimes a punctuation mark is just a punctuation mark.) As you can see, what we've been calling the "line-input operator" is really made of two components; the angle brackets (the real line-input operator) are around an input filehandle. Each line of input is then tested to see if it begins with root followed by a colon, triggering unseen actions.

A filehandle open for writing or appending may be used with print or printf, appearing immediately after the keyword but before the list of arguments:

print LOG "Captain's log, stardate 3.14159\n";  # output goes to LOG
printf STDERR "%d percent complete.\n", $done/$total * 100;

Did you notice that there's no comma between the filehandle and the items to be printed?[259] This looks especially weird if you use parentheses. Either of these forms is correct:

[259]If you got straight A's in freshman English or Linguistics, when we say that this is called "indirect object syntax," you may say "Ah, of course! I see why there's no comma after the filehandle name -- it's an indirect object!" We didn't get straight A's; we don't understand why there's no comma; we merely omit it because Larry told us that we should omit the comma.

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

11.4.1. Changing the Default Output Filehandle

By default, if you don't give a filehandle to print (or to printf, as everything we say here about one applies equally well to the other), the output will go to STDOUT. But that default may be changed with the select operator. Here we'll send some output lines to BEDROCK:

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

Once you've selected a filehandle as the default for output, it will stay that way. But it's generally a bad idea to confuse the rest of the program, so you should generally set it back to STDOUT when you're done.[260]

[260]In the unlikely case that STDOUT might not be the selected filehandle, you could save and restore the filehandle, using the technique shown in the documentation for select in the perlfunc manpage. And as long as we're sending you to that manpage, we may as well tell you that there are actually two builtin functions in Perl named select, and both covered in the perlfunc manpage. The other select always has four arguments, so it's sometimes called "four-argument select".

Also by default, the output to each filehandle is buffered. Setting the special $| variable to 1 will set the currently selected filehandle (that is, the one selected at the time that the variable is modified) to always flush the buffer after each output operation. So if you wanted to be sure that the logfile gets its entries at once, in case you might be reading the log to monitor progress of your long-running program, you could use something like this:

select LOG;
$| = 1;  # don't keep LOG entries sitting in the buffer
select STDOUT;
# ... time passes, babies learn to walk, tectonic plates shift, and then...
print LOG "This gets written to the LOG at once!\n";
Previous | Home | Next
11.3. Fatal Errors with die | Book Index | 11.5. Reopening a Standard Filehandle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.5. Reopening a Standard Filehandle

We mentioned earlier that if you were to reopen a filehandle (that is, if you were to open a filehandle FRED when you've already got an open filehandle named FRED, say), the old one would be closed for you automatically. And we said that you shouldn't reuse one of the six standard filehandle names unless you intended to get that one's special features. And we also said that the messages from die and warn, along with Perl's internally generated complaints, go automatically to STDERR. If you put those three pieces of information together, you now have an idea about how you could send error messages to a file, rather than to your program's standard error stream:[261]

[261]Don't do this without a reason. It's nearly always better to let the user set up redirection when launching your program, rather than have redirection hardcoded. But this is handy in cases where your program is being run automatically by another program (say, by a web server or a scheduling utility like cron or at). Another reason might be that your program is going to start another process (probably with system or exec, which we'll see in Chapter 14, "Process Management"), and you need that process to have different I/O connections.

# Send errors to my private error log
open STDERR, ">>/home/barney/.error_log"
  or die "Can't open error log for append: $!";

After reopening STDERR, any error messages from Perl will go into the new file. But what happens if the or die part is executed -- where will that message go, if the new file couldn't be opened to accept the messages?

The answer is that if one of the three system filehandles -- STDIN, STDOUT, or STDERR -- fails to be reopened, Perl kindly restores the original one.[262] That is, Perl closes the original one (of those three) only when it sees that opening the new connection is successful. Thus, this technique could be used to redirect any (or all) of those three system filehandles from inside your program,[263] almost as if the program had been run with that I/O redirection from the shell in the first place.

[262]At least, this is true if you haven't changed Perl's special $^F variable, which tells Perl that only those three are special like this. But you'd never change that.

[263]But don't open STDIN for output or the others for input. Just thinking about that makes our heads hurt.

Previous | Home | Next
11.4. Using Filehandles | Book Index | 11.6. File Tests
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.6. File Tests

Now you know how to open a filehandle for output. Normally, that will create a new file, wiping out any existing file with the same name. Perhaps you want to check that there isn't a file by that name. Perhaps you need to know how old a given file is. Or perhaps you want to go through a list of files to find which ones are larger than a certain number of bytes and not accessed for a certain amount of time. Perl has a complete set of tests you can use to find out information about files.

Let's try that first example, where we need to check that a given file doesn't exist, so that we don't accidentally overwrite a vital spreadsheet data file, or that important birthday calendar. For this, we need the -e file test, testing for existence:

die "Oops! A file called '$filename' already exists.\n"
  if -e $filename;

Notice that we don't include $! in this die message, since we're not reporting that the system refused a request in this case. Here's an example of checking whether a file is being kept up-to-date. Let's say that our program's configuration file should be updated every week or two. (Maybe it's checking for computer viruses, say.) If the file hasn't been modified in the past 28 days, then something is wrong:

warn "Config file is looking pretty old!\n"
  if -M CONFIG > 28;

The third example is more complex. Here, let's say that disk space is filling up and rather than buy more disks, we've decided to move any large, useless files to the backup tapes. So let's go through our list of files[264] to see which of them are larger than 100 K. But even if a file is large, we shouldn't move it to the backup tapes unless it hasn't been accessed in the last 90 days (so we know that it's not used too often):[265]

[264]It's more likely that, instead of having the list of files in an array, as our example shows, you'll read it directly from the filesystem using a glob or directory handle, as shown in Chapter 12, "Directory Operations". Since we haven't seen that yet, we'll just start with the list and go from there.

[265]There's a way to make this example more efficient, as we'll see by the end of the chapter.

my @original_files = qw/ fred barney betty wilma pebbles dino bamm-bamm /;
my @big_old_files;  # The ones we want to put on backup tapes
foreach my $filename (@original_files) {
  push @big_old_files, $_
    if -s $filename > 100_000 and -A $filename > 90;
}

This is the first time that we've seen it, so maybe you noticed that the control variable of the foreach loop is a my variable. That declares it to have the scope of the loop itself, so this example should work under use strict. Without the my keyword, this would be using the global $filename.

The file tests all look like a hyphen and a letter, which is the name of the test, followed by either a filename or a filehandle to be tested. Many of them return a true/false value, but several give something more interesting. See Table 11-1 for the complete list, and then read the following discussion to learn more about the special cases.

Table 11-1. File tests and their meanings

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

-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)

The tests -r, -w, -x, and -o tell whether the given attribute is true for the effective user or group ID,[266] which essentially refers to the person who is "in charge of" running the program.[267] These tests look at the "permission bits" on the file to see what is permitted. If your system uses Access Control Lists (ACLs), the tests will use those as well. These tests generally tell whether the system would try to permit something, but it doesn't mean that it really would be possible. For example, -w may be true for a file on a CD-ROM, even though you can't write to it, or -x may be true on an empty file, which can't truly be executed.

[266]The -o and -O tests relate only to the user ID and not to the group ID.

[267]Note for advanced students: the corresponding -R, -W, -X, and -O tests use the real user or group ID, which becomes important if your program may be running set-ID; in that case, it's generally the ID of the person who requested running it. See any good book about advanced Unix programming for a discussion of set-ID programs.

The -s test does return true if the file is nonempty, but it's a special kind of true. It's the length of the file, measured in bytes, which evaluates as true for a nonzero number.

On a Unix filesystem,[268] there are just seven types of items, represented by the seven file tests -f, -d, -l, -S, -p, -b, and -c. Any item should be one of those. But if you have a symbolic link pointing to a file, that will report true for both -f and -l. So if you want to know whether something is a symbolic link, you should generally test that first. (We'll learn more about symbolic links in Chapter 13, "Manipulating Files and Directories".)

[268]This is the case on many non-Unix filesystems, but not all of the file tests are meaningful everywhere. For example, you aren't likely to have block special files on your non-Unix system.

The age tests, -M, -A, and -C (yes, they're uppercase), return the number of days since the file was last modified, accessed, or had its inode changed.[269] (The inode contains all of the information about the file except for its contents -- see the stat system call manpage or a good book on Unix internals for details.) This age value is a full floating-point number, so you might get a value of 2.00001 if a file were modified two days and one second ago. (These "days" aren't necessarily the same as a human would count; for example, if it's one thirty in the morning when you check a file modified at about an hour before midnight, the value of -M for this file would be around 0.1, even though it was modified "yesterday.")

[269]This information will be somewhat different on non-Unix systems, since not all keep track of the same times that Unix does. For example, on some systems, the ctime field (which the -C test looks at) is the file creation time (which Unix doesn't keep track of), rather than the inode change time; see the perlport manpage.

When checking the age of a file, you might even get a negative value like -1.2, which means that the file's last-access timestamp is set at about thirty hours in the future! The zero point on this timescale is the moment your program started running,[270] so that value might mean that a long-running program was looking at a file that had just been accessed. Or a timestamp could be set (accidentally or intentionally) to a time in the future.

[270]As recorded in the $^T variable, which you could update (with a statement like $^T = time;) if you needed to get the ages relative to a different starting time.

The tests -T and -B take a try at telling whether a file is text or binary. But people who know a lot about filesystems know that there's no bit (at least in Unix-like operating systems) to indicate that a file is a binary or text file -- so how can Perl tell? The answer is that Perl cheats: it opens the file, looks at the first few thousand bytes, and makes an educated guess. If it sees a lot of null bytes, unusual control characters, and bytes with the high bit set, then that looks like a binary file. If there's not much weird stuff then it looks like text. As you might guess, it sometimes guesses wrong. If a text file has a lot of Swedish or French words (which may have characters represented with the high bit set, as some ISO-8859-something variant, or perhaps even a Unicode version), it may fool Perl into declaring it binary. So it's not perfect, but if you just need to separate your source code from compiled files, or HTML files from PNGs, these tests should do the trick.

You'd think that -T and -B would always disagree, since a text file isn't a binary and vice versa, but there are two special cases where they're in complete agreement. If the file doesn't exist, both are false, since it's neither a text file nor a binary. Alternatively, if the file is empty, it's an empty text file and an empty binary file at the same time, so they're both true.

The -t file test returns true if the given filehandle is a TTY -- in short, if it's able to be interactive because it's not a simple file or pipe. When -t STDIN returns true, it generally means that you can interactively ask the user questions. If it's false, your program is probably getting input from a file or pipe, rather than a keyboard.

Don't worry if you don't know what some of the other file tests mean -- if you've never heard of them, you won't be needing them. But if you're curious, get a good book about programming for Unix. (On non-Unix systems, these tests all try to give results analogous to what they do on Unix. Usually you'll be able to guess correctly what they'll do.)

If you omit the filename or filehandle parameter to a file test (that is, if you have just -r or just -s, say), the default operand is the file named in $_.[271] So, to test a list of filenames to see which ones are readable, you simply type:

[271]The -t file test is an exception; since that test isn't useful with filenames (they're never TTYs). By default it tests STDIN.

foreach (@lots_of_filenames) {
  print "$_ is readable\n" if -r;  # same as -r $_
}

But if you omit the parameter, be careful that whatever follows the file test doesn't look like it could be a parameter. For example, if you wanted to find out the size of a file in K rather than in bytes, you might be tempted to divide the result of -s by 1000 (or 1024), like this:

# The filename is in $_
my $size_in_K = -s / 1000;  # Oops!

When the Perl parser sees the slash, it doesn't think about division; since it's looking for the optional operand for -s, it sees what looks like the start of a regular expression in forward slashes. One simple way to prevent this kind of confusion is to put parentheses around the file test:

my $size_in_k = (-s) / 1024;  # Uses $_ by default

Of course, it's always safe to explicitly give a file test a parameter.

11.6.1. The stat and lstat Functions

While these file tests are fine for testing various attributes regarding a particular file or filehandle, they don't tell the whole story. For example, there's no file test that returns the number of links to a file or the owner's user-ID (uid). To get at the remaining information about a file, merely call the stat function, which returns pretty much everything that the stat Unix system call returns (hopefully more than you want to know).[272]

[272]On a non-Unix system, both stat and lstat, as well as the file tests, should return "the closest thing available." For example, a system that doesn't have user IDs (that is, a system that has just one "user," in the Unix sense) might return zero for the user and group IDs, as if the one and only user is the system administrator. If stat or lstat fails, it will return an empty list. If the system call underlying a file test fails (or isn't available on the given system), that test will generally return undef. See the perlport manpage for the latest about what to expect on different systems.

The operand to stat is a filehandle, or an expression that evaluates to a filename. The return value is either the empty list, indicating that the stat failed (usually because the file doesn't exist), or a 13-element list of numbers, most easily described using the following list of scalar variables:

my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
  $size, $atime, $mtime, $ctime, $blksize, $blocks)
    = stat($filename);

The names here refer to the parts of the stat structure, described in detail in the stat(2) manpage. You should probably look there for the detailed descriptions. But in short, here's a quick summary of the important ones:

$dev and $ino
The device number and inode number of the file. Together they make up a "license plate" for the file. Even if it has more than one name (hard link), the combination of device and inode numbers should always be unique.

$mode
The set of permission bits for the file, and some other bits. If you've ever used the Unix command ls -l to get a detailed (long) file listing, you'll see that each line of output starts with something like -rwxr-xr-x. The nine letters and hyphens of file permissions[273] correspond to the nine least-significant bits of $mode, which would in this case give the octal number 0755. The other bits, beyond the lowest nine, indicate other details about the file. So if you need to work with the mode, you'll generally want to use the bitwise operators covered later in this chapter.

[273]The first character in that string isn't a permission bit; it indicates the type of entry: a hyphen for an ordinary file, d for directory, or l for symbolic link, among others. The ls command determines this from the other bits past the least-significant nine.

$nlink
The number of (hard) links to the file or directory. This is the number of true names that the item has. This number is always 2 or more for directories and (usually) 1 for files. We'll see more about this when we talk about creating links to files in Chapter 13, "Manipulating Files and Directories". In the listing from ls -l, this is the number just after the permission-bits string.

$uid and $gid
The numeric user-ID and group-ID showing the file's ownership.

$size
The size in bytes, as returned by the -s file test.

$atime , $mtime, and $ctime
The three timestamps, but here they're represented in the system's timestamp format: a 32-bit number telling how many seconds have passed since the Epoch, an arbitrary starting point for measuring system time. On Unix systems and some others, the Epoch is the beginning of 1970 at midnight Universal Time, but the Epoch is different on some machines. There's more information later in this chapter on turning that timestamp number into something useful.

Invoking stat on the name of a symbolic link returns information on what the symbolic link points at, not information about the symbolic link itself (unless the link just happens to be pointing at nothing currently accessible). If you need the (mostly useless) information about the symbolic link itself, use lstat rather than stat (which returns the same information in the same order). If the operand isn't a symbolic link, lstat returns the same things that stat would.

Like the file tests, the operand of stat or lstat defaults to $_, meaning that the underlying stat system call will be performed on the file named by the scalar variable $_.

11.6.2. The localtime Function

When you have a timestamp number (such as the ones from stat), it will typically look something like 1080630098. That's not very useful for most humans, unless you need to compare two timestamps by subtracting. You may need to convert it to something human-readable, such as a string like "Tue Mar 30 07:01:38 2004". Perl can do that with the localtime function in a scalar context:

my $timestamp = 1080630098;
my $date = localtime $timestamp;

In a list context, localtime returns a list of numbers, several of which may not be quite what you'd expect:

my($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst)
  = localtime $timestamp;

The $mon is a month number, ranging from 0 to 11, which is handy as an index into an array of month names. The $year is the number of years since 1900, oddly enough, so add 1900 to get the real year number. The $wday ranges from 0 (for Sunday) through 6 (for Saturday), and the $yday is the day-of-the-year (ranging from 0 for January 1, through 364 or 365 for December 31).

There are two related functions that you'll also find useful. The gmtime function is just the same as localtime, except that it returns the time in Universal Time (what we once called Greenwich Mean Time). If you need the current timestamp number from the system clock, just use the time function. Both localtime and gmtime default to using the current time value if you don't supply a parameter:

my $now = gmtime;  # Get the current universal timestamp as a string

For more information on manipulating date and time information, see the information about some useful modules in Appendix B, "Beyond the Llama".

11.6.3. Bitwise Operators

When you need to work with numbers bit-by-bit, as when working with the mode bits returned by stat, you'll need to use the bitwise operators. The bitwise-and operator (&) reports which bits are set in the left argument and in the right argument. For example, the expression 10 & 12 has the value 8. The bitwise-and needs to have a one-bit in both operands to produce a one-bit in the result. That means that the logical-and operation on ten (which is 1010 in binary) and twelve (which is 1100) gives eight (which is 1000, with a one-bit only where the left operand has a one-bit and the right operand also has a one-bit). See Figure 11-1.

Figure 11-1. Bitwise-and addition

The different bitwise operators and their meanings are shown in this table:

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 the least-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)

~ 10

Bitwise negation, also called unary bit complement -- return the number with the opposite bit for each bit in the operand (this gives 0xFFFFFFF5, but see the text)

So, here's an example of some things you could do with the $mode returned by stat. The results of these bit manipulations could be useful with chmod, which we'll see in Chapter 13, "Manipulating Files and Directories":

# $mode is the mode value returned from a stat of CONFIG
warn "Hey, the configuration file is world-writable!\n"
  if $mode & 0002;                                # configuration security problem
my $classical_mode = 0777 & $mode;                # mask off extra high-bits
my $u_plus_x = $classical_mode | 0100;            # turn one bit on
my $go_minus_r = $classical_mode & (~ 0044);      # turn two bits off

11.6.4. Using Bitstrings

All of the bitwise operators can work with bitstrings, as well as with integers. If the operands are integers, the result will be an integer. (The integer will be at least a 32-bit integer, but may be larger if your machine supports that. That is, if you have a 64-bit machine, ~10 may give the 64-bit result 0xFFFFFFFFFFFFFFF5, rather than the 32-bit result 0xFFFFFFF5.)

But if any operand of a bitwise operator is a string, Perl will perform the operation on that bitstring. That is, "\xAA" | "\x55" will give the string "\xFF". Note that these values are single-byte strings; the result is a byte with all eight bits set. Bitstrings may be arbitrarily long.

This is one of the very few places where Perl distinguishes between strings and numbers. See the perlop manpage for more information on using bitwise operators on strings.

11.6.5. Using the Special Underscore Filehandle

Every time you use stat, lstat, or a file test in a program, Perl has to go out to the system to ask for a stat buffer on the file (that is, the return buffer from the stat system call). That means if you want to know whether a file is both readable and writable, you've essentially asked the system twice for the same information (which isn't likely to change in a fairly nonhostile environment).

This looks like a waste of time,[274] and in fact, it can be avoided. Doing a file test, stat, or lstat on the special _ filehandle (that is, the operand is nothing but a single underscore) tells Perl to use whatever happened to be lounging around in memory from the previous file test, stat, or lstat function, rather than going out to the operating system again. Sometimes this is dangerous: a subroutine call can invoke stat without your knowledge, blowing your buffer away. But if you're careful, you can save yourself a few unneeded system calls, thereby making your program considerably faster. Here's that example of finding files to put on the backup tapes again, using the new tricks we've learned:

[274]Because it is. Asking the system for information is relatively slow.

my @original_files = qw/ fred barney betty wilma pebbles dino bamm-bamm /;
my @big_old_files;                       # The ones we want to put on backup tapes
foreach (@original_files) {
  push @big_old_files, $_
    if (-s) > 100_000 and -A _ > 90;     # More efficient than before
}

Note that we used the default of $_ for the first test -- this is no more efficient (except perhaps for the programmer), but it gets the data from the operating system. The second test uses the magic _ filehandle; for this test, the data left around after getting the file's size is used, which is exactly what we want.

Note that testing the _ filehandle is not the same as allowing the operand of a file test, stat, or lstat to default to testing $_; using $_ would be a fresh test each time on the current file named by the contents of $_, but using _ saves the trouble of calling the system again. Here is another case where similar names were chosen for radically different functions. By now, you are probably used to it.

Previous | Home | Next
11.5. Reopening a Standard Filehandle | Book Index | 11.7. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.7. Exercises

See Section A.10, "Answers to Chapter 11 Exercises" for answers to the following exercises:

  1. [20] Make a program which asks the user for a source file name, a destination file name, a search pattern, and a replacement string. (Be sure to ask the user interactively for these; don't get them from the command-line arguments.) Your program should read the source file and write it out as the destination file, replacing the search pattern with the replacement string wherever it appears. That is, the destination file will be a modified duplicate of the source file. Can you overwrite an existing file (not the same as the input file)? Can you use regular expression metacharacters in the search pattern? (That is, can you enter (fred|wilma) flintstone to search for either name?) Can you use the memory variables and backslash escapes in the replacement string? (That is, can you use \u\L$1\E Flintstone as the replacement string to properly capitalize the names of Fred and Wilma?) Don't worry if you can't accomplish each of these things; it's more important simply to see what happens when you try.

  2. [15] Make a program which takes a list of files named on the command line and reports for each one whether it's readable, writable, executable, or doesn't exist. (Hint: It may be helpful to have a function which will do all of the file tests for one file at a time.) What does it report about a file which has been chmod'ed to 0? (That is, if you're on a Unix system, use the command chmod 0 some_file to mark that file as neither being readable, writable, nor executable.) In most shells, use a star as the argument to mean all of the normal files in the current directory. That is, you could type something like ./ex11-2 * to ask the program for the attributes of many files at once.

  3. [10] Make a program to identify the oldest file named on the command line and report its age in days. What does it do if the list is empty? (That is, if no files are mentioned on the command line.)

Previous | Home | Next
11.6. File Tests | Book Index | 12. Directory Operations
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 12. Directory Operations

Contents:

Moving Around the Directory Tree
Globbing
An Alternate Syntax for Globbing
Directory Handles
Recursive Directory Listing
Exercises

The files we created in the previous chapter were generally in the same place as our program. But modern operating systems let us organize files into directories, allowing us to keep our Beatles MP3s away from our important Llama book chapter sources so that we don't accidentally send an MP3 file to the publisher. Perl lets you manipulate these directories directly, in ways that are even fairly portable from one operating system to another.

12.1. Moving Around the Directory Tree

Your program runs with a "working directory," which is the starting point for relative pathnames. That is, if you refer to the file fred, that means "fred in the current working directory."

The chdir operator changes the working directory. It's just like the Unix shell's cd command:

chdir "/etc" or die "cannot chdir to /etc: $!";

Because this is a system request, the value of $! will be set if an error occurs. You should normally check $! when a false value is returned from chdir, since that indicates that something has not gone as requested.

The working directory is inherited by all processes that Perl starts (we'll talk more about that in Chapter 14, "Process Management"). However, the change in working directory cannot affect the process that invoked Perl, such as the shell.[275] So you can't make a Perl program to replace your shell's cd command.

[275]This isn't a limitation on Perl's part; it's actually a feature of Unix, Windows, and other systems. If you really need to change the shell's working directory, see the documentation of your shell.

If you omit the parameter, Perl determines your home directory as best as possible and attempts to set the working directory to your home directory, similar to using the cd command at the shell without a parameter. This is one of the few places where omitting the parameter doesn't use $_.

Some shells permit you to use a tilde-prefixed path with cd to use another user's home directory as a starting point (like cd ~merlyn). This is a function of the shell, not the operating system, and Perl is calling the operating system directly. Thus, a tilde-prefix will not work with chdir.

Previous | Home | Next
11.7. Exercises | Book Index | 12.2. Globbing
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.2. Globbing

Normally, the shell expands any filename patterns on each command line into the matching filenames. This is called globbing. For example, if you give a filename pattern of *.pm to the echo command, the shell expands this list to a list of names that match:

$ echo *.pm
barney.pm dino.pm fred.pm wilma.pm
$

The echo command doesn't have to know anything about expanding *.pm, because the shell has already expanded it. This works even for your Perl programs:

$ cat >show-args
foreach $arg (@ARGV) {
  print "one arg is $arg\n";
}
^D
$ perl show-args *.pm
one arg is barney.pm
one arg is dino.pm
one arg is fred.pm
one arg is wilma.pm
$

Note that show-args didn't need to know anything about globbing -- the names were already expanded in @ARGV.

But sometimes we end up with a pattern like *.pm inside our Perl program. Can we expand this pattern into the matching filenames without working very hard? Sure -- just use the glob operator:

my @all_files = glob "*";
my @pm_files = glob "*.pm";

Here, @all_files gets all the files in the current directory, alphabetically sorted, and not including the files beginning with a period, just like the shell. And @pm_files gets the same list as we got before by using *.pm on the command line.

In fact, anything you can say on the command line, you can also put as the (single) argument to glob, including multiple patterns separated by spaces:

my @all_files_including_dot = glob ".* *";

Here, we've included an additional "dot star" parameter to get the filenames that begin with a dot as well as the ones that don't. Please note that the space between these two items inside the quoted string is significant, as it separates two different items to be globbed.[276]

[276]Windows users may be accustomed to using a glob of *.* to mean "all files". But that actually means "all files with a dot in their names," even in Perl on Windows.

The reason this works exactly as the shell works is that prior to Perl Version 5.6, the glob operator simply called /bin/csh [277] behind the scenes to perform the expansion. Because of this, globs were time-consuming and could break in large directories, or in some other cases. Conscientious Perl hackers avoided globbing in favor of directory handles, which will be discussed in Section 12.4, "Directory Handles" later in this chapter. However, if you're using a modern version of Perl, you should no longer be concerned about such things.

[277]Or it will call a valid substitute if a C-shell wasn't available.

Previous | Home | Next
12. Directory Operations | Book Index | 12.3. An Alternate Syntax for Globbing
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.3. An Alternate Syntax for Globbing

Although we use the term globbing freely, and we talk about the glob operator, you might not see the word glob in very many of the programs that use globbing. Why not? Well, most legacy code was written before the glob operator was given a name. Instead, it was called up by the angle-bracket syntax, similar to reading from a filehandle:

my @all_files = <*>; ## exactly the same as my @all_files = glob "*";

The value between the angle brackets is interpolated similar to a double-quoted string, which means that Perl variables are expanded to their current Perl values before being globbed:

my $dir = "/etc";
my @dir_files = <$dir/* $dir/.*>;

Here, we've fetched all the non-dot and dot files from the designated directory, because $dir has been expanded to its current value.

So, if using angle brackets means both filehandle reading and globbing, how does Perl decide which of the two operators to use? Well, a filehandle has to be a Perl identifier. So if the item between the angle brackets is strictly a Perl identifier, it's a filehandle read; otherwise, it's a globbing operation. For example:

my @files = <FRED/*>;   ## a glob
my @lines = <FRED>;    ## a filehandle read
my $name = "FRED";
my @files = <$name/*>; ## a glob

The one exception is if the contents are a simple scalar variable (not an element of a hash or array), then it's an indirect filehandle read,[278] where the variable contents give the name of the filehandle to be read:

[278]If the indirect handle is a text string, then it's subject to the "symbolic reference" test that is forbidden under use strict. However, the indirect handle might also be a typeglob or reference to an IO object, and then it would work even under use strict.

my $name = "FRED";
my @lines = <$name>; ## an indirect filehandle read of FRED handle

Determining whether it's a glob or a filehandle read is made at compile time, and thus it is independent of the content of the variables.

If you want, you can get the operation of an indirect filehandle read using the readline operator,[279] which also makes it clearer:

[279]If you're using Perl 5.005 or later.

my $name = "FRED";
my @lines = readline FRED;  ## read from FRED
my @lines = readline $name; ## read from FRED

But the readline operator is rarely used, as indirect filehandle reads are uncommon and are generally performed against a simple scalar variable anyway.

Previous | Home | Next
12.2. Globbing | Book Index | 12.4. Directory Handles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.4. Directory Handles

Another way to get a list of names from a given directory is with a directory handle. A directory handle looks and acts like a filehandle. You open it (with opendir instead of open), you read from it (with readdir instead of readline), and you close it (with closedir instead of close). But instead of reading the contents of a file, you're reading the names of files (and other things) in a directory. For example:

my $dir_to_process = "/etc";
opendir DH, $dir or die "Cannot open $dir: $!";
foreach $file (readdir DH) {
  print "one file in $dir is $file\n";
}
closedir DH;

Like filehandles, directory handles are automatically closed at the end of the program or if the directory handle is reopened onto another directory.

Unlike globbing, which in older versions of Perl fired off a separate process, a directory handle never fires off another process. So it makes them more efficient for applications that demand every ounce of power from the machine. However, it's also a lower-level operation, meaning that we have to do more of the work ourselves.

For example, the names are returned in no particular order.[280] And the list includes all files, not just those matching a particular pattern (like *.pm from our globbing examples). And the list includes all files, especially the dot files, and particularly the dot and dot-dot entries.[281]

[280]It's actually the unsorted order of the directory entries, similar to the order you get from ls -f or find.

[281]Do not make the mistake of many old Unix programs and presume that dot and dot-dot are always returned as the first two entries (sorted or not). If that hadn't even occurred to you, pretend we never said it, because it's a false presumption. In fact, we're now sorry for even bringing it up.

So, if we wanted only the pm-ending files, we could use a skip-over function inside the loop:

while ($name = readdir DIR) {
  next unless $name =~ /\.pm$/;
  ... more processing ...
}

Note here that the syntax is that of a regular expression, not a glob. And if we wanted all the non-dot files, we could say that:

next if $name =~ /^\./;

Or if we wanted everything but the common dot (current directory) and dot-dot (parent directory) entries, we could explicitly say that:

next if $name eq "." or $name eq "..";

Now we'll look at the part that gets most people mixed up, so pay close attention. The filenames returned by the readdir operator have no pathname component. It's just the name within the directory. So, we're not looking at /etc/passwd, we're just looking at passwd. (And because this is another difference from the globbing operation, it's easy to see how people get confused.)

So you'll need to patch up the name to get the full name:

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
  ...
}

Without the patch, the file tests would have been checking files in the current directory, rather than in the directory named in $dirname. This is the single most-common mistake when using directory handles.

Previous | Home | Next
12.3. An Alternate Syntax for Globbing | Book Index | 12.5. Recursive Directory Listing
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.5. Recursive Directory Listing

You probably won't need recursive directory access for the first few dozen hours of your Perl programming career. So rather than distract you with the possibility of replacing all those ugly find scripts with Perl right now, we'll simply entice you by saying that Perl comes with a nice library called File::Find, which you can use for nifty recursive directory processing. We're also saying this to keep you from writing your own routines, which everyone seems to want to do after those first few dozen hours of programming, and then getting puzzled about things like "local directory handles" and "how do I change my directory back?" So, when you're ready, the knowledge will come, but stay with us to learn about Manipulating Files and Directories (in the next chapter) instead, right after you finish these exercises.

Previous | Home | Next
12.4. Directory Handles | Book Index | 12.6. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.6. Exercises

See Section A.11, "Answers to Chapter 12 Exercises" for answers to the following exercises.

  1. [12] Write a program to ask the user for a directory name, then change to that directory. If the user enters a line with nothing but whitespace, change to his or her home directory as a default. After changing, list the ordinary directory contents (not the items whose names begin with a dot) in alphabetical order. (Hint: Will that be easier to do with a directory handle or with a glob?) If the directory change doesn't succeed, just alert the user -- but don't try show the contents.

  2. [4] Modify the program to include all files, not just the ones that don't begin with a dot.

  3. [5] If you used a directory handle for the previous exercise, rewrite it to use a glob. Or if you used a glob, try it now with a directory handle.

Previous | Home | Next
12.5. Recursive Directory Listing | Book Index | 13. Manipulating Files and Directories
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 13. Manipulating Files and Directories

Contents:

Removing Files
Renaming Files
Links and Files
Making and Removing Directories
Modifying Permissions
Changing Ownership
Changing Timestamps
Using Simple Modules
Exercises

Perl is commonly used to wrangle files and directories. Because Perl grew up in a Unix environment and still spends most of its time there, most of the description in this chapter may seem Unix-centric. But the nice thing is that to whatever degree possible, Perl works exactly the same way on non-Unix systems.

And now a word of warning -- some cultures consider the number "13" to be very unlucky. We deliberately placed this material as Chapter 13, "Manipulating Files and Directories" of this book, since we're about to do some pretty dangerous things if bugs creep into the code (like remove files without a chance of recovery), so be very careful when you're playing with the exercises.

13.1. Removing Files

Most of the time, we make files so that the data can stay around for a while. But when the data has outlived its life, it's time to make the file go away. At the Unix shell level, we'd type an rm command to remove a file or files:

$ rm slate bedrock lava

In Perl, we use the unlink operator:

unlink "slate", "bedrock", "lava";

This sends the three named files away to bit heaven, never to be seen again.

Now, since unlink takes a list, and the glob function (described in Chapter 12, "Directory Operations") returns a list, we can combine the two to delete many files at once:

unlink glob "*.o";

This is similar to rm *.o at the shell, except that we didn't have to fire off a separate rm process. So we can make those important files go away that much faster!

The return value from unlink tells us how many files have been successfully deleted. So, back to the first example, we can check its success:

my $successful = unlink "slate", "bedrock", "lava";
print "I deleted $successful file(s) just now\n";

Sure, if this number is 3, we know it removed all of the files, and if it's 0, then we removed none of them. But what if it's 1 or 2? Well, there's no clue which ones were removed. If you need to know, do them one at a time in a loop:

foreach my $file (qw(slate bedrock lava)) {
  unlink $file or warn "failed on $file: $!\n";
}

Here, each file being deleted one at a time means the return value will be 0 (failed) or 1 (succeeded), which happens to look like a nice Boolean value, controlling the execution of warn. Using or warn is similar to or die, except that it's not fatal, of course (as we said back in Chapter 11, "Filehandles and File Tests"). In this case, we put the newline on the end of the message to warn, because it's not a bug in our program that causes the message.

When a particular unlink fails, the $! variable is set to something related to the operating system error, which we've included in the message. This makes sense to use only when doing one filename at a time, because the next operating system failed request resets the variable. You can't remove a directory with unlink (just like you can't remove a directory with the simple rm invocation either). Look for the rmdir function coming up shortly for that.

Now, here's a little-known Unix fact. It turns out that you can have a file that you can't read, you can't write, you can't execute, maybe you don't even own the file -- that is, it's somebody else's file altogether -- but you can still delete the file. That's because the permission to unlink a file doesn't depend upon the permission bits on the file itself; it's the permission bits on the directory that contains the file that matter.

We mention this because it's normal for a beginning Perl programmer, in the course of trying out unlink, to make a file, to chmod it to 0 (so that it's not readable or writable), and then to see whether this makes unlink fail. But instead it vanishes without so much as a whimper.[282] If you really want to see a failed unlink, though, just try to remove /etc/passwd or a similar system file. Since that's a file controlled by the system administrator, you won't be able to remove it.[283]

[282]Some of these folks know that rm would generally ask before deleting such a file. But rm is a command, and unlink is a system call. System calls never ask permission, and they never say they're sorry.

[283]Of course, if you're silly enough to try this kind of thing when you are logged in as the system administrator, you deserve what you get.

Previous | Home | Next
12.6. Exercises | Book Index | 13.2. Renaming Files
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.2. Renaming Files

Giving an existing file a new name is simple with the rename function:

rename "old", "new";

This is similar to the Unix mv command, taking a file named old and giving it the name new in the same directory. You can even move things around:

rename "over_there/some/place/some_file", "some_file";

This moves a file called some_file from another directory into the current directory, provided the user running the program has the appropriate permissions.[284]

[284]And the files must reside on the same filesystem. We'll see why this rule exists a little later in this chapter.

Like most functions that request something of the operating system, rename returns false if it fails, and sets $! with the operating system error, so you can (and often should) use or die (or or warn) to report this to the user.

One frequent[285] question in the Unix shell-usage newsgroups is how to rename everything that ends with ".old " to the same name with ".new". Here's how to do it in Perl nicely:

[285]This isn't just any old frequent question; the question of renaming a batch of files at once is the mostfrequent question asked in these newsgroups. And that's why it's the first question answered in the FAQs for those newsgroups. And yet, it stays in first place. Hmmm.

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";
  }
}

The check for the existence of $newfile is needed because rename will happily rename a file right over the top of an existing file, presuming the user has permission to remove the destination filename. We put the check in so that it's less likely that we'll lose information this way. Of course, if you wanted to replace existing files like wilma.new, you wouldn't bother testing with -e first.

Those first two lines inside the loop can be combined (and often are) to simply be:

(my $newfile = $file) =~ s/\.old$/.new/;

This works to declare $newfile, copy its initial value from $file, then select $newfile to be modified by the substitution. You can read this as "transform $file to $newfile using this replacement on the right." And yes, because of precedence, those parentheses are required.

Also, some programmers seeing this substitution for the first time wonder why the backslash is needed on the left, but not on the right. The two sides aren't symmetrical: the left part of a substitution is a regular expression, and the right part is a double-quotish string. So we use the pattern /\.old$/ to mean ".old anchored at the end of the string" (anchored at the end, because we don't want to rename the first occurrance of .old in a file called betty.old.old), but on the right we can simply write .new to make the replacement.

Previous | Home | Next
13. Manipulating Files and Directories | Book Index | 13.3. Links and Files
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.3. Links and Files

To understand more about what's going on with files and directories, it helps to understand the Unix model of files and directories, even if your non-Unix system doesn't work in exactly this way. As usual, there's more to the story than we're able to explain here, so check any good book on Unix internal details if you need the full story.

A mounted volume is a hard disk drive (or something else that works more-or-less like that, such as a disk partition, a floppy disk, a CD-ROM, or a DVD-ROM). It may contain any number of files and directories. Each file is stored in a numbered inode, which we can think of as a particular piece of disk real estate. One file might be stored in inode 613, while another is in inode 7033.

To locate a particular file, though, we'll have to look it up in a directory. A directory is a special kind of file, maintained by the system. Essentially, it is a table of filenames and their inode numbers.[286] Along with the other things in the directory, there are always two special directory entries. One is . (called "dot"), which is the name of that very directory; and the other is .. ("dot-dot"), which is the directory one step higher in the hierarchy (i.e., the directory's parent directory).[287]

[286]On Unix systems (others don't generally have inodes, hard links, and such), you can use the ls command's -i option to see files' inode numbers. Try a command like ls -ail. When two or more inode numbers are the same for multiple items on a given filesystem, there's really just one file involved, one piece of the disk.

[287]The Unix system root directory has no parent. In that directory, .. is the same directory as ., which is the system root directory itself.

Figure 13-1 provides an illustration of two inodes. One is for a file called chicken, and the other is Barney's directory of poems, /home/barney/poems, which contains that file. The file is stored in inode 613, while the directory is stored in inode 919. (The directory's own name, poems, doesn't appear in the illustration, because that's stored in another directory.) The directory contains entries for three files (including chicken) and two directories (one of which is the reference back to the directory itself, in inode 919), along with each item's inode number.

Figure 13-1. The chicken before the egg

When it's time to make a new file in a given directory, the system adds an entry with the file's name and the number of a new inode. How can the system tell that a particular inode is available, though? Each inode holds a number called its link count. The link count is always zero if the inode isn't listed in any directory, so any inode with a link count of zero is available for new file storage. When the inode is added to a directory, the link count is incremented; when the listing is removed, the link count is decremented. For the file chicken as illustrated above, the inode count of 1 is shown in the box above the inode's data.

But some inodes have more than one listing. For example, we've already seen that each directory entry includes ., which points back to that directory's own inode. So the link count for a directory should always be at least two: its listing in its parent directory and its listing in itself. In addition, if it has subdirectories, each of those will add a link, since each will contain ...[288] In Figure 13-1, the directory's inode count of 2 is shown in the box above its data. A link count is the number of true names for the inode.[289]

[288]This implies that the link count of a directory is always equal to two plus the number of directories it contains. On some systems that's true, in fact, but some other systems work differently.

[289]In the traditional output of ls -l, the number of hard links to the item appears just to the right of the permission flags (like "-rwxr-xr-x"). Now you know why this number is more than one for directories and nearly always 1 for ordinary files.

Could an ordinary file inode have more than one listing in the directory? It certainly could. Suppose that, working in the directory shown above, Barney uses the Perl's link function to create a new link:

link "chicken", "egg"
  or warn "can't link chicken to egg: $!";

This is similar to typing "ln chicken egg" at the Unix shell prompt. If link succeeds, it returns true. If it fails, it returns false and sets $!, which Barney is checking in the error message. After this runs, the name egg is another name for the file chicken, and vice versa; neither name is "more real" than the other, and (as you may have guessed) it would take some detective work to find out which came first. Figure 13-2 shows a picture of the new situation, where there are two links to inode 613.

Figure 13-2. The egg is linked to the chicken

These two filenames are thus talking about the same place on the disk. If the file chicken holds 200 bytes of data, egg holds the same 200 bytes, for a total of 200 bytes (since it's really just one file with two names). If Barney appends a new line of text to file egg, that line will also appear at the end of chicken. [290]

[290]If you experiment with making links and changing text files, be aware that most text editors don't edit the file "in place" but instead save a modified copy. If Barney were to edit egg with a text editor, he'd most likely end up with a new file called egg and the old file called chicken -- two separate files, rather than two links to the same file.

Now, if Barney were to accidentally (or intentionally) delete chicken, that data will not be lost -- it's still available under the name egg. And vice versa: if he were to delete egg, he'd still have chicken. Of course, if he deletes both of them, the data will be lost.[291]

[291]Although the system won't necessarily overwrite this inode right away, there's no easy way in general to get the data back once the link count has gone to zero. Have you made a backup recently?

There's another rule about the links in directory listings: the inode numbers in a given directory listing all refer to inodes on that same mounted volume.[292] This rule ensures that if the physical medium (the diskette, perhaps) is moved to another machine, all of the directories stick together with their files. That's why you can use rename to move a file from one directory to another, but only if both directories are on the same filesystem (mounted volume). If they were on different disks, the inode's data would have to be relocated, which is too complex an operation for a simple system call.

[292]The one exception is the special .. entry in the volume's root directory, which refers to the directory in which that volume is mounted.

And yet another restriction on links is that they can't make new names for directories. That's because the directories are arranged in a hierarchy. If you were able to change that, utility programs like find and pwd could easily become lost trying to find their way around the filesystem.

So, links can't be added to directories, and they can't cross from one mounted volume to another. Fortunately, there's a way to get around these restrictions on links, by using a new and different kind of link: a symbolic link .[293] A symbolic link (also called a soft link to distinguish it from the true or hard links that we've been talking about up to now) is a special entry in a directory that tells the system to look elsewhere. Let's say that Barney (working in the same directory of poems as before) creates a symbolic link with Perl's symlink function, like this:

[293]Some veryold Unix systems don't support symlinks, but those are pretty rare nowadays.

symlink "dodgson", "carroll"
  or warn "can't symlink dodgson to carroll: $!";

This is similar to what would happen if Barney used the command "ln -s dodgson carroll" from the shell. Figure 13-3 shows a picture of the result, including the poem in inode 7033.

Figure 13-3. A symlink to inode 7033

Now if Barney chooses to read /home/barney/poems/carroll, he gets the same data as if he had opened /home/barney/poems/dodgson, because the system follows the symbolic link automatically. But that new name isn't the "real" name of the file, because (as you can see in the diagram) the link count on inode 7033 is still just one. That's because the symbolic link simply tells the system, "If you got here looking for carroll, now you want to go off to find something called dodgson instead."

A symbolic link can freely cross mounted filesystems or provide a new name for a directory, unlike a hard link. In fact, a symbolic link could point to any filename, one in this directory or in another one -- or even to a file that doesn't exist! But that also means that a soft link can't keep data from being lost as a hard link can, since the symlink doesn't contribute to the link count. If Barney were to delete dodgson, the system would no longer be able to follow the soft link.[294] Even though there would still be an entry called carroll, trying to read from it would give an error like file not found. The file test -l 'carroll' would report true, but -e 'carroll' would be false: it's a symlink, but it doesn't exist.

[294]Deleting carroll would merely remove the symlink, of course.

Since a soft link could point to a file that doesn't yet exist, it could be used when creating a file as well. Barney has most of his files in his home directory, /home/barney, but he also needs frequent access to a directory with a long name that is difficult to type: /usr/local/opt/system/httpd/root-dev/users/staging/barney/cgi-bin. So he sets up a symlink named /home/barney/my_stuff, which points to that long name, and now it's easy for him to get to it. If he creates a file (from his home directory) called my_stuff/bowling, that file's real name is /usr/local/opt/system/httpd/root-dev/users/staging/barney/cgi-bin/bowling. Next week, when the system administrator moves these files of Barney's to /usr/local/opt/internal/httpd/www-dev/users/staging/barney/cgi-bin, Barney just repoints the one symlink, and now he and all of his programs can still find his files with ease.

It's normal for either /usr/bin/perl or /usr/local/bin/perl (or both) to be symbolic links to the true Perl binary on your system. This makes it easy to switch to a new version of Perl. Say you're the system administrator, and you've built the new Perl. Of course, your older version is still running, and you don't want to disrupt anything. When you're ready for the switch, you simply move a symlink or two, and now every program that begins with #!/usr/bin/perl will automatically use the new version. In the unlikely case that there's some problem, it's a simple thing to replace the old symlinks and have the older Perl running the show again. (But, like any good admin, you notified your users to test their code with the new /usr/bin/perl-7.2 well in advance of the switch, and you told them that they can keep using the older one during the next month's grace period by changing their programs' first lines to #!/usr/bin/perl-6.1, if they need to.)

Perhaps suprisingly, both hard and soft links are very useful. Many non-Unix operating systems have neither, and the lack is sorely felt. On some non-Unix systems, symbolic links may be implemented as a "shortcut" or an "alias" -- check the perlport manpage for the latest details.

To find out where a symbolic link is pointing, use the readlink function. This will tell you where the symlink leads, or it will return undef if its argument wasn't a symlink:

my $where = readlink "carroll";             # Gives "dodgson"

my $perl = readlink "/usr/local/bin/perl";  # Maybe tells where perl is

You can remove either kind of link with unlink -- and now you see where that operation gets its name. unlink simply removes the directory entry associated with the given filename, decrementing the link count and thus possibly freeing the inode.

Previous | Home | Next
13.2. Renaming Files | Book Index | 13.4. Making and Removing Directories
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.4. Making and Removing Directories

Making a directory inside an existing directory is easy. Just invoke the mkdir function:

mkdir "fred", 0755 or warn "Cannot make fred directory: $!";

Again, true means success, and $! is set on failure.

But what's that second parameter, 0755? That's the initial permission setting[295] on the newly created directory (you can always change it later). The value here is specified as an octal value because the value will be interpreted as a Unix permission value, which has a meaning based on groups of three bits each, and octal values represent that nicely. Yes, even on Windows or MacPerl, you still need to know a little about Unix permissions values to use the mkdir function. Mode 0755 is a good one to use, because it gives you full permission, but lets everyone else have read access but no permission to change anything.

[295]The permission value is modified by the umask value in the usual way. See umask(2) for further information.

The mkdir function doesn't require you to specify this value in octal -- it's just looking for a numeric value (either a literal or a calculation). But unless you can quickly can figure that 0755 octal is 493 decimal in your head, it's probably easier to let Perl calculate that. And if you accidentally leave off the leading zero, you get 755 decimal, which is 1363 octal, a strange permission combination indeed.

As we saw earlier (in Chapter 2, "Scalar Data"), a string value being used as a number is never interpreted as octal, even if it starts with a leading 0. So this doesn't work:

my $name = "fred";
my $permissions = "0755";  # danger... this isn't working
mkdir $name, $permissions;

Oops, we just created a directory with that bizarre 01363 permissions, because 0755 was treated as decimal. To fix that, use the oct function, which forces octal interpretation of a string whether or not there's a leading zero:

mkdir $name, oct($permissions);

Of course, if you are specifying the permission value directly within the program, just use a number instead of a string. The need for the extra oct function shows up most often when the value comes from user input. For example, suppose we take the arguments from the command line:

my ($name, $perm) = @ARGV;  # first two args are name, permissions
mkdir $name, oct($perm) or die "cannot create $name: $!";

The value here for $perm is interpreted as a string initially, and thus the oct function interprets the common octal representation properly.

To remove empty directories, use the rmdir function in a manner similar to the unlink function:

rmdir glob "fred/*";  # remove all empty directories below fred/

foreach my $dir (qw(fred barney betty)) {
  rmdir $dir or warn "cannot rmdir $dir: $!\n";
}

As with unlink, rmdir returns the number of directories removed, and if invoked with a single name, sets $! in a reasonable manner on a failure.

The rmdir operator fails for non-empty directories. As a first pass, you can attempt to delete the contents of the directory with unlink, then try to remove what should now be an empty directory. For example, suppose we need a place to write many temporary files during the execution of a program:

my $temp_dir = "/tmp/scratch_$$";       # based on process ID; see the text
mkdir $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_dir
rmdir $temp_dir;                        # delete now-empty directory

The initial temporary directory name includes the current process ID, which is unique for every running process and is accessed with the $$ variable (similar to the shell). We do this to avoid colliding with any other processes, as long as they also include their process ID as part of their pathname as well. (In fact, it's common to use the program's name as well as the process ID, so if the program is called quarry, the directory would probably be something like /tmp/quarry_$$.)

At the end of the program, that last unlink should remove all the files in this temporary directory, and then the rmdir function can delete the then-empty directory. However, if we've created subdirectories under that directory, the unlink operator fails on those, and the rmdir also fails. For a more robust solution, check out the rmtree function provided by the File::Path module of the standard distribution.

Previous | Home | Next
13.3. Links and Files | Book Index | 13.5. Modifying Permissions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.5. Modifying Permissions

The Unix chmod command changes the permissions on a file or directory. Similarly, Perl has the chmod function to perform this task:

chmod 0755, "fred", "barney";

As with many of the operating system interface functions, chmod returns the number of items successfully altered, and when used with a single argument, sets $! in a sensible way for error messages when it fails. The first parameter is the Unix permission value (even for non-Unix versions of Perl). For the same reasons we presented earlier in describing mkdir, this value is usually specified in octal.

Symbolic permissions (like +x or go=u-w) accepted by the Unix chmod command are not valid for the chmod function.[296]

[296]Unless you've installed and invoke the File::chmod module from CPAN, which can apparently upgrade the chmod operator to understand symbolic mode values.

Previous | Home | Next
13.4. Making and Removing Directories | Book Index | 13.6. Changing Ownership
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.6. Changing Ownership

If the operating system permits it, you may change the ownership and group membership of a list of files with the chown function. The user and group are both changed at once, and both have to be the numeric user-ID and group-ID values. For example:

my $user = 1004;
my $group = 100;
chown $user, $group, glob "*.o";

What if you have a username like merlyn instead of the number? Simple. Just call the getpwnam function to translate the name into a number, and the corresponding getgrnam[297] to translate the group name into its number:

[297]These two are among the ugliest function names known to mankind. But don't blame Larry for them; he's just giving them the same names that the folks at Berkeley did.

defined(my $user = getpwnam "merlyn") or die "bad user";
defined(my $group = getgrnam "users") or die "bad group";
chown $user, $group, glob "/home/merlyn/*";

The defined function verifies that the return value is not undef, which will be returned if the requested user or group is not valid.

The chown function returns the number of files affected, and it sets $! on error.

Previous | Home | Next
13.5. Modifying Permissions | Book Index | 13.7. Changing Timestamps
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.7. Changing Timestamps

In those rare cases when you want to lie to other programs about when a file was most recently modified or accessed, you can use the utime function to fudge the books a bit. The first two arguments give the new access time and modification time, while the remaining arguments are the list of filenames to alter to those timestamps. The times are specified in internal timestamp format (the same type of values returned from the stat function that we mentioned in Chapter 12, "Directory Operations").

One convenient value to use for the timestamps is "right now", returned in the proper format by the time function. So to update all the files in the current directory to look like they were modified a day ago, but accessed just now, we could simply do this:

my $now = time;
my $ago = $now - 24 * 60 * 60;  # seconds per day
utime $now, $ago, glob "*";     # set access to now, mod to a day ago

Of course, nothing stops you from creating a file that is arbitrarily stamped far in the future or past (within the limits of the Unix timestamp values of 1970 to 2038, or whatever your non-Unix system uses, until we get 64-bit timestamps). Maybe you could use this to create a directory where you keep your notes for that time-travel novel you're writing.

The third timestamp (the ctime value) is always set to "now" whenever anything alters a file, so there's no way to set it (it would have to be reset to "now" after you set it) with the utime function. That's because it's primary purpose is for incremental backups: if the file's ctime is newer than the date on the backup tape, it's time to back it up again.

Previous | Home | Next
13.6. Changing Ownership | Book Index | 13.8. Using Simple Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.8. Using Simple Modules

Suppose that you've got a long filename like /usr/local/bin/perl in your program, and you need to find out the basename. That's easy enough, since the basename is everything after the last slash (it's just "perl" in this case):

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

As we saw earlier, first Perl will do the assignment inside the parentheses, then it will do the substitution. The substitution is supposed to replace any string ending with a slash (that is, the directory name portion) with an empty string, leaving just the basename.

And if you try this, it seems to work. Well, it seems to, but actually, there are three problems.

First, a Unix file or directory name could contain a newline character. (It's not something that's likely to happen by accident, but it's permitted.) So, since the regular expression dot (".") can't match a newline, a filename like the string "/home/fred/flintstone\n/brontosaurus" won't work right -- that code would think the basename is "flintstone\n/brontosaurus". You could fix that with the /s option to the pattern (if you remembered about this subtle and infrequent case), making the substitution look like this: s#.*/##s

The second problem is that this is Unix-specific. It assumes that the forward slash will always be the directory separator, as it is on Unix, and not the backslash or colon that some systems use.

And the third (and biggest) problem with this is that we're trying to solve a problem that someone else has already solved. Perl comes with a number of modules, which are smart extensions to Perl that add to its functionality. And if those aren't enough, there are many other useful modules available on CPAN, with new ones being added every week. You (or, better yet, your system administrator) can install them if you need their functionality.

In the rest of this section, we'll show you how to use some of the features of a couple of simple modules that come with Perl. (There's more that these modules can do; this is just an overview to illustrate the general principles of how to use a simple module.)

Alas, we can't show you everything you'd need to know about using modules in general, since you'd have to understand advanced topics like references and objects in order to use some modules.[298] But this section should prepare you for using many simple modules. Further information on some interesting and useful modules is included in Appendix B, "Beyond the Llama".

[298]As we'll see in the next few pages, though, you may be able to use a module that uses objects and references without having to understand those advanced topics.

13.8.1. The File::Basename Module

In the previous example, we found the basename of a filename in a way that's not portable. We showed that something that seemed straightforward was susceptible to subtle mistaken assumptions (here, the assumption was that newlines would never appear in file or directory names). And we were re-inventing the wheel, solving a problem that others have solved (and debugged) many times before us.

Here's a better way to extract the basename of a filename. Perl comes with a module called File::Basename. With the command perldoc File::Basename, or with your system's documentation system, you can read about what it does. That's the first step when using a new module. (It's often the third and fifth step, as well.)

Soon you're ready to use it, so you declare it with a use directive near the top of your program:[299]

[299]It's traditional to declare modules near the top of the file, since that makes it easy for the maintenance programmer to see which modules you'll be using. That greatly simplifies matters when it's time to install your program on a new machine, for example.

use File::Basename;

During compilation, Perl sees that line and loads up the module. Now, it's as if Perl has some new functions that you may use in the remainder of your program.[300] The one we wanted in the earlier example is the basename function itself:

[300]You guessed it: there's more to the story, having to do with packages and fully qualified names. When your programs are growing beyond a few hundred lines in the main program (not counting code in modules), which is quite large in Perl, you should probably read up about these advanced features. Start with the perlmod manpage.

my $name = "/usr/local/bin/perl";
my $basename = basename $name;  # gives 'perl'

Well, that worked for Unix. What if our program were running on MacPerl or Windows or VMS, to name a few? There's no problem -- this module can tell which kind of machine you're using, and it uses that machine's filename rules by default. (Of course, you'd have that machine's kind of filename string in $name, in that case.)

There are some related functions also provided by this module. One is the dirname function, which pulls the directory name from a full filename. The module also lets you separate a filename from its extension, or change the default set of filename rules.[301]

[301]You might need to change the filename rules if you were trying to work with a Unix machine's filenames from a Windows machine -- perhaps while sending commands over an FTP connection, for example.

13.8.2. Using Only Some Functions from a Module

Suppose you discovered that when you went to add the File::Basename module to your existing program, you already have a subroutine called &dirname -- that is, you already have a subroutine with the same name as one of the module's functions.[302] Now there's trouble, because the new dirname is also implemented as a Perl subroutine (inside the module). What do you do?

[302]Well, it's not likely that you would already have a &dirname subroutine that you use for another purpose, but this is just an example. Some modules offer hundreds (really!) of new functions, making a name collision that much more frequent.

Simply give File::Basename, in your use declaration, an import list showing exactly which function names it should give you, and it'll supply those and no others. Here, we'll get nothing but basename:

use File::Basename qw/ basename /;

And here, we'll ask for no new functions at all:

use File::Basename qw/ /;

Why would you want to do that? Well, this directive tells Perl to load up File::Basename, just as before, but not to import any function names. Importing lets us use the short, simple function names like basename and dirname. But even if we don't import those names, we can still use the functions. When they're not imported, though, we have to call them by their full names:

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

As you see, the full name of the dirname function from the module is File::Basename::dirname. We can always use the function's full name (once we've loaded the module) whether we've imported the short name dirname or not.

Most of the time, you'll want to use a module's default import list. But you can always override that with a list of your own, if you want to leave out some of the default items. Another reason to supply your own list would be if you wanted to import some function not on the default list, since most modules include some (infrequently needed) functions that are not on the default import list.

As you'd guess, some modules will, by default, import more symbols than others. Each module's documentation should make it clear which symbols it imports, if any, but you are always free to override the default import list by specifying one of your own, just as we did with File::Basename. Supplying an empty list imports no symbols.

13.8.3. The File::Spec Module

Now you can find out a file's basename. That's useful, but you'll often want to put that together with a directory name to get a full filename. For example, here we want to take a filename like /home/rootbeer/ice-2.1.txt and add a prefix to the basename:

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 basename
my $new_name = "$dirname/$basename";

rename($old_name, $new_name)
  or warn "Can't rename '$old_name' to '$new_name': $!";

Do you see the problem here? Once again, we're making the assumption that filenames will follow the Unix conventions and use a forward slash between the directory name and the basename. Fortunately, Perl comes with a module to help with this problem, too.

The File::Spec module is used for manipulating file specifications, which are the names of files, directories, and the other things that are stored on filesystems. Like File::Basename, it understands what kind of system it's running on, and it chooses the right set of rules every time. But unlike File::Basename, File::Spec is an object-oriented (often abbreviated "OO") module.

If you've never caught the fever of OO, don't let that bother you. If you understand objects, that's great; you can use this OO module. If you don't understand objects, that's okay, too. You just type the symbols as we show you, and it works just as if you knew what you were doing.

In this case, we learn from reading the documentation for File::Spec that we want to use a method called catfile. What's a method? It's just a different kind of function, as far as we're concerned here. The difference is that you'll always call the methods from File::Spec with their full names, like this:

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': $!";

As you can see, the full name of a method is the name of the module (called a class, here), a small arrow, and the short name of the method. It is important to use the small arrow, rather than the double-colon that we used with File::Basename.

Since we're calling the method by its full name, though, what symbols does the module import? None of them. That's normal for OO modules. So you don't have to worry about having a subroutine with the same name as one of the many methods of File::Spec.

Should you bother using modules like these? It's up to you, as always. If you're sure your program will never be run anywhere but on a Unix machine, say, and you're sure you completely understand the rules for filenames on Unix,[303] then you may prefer to hardcode your assumptions into your programs. But these modules give you an easy way to make your programs more robust in less time -- and more portable at no extra charge.

[303]If you didn't know that filenames and directory names could contain newline characters, as we mentioned earlier in this section, then you don't know all the rules, do you?

Previous | Home | Next
13.7. Changing Timestamps | Book Index | 13.9. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.9. Exercises

The programs here are potentially dangerous! Be careful to test them in a mostly empty directory to make it difficult to accidentally delete something useful.

See Section A.12, "Answers to Chapter 13 Exercises" for answers to the following exercises.

  1. [6] Write a program that works like rm, deleting any files named on the command line. (You don't need to handle any of the options of rm.)

  2. [10] Write a program that works like mv, renaming the first command-line argument to the second command-line argument. (You don't need to handle any of the options of mv or additional arguments.) Remember to allow for the destination to be a directory; if it is, use the same original basename in the new directory.

  3. [7] If your operating system supports it, write a program that works like ln, making a hard link from the first command-line argument to the second. (You don't need to handle options of ln or more arguments.) If your system doesn't have hard links, just print out a message telling what operation you would perform if it were available. Hint: This program has something in common with the previous one -- recognizing that could save you time in coding.

  4. [7] If your operating system supports it, fix up the program from the previous exercise to allow an optional -s switch before the other arguments to indicate that you want to make a soft link instead of a hard link. (Even if you don't have hard links, see whether you can at least make soft links with this program.)

  5. [7] If your operating system supports it, write a program to find any symbolic links in the current directory and print out their values (like ls -l would: name -> value).

Previous | Home | Next
13.8. Using Simple Modules | Book Index | 14. Process Management
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 14. Process Management

Contents:

The system Function
The exec Function
The Environment Variables
Using Backquotes to Capture Output
Processes as Filehandles
Getting Down and Dirty with Fork
Sending and Receiving Signals
Exercises

One of the best parts of being a programmer is launching someone else's code so that you don't have to write it yourself. It's time to learn how to manage your children[304] by launching other programs directly from Perl.

[304]Child processes, that is.

And like everything else in Perl, There's More Than One Way To Do It, with lots of overlap, variations, and special features. So if you don't like the first way, just read on for another page or two for a solution more to your liking.

Perl is very portable; most of the rest of this book doesn't need many notes saying that it works this way on Unix systems and that way on Windows and the other way on VMS. But when you're starting other programs on your machine, different programs are available on a Macintosh than you'll likely find on a Cray. The examples in this chapter are primarily Unix-based; if you have a non-Unix system, you can expect to see some differences.

14.1. The system Function

The simplest way to launch a child process in Perl to run a program is the system function. For example, to invoke the Unix date command from within Perl, it looks like:

system "date";

The child process runs the date command, which inherits Perl's standard input, standard output, and standard error. This mean that the normal short date-and-time string generated by date ends up wherever Perl's STDOUT was already going.

The parameter to the system function is generally whatever you'd normally type at the shell. So if it were a more complicated command, like "ls -l $HOME ", we'd just have put all that into the parameter:

system 'ls -l $HOME';

Note that we had to switch here from double quotes to single quotes, since $HOME is the shell's variable. Otherwise, the shell would never have seen the dollar sign, since that's also an indicator for Perl to interpolate. Alternatively, we could write:

system "ls -l \$HOME";

But that can get quickly unwieldly.

Now, the date command is output-only, but let's say it had been a chatty command, asking first "for which time zone do you want the time?"[305] That'll end up on standard output, and then the program will listen on standard input (inherited from Perl's STDIN) for the response. You'll see the question, and type in the answer (like "Zimbabwe time"), and then date will finish its duty.

[305]As far as we know, no one has made a date command that works like this.

While the child process is running, Perl is patiently waiting for it to finish. So if the date command took 37 seconds, then Perl is paused for those 37 seconds. You can use the shell's facility to launch a background process,[306] however:

[306]See what we mean about this depending upon your system? The Unix shell (/bin/sh) lets you use the ampersand on this kind of command to make a background process. If your non-Unix system doesn't support this way to launch a background process, then you can't do it this way, that's all.

system "long_running_command with parameters &";

Here, the shell gets launched, which then notices the ampersand at the end of the command line, causing the long_running_command to be made into a background process. And then the shell exits rather quickly, which Perl notices and moves on. In this case, the long_running_command is really a grandchild of the Perl process, to which Perl really has no direct access or knowledge.

When the command is "simple enough," no shell gets involved, so for the date and ls commands earlier, the requested command is launched directly by Perl, which searches the inherited PATH[307] to find the command, if necessary. But if there's anything weird in the string (such as shell metacharacters like the dollar sign, semicolon, or vertical bar), then the standard Bourne Shell (/bin/sh[308]) gets invoked to work through the complicated stuff. In that case, the shell is the child process, and the requested commands are grandchildren (or further offspring). For example, you can write an entire little shell script in the argument:

[307]The PATH can be changed by adjusting $ENV{'PATH'} at any time. Initially, this is the environment variable inherited from the parent process (usually the shell). Changing this value affects new child processes, but cannot affect any preceding parent processes. The PATH is the list of directories where executable programs (commands) are found, even on some non-Unix systems.

[308]Or whatever was determined when Perl was built. Practically always, this is just /bin/sh on Unix-like systems.

system 'for in *; do echo == $i ==; cat $i; done';

Here again, we're using single quotes, because the dollar signs here are meant for the shell and not for Perl. Double quotes would have permitted Perl to expand $i to its current Perl value, and not let the shell expand it to its own value.[309] By the way, that little shell script goes through all of the normal files in the current directory, printing out each one's name and contents; you can try it out yourself if you don't believe us.

[309]Of course, if you set $i = '$i', then it would work anyway, until a maintenance programmer came along and "fixed" that line out of existence.

14.1.1. Avoiding the Shell

The system operator may also be invoked with more than one argument,[310] in which case a shell doesn't get involved, no matter how complicated the text:

[310]Or with a parameter in the indirect-object slot, like system { 'fred' } 'barney';, which runs the program barney, but lies to it so it thinks that it's called 'fred'. See the perlfunc manpage.

my $tarfile = "something*wicked.tar";
my @dirs = qw(fred|flintstone <barney&rubble> betty );
system "tar", "cvf", $tarfile, @dirs;

In this case, the first parameter ("tar" here) gives the name of a command found in the normal PATH-searching way, while the remaining arguments are passed, one by one, directly to that command. Even if the arguments have shell-significant characters, such as the name in $tarfile or the directory names in @dirs, the shell never gets a chance to mangle the string. So that tar command will get precisely five parameters. Compare this with:

system "tar cvf $tarfile @dirs";  # Oops!

Here, we've now piped a bunch of stuff into a flintstone command and put it into the background, and opened betty for output.

And that's a bit scary,[311] especially if those variables are from user input -- such as from a web form or something. So, if you can arrange things so that you can use the multiple-argument version of system, you probably should use that way to launch your subprocess. (You'll have to give up the ability to have the shell do the work for you to set up I/O redirection, background processes, and the like, though. There's no such thing as a free launch.)

[311]Unless you're using taint checking and have done all the right things to prescan your data to ensure that the user isn't trying to pull a fast one on you.

Note that redundantly, a single argument invocation of system is nearly equivalent to the proper multiple-argument version of system:

system $command_line;
system "/bin/sh", "-c", $command_line;

But nobody writes the latter, unless you want things to be processed by a different shell, like the C-shell:

system "/bin/csh", "-fc", $command_line;

Even this is pretty rare, since the One True Shell[312] seems to have a lot more flexibility, especially for scripted items.

[312]That's /bin/sh, or whatever your Unix system has installed as the most Bourne-like shell. If you don't have a One True Shell, Perl figures out how to invoke some other command-line interpreter, with notable consequences -- noted, that is, in the documentation for that Perl port.

The return value of the system operator is based upon the exit status of the child command[313]. In Unix, an exit value of 0 means that everything is OK, and a non-zero exit value usually indicates that something went wrong:

[313]It's actually the "wait" status, which is the child exit code times 256, plus 128 if core was dumped, plus the signal number triggering termination, if any. But we rarely check the specifics of that, and a simple true/false value suffices for nearly all applications.

unless (system "date") {
  # Return was zero - meaning success
  print "We gave you a date, OK!\n";
}

Note that this is backward from the normal "true is good -- false is bad" strategy for most of the operators, so to write a typical "do this or die" style, we'll need to flip false and true. The easiest way is to simply prefix the system operator with a bang (the logical-not operator):

!system "rm -rf files_to_delete" or die "something went wrong";

In this case, including $! in the error message would not be appropriate, because the failure is most likely somewhere within the experience of the rm command, and it's not a system-call related error within Perl that $! can reveal.

Previous | Home | Next
13.9. Exercises | Book Index | 14.2. The exec Function
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.2. The exec Function

Everything we've just said about system syntax and semantics is also true about the exec function, except for one (very important) thing. The system function creates a child process, which then scurries off to perform the requested action while Perl naps. The exec function causes the Perl process itself to perform the requested action. Think of it as more like a "goto" than a subroutine call.

For example, suppose we wanted to run the bedrock command in the /tmp directory, passing it arguments of -o args1 followed by whatever arguments our own program was invoked with. That'd look like this:

chdir "/tmp" or die "Cannot chdir /tmp: $!";
exec "bedrock", "-o", "args1", @ARGV;

When we reach the exec operation, Perl locates bedrock, and "jumps into it." At that point, there is no Perl process any more,[314] just the process running the bedrock command. When bedrock is finished, there's no Perl to come back to, so we'd get a prompt back if we invoked this program from the command line.

[314]Actually, it's the same process, having performed the Unix exec(2) system call (or equivalent). The process ID remains the same.

Why is this useful? Well, if the purpose of this Perl program were to set up a particular environment to run another program, the purpose is fulfilled as soon as the other program has started. If we'd used system instead of exec, we'd have a Perl program just standing around tapping its toes waiting for the other program to complete, just so Perl could finally immediately exit as well, and that's a wasted resource.

Having said that, it's actually quite rare to use exec, except in combination with fork (which we'll see later). If you are puzzling over system versus exec, just pick system, and nearly all of the time, you'll be just fine.

Because Perl is no longer in control once the requested command has started, it doesn't make any sense to have any Perl code following the exec, except for handling the error when the requested command cannot be started:

exec "date";
die "date couldn't run: $!";

In fact, if you have warnings turned on, and if you have any code after the exec other than a die,[315] you'll get notified.

[315]Or exit. Or if it's at the end of a block. This may change in a new release of Perl, too.

Previous | Home | Next
14. Process Management | Book Index | 14.3. The Environment Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.3. The Environment Variables

When you're starting another process (with any of the methods discussed here), you may need to set up its environment in one way or another. As we mentioned earlier, you could start the process with a certain working directory, which it inherits from your process. Another common configuration detail is the environment variables.

The best-known environment variable is PATH. (If you've never heard of it, you probably haven't used a system that has environment variables.) On Unix and similar systems, PATH is a colon-separated list of directories that may hold programs. When you type a command like rm fred, the system will look for the rm command in that list of directories, in order. Perl (or your system) will use PATH whenever it needs to find the program to run. If the program in turn runs other programs, those may also be found along the PATH. (Of course, if you give a complete name for a command, such as /bin/echo, there's no need to search PATH. But that's generally much less convenient.)

In Perl, the environment variables are available via the special %ENV hash; each key in this hash represents one environment variable. At the start of your program's execution, %ENV holds values it has inherited from its parent process (generally the shell). Modifying this hash changes the environment variables, which will then be inherited by new processes and possibly used by Perl as well. For example, suppose you wished to run the system's make utility (which typically runs other programs), and you want to use a private directory as the first place to look for commands (including make itself). And let's say that you don't want the IFS environment variable to be set when you run the command, because that might cause make or some subcommand do the wrong thing. Here we go:

$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
delete $ENV{'IFS'};
my $make_result = system "make";

Newly created processes will generally inherit from their parent the environment variables, the current working directory, the standard input, output, and error streams, and a few more-esoteric items. See the documentation about programming on your system for more details. (But your program can't change the environment for the shell or other parent process that started it, on most systems.)

Previous | Home | Next
14.2. The exec Function | Book Index | 14.4. Using Backquotes to Capture Output
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.4. Using Backquotes to Capture Output

With both system and exec, the output of the launched command ends up wherever Perl's standard output is going. Sometimes, it's interesting to capture that output as a string value to perform further processing. And that's done simply by creating a string using backquotes instead of single or double quotes:

my $now = `date`;             # grab the output of date
print "The time is now $now"; # newline already present

Normally, this date command spits out a string approximately 30 characters long to its standard output, giving the current date and time followed by a newline. When we've placed date between backquotes, Perl executes the date command, arranging for its standard output to be captured as a string value, and in this case assigned to the $now variable.

This is very similar to the Unix shell's meaning for backquotes. However, the shell also performs the additional job of ripping off the final end-of-line to make it easier to use the value as part of other things. Perl is honest; it gives the real output. To get the same result in Perl, we can simply add an additional chomp operation on the result:

chomp(my $no_newline_now = `date`);
print "A moment ago, it was $no_newline_now, I think.\n";

The value beween backquotes is just like the single-argument form of system,[316] and is interpreted as a double-quoted string, meaning that backslash-escapes and variables are expanded appropriately.[317] For example, to fetch the Perl documentation on a list of Perl functions, we might invoke the perldoc command repeatedly, each time with a different argument:

[316]That is, it's also always interpreted by the One True Shell (/bin/sh) or alternative, as with system.

[317]So, if you want to pass a real backslash to the shell, you'll need to use two. If you need to pass two (which happens frequently on Windows systems), you'll need to use four.

my @functions = qw{ int rand sleep length hex eof not exit sqrt umask };
my %about;

foreach (@functions) {
  $about{$_} = `perldoc -t -f $_`;
}

Note that $_ will be a different value for each invocation, letting us grab the output of a different command varying only in one of its parameters. Also note that if you haven't seen some of these functions yet, it might be useful to look them up in the documentation to see what they do!

There's no easy equivalent of single quotes for backquotes[318] ; variable references and backslash items are always expanded. Also, there's no easy equivalent of the multiple-argument version of system (where a shell is never involved). If the command inside the backquotes is complex enough, a Unix Bourne Shell (or whatever your system uses instead) is invoked to interpret the command automatically.

[318]For a couple of harder ways, you can place your string inside qx'...'delimiters, or you can put it all in a variable using a single-quoted string, then interpolate that string into a backquoted string, since the interpolation will be only one level.

At the risk of actually introducing the behavior by demonstrating how not to do it, we'd also like to suggest that you avoid using backquotes in a place where the value isn't being captured.[319] For example:

[319]This is called a "void" context.

print "Starting the frobnitzigator:\n";
`frobnitz -enable`; # please don't do this!
print "Done!\n";

The problem is that Perl has to work a bit harder to capture the output of this command, even when you're just throwing it away, and then you also lose the option to use multiple arguments to system to precisely control the argument list. So from both a security standpoint and an efficiency viewpoint, just use system instead, please.

Standard error of a backquoted command is inherited from Perl's current standard error output. If the command spits out error messages to standard error, you'll probably see them on the terminal, which could be confusing to the user who hasn't personally invoked the frobnitz command. If you want to capture error messages with standard output, you can use the shell's normal "merge standard error to the current standard output," which is spelled 2>&1 in the normal Unix shell:

my $output_with_errors = `frobnitz -enable 2>&1`;

Note that this will make the standard error output intermingled with the standard output, much as it appears on the terminal (although possibly in a slightly different sequence because of buffering). If you need the output and the error output separated, there are many harder-to-type solutions.[320]

[320]Such as IPC::Open3 in the standard Perl library, or writing your own forking code, as we will see later.

Similarly, standard input is inherited from Perl's current standard input. Most commands we typically use with backquotes do not read standard input, so that's rarely a problem. However, let's say the date command asked which time zone (as we imagined earlier). That'll be a problem, because the prompt for "which time zone" will be sent to standard output, which is being captured as part of the value, and then the date command will start trying to read from standard input. But since the user has never seen the prompt, he or she doesn't know to be typing anything! Pretty soon, the user calls you up and tells you that your program is stuck.

So, stay away from commands that read standard input. If you're not sure whether something reads from standard input, then add a redirection from /dev/null for input, like this:

my $result = `some_questionable_command arg arg argh </dev/null`;

Then the child shell will redirect input from /dev/null, and the grandchild questionable command will at worst try to read and immediately get an end of file.

14.4.1. Using Backquotes in a List Context

If the output from a command has multiple lines, the scalar use of backquotes returns it as a single long string containing newline characters. However, using the same backquoted string in a list context yields a list containing one line of output per element.

For example, the Unix who command normally spits out a line of text for each current login on the system as follows:

merlyn     tty/42     Dec 7  19:41
rootbeer   console    Dec 2  14:15
rootbeer   tty/12     Dec 6  23:00

The left column is the username, the middle column is the tty name (that is, the name of the user's connection to the machine), and the rest of the line is the date and time of login (and possibly remote login information, but not in this example). In a scalar context, we get all that at once, which we would then need to split up:

my $who_text = `who`;

But in a list context, we automatically get the data broken up by lines:

my @who_lines = `who`;

We'll have a number of separate elements in @who_lines, each one terminated by a newline. Of course, adding a chomp around the outside of that will rip off those newlines, but let's go a different direction. If we put that as part of the value for a foreach, we'll iterate over the lines automatically, placing each one in $_:

foreach (`who`) {
  my($user, $tty, $date) = /(\S+)\s+(\S+)\s+(.*)/;
  $ttys{$user} .= "$tty at $date\n";
}

This loop will iterate three times for the data above. (Your system will probably have more than three active logins at any given time.) Notice that we've got a regular expression match, and in the absence of the binding operator ("=~"), that's matching against $_, which is good because that's where the data is.

Also notice the regular expression is looking for a nonblank word, some whitespace, a nonblank word, some whitespace, and then the rest of the line up to, but not including, the newline (since dot doesn't match newline by default).[321] That's also good, because that's what the data looks like each time in $_. That'll make $1 be "merlyn", $2 be "tty/42", and $3 be "Dec 7 19:41", as a successful match on the first time through the loop.

[321]Now you can see why dot doesn't match newline by default. It makes it easy to write patterns like this one, in which we don't have to worry about a newline at the end of the string.

However, this regular expression match is in a list context, so instead of returning back a true/false value (as when you have a regular expression match in a scalar context), we take the memory variables and bundle them up in sequence as a list. In this case, the right side of that assignment is thus a three-element list, which happens to correspond to the three elements of the literal list on the left, and we get those nice corresponding assignments. So, $user ends up being "merlyn", and so on.

The second statement inside the loop simply stores away the tty and date information, appending to a (possibly undef) value in the hash, because a user might be logged in more than once, as user "rootbeer" was in our example.

Previous | Home | Next
14.3. The Environment Variables | Book Index | 14.5. Processes as Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.5. Processes as Filehandles

So far, we've been looking at ways to deal with synchronous processes, where Perl stays in charge, launches a command, (usually) waits for it to finish, then possibly grabs its output. But Perl can also launch a child process that stays alive, communicating[322] to Perl on an ongoing basis until the task is complete.

[322]Via pipes, or whatever your operating system provides for simple interprocess communication.

The syntax for launching a concurrent (parallel) child process is to put the command as the "filename" for an open call, and either precede the command or follow the command with a vertical bar, which is the "pipe" character. For that reason, this is often called a piped open:

open DATE, "date|" or die "cannot pipe from date: $!";
open MAIL, "|mail merlyn" or die "cannot pipe to mail: $!";

In the first example, with the vertical bar on the right, the command is launched with its standard output connected to the DATE filehandle opened for reading, similar to the way that the command date | your_program would work from the shell. In the second example, with the vertical bar on the left, the command's standard input is connected to the MAIL filehandle opened for writing, similar to what happens with the command your_program | mail merlyn. In either case, the command is now launched and continues independently of the Perl process.[323]

[323]If the Perl process exits before the command is complete, a command that's been reading will see end-of-file, while a command that's been writing will get a "broken pipe" error signal on the next write, by default.

The open fails if the child process cannot be created. If the command itself does not exist or exits erroneously, this will (generally) not be seen as an error when opening, but as an error when closing. We'll get to that in a moment.

For all intents and purposes, the rest of the program doesn't know, doesn't care, and would have to work pretty hard to figure out that this is a filehandle opened on a process rather than on a file. So, to get data from a filehandle opened for reading, we'll just do the normal read:

my $now = <DATE>;

And to send data to the mail process (waiting for the body of a message to deliver to merlyn on standard input), a simple print-with-a-filehandle will do:

print MAIL "The time is now $now"; # presume $now ends in newline

In short, you can pretend that these filehandles are hooked up to magical files, one that contains the output of the date command, and one that will automatically be mailed by the mail command.

If a process is connected to a filehandle that is open for reading, and then exits, the filehandle returns end-of-file, just like reading up to the end of a normal file. When you close a filehandle open for writing to a process, the process will see end-of-file. So, to finish sending the email, close the handle:

close MAIL;
die "mail: non-zero exit of $?" if $?;

Closing a filehandle attached to a process waits for the process to complete, so that Perl can get the process's exit status. The exit status is then available in the $? variable (reminiscent of the same variable in the Bourne Shell), and is the same kind of number as the value returned by the system function: zero for success, nonzero for failure. Each new exited process overwrites the previous value though, so save it quickly if you want it. (The $? variable also holds the exit status of the most recent system or backquoted command, if you're curious.)

The processes are synchronized just like a pipelined command. If you try to read and no data is available, the process is suspended (without consuming additional CPU time) until the sending program has started speaking again. Similarly, if a writing process gets ahead of the reading process, the writing process is slowed down until the reader starts to catch up. There's a buffer (usually 4K bytes or so) in between so they don't have to stay precisely in lock step.

Why use processes as filehandles? Well, it's the only easy way to write to a process based on the results of a computation. But if you're just reading, backquotes are often much easier to manage, unless you want to have the results as they come in.

For example, the Unix find command locates files based on their attributes, and it can take quite a while if used on a fairly large number of files (such as starting from the root directory). You can put a find command inside backquotes, but it's often nicer to see the results as they are found:

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 $_;
}

The find command here is looking for all the files that were not accessed within the past 90 days and that are larger than 1000 blocks. (These are good candidates to be moved off to longer-term storage.) While find is searching and searching, Perl can wait. As each file is found, Perl responds to the incoming name and displays some information about that file for further research. Had this been written with backquotes, we'd not see any output until the find commmand had finished, and it's comforting to see that it's actually doing the job even before it's done.

Previous | Home | Next
14.4. Using Backquotes to Capture Output | Book Index | 14.6. Getting Down and Dirty with Fork
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.6. Getting Down and Dirty with Fork

In addition to the high-level interfaces already described, Perl provides nearly direct access to the low-level process management system calls of Unix and some other systems. If you've never done this before,[324] you will probably want to skip this section. While it's a bit much to cover all that stuff in a chapter like this, let's at least look at a quick reimplementation of this:

[324]Or you're not running on a system that has support for forking. But the Perl developers are working hard to add forking even on systems whose underlying process model is very different than the one in Unix.

system "date";

Let's look at how that would be done using the low-level system calls:

defined(my $pid = fork) or die "Cannot fork: $!";
unless ($pid) {
  # Child process is here
  exec "date";
  die "cannot exec date: $!";
}
# Parent process is here
waitpid($pid, 0);

Here, we've checked the return value from fork, which will be undef if it failed. Usually it will succeed, causing two separate processes to continue to the next line, but only the parent process has a nonzero value in $pid, so only the child process executes the exec function. The parent process skips over that and executes the waitpid function, waiting for that particular child to finish (if others finish in the meantime, they are ignored). If that all sounds like gobbledygook, just remember that you can continue to use the system function without being laughed at by your friends.

When you go to this extra trouble, you also have full control over arbitary pipe creation, rearranging filehandles, and noticing your process ID and your parent's process ID (if knowable). But again, that's all a bit complicated for this chapter, so see the details in the perlipc manpage (and in any good book on application programming on your system) for further information.

Previous | Home | Next
14.5. Processes as Filehandles | Book Index | 14.7. Sending and Receiving Signals
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.7. Sending and Receiving Signals

A Unix signal is a tiny message sent to a process. It can't say much; it's like a car horn honking -- does that honk you hear mean "look out -- the bridge collapsed" or "the light has changed -- get going" or "stop driving -- you've got a baby on the roof" or "hello, world"? Well, fortunately, Unix signals are a little easier to interpret than that, because there's a different one for each of these situations.[325]

[325]Well, not exactly these situations, but analogous Unix-like ones. For these, the signals are SIGHUP, SIGCONT, SIGINT, and the fake SIGZERO (signal number zero).

Different signals are identified by a name (such as SIGINT, meaning "interrupt signal") and a corresponding small integer (in the range from 1 to 16, 1 to 32, or 1 to 63, depending on your Unix flavor). Signals are typically sent when a significant event happens, such as pressing the interrupt character (typically Control-C) on the terminal, which sends a SIGINT to all the processes attached to that terminal.[326] Some signals are sent automatically by the system, but they can also come from another process.

[326]And you thought that pressing Control-C stopped your program. Actually, it simply sends the SIGINT signal, and that stops the program by default. As we'll see later in this chapter, you can make a program that does something different when SIGINT comes in, rather than stopping at once.

You can send signals from your Perl process to another process, but you have to know the target's process ID number. How to figure that out is a bit complicated,[327] but let's say you know that you want to send a SIGINT to process 4201. That's easy enough:

[327]Usually you have the process ID because it's a child process you produced with fork, or you found it in a file or from an external program. Using an external program can be difficult and problematic, which is why many long-running programs save their own current process ID into a file, usually described in the program's documentation.

kill 2, 4201 or die "Cannot signal 4201 with SIGINT: $!";

It's named "kill" because one of the primary purposes of signals is to stop a process that's gone on long enough. You can also use the string 'INT' in place of the 2 there, because signal number 2 is SIGINT. If the process no longer exists,[328] you'll get a false return value, so you can also use this technique to see whether a process is still alive. A special signal number of 0 says "just check to see whether I could send a signal if I wanted to, but I don't want to, so don't actually send anything." So a process probe might look like:

[328]Sending a signal will also fail if you're not the superuser and it's someone else's process. It would be rude to send SIGINT to someone else's programs, anyway.

unless (kill 0, $pid) {
  warn "$pid has gone away!";
}

Perhaps a little more interesting than sending signals is catching signals. Why might you want to do this? Well, suppose you have a program that creates files in /tmp, and you normally delete those files at the end of the program. If someone presses Control-C during the execution, that leaves trash in /tmp, a very unpolite thing to do. To fix this, create a signal handler that takes care of the cleanup:

my $temp_directory = "/tmp/myprog.$$"; # create files below here
mkdir $temp_directory, 0700 or die "Cannot create $temp_directory: $!";

sub clean_up {
  unlink glob "$temp_directory/*";
  rmdir $temp_directory;
}

sub my_int_handler {
  &clean_up;
  die "interrupted, exiting...\n";
}

$SIG{'INT'} = 'my_int_handler';
.
.   # Time passes, the program runs, creates some temporary
.   # files in the temp directory, maybe somone presses Control-C
.
# Now it's the end of normal execution
&clean_up;

The assignment into the special %SIG hash activates the handler (until revoked). The key is the name of the signal (without the constant SIG prefix), and the value is a string[329] naming the subroutine, without the ampersand. From then on, if a SIGINT comes along, Perl stops whatever it's doing and jumps immediately to the subroutine. Our subroutine cleans up the temp files and then exits. (And if nobody presses Control-C, we'll still call &clean_up at the end of normal execution.)

[329]The value can also be a subroutine reference, but we're not doing those here.

If the subroutine returns rather than exiting, execution resumes right where it was interrupted. This can be useful if the interrupt needs to actually interrupt something rather than causing it to stop. For example, suppose processing each line of a file takes a few seconds, which is pretty slow, and you want to abort the overall processing when an interrupt is processed, but not in the middle of processing a line. Just set a flag in the interrupt procedure, and check it at the end of each line's processing:

my $int_count;
sub my_int_handler { $int_count++ }
$SIG{'INT'} = 'my_int_handler';
...
$int_count = 0;
while (<SOMEFILE>) {
  ... some processing that takes a few seconds ...
  if ($int_count) {
    # interrupt was seen!
    print "[processing interrupted...]\n";
    last;
  }
}

Now as each line is processed, the value of $int_count will be 0 if no one has pressed Control-C, and so the loop continues to the next item. However, if an interrupt comes in, the interrupt handler increments the $int_count flag, breaking out of the loop when checked at the end.

So, you can either set a flag or break out of the program, and that covers most of what you'll need from catching signals. The current implementation of signal handlers is not entirely without faults,[330] however, so keep the stuff you're doing in there to an absolute minimum, or your program may end up blowing up sometime when you least expect it.

[330]This is one of the top items on the Perl developers' list of things to be fixed, so we expect reliable signal handling to be one of the first items on the new feature list for Perl 6. The problem is that a signal may come in at any time, even when Perl isn't ready for one. If Perl is (for example) in the middle of allocating some memory when a signal comes in, the signal handler can accidentally try to allocate some memory and -- your program is dead. You can't control when your Perl code will allocate memory, but XSUB code (usually written in C) can safely handle signals. See the Perl documentation for more information about this advanced topic.

Previous | Home | Next
14.6. Getting Down and Dirty with Fork | Book Index | 14.8. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.8. Exercises

See Section A.13, "Answers to Chapter 14 Exercises" for answers to the following exercises:

  1. [6] Write a program that changes to some particular (hardcoded) directory, like the system's root directory, then executes the ls -l command to get a long-format directory listing in that directory. (If you use a non-Unix system, use your own system's command to get a detailed directory listing.)

  2. [10] Modify the previous program to send the output of the command to a file called ls.out in the current directory. The error output should go to a file called ls.err. (You don't need to do anything special about the fact that either of these files may end up being empty.)

  3. [8] Write a program to parse the output of the date command to determine the current day of the week. If the day of the week is a weekday, print get to work, otherwise print go play. The output of the date command begins with Mon on a Monday.[331] If you don't have a date command on your non-Unix system, make a fake little program that simply prints a string like date might print. We'll even give you this two-line program if you promise not to ask us how it works:

    [331]At least when the days of the week are being given in English. You might have to adjust accordingly if that's not the case on your system.

    #!/usr/bin/perl
print localtime( ) . "\n";
Previous | Home | Next
14.7. Sending and Receiving Signals | Book Index | 15. Strings and Sorting
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 15. Strings and Sorting

Contents:

Finding a Substring with index
Manipulating a Substring with substr
Formatting Data with sprintf
Advanced Sorting
Exercises

As we mentioned near the beginning of this book, Perl is designed to be good at solving programming problems that are about 90% working with text and 10% everything else. So it's no surprise that Perl has strong text processing abilities, including all that we've done with regular expressions. But sometimes the regular expression engine is too fancy, and you'll need a simpler way of working with a string, as we'll see in this chapter.

15.1. Finding a Substring with index

Finding a substring depends on where you have lost it. If you happen to have lost it within a bigger string, you're in luck, because the index function can help you out. Here's how it looks:

$where = index($big, $small);

Perl locates the first occurrence of the small string within the big string, returning an integer location of the first character. The character position returned is a zero-based value -- if the substring is found at the very beginning of the string, index returns 0. If it's one character later, the return value is 1, and so on. If the substring can't be found at all, the return value is -1 to indicate that.[332] In this example, $where gets 6:

[332]Former C programmers will recognize this as being like C's index function. Current C programmers ought to recognize it as well -- but by this point in the book, you should really be a former C programmer.

my $stuff = "Howdy world!";
my $where = index($stuff, "wor");

Another way you could think of the position number is the number of characters to skip over before getting to the substring. Since $where is 6, we know that we have to skip over the first six characters of $stuff before we find wor.

The index function will always report the location of the first found occurrence of the substring. But you can tell it to start searching at a later point than the start of the string by using the optional third parameter, which tells index to start at that position:

my $stuff  = "Howdy world!";
my $where1 = index($stuff, "w");               # $where1 gets 2
my $where2 = index($stuff, "w", $where1 + 1);  # $where2 gets 6
my $where3 = index($stuff, "w", $where2 + 1);  # $where3 gets -1 (not found)

(Of course, you wouldn't normally search repeatedly for a substring without using a loop.) That third parameter is effectively giving a minimum value for the return value; if the substring can't be found at that position or later, the return value will be -1.

Once in a while, you might prefer to have the last found occurrence of the substring.[333] You can get that with the rindex function. In this example, we can find the last slash, which turns out to be at position 4 in a string:

[333]Well, it's not really the last one found -- Perl cleverly starts searching from the other end of the string, and then returns the first location it finds, which amounts to the same result. Of course, the return value is the same zero-based number as we always use for describing locations of substrings.

my $last_slash = rindex("/etc/passwd", "/");  # value is 4

The rindex function also has an optional third parameter, but in this case it effectively gives the maximum permitted return value:

my $fred = "Yabba dabba doo!";
my $where1 = rindex($fred, "abba");  # $where1 gets 7
my $where2 = rindex($fred, "abba", $where1 - 1);  # $where2 gets 1
my $where3 = rindex($fred, "abba", $where2 - 1);  # $where3 gets -1
Previous | Home | Next
14.8. Exercises | Book Index | 15.2. Manipulating a Substring with substr
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.2. Manipulating a Substring with substr

The substr operator works with only a part of a larger string. It looks like this:

$part = substr($string, $initial_position, $length);

It takes three arguments: a string value, a zero-based initial position (like the return value of index), and a length for the substring. The return value is the substring:

my $mineral = substr("Fred J. Flintstone", 8, 5);  # gets "Flint"
my $rock = substr "Fred J. Flintstone", 13, 1000;  # gets "stone"

As you may have noticed in the previous example, if the requested length (1000 characters, in this case) would go past the end of the string, there's no complaint from Perl, but you simply get a shorter string than you might have. But if you want to be sure to go to the end of the string, however long or short it may be, just omit that third parameter (the length), like this:

my $pebble = substr "Fred J. Flintstone", 13;  # gets "stone"

The initial position of the substring in the larger string can be negative, counting from the end of the string (that is, position -1 is the last character).[334] In this example, position -3 is three characters from the end of the string, which is the location of the letter i:

[334]This is analogous to what we saw with array indices in Chapter 3, "Lists and Arrays ". Just as arrays may be indexed either from 0 (the first element) upwards or from -1 (the last element) downwards, substring locations may be indexed from position 0 (at the first character) upwards or from position -1 (at the last character) downwards.

my $out = substr("some very long string", -3, 2);  # $out gets "in"

As you might expect, index and substr work well together. In this example, we can extract a substring that starts at the location of the letter l:

my $long = "some very very long string";
my $right = substr($long, index($long, "l") );

Now here's something really cool: The selected portion of the string can be changed if the string is a variable:[335]

[335]Well, technically, it can be any lvalue. What that term means precisely is beyond the scope of this book, but you can think of it as anything that can be put on the left side of the equals sign (=) in a scalar assignment. That's usually a variable, but it can (as you see here) even be an invocation of the substr operator.

my $string = "Hello, world!";
substr($string, 0, 5) = "Goodbye";  # $string is now "Goodbye, world!"

As you see, the assigned (sub)string doesn't have to be the same length as the substring it's replacing. The string's length is adjusted to fit. Or if that wasn't cool enough to impress you, you could use the binding operator (=~) to restrict an operation to work with just part of a string. This example replaces fred with barney wherever possible within just the last twenty characters of a string:

substr($string, -20) =~ s/fred/barney/g;

To be completely honest, we've never actually needed that functionality in any of our own code, and chances are that you'll never need it either. But it's nice to know that Perl can do more than you'll ever need, isn't it?

Much of the work that substr and index do could be done with regular expressions. Use those where they're appropriate. But substr and index can often be faster, since they don't have the overhead of the regular expression engine: they're never case-insensitive, they have no metacharacters to worry about, and they don't set any of the memory variables.

Besides assigning to the substr function (which looks a little weird at first glance, perhaps), you can also use substr in a slightly more traditional manner[336] with the four-argument version, in which the fourth argument is the replacement substring:

[336]By traditional we mean in the "function invocation" sense, but not the "Perl" sense, since this feature was introduced to Perl relatively recently.

my $previous_value = substr($string, 0, 5, "Goodbye");

The previous value comes back as the return value, although as always, you can use this function in a void context to simply discard it.

Previous | Home | Next
15. Strings and Sorting | Book Index | 15.3. Formatting Data with sprintf
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.3. Formatting Data with sprintf

The sprintf function takes the same arguments as printf (except for the optional filehandle, of course), but it returns the requested string instead of printing it. This is handy if you want to store a formatted string into a variable for later use, or if you want more control over the result than printf alone would provide:

my $date_tag = sprintf
  "%4d/%02d/%02d %2d:%02d:%02d",
  $yr, $mo, $da, $h, $m, $s;

In that example, $date_tag gets something like "2038/01/19 3:00:08". The format string (the first argument to sprintf) used a leading zero on some of the format number, which we didn't mention when we talked about printf formats in Chapter 6, "I/O Basics". The leading zero on the format number means to use leading zeroes as needed to make the number as wide as requested. Without a leading zero in the formats, the resulting date-and-time string would have unwanted leading spaces instead of zeroes, looking like "2038/ 1/19 3: 0: 8".

15.3.1. Using sprintf with "Money Numbers"

One popular use for sprintf is when a number needs to be rendered with a certain number of places after the decimal point, such as when an amount of money needs to be shown as 2.50 and not 2.5 -- and certainly not as 2.49997! That's easy to accomplish with the "%.2f" format:

my $money = sprintf "%.2f", 2.49997;

The full implications of rounding are numerous and subtle, but in most cases you should keep numbers in memory with all of the available accuracy, rounding off only for output.

If you have a "money number" that may be large enough to need commas to show its size, you might find it handy to use a subroutine like this one.[337]

[337]Yes, we know that not everywhere in the world are commas used to separate groups of digits, not everywhere are the digits grouped by threes, and not everywhere the currency symbol appears as it does for U.S. dollars. But this is a good example anyway, so there!

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;
}

This subroutine uses some techniques you haven't seen yet, but they logically follow from what we've shown you. The first line of the subroutine formats the first (and only) parameter to have exactly two digits after the decimal point. That is, if the parameter were the number 12345678.9, now our $number is the string "12345678.90".

The next line of code uses a while modifier. As we mentioned when we covered that modifier in Chapter 10, "More Control Structures", that can always be rewritten as a traditional while loop:

while ($number =~ s/^(-?\d+)(\d\d\d)/$1,$2/) {
  1;
}

What does that say to do? It says that, as long as the substitution returns a true value (signifying success), the loop body should run. But the loop body does nothing! That's okay with Perl, but it tells us that the purpose of that statement is to do the conditional expression (the substitution), rather than the useless loop body. The value 1 is traditionally used as this kind of a placeholder, although any other value would be equally useful.[338] This works just as well as the loop above:

[338]Which is to say, useless. By the way, in case you're wondering, Perl optimizes away the constant expression so it doesn't even take up any runtime.

'keep looping' while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;

So, now we know that the substitution is the real purpose of the loop. But what is the substitution doing? Remember that $number will be some string like "12345678.90" at this point. The pattern will match the first part of the string, but it can't get past the decimal point. (Do you see why it can't?) Memory $1 will get "12345", and $2 will get "678", so the substitution will make $number into "12345,678.90" (remember, it couldn't match the decimal point, so the last part of the string is left untouched).

Do you see what the dash is doing near the start of that pattern? (Hint: The dash is allowed at only one place in the string.) We'll tell you at the end of this section, in case you haven't figured it out.

We're not done with that substitution statement yet. Since the substitution succeeded, the do-nothing loop goes back to try again. This time, the pattern can't match anything from the comma onward, so $number becomes "12,345,678.90". The substitution thus adds a comma to the number each time through the loop.

Speaking of the loop, it's still not done. Since the previous substitution was a success, we're back around the loop to try again. But this time, the pattern can't match at all, since it has to match at least four digits at the start of the string, so now that is the end of the loop.

Why couldn't we have simply used the /g modifier to do a "global" search-and-replace, to save the trouble and confusion of the 1 while? We couldn't use that because we're working backwards from the decimal point, rather than forward from the start of the string. Putting the commas in a number like this can't be done simply with the s///g substitution alone.[339]

[339]At least, it can't be done without some more-advanced regular expression techniques than we've shown you so far. Those darn Perl developers keep making it harder and harder to write Perl books that use the word "can't."

So, did you figure out the dash? It's allowing for a possible minus-sign at the start of the string. The next line of code makes the same allowance, putting the dollar-sign in the right place so that $number is something like "$12,345,678.90", or perhaps "-$12,345,678.90" if it's negative. Note that the dollar sign isn't necessarily the first character in the string, or that line would be a lot simpler. Finally, the last line of code returns our nicely formatted "money number," ready to be printed in the annual report.

Previous | Home | Next
15.2. Manipulating a Substring with substr | Book Index | 15.4. Advanced Sorting
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.4. Advanced Sorting

Earlier, in Chapter 3, "Lists and Arrays ", we showed that you could sort a list in ascending ASCIIbetical order by using the builtin sort operator. What if you want a numeric sort? Or a case-insensitive sort? Or maybe you want to sort items according to information stored in a hash. Well, Perl lets you sort a list in whatever order you'd need; we'll see all of those examples by the end of the chapter.

You'll tell Perl what order you want by making a sort-definition subroutine, or sort subroutine for short. Now, when you first hear the term "sort subroutine," if you've been through any computer science courses, visions of bubble sort and shell sort and quick sort race through your head, and you say, "No, never again!" Don't worry; it's not that bad. In fact, it's pretty simple. Perl already knows how to sort a list of items; it merely doesn't know which order you want. So the sort-definition subroutine simply tells it the order.

Why is this necessary? Well, if you think about it, sorting is putting a bunch of things in order by comparing them all. Since you can't compare them all at once, you need to compare two at a time, eventually using what you find out about each pair's order to put the whole kit'n'caboodle in line. Perl already understands all of those steps except for the part about how you'd like to compare the items, so that's all you have to write.

This means that the sort subroutine doesn't need to sort many items after all. It merely has to be able to compare two items. If it can put two items in the proper order, Perl will be able to tell (by repeatedly consulting the sort subroutine) what order you want for your data.

The sort subroutine is defined like an ordinary subroutine (well, almost). This routine will be called repeatedly, each time checking on a pair of elements from the list to be sorted.

Now, if you were writing a subroutine that's expecting to get two parameters that need sorting, you might write something like this to start:

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
  ...
}

But the sort subroutine will be called again and again, often hundreds or thousands of times. Declaring the variables $a and $b and assigning them values at the top of the subroutine will take just a little time, but multiply that by the thousands of times that the routine will be called, and you can see that it contributes significantly to the overall execution speed.

We don't do it like that. (In fact, if you did it that way, it wouldn't work.) Instead, it is as if Perl has done this for us, before our subroutine's code has even started.[340] You'll really write a sort subroutine without that first line; both $a and $b have been assigned for you. When the sort subroutine starts running, $a and $b are two elements from the original list.

[340]To be honest, it's closer to being as if Perl has used local($a, $b) in a private block around the sort invocation, because these variables are really globals rather than lexical variables. (Unless you do something unusual, though, you can't tell the difference inside the sort subroutine; you can pretend these are my variables. use strict makes a special exception for these two globals, so you don't need to declare them in any way.) This means that if your program already has its own $a or $b, you won't be able to access those while Perl is sorting the list. Also, be sure to note that the two items to be sorted are not passed in via @_ (unless you use a subroutine prototype, which we won't cover in this book, but see the documentation for the full details). Inside the sort subroutine, just use $a and $b, and try not to worry too much about where they came from. And as if that wasn't enough, if there's a lexical $a or $b somewhere in scope, the subroutine definition doesn't work either. Whew!

The subroutine returns a coded value describing how the elements compare (like C's qsort(3) does, but it's Perl's own internal sort implementation). If $a should appear before $b in the final list, the sort subroutine returns -1 to say so. If $b should appear before $a, it returns 1.

If the order of $a and $b doesn't matter, the subroutine returns 0. Why would it not matter? Perhaps you're doing a case-insensitive sort and the two strings are fred and Fred. Or perhaps you're doing a numeric sort, and the two numbers are equal.

We could now write a numeric sort subroutine like this:

sub by_number {
  # a sort subroutine, expect $a and $b
  if ($a < $b) { -1 } elsif ($a > $b) { 1 } else { 0 }
}

To use the sort subroutine, just put its name (without an ampersand) between the keyword sort and the list to be sorted. This example puts a numerically sorted list of numbers into @result:

my @result = sort by_number @some_numbers;

We called the subroutine by_number because that describes how it's sorting. But more importantly, you can read the line of code that uses it with sort as saying "sort by number," as you would in English. Many sort-subroutine names begin with by_ to describe how they sort. Or we could have called this one numerically, for a similar reason, but that's more typing and more chance to mess something up.

Notice that we don't have to do anything in the sort subroutine to declare $a and $b, and to set their values -- and if we did, the subroutine wouldn't work right. We just let Perl set up $a and $b for us, and so all we need to write is the comparison.

In fact, we can make it even simpler (and more efficient). Since this kind of three-way comparison is frequent, Perl has a convenient shortcut to use to write it. In this case, we use the spaceship operator (<=>).[341] This operator compares two numbers and returns -1, 0, or 1 as needed to sort them numerically. So we could have written that sort subroutine better, like this:

[341]We call it that because it looks like one of the Tie-fighters from Star Wars. Well, it looks like that to us, anyway.

sub by_number { $a <=> $b }

Since the spaceship compares numbers, you may have guessed that there's a corresponding three-way string-comparison operator: cmp. These two are easy to remember and keep straight. The spaceship has a family resemblance to the numeric comparison operators like >=, but it's three characters long instead of two because it has three possible return values instead of two. And cmp has a family resemblance to the string comparison operators like ge, but it's three characters long instead of two because it also has three possible return values instead of two.[342]

[342]This is no accident. Larry does things like this on purpose, to make Perl easier to learn and remember. Remember, he's a linguist at heart, so he's studied how people think of languages.

Of course, cmp by itself provides the same order as the default sort. You'd never need to write this subroutine, which yields merely the default sort order:[343]

[343]You'd never need to write this unless, of course, you were writing an introductory Perl book and needed it for an example.

sub ASCIIbetically { $a cmp $b }
my @strings = sort ASCIIbetically @any_strings;

But you can use cmp to build a more complex sort order, like a case-insensitive sort:

sub case_insensitive { "\L$a" cmp "\L$b" }

In this case, we're comparing the string from $a (forced to lowercase) against the string from $b (forced to lowercase), giving a case-insensitive sort order.

Note that we're not modifying the elements themselves; we're merely using their values. That's actually important: for efficiency reasons, $a and $b aren't copies of the data items. They're actually new, temporary aliases for elements of the original list, so if we changed them we'd be mangling the original data. Don't do that -- it's neither supported nor recommended.

When your sort subroutine is as simple as the ones we show here (and most of the time, it is), you can make the code even simpler yet, by replacing the name of the sort routine with the entire sort routine "in line," like so:

my @numbers = sort { $a <=> $b } @some_numbers;

In fact, in modern Perl, you'll hardly ever see a separate sort subroutine; you'll frequently find sort routines written inline as we've done here.

Suppose you want to sort in descending numeric order. That's easy enough to do with the help of reverse:

my @descending = reverse sort { $a <=> $b } @some_numbers;

But here's a neat trick. The comparison operators (<=> and cmp) are very nearsighted; that is, they can't see which operand is $a and which is $b, but only which value is on the left and which is on the right. So if $a and $b were to swap places, the comparison operator would get the results backwards every time. That means that this is another way to get a reversed numeric sort:

my @descending = sort { $b <=> $a } @some_numbers;

You can (with a little practice) read this at a glance. It's a descending-order comparison (because $b comes before $a, which is descending order), and it's a numeric comparison (because it uses the spaceship instead of cmp). So, it's sorting numbers in reverse order.

15.4.1. Sorting a Hash by Value

Once you've been sorting lists happily for a while you'll run into a situation where you want to sort a hash by value. For example, three of our characters went out bowling last night, and we've got their bowling scores in the following hash. We want to be able to print out the list in the proper order, with the game winner at the top, so we want to sort the hash by score:

my %score = ("barney" => 195, "fred" => 205, "dino" => 30);
my @winners = sort by_score keys %score;

Of course, we aren't really going to be able to sort the hash by score; that's just a verbal shortcut. You can't sort a hash! But when we've used sort with hashes before now, we've been sorting the keys of the hash (in ASCIIbetical order). Now, we're still going to be sorting the keys of the hash, but the order is now defined by their corresponding values from the hash. In this case, the result should be a list of our three characters' names, in order according to their bowling scores.

Writing this sort subroutine is fairly easy. What we want is to use a numeric comparison on the scores, rather than the names. That is, instead of comparing $a and $b (the players' names), we want to compare $score{$a} and $score{$b} (their scores). If you think of it that way, it almost writes itself, as in:

sub by_score { $score{$b} <=> $score{$a} }

Let's step through this and see how it works. Let's imagine that the first time it's called, Perl has set $a to barney and $b to fred. So the comparison is $score{"fred"} <=> $score{"barney"}, which (as we can see by consulting the hash) is 205 <=> 195. Remember, now, the spaceship is nearsighted, so when it sees 205 before 195, it says, in effect: "No, that's not the right numeric order; $b should come before $a." So it tells Perl that fred should come before barney.

Maybe the next time the routine is called, $a is barney again but $b is now dino. The nearsighted numeric comparison sees 30 <=> 195 this time, so it reports that that they're in the right order; $a does indeed sort in front of $b. That is, barney comes before dino. At this point, Perl has enough information to put the list in order: fred is the winner, then barney in second place, then dino.

Why did the comparison use the $score{$b} before the $score{$a}, instead of the other way around? That's because we want bowling scores arranged in descending order, from the highest score of the winner down. So you can (again, after a little practice) read this one at sight as well: $score{$b} <=> $score{$a} means to sort according to the scores, in reversed numeric order.

15.4.2. Sorting by Multiple Keys

We forgot to mention that there was a fourth player bowling last night with the other three, so the hash really looked like this:

my %score = (
  "barney" => 195, "fred" => 205,
  "dino" => 30, "bamm-bamm" => 195,
);

Now, as you can see, bamm-bamm has the same score as barney. So which one will be first in the sorted list of players? There's no telling, because the comparison operator (seeing the same score on both sides) will have to return zero when checking those two.

Maybe that doesn't matter, but we generally prefer to have a well-defined sort. If several players have the same score, we want them to be together in the list, of course. But within that group, the names should be in ASCIIbetical order. But how can we write the sort subroutine to say that? Again, this turns out to be pretty easy:

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
}

How does this work? Well, if the spaceship sees two different scores, that's the comparison we want to use. It returns -1 or 1, a true value, so the low-precedence short-circuit or will mean that the rest of the expression will be skipped, and the comparison we want is returned. (Remember, the short-circuit or returns the last expression evaluated.) But if the spaceship sees two identical scores, it returns 0, a false value, and thus the cmp operator gets its turn at bat, returning an appropriate ordering value considering the keys as strings. That is, if the scores are the same, the string-order comparison breaks the tie.

We know that when we use the by_score_and_name sort subroutine like this, it will never return 0. (Do you see why it won't? The answer is in the footnote.[344]) So we know that the sort order is always well-defined; that is, we know that the result today will be the same as the result with the same data tomorrow.

[344]The only way it could return 0 would be if the two strings were identical, and (since the strings are keys of a hash) we already know that they're different. Of course, if you passed a list with duplicate (identical) strings to sort, it would return 0 when comparing those, but we're passing a list of hash keys.

There's no reason that your sort subroutine has to be limited to two levels of sorting, of course. Here the Bedrock library program puts a list of patron ID numbers in order according to a five-level sort.[345] This example sorts according to the amount of each patron's outstanding fines (as calculated by a subroutine &fines, not shown here), the number of items they currently have checked out (from %items), their name (in order by family name, then by personal name, both from hashes), and finally by the patron's ID number, in case everything else is the same:

[345]It's not unusual in the modern world to need a five-level sort like this, although it was quite infrequent in prehistoric times.

@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;
Previous | Home | Next
15.3. Formatting Data with sprintf | Book Index | 15.5. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.5. Exercises

See Section A.14, "Answers to Chapter 15 Exercises" for answers to the following exercises:

  1. [10] Write a program to read in a list of numbers and sort them numerically, printing out the resulting list in a right-justified column. Try it out on this sample data, or use the file numbers, from the O'Reilly web site (see the Preface):

    17 1000 04 1.50 3.14159 -10 1.5 4 2001 90210 666

  2. [15] Make a program that will print the following hash's data sorted in case-insensitive alphabetical order by last name. When the last names are the same, sort those by first name (again, without regard for case). That is, the first name in the output should be Fred's, while the last one should be Betty's. All of the people with the same family name should be grouped together. Don't alter the data. The names should be printed with the same capitalization as shown here. (You can find the source code to create a hash like this in the file sortable_hash with the other downloaded files.)

    my %last_name = qw{
  fred flintstone Wilma Flintstone Barney Rubble
  betty rubble Bamm-Bamm Rubble PEBBLES FLINTSTONE
};

  3. [15] Make a program that looks through a given string for every occurrence of a given substring, printing out the positions where the substring is found. For example, given the input string "This is a test." and the substring "is", it should report positions 2 and 5. If the substring were "a", it should report 8. What does it report if the substring is "t"?

Previous | Home | Next
15.4. Advanced Sorting | Book Index | 16. Simple Databases
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 16. Simple Databases

Contents:

DBM Files and DBM Hashes
Manipulating Data with pack and unpack
Fixed-length Random-access Databases
Variable-length (Text) Databases
Exercises

Databases permit us to allow data to persist beyond the end of our program. The kinds of databases we're talking about in this chapter are merely simple ones; how to use full-featured database implementations (Oracle, Sybase, Informix, mySQL, and others) is a topic that could fill an entire book, and usually does. The databases in this chapter are those that are simple enough to implement that you don't need to know about modules to use them.[346]

[346]To be sure, on some of these, the core of Perl will load a module for you. But you don't need to know anything about modules to use these databases.

16.1. DBM Files and DBM Hashes

Every system thas has Perl also has a simple database already available in the form of DBM files. This lets your program store data for quick lookup in a file or in a pair of files. When two files are used, one holds the data and the other holds a table of contents, but you don't need to know that in order to use DBM files. We're intentionally being a little vague about the exact implementation, because that will vary depending upon your machine and configuration; see the AnyDBM_file manpage for more information. Also, among the downloadable files from the O'Reilly website is a utility called which_dbm, which tries to tell you which implementation you're using, how many files there are, and what extensions they use, if any.

Some DBM file implementations (we'll call it "a file," even though it may be two actual files) have a limit of around 1000 bytes for each key and value in the file. Your actual limit may be larger or smaller than this number, but as long as you aren't trying to store gigantic text strings in the file, it shouldn't be a problem. There's no limit to the number of individual data items in the file, as long as you have enough disk space.

In Perl, we can access the DBM file as a special kind of hash called a DBM hash. This is a powerful concept, as we'll see.

16.1.1. Opening and Closing DBM Hashes

To associate a DBM database with a DBM hash (that is, to open it), use the dbmopen function,[347] which looks similar to open, in a way:

[347]Here we depart from other beginner documentation, which claims that dbmopen is deprecated and suggests that you use the more complicated tie interface instead. We disagree, since dbmopen works just fine, and it keeps you from having to think harder about what you're doing. Keep the common tasks simple!

dbmopen(%DATA, "my_database", 0644)
  or die "Cannot create my_database: $!";

The first parameter is the name of a Perl hash. (If this hash already has values, the values are inaccessible while the DBM file is open.) This hash becomes connected to the DBM database whose name was given as the second parameter, often stored on disk as a pair of files with the extensions .dir and .pag. (The filename as given in the second parameter shouldn't include either extension, though; the extensions will be automatically added as needed.) In this case, the files might be called my_database.dir and my_database.pag.

Any legal hash name may be used as the name of the DBM hash, although uppercase-only hash names are traditional because their resemblance to filehandles reminds us that the hash is connected to a file. The hash name isn't stored anywhere in the file, so you can call it whatever you'd like.

If the file doesn't exist, it will be created and given a permission mode based upon the value in the third parameter.[348] The number is typically specified in octal; the frequently used value of 0644 gives read-only permission to everyone but the owner, who gets read/write permission. If you're trying to open an existing file, you'd probably rather have the dbmopen fail if the file isn't found, so just use undef as the third parameter.

[348]The actual mode will be modified by the umask; see the perlfuncmanpage for more information.

The return value from the dbmopen is true if the database could be opened or created, and false otherwise, just like open. You should generally use or die in the same spirit as open.

The DBM hash typically stays open throughout the program. When the program terminates, the association is terminated. You can also break the association in a manner similar to closing a filehandle, by using dbmclose:

dbmclose(%DATA);

16.1.2. Using a DBM Hash

Here's the beauty of the DBM hash: it works just like the hashes you already understand! To read from the file, look at an element of the hash. To write to the file, store something into the hash. In short, it's like any other hash, but instead of being stored in memory, it's stored on disk. And thus, when your program opens it up again, the hash is already stuffed full of the data from the previous invocation.

All of the normal hash operations are available:

$DATA{"fred"} = "bedrock";      # create (or update) an element
delete $DATA{"barney"};         # remove an element of the database

foreach my $key (keys %DATA) {  # step through all values
  print "$key has value of $DATA{$key}\n";
}

That last loop could have a problem, since keys has to traverse the entire hash, possibly producing a very large list of keys. If you are scanning through a DBM hash, it's generally more memory-efficient to use the each function:

while (my($key, $value) = each(%DATA)) {
  print "$key has value of $value\n";
}

If you are accessing DBM files that are maintained by C programs, you should be aware that C programs generally tack on a trailing NUL ("\0") character to the end of their strings, for reasons known only to Kernighan and Ritchie.[349] The DBM library routines do not need this NUL (they handle binary data using a byte count, not a NUL-terminated string), and so the NUL is stored as part of the data.

[349]Well, they're not the only ones: it's because C uses the NUL byte as the end-of-string marker.

To cooperate with these programs, you must therefore append a NUL character to the end of your keys and values, and discard the NUL from the end of the returned values to have the data make sense. For example, to look up merlyn in the sendmail aliases database on a Unix system, you might do something like this:

dbmopen(my %ALI, "/etc/aliases", undef) or die "no aliases?";
my $value = $ALI{"merlyn\0"};                  # note appended NUL
$value =~ s/\0$//;                             # remove trailing NUL
print "Randal's mail is headed for: $value\n"; # show result

If your DBM files may be concurrently accessed by more than one process (for example if they're being updated over the Web), you'll generally need to use an auxiliary lock file. The details of this are beyond the scope of this book; see The Perl Cookbook by Tom Christiansen and Nathan Torkington (O'Reilly & Associates, Inc.).

Previous | Home | Next
15.5. Exercises | Book Index | 16.2. Manipulating Data with pack and unpack
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.2. Manipulating Data with pack and unpack

When storing data into a DBM file (or in one of the other types of databases we'll see in this chapter), you may need to store more than one item under a single key. And sometimes you'll need to be able to prepare some information to be sent over a network connection or to a system-level function, or to decode it upon arrival. That's why Perl has the pack and unpack functions.

The pack function takes a format string and a list of arguments and packs the arguments together to make a string. Here, we can pack three numbers of varying sizes into a seven-byte string using the formats c, s, and l (these might remind some folks of the words "char", "short", and "long"). The first number gets packed into one byte, the second into two bytes, and the third into four bytes, which explains why we say this is a seven-byte string:

my $buffer = pack("c s l", 31, 4159, 265359);

When you want the original list of items back, you can use the same format string with the unpack function:

my($char, $short, $long) = unpack("c s l", $buffer);

There are many different format letters available; some of these are the same on every machine (so they're useful for sending data over a network), while others depend upon how your machine likes to work with data (these are useful for interacting with your system's own data). See the perlfunc manpage for the latest list of format letters, as new ones are being added in every new version of Perl.

Whitespace may be used at will in a format string to improve readability, as we did in the previous example. For most format letters, you can follow the format letter with a number to indicate a number of times; that is, a format of "ccccccc" may be written more compactly as "c7". Instead of a number, you may follow the last format letter with a star (*), which means to use that format as many times as needed to use up the remaining items in the list (in pack) or to use up the rest of the string (in unpack). So a format of "c*" will either unpack a string into a list of small integers, or pack up those small integers to make a string. For some format letters, such as a, the number is not a repeat count; "a20" is a twenty-character ASCII string, padded with NUL characters as needed.

Previous | Home | Next
16. Simple Databases | Book Index | 16.3. Fixed-length Random-access Databases
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.3. Fixed-length Random-access Databases

Another form of persistent data is the fixed-length, record-oriented disk file.[350] In this scheme, the data consists of a number of records of identical length. The numbering of the records is either not important or determined by some indexing scheme.

[350]By "fixed-length," we don't mean that the file itself is of a fixed length; it's each individual record that is of a fixed length. In this section, we'll use an example file in which every record is 55 bytes long.

For example, we might want to store some information about each bowler at Bedrock Lanes. Let's say we decide to have a series of records, one per bowler, in which the data holds the player's name, age, last five bowling scores, and the time and date of his last game.

We need to decide upon a suitable format for this data. Let's say that after studying the available formats in the documentation for pack, we decide to use 40 characters for the player's name, a one-byte integer for his age,[351] five two-byte integers for his last five scores,[352] and a four-byte integer for the timestamp of his most-recent game,[353] giving a format string of "a40 C I5 L". Each record is thus 55 bytes long. If we were reading all of the data in the database, we'd read chunks of 55 bytes until we got to the end. If we wanted to go to the fifth record, we'd skip ahead 4 x 55 bytes (220 bytes) and read the fifth record directly.

[351]Since one byte may have 256 different values, this will hold ages from 0 to 255 with ease. If Methuselah comes to bowl in Bedrock, we'll have to redesign the database.

[352]We can't use one-byte integers for the scores, because a bowling score can be as high as 300. Two-byte integers can hold values from 0 to 65535 (if unsigned) or -32768 to 32767 (if signed). We can use some of these extra values as special codes; for example, if a player has only three games on record, the other scores could be set to 9999 to indicate this.

[353]The standard Unix timestamp format (and the time value used by many other systems) is a 32-bit integer, which fits into four bytes, of course. You'll probably find it handy to use a module to manipulate time and date formats.

Perl supports programs that use such a disk file. In order to do so, however, you need to learn a few more things, including how to:

  1. Open a disk file for both reading and writing

  2. Move around in this file to an arbitrary position

  3. Fetch data by a length rather than up to the next newline

  4. Write data down in fixed-length blocks

The open function has an additional mode we haven't shown yet. If you use "+<" at the front of the filename parameter's string, that is similar to using "<" to open the existing file for reading, except that it also asks for write permission on the file. Thus you can have read/write access to the file:

open(FRED, "<fred");  # open file fred for reading (error if file absent)
open(FRED, "+<fred"); # open file fred read/write (error if file absent)

Similarly, "+>" says to create a new file (as ">" would), but to have read access to it as well, thus also giving read/write access:

open(WILMA, ">wilma");  # make new file wilma (wiping out existing file)
open(WILMA, "+>wilma"); # make new file wilma, but also with read access

Do you see the important difference between the two new modes? Both give read/write access to a file. But "+<" lets you work with an existing file; it doesn't create it. The second mode, "+>" isn't often useful, because it gives read/write access to a new, empty file that it has just created. That's mostly used for temporary (scratch) files.

Once we've got the file open, we need to move around in it. You do this with the seek function:

seek(FRED, 55 * $n, 0);  # seek to start of record $n

The first parameter to seek is a filehandle, the second parameter gives the offset in bytes from the start of the file, and the third parameter is zero.[354] To get to a certain record in our file of bowling data, you'll need to skip over some other records. Since each record is 55 bytes long, we'll multiply $n times 55 to find out which byte position we want. (Note that the record numbers are thus zero-based; record zero is at the beginning of the file.)

[354]Actually, the third parameter is the "whence" parameter. You can use a different value than zero if you want to seek to a position relative to the current position, or relative to the end of the file; see the perlfuncmanpage for more information. Most people will simply want to use zero here.

Once the file pointer has been positioned with seek, the next input or output operation will start at that position.

When we're ready to read from the file, we can't use the ordinary line-input operator because that's made to read lines, not 55-byte records. There may not be a newline character in this entire file, or it may appear in packed data in the middle of a record. Instead, we'll use the read function:

my $buf;  # The input buffer variable
my $number_read = read(FRED, $buf, 55);

As you can see, the first parameter to read is the filehandle. The second parameter is a buffer variable; the data read will be placed into this variable. (Yes, this is an odd way to get the result.) The third parameter is the number of bytes to read; here we've asked for 55 bytes, since that's the size of our record. Normally, you can expect the length of $buf to be the specified number of bytes, and you can expect that the return value (in $number_read) to be the same. But if your current position in the file is only five bytes from the end when you request 55 bytes, you'll get only five. Under normal circumstances, you'll get as many bytes as you ask for.

Once you've got those 55 bytes, what can you do with them? You can unpack them (using the format we previously designed) to get the bowler's name and other information, of course:

my($name, $age, $score_1, $score_2, $score_3, $score_4, $score_5, $when)
  = unpack "a40 C I5 L", $buf;

Since we can read the information from the file with read, can you guess how we can write it back into the file? Sorry, it's not write; that was a trick question.[355] You already know the correct function, which is print. But you have to be sure that the data string is exactly the right size; if it's too large, you'll overwrite the next record's data, but if it's too small, leftover data in the current record may be mixed with the new data. To ensure that the length is correct, we'll use pack. Let's say that Wilma has just bowled a game and her new score is in $new_score. That will be the first of the five most-recent scores we keep for her ($score_5, as the oldest one, will be discarded), and in place of $when (the timestamp of her previous game), we'll store the current time from the time function:

[355]Perl actually does have a write function, but that is used with formats, which are beyond the scope of this book. See the perlformmanpage.

print FRED pack("a40 C I5 L",
  $name, $age,
  $new_score, $score_1, $score_2, $score_3, $score_4,
  time);

On some systems, you'll have to use seek whenever you switch from reading to writing, even if the current position in the file is already correct. It's not a bad idea, then, to always use seek right before reading or printing.

Rather than use the two constant values "a40 C I5 L" and 55 throughout the program, as we've done here, it would generally be better to define them just once near the top of the code. That way, if we ever need to change the database format, we don't have to go searching through our code for places where the number 55 appears. Here's one way you might define both of those values, using the length function to determine the length of a string so you won't have to count bytes:

my $pack_format = "a40 C I5 L";
my $pack_length = length pack($pack_format, "dummy data",
  0, 1, 2, 3, 4, 5, 6);
Previous | Home | Next
16.2. Manipulating Data with pack and unpack | Book Index | 16.4. Variable-length (Text) Databases
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.4. Variable-length (Text) Databases

Many simple databases are merely text files written in a format that allows a program to read and maintain them. For example, a configuration file for some program might be a text file, with one configuration parameter being set on each line. Or maybe the file is a mailing list, with one name and address on each line (probably with the components of the name and address separated by tab characters).

Updating text files is more difficult than it probably seems at first. But that's only because we're used to seeing text files rendered as pages (or screens) of text. If you could see the file as it is written in the filesystem, the difficulty is more apparent. Since we can't show you the file as it's actually written without opening up a disk drive, here's our rendition of a piece of a text file[356]:

[356]Of course, the real file wouldn't have lines at all; it's one long stream of text. And the newline character should really be a single-character code. But these differences don't hurt this as an example.

He had bought a large map representing the sea,\n  Without the l
east vestige of land:\nAnd the crew were much pleased when they
found it to be\n  A map they could all understand.\n\n"What's th
e good of Mercator's North Poles and Equators,\n  Tropics, Zones
, and Meridian Lines?"\nSo the Bellman would cry: and the crew w
ould reply\n  "They are merely conventional signs!\n\n"Other map
s are such shapes, with their islands and capes!\n  But we've go
t our brave Captain to thank:"\n(So the crew would protest) "tha
t he's bought us the best-\n  A perfect and absolute blank!"\n\n

If you had this file open in your text editor, it would be easy to change a word, add a comma, or fix a misspelling. If your editor is powerful enough, in fact, you could change the indentation of each line with a single command. But the text file is a stream of bytes; if you wanted to add even a single comma, the remainder of the text file (possibly thousands or millions of bytes) would have to move over to make room. Nearly every tiny change would mean lots of slow copying operations on the file. So how can we edit the file efficiently?

The most common way of programmatically updating a text file is by writing an entirely new file that looks similar to the old one, but making whatever changes we need as we go along. As you'll see, this technique gives nearly the same result as updating the file itself, but it has some beneficial side effects as well.

In this example, we've got hundreds of files with a similar format. One of them is fred03.dat, and it's full of lines like these:

Program name: granite
Author: Gilbert Bates
Company: RockSoft
Department: R&D
Phone: +1 503 555-0095
Date: Tues March 9, 1999
Version: 2.1
Size: 21k
Status: Final beta

We need to fix this file so that it has some different information. Here's roughly what this one should look like when we're done:

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

In short, we need to make three changes. The name of the Author should be changed; the Date should be updated to today's date, and the Phone should be removed completely. And we have to make these changes in hundreds of similar files as well.

Perl supports a way of in-place editing of files with a little extra help from the diamond operator ("<>"). Here's a program to do what we want, although it may not be obvious how it works at first. This program's only new feature is the special variable $^I; ignore that for now, and we'll come back to it:

#!/usr/bin/perl -w

use strict;

chomp(my $date = `date`);
@ARGV = glob "fred*.dat" or die "no files found";
$^I = ".bak";

while (<>) {
  s/^Author:.*/Author: Randal L. Schwartz/;
  s/^Phone:.*\n//;
  s/^Date:.*/Date: $date/;
  print;
}

Since we need today's date, the program starts by using the system date command. A better way to get the date (in a slightly different format) would almost surely be to use Perl's own localtime function in a scalar context:

my $date = localtime;

To get the list of files for the diamond operator, we read them from a glob. The next line sets $^I, but keep ignoring that for the moment.

The main loop reads, updates, and prints one line at a time. (With what you know so far, that means that all of the files' newly modified contents will be dumped to your terminal, scrolling furiously past your eyes, without the files being changed at all. But stick with us.) Note that the second substitution can replace the entire line containing the phone number with an empty string -- leaving not even a newline -- so when that's printed, nothing comes out, and it's as if the Phone never existed. Most input lines won't match any of the three patterns, and those will be unchanged in the output.

So this result is close to what we want, except that we haven't shown you how the updated information gets back out on to the disk. The answer is in the variable $^I. By default it's undef, and everything is normal. But when it's set to some string, it makes the diamond operator ("<>") even more magical than usual.

We already know about much of the diamond's magic -- it will automatically open and close a series of files for you, or read from the standard-input stream if there aren't any filenames given. But when there's a string in $^I, that string is used as a backup filename's extension. Let's see that in action.

Let's say it's time for the diamond to open our file fred03.dat. It opens it like before, but now it renames it, calling it fred03.dat.bak.[357] We've still got the same file open, but now it has a different name on the disk. Next, the diamond creates a new file and gives it the name fred03.dat. That's okay; we weren't using that name any more. And now the diamond selects the new file as the default for output, so that anything that we print will go into that file.[358]

[357]Some of the details of this procedure will vary on non-Unix systems, but the end result should be nearly the same. See the release notes for your port of Perl.

[358]The diamond also tries to duplicate the original file's permission and ownership settings as much as possible; for example, if the old one was world-readable, the new one should be, as well.

So now the while loop will read a line from the old file, update that, and print it out to the new file. This program can update hundreds of files in a few seconds on a typical machine. Pretty powerful, huh?

Once the program has finished, what does the user see? The user says, "Ah, I see what happened! Perl edited my file fred03.dat, making the changes I needed, and saved me a copy of the original in the backup file fred03.dat.bak just to be helpful!" But we now know the truth: Perl didn't really edit any file. It made a modified copy, said "Abracadabra!", and switched the files around while we were watching sparks come out of the magic wand. Tricky.

Some folks use a tilde ("~") as the value for $^I, since that resembles what emacs does for backup files. Another possible value for $^I is the empty string. This enables in-place editing, but doesn't save the original data in a backup file. But since a small typo in your pattern could wipe out all of the old data, using the empty string is recommended only if you want to find out how good your backup tapes are. It's easy enough to delete the backup files when you're done. And when something goes wrong and you need to rename the backup files to their original names, you'll be glad that you know how to use Perl to do that (see the multiple-file rename example in Chapter 13, "Manipulating Files and Directories").

16.4.1. In-place Editing from the Command Line

A program like the example from the previous section is fairly easy to write. But Larry decided it wasn't easy enough.

Imagine that you need to update hundreds of files that have the misspelling Randal instead of the one-l name Randal. You could write a program like the one in the previous section. Or you could do it all with a one-line program, right on the command line:

$ perl -p -i.bak -w -e 's/Randal/Randal/g' fred*.dat

Perl has a whole slew of command-line options that can be used to build a complete program in a few keystrokes.[359] Let's see what these few do.

[359]See the perlrunmanpage for the complete list.

Starting the command with perl does something like putting #!/usr/bin/perl at the top of a file does: it says to use the program perl to process what follows.

The -p option tells Perl to write a program for you. It's not much of a program, though; it looks something like this:[360]

[360]Actually, the print occurs in a continue block. See the perlsynand perlrunmanpages for more information.

while (<>) { print; }.

If you want even less, you could use -n instead; that leaves out the print statement. (Fans of awk will recognize -p and -n.) Again, it's not much of a program, but it's pretty good for the price of a few keystrokes.

The next option is -i.bak, which you might have guessed sets $^I to ".bak" before the program starts. If you don't want a backup file, you can use -i alone, with no extension.

We've seen -w before -- it turns on warnings.

The -e option says "executable code follows." That means that the s/Randal/Randal/g string is treated as Perl code. Since we've already got a while loop (from the -p option), this code is put inside the loop, before the print. For technical reasons, the last semicolon in the -e code is optional. But if you have more than one -e, and thus more than one chunk of code, only the semicolon at the end of the last one may safely be omitted.

The last command-line parameter is fred*.dat, which says that @ARGV should hold the list of filenames that match that glob. Put the pieces all together, and it's as if we had written a program like this:

#!/usr/bin/perl -w

@ARGV = glob "fred*.dat";
$^I = ".bak";

while (<>) {
  s/Randal/Randal/g;
  print;
}

Compare this program to the one we used in the previous section. It's pretty similar. These command-line options are pretty handy, aren't they?

Previous | Home | Next
16.3. Fixed-length Random-access Databases | Book Index | 16.5. Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.5. Exercises

These exercises are all related; it may be helpful to see what the second and third should do before starting on the first. See Section A.15, "Answers to Chapter 16 Exercises" for answers.

  1. [15] Make a program that will read through the perlfunc.pod file looking for identifier names on =item lines (as in the similar exercise at the end of Chapter 9, "Using Regular Expressions"). The program should write a database showing the first line number on which each identifier appears. That is, if fred was mentioned on lines 23, 29, and 54, the value stored under the key fred would be 23. (Hint: the special $. variable gives the line number of the line that was just read.)

  2. [10] Make a program that will take a Perl function name on the command line, and report what =item line of the perlfunc.pod file first mentions that function. Your program should not have to read through a long file to get this answer. What should your program do if the function name isn't found?

  3. [10] (Extra credit exercise.) Modify the program from the previous exercise so that when the function is found in the database, your program will launch your favorite pager program to view the perlfunc.pod file at that line. (Hint: many programs that can be used for viewing text files work like less does, with a command line like less +1234 filename to start viewing the file at line 1234. Your favorite text editor may also support this convention, which is also used by more, pico, vi, emacs, and view.)

Previous | Home | Next
16.4. Variable-length (Text) Databases | Book Index | 17. Some Advanced Perl Techniques
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 17. Some Advanced Perl Techniques

Contents:

Trapping Errors with eval
Picking Items from a List with grep
Transforming Items from a List with map
Unquoted Hash Keys
More Powerful Regular Expressions
Slices
Exercise

What we've put in the rest of this book is the core of Perl, the part that every Perl user should understand. But there are a few other techniques that, while not obligatory, are still valuable tools to have in your toolbox. We've gathered the most important of those for this chapter.

Don't be misled by the title of the chapter, though; the techniques here aren't especially more difficult to understand than what we have elsewhere. They are "advanced" merely in the sense that they aren't necessary for beginners. The first time you read this book, you may want to skip (or skim) this chapter so you can get right to using Perl. Come back to it a month or two later, when you're ready to get even more out of Perl. Consider this entire chapter a huge footnote[361].

[361]We contemplated doing that in one of the drafts, but got firmly rejected by O'Reilly's editors.

17.1. Trapping Errors with eval

Sometimes, your ordinary, everyday code can cause a fatal error in your program. Each of these typical statements could crash a program:

$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: $!";

You could go to some trouble to catch some of these, but it's hard to get them all. (How could you check the string $wilma from that example to ensure that it makes a valid regular expression?) Fortunately, Perl provides a simple way to catch fatal errors: wrap the code in an eval block:

eval { $barney = $fred / $dino } ;

Now, even if $dino is zero, that line won't crash the program. The eval is actually an expression (not a control structure, like while or foreach) so that semicolon is required at the end of the block.

When a normally fatal error happens during the execution of an eval block, the block is done running, but the program doesn't crash. So that means that right after an eval finishes, you'll be wanting to know whether it exited normally or whether it caught a fatal error for you. The answer is in the special $@ variable. If the eval caught a fatal error, $@ will hold what would have been the program's dying words, perhaps something like: Illegal division by zero at my_program line 12. If there was no error, $@ will be empty. Of course, that means that $@ is a useful Boolean (true/false) value, true if there was an error, so you'll sometimes see code like this after an eval block:

print "An error occurred: $@" if $@;

The eval block is a true block, so it makes a new scope for lexical (my) variables. This piece of a program shows an eval block hard at work:

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";
  }
}

How many possible fatal errors are being trapped here? If there is an error in opening the file, that error is trapped. Calculating the average may divide by zero, so that error is trapped. Even the call to the mysteriously named &do_something subroutine will be protected against fatal errors, because an eval block traps any otherwise-fatal errors that occur during the time that it's active. (This feature is handy if you have to call a subroutine written by someone else, and you don't know whether they've coded defensively enough to avoid crashing your program.)

If an error occurs during the processing of one of the files, we'll get an error message, but the program will go on to the next file without further complaint.

You can nest eval blocks inside other eval blocks. The inner one traps errors while it runs, keeping them from reaching the outer blocks. (Of course, after the inner eval finishes, if it caught an error, you may wish to re-post the error by using die, thereby letting the outer eval catch it.) An eval block traps any errors that occur during its execution, including errors that happen during subroutine calls (as we saw in the example earlier).

We mentioned earlier that the eval is an expression, which is why the trailing semicolon is needed after the closing curly brace. But since it's an expression, it has a return value. If there's no error, it's like a subroutine: the return value is the last expression evaluated, or it's returned early with an optional return keyword. Here's another way to do the math without having to worry about divide-by-zero:

my $barney = eval { $fred / $dino };

If the eval traps a fatal error, the return value is either undef or an empty list, depending upon the context. So in the previous example, $barney is either the correct result from dividing, or it's undef; we don't really need to check $@ (although it's probably a good idea to check defined($barney) before we use it further).

There are four kinds of problems that eval can't trap. The first group are the very serious errors that crash Perl itself, such as running out of memory or getting an untrapped signal. Since Perl itself isn't running, there's no way it can trap these errors.[362]

[362]Some of these errors are listed with an (X) code on the perldiag manpage, if you're curious.

Of course, syntax errors inside the eval block are caught at compile time -- they're never returned in $@.

The exit operator terminates the program at once, even if it's called from a subroutine inside an eval block. (This correctly implies that when writing a subroutine, you should use die rather than exit to signal when something goes wrong.)

The fourth and final kind of problem that an eval block can't trap are warnings, either user-generated ones (from warn) or Perl's internally generated warnings (requested with the -w command-line option or the use warnings pragma). There's a separate mechanism from eval for trapping warnings; see the discussion of the __WARN__ pseudosignal in the Perl documentation for the details.

We should also mention that there's another form of eval that can be dangerous if it's mishandled. In fact, you'll sometimes run across someone who will say that you shouldn't use eval in your code for security reasons. They're (mostly) right that eval should be used only with great care, but they're talking about the other form of eval, sometimes called "eval of a string". If the keyword eval is followed directly by a block of code in curly braces, as we're doing here, there's no need to worry -- that's the safe kind of eval.

Previous | Home | Next
16.5. Exercises | Book Index | 17.2. Picking Items from a List with grep
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.2. Picking Items from a List with grep

Sometimes you'll want only certain items from a list. Maybe it's only the odd numbers selected from a list of numbers, or maybe it's only the lines mentioning Fred from a file of text. As we'll see in this section, picking some items from a list can be done simply with the grep operator.

Let's try that first one and get the odd numbers from a large list of numbers. We don't need anything new to do that:

my @odd_numbers;

foreach (1..1000) {
  push @odd_numbers, $_ if $_ % 2;
}

That code uses the modulus operator (%), which we saw in Chapter 2, "Scalar Data". If a number is even, that number "mod two" gives zero, which is false. But an odd number will give one; since that's true, only the odd numbers will be pushed onto the array.

Now, there's nothing wrong with that code as it stands -- except that it's a little longer to write and slower to run than it might be, since Perl provides the grep operator:

my @odd_numbers = grep { $_ % 2 } 1..1000;

That line gets a list of 500 odd numbers in one quick line of code. How does it work? The first argument to grep is a block that uses $_ as a placeholder for each item in the list, and returns a Boolean (true/false) value. The remaining arguments are the list of items to search through. The grep operator will evaluate the expression once for each item in the list, much as our original foreach loop did. For the ones where the last expression of the block returns a true value, that element is included in the list that results from grep.

While the grep is running, $_ is aliased to one element of the list after another. We've seen this behavior before, in the foreach loop. It's generally a bad idea to modify $_ inside the grep expression, because this will damage the original data.

The grep operator shares its name with a classic Unix utility that picks matching lines from a file by using regular expressions. We can do that with Perl's grep, which is much more powerful. Here we pull only the lines mentioning fred from a file:

my @matching_lines = grep { /\bfred\b/i } <FILE>;

There's a simpler syntax for grep, too. If all you need for the selector is a simple expression (rather than a whole block), you can just use that expression, followed by a comma, in place of the block. Here's the simpler way to write that latest example:

my @matching_lines = grep /\bfred\b/i, <FILE>;
Previous | Home | Next
17. Some Advanced Perl Techniques | Book Index | 17.3. Transforming Items from a List with map
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.3. Transforming Items from a List with map

Another common task is transforming items from a list. For example, suppose you have a list of numbers that should be formatted as "money numbers" for output, as with the subroutine &big_money (from Chapter 15, "Strings and Sorting"). But we don't want to modify the original data; we need a modified copy of the list just for output. Here's one way to do that:

my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data;

foreach (@data) {
  push @formatted_data, &big_money($_);
}

That looks similar in form to the example code used at the beginning of the section on grep, doesn't it? So it may not surprise you that the replacement code resembles the first grep example:

my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);

my @formatted_data = map { &big_money($_) } @data;

The map operator looks much like grep because it has the same kind of arguments: a block that uses $_, and a list of items to process. And it operates in a similar way, evaluating the block once for each item in the list, with $_ aliased to a different original list element each time. But the last expression of the block is used differently; instead of giving a Boolean value, the final value actually becomes part of the resulting list.[363]

[363]One other important difference is that the expression used by map is evaluated in a list context and may return any number of items, not necessarily one each time.

Any grep or map statement could be rewritten as a foreach loop pushing items onto a temporary array. But the shorter way is typically more efficient and more convenient. Since the result of map or grep is a list, it can be passed directly to another function. Here we can print that list of formatted "money numbers" as an indented list under a heading:

print "The money numbers are:\n",
  map { sprintf("%25s\n", $_) } @formatted_data;

Of course, we could have done that processing all at once, without even the temporary array @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;

As we saw with grep, there's also a simpler syntax for map. If all you need for the selector is a simple expression (rather than a whole block), you can just use that expression, followed by a comma, in place of the block:

print "Some powers of two are:\n",
  map "\t" . ( 2 ** $_ ) . "\n", 0..15;
Previous | Home | Next
17.2. Picking Items from a List with grep | Book Index | 17.4. Unquoted Hash Keys
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.4. Unquoted Hash Keys

Perl offers many shortcuts that can help the programmer. Here's a handy one: you may omit the quote marks on some hash keys.

Of course, you can't omit the quote marks on just any key, since a hash key may be any arbitrary string. But keys are often simple. If the hash key is made up of nothing but letters, digits, and underscores without starting with a digit, you may be able to omit the quote marks. This kind of simple string without quote marks is called a bareword, since it stands alone without quotes.

One place you are permitted to use this shortcut is the most common place a hash key appears: in the curly braces of a hash element reference. For example, instead of $score{"fred"}, you could write simply $score{fred}. Since many hash keys are simple like this, not using quotes is a real convenience. But beware; if there's anything inside the curly braces besides a bareword, Perl will interpret it as an expression.

Another place where hash keys appear is when assigning an entire hash using a list of key-value pairs. The big arrow (=>) is especially useful between a key and a value, because (again, only if the key is a bareword) the big arrow quotes it for you:

# Hash containing bowling scores
my %score = (
  barney   => 195,
  fred     => 205,
  dino     => 30,
);

This is the one important difference between the big arrow and a comma; a bareword to the left of the big arrow is implicitly quoted. (Whatever is on the right is left alone, though.) This feature of the big arrow doesn't have to be used only for hashes, although that's the most frequent use.

Previous | Home | Next
17.3. Transforming Items from a List with map | Book Index | 17.5. More Powerful Regular Expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.5. More Powerful Regular Expressions

After already reading three chapters about regular expressions, you know that they're a powerful feature in the core of Perl. But there are even more features that the Perl developers have added; we'll see some of the most important ones in this section. At the same time, you'll see a little more about the internal operation of the regular expression engine.

17.5.1. Non-greedy Quantifiers

The four quantifiers we've already seen (in Chapter 8, "More About Regular Expressions") are all greedy. That means that they match as much as they can, only to reluctantly give some back if that's necessary to allow the overall pattern to succeed. Here's an example: Suppose you're using the pattern /fred.+barney/ on the string fred and barney went bowling last night. Of course, we know that the regular expression will match that string, but let's see how it goes about it.[364]

[364]The regular expression engine makes a few optimizations that make the true story different than we tell it here, and those optimizations change from one release of Perl to the next. You shouldn't be able to tell from the functionality that it's not doing as we say, though. If you want to know how it really works, you should read the latest source code. Be sure to submit patches for any bugs you find.

First, of course, the subpattern fred matches the identical literal string. The next part of the pattern is the .+, which matches any character except newline, at least one time. But the plus quantifier is greedy; it prefers to match as much as possible. So it immediately matches all of the rest of the string, including the word night. (This may surprise you, but the story isn't over yet.)

Now the subpattern barney would like to match, but it can't -- we're at the end of the string. But since the .+ could still be successful even if it matched one fewer character, it reluctantly gives back the letter t at the end of the string. (It's greedy, but it wants the whole pattern to succeed even more than it wants to match everything all by itself.)

The subpattern barney tries again to match, and still can't. So the .+ gives back the letter h and lets it try again. One character after another, the .+ gives back what it matched until finally it gives up all of the letters of barney. Now, finally, the subpattern barney can match, and the overall match succeeds.

Regular expression engines do a lot of backtracking like that, trying every different way of fitting the pattern to the string until one of them succeeds, or until none of them has.[365] But as you could see from this example, that can involve a lot of backtracking, as the quantifier gobbles up too much of the string and has to be forced to return some of it.

[365]In fact, some regular expression engines try every different way, even continuing on after they find one that fits. But Perl's regular expression engine is primarily interested in whether the pattern can or cannot match, so finding even one match means that the engine's work is done. Again, see Jeffrey Friedl's Mastering Regular Expressions.

For each of the greedy quantifiers, though, there's also a non-greedy quantifier available. Instead of the plus (+), we can use the non-greedy quantifier +?, which matches one or more times (just as the plus does), except that it prefers to match as few times as possible, rather than as many as possible. Let's see how that new quantifier works when the pattern is rewritten as /fred.+?barney/.

Once again, fred matches right at the start. But this time the next part of the pattern is .+?, which would prefer to match no more than one character, so it matches just the space after fred. The next subpattern is barney, but that can't match here (since the string at the current position begins with and barney...). So the .+? reluctantly matches the a and lets the rest of the pattern try again. Once again, barney can't match, so the .+? accepts the letter n and so on. Once the .+? has matched five characters, barney can match, and the pattern is a success.

There was still some backtracking, but since the engine had to go back and try again just a few times, it should be a big improvement in speed. Well, it's an improvement if you'll generally find barney near fred. If your data often had fred near the start of the string and barney only at the end, the greedy quantifier might be a faster choice. In the end, the speed of the regular expression depends upon the data.

But the non-greedy quantifiers aren't just about efficiency. Although they'll always match (or fail to match) the same strings as their greedy counterparts, they may match different amounts of the strings. For example, suppose you had some HTML-like[366] text, and you want to remove all of the tags <BOLD> and </BOLD>, leaving their contents intact. Here's the text:

[366]Once again, we aren't using real HTML because you can't correctly parse HTML with simple regular expressions. If you really need to work with HTML or a similar markup language, use a module that's made to handle the complexities.

I'm talking about the cartoon with Fred and <BOLD>Wilma</BOLD>!

And here's a substitution to remove those tags. But what's wrong with it?

s#<BOLD>(.*)</BOLD>#$1#g;

The problem is that the star is greedy.[367] What if the text had said this instead?

[367]There's another possible problem: we should have used the /s modifier as well, since the end tag may be on a different line than the start tag. It's a good thing that this is just an example; if we were writing something like this for real, we would have taken our own advice and used a well-written module.

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

In that case, the pattern would match from the first <BOLD> to the last </BOLD>, leaving intact the ones in the middle of the line. Oops! Instead, we want a non-greedy quantifier. The non-greedy form of star is *?, so the substitution now looks like this:

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

And it does the right thing.

Since the non-greedy form of the plus was +? and the non-greedy form of the star was *?, you've probably realized that the other two quantifiers look similar. The non-greedy form of any curly-brace quantifier looks the same, but with a question mark after the closing brace, like {5,10}? or {8,}?.[368] And even the question-mark quantifier has a non-greedy form: ??. That matches either once or not at all, but it prefers not to match anything.

[368]In theory, there's also a non-greedy quantifier form that specifies an exact number, like {3}?. But since that says to match exactly three of the preceding item, it has no flexibility to be either greedy or non-greedy.

17.5.2. Matching Multiple-line Text

Classic regular expressions were used to match just single lines of text. But since Perl can work with strings of any length, Perl's patterns can match multiple lines of text as easily as single lines. Of course, you have to include an expression that holds more than one line of text. Here's a string that's four lines long:

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

Now, the anchors ^ and $ are normally anchors for the start and end of the whole string (see Section 8.3, "Anchors" in Chapter 8, "More About Regular Expressions"). But the /m regular expression option lets them match at internal newlines as well (think m for multiple lines). This makes them anchors for the start and end of each line, rather than the whole string. So this pattern can match:

print "Found 'wilma' at start of line\n" if /^wilma\b/im;

Similarly, you could do a substitution on each line in a multiline string. Here, we read an entire file into one variable,[369] then add the file's name as a prefix at the start of each line:

[369]Hope it's a small one. The file, that is, not the variable.

open FILE, $filename
  or die "Can't open '$filename': $!";
my $lines = join '', <FILE>;
$lines =~ s/^/$filename: /gm;
Previous | Home | Next
17.4. Unquoted Hash Keys | Book Index | 17.6. Slices
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.6. Slices

It often happens that we need to work with only a few elements from a given list. For example, the Bedrock Library keeps information about their patrons in a large file.[370] Each line in the file describes one patron with six colon-separated fields: a person's name, library card number, home address, home phone number, work phone number, and number of items currently checked out. A little bit of the file looks something like this:

[370]It should really be a full-featured database rather than a flat file. They plan to upgrade their system, right after the next Ice Age.

fred flintstone:2168:301 Cobblestone Way:555-1212:555-2121:3
barney rubble:709918:3128 Granite Blvd:555-3333:555-3438:0

One of the library's applications needs only the card numbers and number of items checked out; it doesn't use any of the other data. It could use code something like this to get only the fields it needs:

while (<FILE>) {
  chomp;
  my @items = split /:/;
  my($card_num, $count) = ($items[1], $items[5]);
  ...  # now work with those two variables
}

But the array @items isn't needed for anything else; it seems like a waste.[371] Maybe it would be better to assign the result of split to a list of scalars, like this:

[371]It's not much of a waste, really. But stay with us. All of these techniques are used by programmers who don't understand slices, so it's worthwhile to see all of them here.

my($name, $card_num, $addr, $home, $work, $count) = split /:/;

Well, that avoids the unneeded array @items -- but now we have four scalar variables that we didn't really need. For this situation, some people used to make up a number of dummy variable names, like $dummy_1, that showed that they really didn't care about that element from the split. But Larry thought that that was too much trouble, so he added a special use of undef. If an item in a list being assigned to is undef, that means simply to ignore the corresponding element of the source list:

my(undef, $card_num, undef, undef, undef, $count) = split /:/;

Is this any better? Well, it has an advantage that there aren't any unneeded variables. But it has the disadvantage that you have to count undefs to tell which element is $count. And this becomes quite unwieldy if there are more elements in the list. For example, some people who wanted just the mtime value from stat were writing code like this:

my(undef, undef, undef, undef, undef, undef, undef,
  undef, undef, $mtime) = stat $some_file;

If you use the wrong number of undefs, you'll get the atime or ctime by mistake, and that's a tough one to debug. There's a better way: Perl can index into a list as if it were an array. This is a list slice. Here, since the mtime is item 9 in the list returned by stat,[372] we can get it with a subscript:

[372]It's the tenth item, but the index number is 9, since the first item is at index 0. This is the same kind of zero-based indexing that we've used already with arrays.

my $mtime = (stat $some_file)[9];

Those parentheses are required around the list of items (in this case, the return value from stat). If you wrote it like this, it wouldn't work:

my $mtime = stat($some_file)[9];  # Syntax error!

A list slice has to have a subscript expression in square brackets after a list in parentheses. The parentheses holding the arguments to a function call don't count.

Going back to the Bedrock Library, the list we're working with is the return value from split. We can now use a slice to pull out item 1 and item 5 with subscripts:

my $card_num = (split /:/)[1];
my $count = (split /:/)[5];

Using a scalar-context slice like this (pulling just a single element from the list) isn't bad, but it would be more efficient and simpler if we didn't have to do the split twice. So let's not do it twice; let's get both values at once by using a list slice in list context:

my($card_num, $count) = (split /:/)[1, 5];

The indices pull out element 1 and element 5 from the list, returning those as a two-element list. When that's assigned to the two my variables, we get exactly what we wanted. We do the slice just once, and we set the two variables with a simple notation.

A slice is often the simplest way to pull a few items from a list. Here, we can pull just the first and last items from a list, using the fact that index -1 means the last element:[373]

[373]Sorting a list merely to find the extreme elements isn't likely to be the most efficient way. But Perl's sort is fast enough that this is generally acceptable, as long as the list doesn't have more than a few hundred elements.

my($first, $last) = (sort @names)[0, -1];

The subscripts of a slice may be in any order and may even repeat values. This example pulls five items from a list of ten:

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

17.6.1. Array Slice

That previous example could be made even simpler. When slicing elements from an array (as opposed to a list), the parentheses aren't needed. So we could have done the slice like this:

my @numbers = @names[ 9, 0, 2, 1, 0 ];

This isn't merely a matter of omitting the parentheses; this is actually a different notation for accessing array elements: an array slice. Earlier (in Chapter 3, "Lists and Arrays "), we said that the at-sign on @names meant "all of the elements." Actually, in a linguistic sense, it's more like a plural marker, much like the letter "s" in words like "cats" and "dogs." In Perl, the dollar sign means there's just one of something, but the at-sign means there's a list of items.

A slice is always a list, so the array slice notation uses an at-sign to indicate that. When you see something like @names[ ... ] in a Perl program, you'll need to do just as Perl does and look at the at-sign at the beginning as well as the square brackets at the end. The square brackets mean that you're indexing into an array, and the at-sign means that you're getting a whole list[374] of elements, not just a single one (which is what the dollar sign would mean). See Figure 17-1.

[374]Of course, when we say "a whole list," that doesn't necessarily mean more elements than one -- the list could be empty, after all.

Figure 17-1. Array slices versus single elements

The punctuation mark at the front of the variable reference (either the dollar sign or at-sign) determines the context of the subscript expression. If there's a dollar sign in front, the subscript expression is evaluated in a scalar context to get an index. But if there's an at-sign in front, the subscript expression is evaluated in a list context to get a list of indices.

So we see that @names[ 2, 5 ] means the same list as ($names[2], $names[5]) does. If you want that list of values, you can simply use the array slice notation. Any place you might want to write the list, you can instead use the simpler array slice.

But the slice can be used in one place where the list can't: a slice may be interpolated directly into a string:

my @names = qw{ zero one two three four five six seven eight nine };
print "Bedrock @names[ 9, 0, 2, 1, 0 ]\n";

If we were to interpolate @names, that would give all of the items from the array, separated by spaces. If instead we interpolate @names[ 9, 0, 2, 1, 0 ], that gives just those items from the array, separated by spaces.[375]

[375]More accurately, the items of the list are separated by the contents of Perl's $" variable, whose default is a space. This should not normally be changed. When interpolating a list of values, Perl internally does join $", @list, where @list stands in for the list expression.

Let's go back to the Bedrock Library for a moment. Maybe now our program is updating Mr. Slate's address and phone number in the patron file, because he just moved into a large new place in the Hollyrock hills. If we've got a list of information about him in @items, we could do something like this to update just those two elements of the array:

my $new_home_phone = "555-6099";
my $new_address = "99380 Red Rock West";
@items[2, 3] = ($new_address, $new_home_phone);

Once again, the array slice makes a more compact notation for a list of elements. In this case, that last line is the same as an assignment to ($items[2], $items[3]), but more compact and efficient.

17.6.2. Hash Slice

In a way exactly analogous to an array slice, we can also slice some elements from a hash in a hash slice. Remember when three of our characters went bowling, and we kept their bowling scores in the %score hash? We could pull those scores with a list of hash elements or with a slice. These two techniques are equivalent, although the second is more concise and efficient:

my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});

my @three_scores = @score{ qw/ barney fred dino/ };

A slice is always a list, so the hash slice notation uses an at-sign to indicate that.[376] When you see something like @score{ ... } in a Perl program, you'll need to do just as Perl does and look at the at-sign at the beginning as well as the curly braces at the end. The curly braces mean that you're indexing into a hash; the at-sign means that you're getting a whole list of elements, not just a single one (which is what the dollar sign would mean). See Figure 17-2.

[376]If it sounds as if we're repeating ourselves here, it's because we want to emphasize that hash slices are analogous to array slices. If it sounds as if we're not repeating ourselves here, it's because we want to emphasize that hash slices are analogous to array slices.

Figure 17-2. Hash slices versus single elements

As we saw with the array slice, the punctuation mark at the front of the variable reference (either the dollar sign or at-sign) determines the context of the subscript expression. If there's a dollar sign in front, the subscript expression is evaluated in a scalar context to get a single key.[377] But if there's an at-sign in front, the subscript expression is evaluated in a list context to get a list of keys.

[377]There's an exception you're not likely to run across, since it isn't used much in modern Perl code. See the entry for $; in the perlvar manpage.

It's normal at this point to wonder why there's no percent sign ("%") here, when we're talking about a hash. That's the marker that means there's a whole hash; a hash slice (like any other slice) is always a list, not a hash.[378] In Perl, the dollar sign means there's just one of something, but the at-sign means there's a list of items, and the percent sign means there's an entire hash.

[378]A hash slice is a slice (not a hash) in the same way that a house fire is a fire (not a house), while a fire house is a house (not a fire). More or less.

As we saw with array slices, a hash slice may be used instead of the corresponding list of elements from the hash, anywhere within Perl. So we can set our friends' bowling scores in the hash (without disturbing any other elements in the hash) in this simple way:

my @players = qw/ barney fred dino /;
my @bowling_scores = (195, 205, 30);
@score{ @players } = @bowling_scores;

That last line does the same thing as if we had assigned to the three-element list ($score{"barney"}, $score{"fred"}, $score{"dino"}).

A hash slice may be interpolated, too. Here, we print out the scores for our favorite bowlers:

print "Tonight's players were: @players\n";
print "Their scores were: @score{@players}\n";
Previous | Home | Next
17.5. More Powerful Regular Expressions | Book Index | 17.7. Exercise
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.7. Exercise

See Section A.16, "Answer to Chapter 17 Exercises" for an answer to the following exercise:

  1. [30] Make a program that reads a list of strings from a file, one string per line, and then lets the user interactively enter patterns that may match some of the strings. For each pattern, the program should tell how many strings from the file matched, then which ones those were. Don't re-read the file for each new pattern; keep the strings in memory. The filename may be hard-coded in the file. If a pattern is invalid (for example, if it has unmatched parentheses), the program should simply report that error and let the user continue trying patterns. When the user enters a blank line instead of a pattern, the program should quit. (If you need a file full of interesting strings to try matching, try the file sample_text in the files you've surely downloaded by now from the O'Reilly website; see the Preface.)

Previous | Home | Next
17.6. Slices | Book Index | A. Exercise Answers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Appendix A. Exercise Answers

Contents:

Answers to Chapter 2 Exercises
Answers to Chapter 3 Exercises
Answers to Chapter 4 Exercises
Answers to Chapter 5 Exercises
Answers to Chapter 6 Exercises
Answers to Chapter 7 Exercises
Answers to Chapter 8 Exercises
Answers to Chapter 9 Exercises
Answer to Chapter 10 Exercise
Answers to Chapter 11 Exercises
Answers to Chapter 12 Exercises
Answers to Chapter 13 Exercises
Answers to Chapter 14 Exercises
Answers to Chapter 15 Exercises
Answers to Chapter 16 Exercises
Answer to Chapter 17 Exercises

This appendix contains the answers to the excerses that appear throughout the book.

A.1. Answers to Chapter 2 Exercises

  1. Here's one way to do it:

    #!/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";

    As you see, we started this program with a typical #! line; your path to Perl may vary. We also turned on warnings.

    The first real line of code sets the value of $pi to our value of [image]. There are several reasons a good programmer will prefer to use a constant[379] value like this: it takes time to type 3.141592654 into your program if you ever need it more than once. It may be a mathematical bug if you accidentally used 3.141592654 in one place and 3.14159 in another. There's only one line to check on to make sure you didn't accidentally type 3.141952654 and send your space probe to the wrong planet. It's easier to type $pi than [image], especially if you don't have Unicode. And it will be easy to maintain the program in case the value of [image] ever changes.[380]

    [379]If you'd prefer a more formal sort of constants, the constant pragma may be what you're looking for.

    [380]It nearly did change by a legislative act in the state of Indiana. http://www.urbanlegends.com/legal/pi_indiana.html

    Next we calculate the circumference, storing it into $circ, and we print it out in a nice message. The message ends with a newline character, because every line of a good program's output should end with a newline. Without it, you might end up with output looking something like this, depending upon your shell's prompt:

    The circumference of a circle of radius 12.5 is
78.53981635.bash-2.01$&cursor;

    The box represents the input cursor, blinking at the end of the line, and that's the shell's prompt at the end of the message.[381] Since the circumference isn't really 78.53981635.bash-2.01$, this should probably be construed as a bug. So use \n at the end of each line of output.

    [381]We asked O'Reilly to spend the extra money to print the input cursor with blinking ink, but they wouldn't do it for us.

  2. Here's one way to do it:

    #!/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";

    This is just like the last one, except that now we ask the user for the radius, and then we use $radius in every place where we previously used the hard-coded value 12.5. If we had written the first program with more foresight, in fact, we would have had a variable named $radius in that one as well. Note that we chomped the line of input. If we hadn't, the mathematical formula would still have worked, because a string like "12.5\n" is converted to the number 12.5 without any problem. But when we print out the message, it would look like this:

    The circumference of a circle of radius 12.5
 is 78.53981635.

    Notice that the newline character is still in $radius, even though we've used that variable as a number. Since we had a space between $radius and the word "is" in the print statement, there's a space at the beginning of the second line of output. The moral of the story is: chomp your input unless you have a reason not to do that.

  3. Here's one way to do it:

    #!/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";

    Here we added the check for a bogus radius. Even if the given radius was impossible, the returned circumference will at least be nonnegative. You could have changed the given radius to be zero, and then calculated the circumference, too; there's more than one way to do it. In fact, that's the Perl motto: There Is More Than One Way To Do It. And that's why each exercise answer starts with "Here's one way to do it."

  4. Here's one way to do it:

    print "Enter first number: ";
chomp($one = <STDIN>);
print "Enter second number: ";
chomp($two = <STDIN>);
$result = $one * $two;
print "The result is $result.\n";

    Notice that we've left off the #! line for this answer. In fact, from here on, we'll assume that you know it's there, so you don't need to read it each time.

    Perhaps those are poor choices for variable names. In a large program, a maintenance programmer might think that $two should have the value of 2. In this short program, it probably doesn't matter, but in a large one we could have called them something more descriptive, with names like $first_response.

    In this program, it wouldn't make any difference if we forgot to chomp the two variables $one and $two, since we never use them as strings once they've been set. But if next week our maintenance programmer edits the program to print a message like: The result of multiplying $one by $two is $result.\n, those pesky newlines will come back to haunt us. Once again, chomp unless you have a reason not to chomp[382] -- like in the next exercise.

    [382]Chomping is like chewing -- not always needed, but most of the time it doesn't hurt.

  5. Here's one way to do it:

    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";

    This program is almost the same as the last one, in a sense. We're "multiplying" a string by a number of times. So we've kept the structure of the previous exercise. In this case, though, we didn't want to chomp the first input item -- the string -- because the exercise asked for the strings to appear on separate lines. So, if the user entered fred and a newline for the string, and 3 for the number, we'd get a newline after each fred just as we wanted.

    In the print statement at the end, we put the newline before $result because we wanted to have the first fred, printed on a line of its own. That is, we didn't want output like this, with only two of the three freds aligned in a column:

    The result is: fred
fred
fred

    At the same time, we didn't need to put another newline at the end of the print output because $result should already end with a newline.

    In most cases, Perl won't mind where you put spaces in your program; you can put in spaces or leave them out. But it's important not to accidentally spell the wrong thing! If the x runs up against the preceding variable name $str, Perl will see $strx, which won't work.

Previous | Home | Next
17.7. Exercise | Book Index | A.2. Answers to Chapter 3 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.2. Answers to Chapter 3 Exercises

  1. Here's one way to do it:

    print "Enter some lines, then press Ctrl-D:\n"; # or maybe Ctrl-Z
@lines = <STDIN>;
@reverse_lines = reverse @lines;
print @reverse_lines;

    ...or, even more simply:

    print "Enter some lines, then press Ctrl-D:\n";
print reverse <STDIN>;

    Most Perl programmers would prefer the second one, as long as you don't need to keep the list of lines around for later use.

  2. Here's one way to do it:

    @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";
}

    We have to subtract one from the index number so that the user can count from 1 to 7 even though the array is indexed from 0 to 6. Another way to accomplish this would be to have a dummy item in the @names array, like this:

    @names = qw/ dummy_item fred betty barney dino wilma pebbles bamm-bamm /;

    Give yourself extra credit if you checked to make sure that the user's choice of index was in fact in the range 1 to 7.

  3. Here's one way to do it, if you want the output all on one line:

    chomp(@lines = <STDIN>);
@sorted = sort @lines;
print "@sorted\n";

    ...or, to get the output on separate lines:

    print sort <STDIN>;
Previous | Home | Next
A. Exercise Answers | Book Index | A.3. Answers to Chapter 4 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.3. Answers to Chapter 4 Exercises

  1. Here's one way to do it:

    sub total {
  my $sum;  # private variable
  foreach (@_) {
    $sum += $_;
  }
  $sum;
}

    This subroutine uses $sum to keep a running total. At the start of the subroutine, $sum is undef, since it's a new variable. Then, the foreach loop steps through the parameter list (from @_), using $_ as the control variable. (Note: once again, there's no automatic connection between @_, the parameter array, and $_, the default variable for the foreach loop.)

    The first time through the foreach loop, the first number (in $_) is added to $sum. Of course, $sum is undef, since nothing has been stored in there. But since we're using it as a number, which Perl sees because of the numeric operator +=, Perl acts as if it's already initialized to 0. Perl thus adds the first parameter to 0, and puts the total back into $sum.

    Next time through the loop, the next parameter is added to $sum, which is no longer undef. The sum is placed back into $sum, and on through the rest of the parameters. Finally, the last line returns $sum to the caller.

    There's a potential bug in this subroutine, depending upon how you think of things. Suppose that this subroutine was called with an empty parameter list (as we considered with the rewritten subroutine &max in the chapter text). In that case, $sum would be undef, and that would be the return value. But in this subroutine, it would probably be "more correct" to return 0 as the sum of the empty list, rather than undef. (Of course, if you wished to distinguish the sum of an empty list from the sum of, say, (3, -5, 2), returning undef would be the right thing to do.)

    If you don't want a possibly undefined return value, though, it's easy to remedy: simply initialize $sum to zero rather than using the default of undef:

    my $sum = 0;

    Now the subroutine will always return a number, even if the parameter list were empty.

  2. Here's one way to do it:

    # Remember to include &total from previous exercise!
print "The numbers from 1 to 1000 add up to ", &total(1..1000), ".\n";

    Note that we can't call the subroutine from inside the double-quoted string,[383] so the subroutine call is another separate item being passed to print. The total should be 500500, a nice round number. And it shouldn't take any noticeable time at all to run this program; passing a parameter list of 1000 values is an everyday task for Perl.

    [383]We can't do this without advanced trickiness, that is. It's rare to find anything that you absolutely can't do in Perl.

Previous | Home | Next
A.2. Answers to Chapter 3 Exercises | Book Index | A.4. Answers to Chapter 5 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.4. Answers to Chapter 5 Exercises

  1. Here's one way to do it:

    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";

    In this one, we used a qw// list (with curly braces as the delimiter) to initialize the hash. That's fine for this simple data set, and it's easy to maintain because each data item is a simple given name and simple family name, with nothing tricky. But if your data might contain spaces -- for example, if robert de niro or mary kay place were to visit Bedrock -- this simple method wouldn't work so well.

    You might have chosen to assign each key/value pair separately, something like this:

    my %last_name;
$last_name{"fred"} = "flintstone";
$last_name{"barney"} = "rubble";
$last_name{"wilma"} = "flintstone";

    Note that (if you chose to declare the hash with my, perhaps because use strict was in effect), you must declare the hash before assigning any elements. You can't use my on only part of a variable, like this:

    my $last_name{"fred"} = "flintstone";  # Oops!

    The my operator works only with entire variables, never with just one element of an array or hash. Speaking of lexical variables, you may have noticed that the lexical variable $name is being declared inside of the chomp function call; it is fairly common to declare each my variable as it is needed, like this.

    This is another case where chomp is vital. If someone enters the five-character string "fred\n" and we fail to chomp it, we'll be looking for "fred\n" as an element of the hash -- and it's not there. Of course, chomp alone won't make this bulletproof; if someone enters "fred \n" (with a trailing space), we don't have a way with what we've seen so far to tell that they meant fred.

    If you added a check whether the given key exists in the hash, so that you'll give the user an explanatory message when they misspell a name, give yourself extra points for that.

  2. Here's one way to do it:

    my(@words, %count, $word);     # (optionally) declare our variables
chomp(@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";
}

    In this one, we declared all of the variables at the top. People who come to Perl from a background in languages like Pascal (where variables are always declared "at the top") may find that way more familiar than declaring variables as they are needed. Of course, we're declaring these because we're pretending that use strict may be in effect; by default, Perl won't require such declarations.

    Next, we use the line-input operator, <STDIN>, in a list context to read all of the input lines into @words, and then we chomp those all at once. So @words is our list of words from the input (if the words were all on separate lines, as they should have been, of course).

    Now, the first foreach loop goes through all of the words. That loop contains the most important statement of the entire program, the statement that says to add one to $count{$word}, and put the result back into $count{$word}. Although you could write it either the short way (with the += operator) or the long way, the short way is just a little bit more efficient, since Perl has to look up $word in the hash just once.[384]

    [384]Also, at least in some versions of Perl, the shorter way will avoid a warning about using an undefined value that may crop up with the longer one. The warning may also be avoided by using the ++ operator to increment the variable, although we haven't shown you that operator yet.

    For each word in the first foreach loop, we add one to $count{$word}. So, if the first word is fred, we add one to $count{"fred"}. Of course, since this is the first time we've seen $count{"fred"}, it's undef. But since we're treating it as a number (with the numeric += operator, or with +, if you wrote it the long way), Perl converts undef to 0 for us, automatically. The total is 1, which is then stored back into $count{"fred"}.

    The next time through that foreach loop, let's say the word is barney. So, we add one to $count{"barney"}, bumping it up from undef to 1, as well.

    Now let's say the next word is fred again. When we add one to $count{"fred"}, which is already 1, we get 2. This goes back into $count{"fred"}, meaning that we've now seen fred twice.

    When we finish the first foreach loop, then, we've counted how many times each word has appeared. The hash has a key for each (unique) word from the input, and the corresponding value is the number of times that word appeared.

    So now, the second foreach loop goes through the keys of the hash, which are the unique words from the input. In this loop, we'll see each different word once. For each one, it says something like "fred was seen 3 times."

    If you want the extra credit on this problem, you could put sort before keys to print out the keys in order. If there will be more than a dozen items in an output list, it's generally a good idea for them to be sorted, so that a human being who is trying to debug the program will fairly quickly be able to find the item he or she wants.

Previous | Home | Next
A.3. Answers to Chapter 4 Exercises | Book Index | A.5. Answers to Chapter 6 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.5. Answers to Chapter 6 Exercises

  1. Here's one way to do it:

    print reverse <>;

    Well, that's pretty simple! But it works because print is looking for a list of strings to print, which it gets by calling reverse in a list context. And reverse is looking for a list of strings to reverse, which it gets by using the diamond operator in list context. So, the diamond returns a list of all of the lines from all of the files of the user's choice. That list of lines is just what cat would print out. Now reverse reverses the list of lines, and print prints them out.

  2. Here's one way to do it:

    print "Enter some lines, then press Ctrl-D:\n";  # or Ctrl-Z
chomp(my @lines = <STDIN>);

print "1234567890" x 7, "12345\n";  # ruler line to column 75

foreach (@lines) {
  printf "%20s\n", $_;
}

    Here, we start by reading in and chomping all of the lines of text. Then we print the ruler line. Since that's a debugging aid, we'd generally comment-out that line when the program is done. We could have typed "1234567890" again and again, or even used copy-and-paste to make a ruler line as long as we needed, but we chose to do it this way because it's kind of cool.

    Now, the foreach loop iterates over the list of lines, printing each one with the %20s conversion. If you chose to do so, you could have created a format to print the list all at once, without the loop:

    my $format = "%20s\n" x @lines;
printf $format, @lines;

    It's a common mistake to get 19-character columns. That happens when you say to yourself,[385] "Hey, why do we chomp the input if we're only going to add the newlines back on later?" So you leave out the chomp and use a format of "%20s" (without a newline).[386] And now, mysteriously, the output is off by one space. So, what went wrong?

    [385]Or to Larry, if he's standing nearby.

    [386]Unless Larry told you not to do that.

    The problem happens when Perl tries to count the spaces needed to make the right number of columns. If the user enters hello and a newline, Perl sees six characters, not five, since newline is a character. So it prints fourteen spaces and a six-character string, sure that it gives the twenty characters you asked for in "%20s". Oops.

    Of course, Perl isn't looking at the contents of the string to determine the width; it merely checks the raw number of characters. A newline (or another special character, such as a tab or a null character) will throw things off.[387]

    [387]As Larry should have explained to you by now.

  3. Here's one way to do it:

    print "What column width would you like? ";
chomp(my $width = <STDIN>);

print "Enter some lines, then press Ctrl-D:\n";  # or Ctrl-Z
chomp(my @lines = <STDIN>);

print "1234567890" x (($width+9)/10), "\n";      # ruler line as needed

foreach (@lines) {
  printf "%${width}s\n", $_;
}

    This is much like the previous one, but we ask for a column width first. We ask for that first because we can't ask for more input after the end-of-file indicator, at least on some systems. Of course, in the real world, you'll generally have a better end-of-input indicator when getting input from the user, as we'll see in later chapters.

    Another change from the previous exercise's answer is the ruler line. We used some math to cook up a ruler line that's at least as long as we need, as suggested as an "extra credit" part of the exercise. Proving that our math is correct is an additional challenge. (Hint: Consider possible widths of 50 and 51, and remember that the right side operand to x is truncated, not rounded.)

    To generate the format this time, we used the expression "%${width}s\n", which interpolates $width. The curly braces are required to "insulate" the name from the following s; without the curly braces, we'd be interpolating $widths, the wrong variable. If you forgot how to use curly braces to do this, though, you could have written an expression like '%' . $width . "s\n" to get the same format string.

    The value of $width brings up another case where chomp is vital. If the width isn't chomped, the resulting format string would resemble "%30\ns\n". That's not useful.

    People who have seen printf before may have thought of another solution. Because printf comes to us from C, which doesn't have string interpolation, we can use the same trick that C programmers use. If an asterisk ("*") appears in place of a numeric field width in a conversion, a value from the list of parameters will be used:

    printf "%*s\n", $width, $_;
Previous | Home | Next
A.4. Answers to Chapter 5 Exercises | Book Index | A.6. Answers to Chapter 7 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.6. Answers to Chapter 7 Exercises

  1. Here's one way to do it:

    /fred/

    Of course, you have to put that into the test program! This is pretty simple. The more important part of this exercise is trying it out on the sample strings. It doesn't match Fred, showing that regular expressions are case-sensitive. (We'll see how to change that later.) It does match frederick and Alfred, since both of those strings contain the four-letter string fred.. (Matching whole words only, so that frederick and Alfred wouldn't match, is another feature we'll see later.)

    If the test program is working correctly,[388] it should show those two matches as something like |<fred>erick| and |Al<fred>|, using the angle brackets to show where fred was found inside each string.

    [388]If the test program didn't work correctly, you probably didn't download it as we suggested. And you probably didn't test what you typed, as we also suggested. But in that case, you probably didn't do the exercises either; you're just reading these answers in the back of the book, and so the test program (which you didn't actually run) performed flawlessly. In that case, this footnote is pointless.

  2. Here's one way to do it:

    /a+b*/

    That matches the letter a one or more times (that's the plus), followed by b zero or more times (that's the star). Well, that's what the exercise asked for, but you may have come up with something different. After all, if you're looking for any number of b's, you know you'll always find what you're looking for. So you could have written /a+/ instead, and matched the same strings.[389]

    [389]To be sure, you'll match different parts of the strings. But any string that matches /a+b*/ will also match /a+/, and vice versa.

    For that matter, when you want to match one or more a's, you know that the match will succeed when you find even the first one. So, /a/ will match the same set of strings as the first two. The description "any string containing at least one a followed by any number of b's" means the exact same thing as "any string containing a." Of the sample strings, this matches all of them except fred.

    There are even more ways to make this pattern than we show here. Often, in trying to write a pattern, you will need to decide which one of many possible patterns best suits your needs.

  3. Here's one way to do it:

    /\\*\**/

    That's what the text asked for: a backslash (typed twice, since we mean a real backslash[390]) zero or more times (that's the first star), followed by an asterisk (backslashed, since star is a metacharacter) zero or more times (that's the last star). Whew!

    [390]Whenever you mean a real backslash in Perl, type two of them. A lone backslash may try to do something magical, but two of them will always mean a real backslash.

    And what about the sample strings? Did it match any of them? You bet: it matches all of them! It's because the backslashes and asterisks aren't required in the pattern; that is, this pattern can match the empty string. Here's a rule you can rely upon: when a pattern may freely match the empty string, it'll always match, since the empty string can be found in any string. In fact, it'll always match in the first place that you look.

    So, this pattern matches all four characters in \\**, as you'd expect. It matches the empty string at the beginning of fred, which you may not have expected. In the string barney \\\***, it matches the empty string at the beginning. You might wish it would hunt down the backslashes and stars at the end of that string, but it doesn't bother. It looks at the beginning, sees zero backslashes followed by zero asterisks, declares the match a success, and goes home to watch television. And in *wilma\, it matches just the star at the beginning; as you see, this pattern never gets away from the beginning of the string, since it always matches at the first opportunity.

    Now, if someone asked you for a pattern to match any number of backslashes followed by any number of asterisks, you'd be technically correct to give them this one. But chances are, that's not what they really wanted. Spoken languages like English may be ambiguous and not say exactly what they mean, but regular expressions always mean exactly what they say they mean.

    In this case, maybe the person who asked for the pattern forgot to say that he or she always wants to match at least one character, when the pattern matches at all. We can do that. If there's at least one backslash, /\\+\**/ will match. (That's just like what we had before, but there's a plus in place of the first star, meaning one or more backslashes.) If there's not at least one backslash, then in order to match at least one character, we'll need at least one asterisk, so we want /\*+/. When you put those two possibilities together, you get:

    /\\+\**|\*+/

    Ugly, isn't it? Regular expressions are powerful but not beautiful. And they've contributed to Perl being maligned as a "write-only language." To be sure that no one criticizes your code in that way, though, it's kind to put an explanatory comment near any pattern that's not obvious. On the other hand, when you've been using these for a year, you will have a different definition of "obvious" than you have today.

    How does this new pattern work with the sample strings? With \\**, it matches all four characters, just like the last one. It won't match fred, which is probably the right behavior given the problem description. For barney \\\***, it matches the six characters at the end, as you hoped. And for *wilma\, it matches the asterisk at the beginning.

  4. Here's one way to do it:

    while (<>) {
  if (/wilma/) {
    print;
  }
}

    This is a grep-like program. For each line of text (contained in $_), we check to see whether the pattern matches. If it matches, we print it. This program uses print's default: if you don't tell it to print something else, it prints $_. So we have written a program that uses $_ all the way through, but never mentions it anywhere. Perl folks love to use the defaults and save time typing, so you'll see a lot of programs that do this.

    And if, for extra credit, you wanted to match a capitalized Wilma as well, /wilma|Wilma/ would do the job. Or, more simply, you could have written /(w|W)ilma/. People who have used other regular expression implementations and already know about character classes, which we'll discuss in the next chapter, could make that last one even shorter (and more efficient).[391]

    [391]If you made the whole pattern case-insensitive, shame on you. We haven't learned that yet. Besides, that would match WILMA, which shouldn't match, according to the exercise description.

  5. Here's one way to do it:

    while (<>) {
  if (/wilma/) {
    if (/fred/) {
      print;
    }
  }
}

    This tests /fred/ only after we find /wilma/ matches, but fred could appear before or after wilma in the line; each test is independent of the other.

    If you wanted to avoid the extra nested if test, you might have written something like this:[392]

    [392]Folks who know about the logical-and operator, which we saw in Chapter 10, "More Control Structures", could do both tests /fred/ and /wilma/ in the same if conditional. That's more efficient, more scalable, and an all-around better way than the ones given here. But we haven't seen logical-and yet.

    while (<>) {
  if (/wilma.*fred|fred.*wilma/) {
    print;
  }
}

    This works because we'll either have wilma before fred, or fred before wilma. If we had written just /wilma.*fred/, that wouldn't have matched a line like fred and wilma flintstone, even though that line mentions both of them.

    We made this an extra-credit exercise because many folks have a mental block here. We showed you an "or" operation (with the vertical bar, "|"), but we never showed you an "and" operation. That's because there isn't one in regular expressions.[393] If you want to know whether one pattern and another are both successful, just test both of them.

    [393]But there are some tricky and advanced ways of doing what some folks would call an "and" operation. These are generally less efficient than using Perl's logical-and, though, depending upon what optimizations Perl and its regular expression engine can make.

Previous | Home | Next
A.5. Answers to Chapter 6 Exercises | Book Index | A.7. Answers to Chapter 8 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.7. Answers to Chapter 8 Exercises

  1. Here's one way to do it:

    /\b(fred|wilma)\s+flintstone\b/

    If you forgot to use the \b word-boundary anchors, take off half a point; without those, this would mistakenly match strings like alfred flintstones. The exercise description said to match words.

  2. The point of this exercise may not be obvious, but in the real world, you'll often have to do something similar. Someday, you'll be unlucky enough to have a confusing program to maintain, and you'll wonder what the author was trying to accomplish.[394]

    [394]If you're especially unlucky, this happens when you look at your own code ten minutes after writing it.

    /"([^"]*)"/ matches a simple string in double quotes. By a "simple" string, we don't mean one like Perl's double-quoted strings, which could contain a backslashed double-quote mark or other backslash magic. This matches just a double-quote mark, the contents of the string (which can't contain a double quote), and a closing quote mark. The contents may be empty. The parentheses aren't needed for grouping, so they seem to be memory parentheses; as we'll see in the next chapter, this regular expression memory, which holds the quoted substring, is probably being saved for some later use. Perhaps this pattern would be used in reading a configuration file with quoted strings, although in that case it should probably use anchors.

    /^0?[0-3]?[0-7]{1,2}$/ matches if the string has nothing but an octal number (perhaps with a leading zero) in the range from 0 through 0377. Note that this one is anchored at both ends, so it doesn't allow anything else in the string before or after the number. (The previous pattern wasn't anchored; it could match anywhere in the string.)

    /^\b[\w.]{1,12}\b$/ matches strings made up of nothing but letters, digits, underscores, and dots, but never starting or ending with a dot. Also, the strings are limited to a maximum of 12 characters.

    You may have noticed that the dot inside the character class is not special, so it doesn't need to be backslashed. That makes the character class match ordinary letters, digits, and underscores, and also dots.

    The way we can be sure that this one won't allow a string to start or end with a dot is that it has both a word-boundary anchor and a start-of-string or end-of-string anchor at each end of the string. The word-boundary anchor can match only if there's a "word" starting or ending there, and a dot can't be part of a word.

    So, this would match strings like perl.tar.gz, but not some_excessively_long_filename or perl.tar. or .profile or ...[395] This pattern could be useful for validating user-chosen filenames.

    [395]You may know that file and directory names beginning with a dot are not displayed by default on Unix systems, and that the special directory name .. always means the directory one level higher in the hierarchy.

  3. Here's one way to do it:

    /^\$[A-Za-z_]\w*$/

    The dollar sign at the start has to be backslashed to mean a real dollar sign. What follows must be a letter or underscore, then zero or more letters, digits, or underscores.

  4. This pattern is surprisingly tricky to get right. Here's how we construct it, step by step.

    We start out by needing to match a word, so that's /\w+/. Of course, we want to remember that word for later, so we add parentheses: /(\w+)/. And we want to match it when it occurs two or more times, so that's /(\w+)\1+/. (The plus sign at the end means one or more times -- but that's in addition to the one time that the word occurred originally.)

    But we're not done yet. Now we need to allow for the whitespace which may come between the words. We don't want to memorize the whitespace (since it may vary), so we'll put it outside the parentheses: /(\w+)\s\1+/. Oh, but there could be any number of whitespace characters, so long as there's at least one, so we'll add a plus sign. So now we have /(\w+)\s+\1+/.

    But that's not right; the final plus sign is modifying the backreference alone. We need it to apply to both the backreference (that is, our repeated word) and the whitespace in front of it: /(\w+)(\s+\1)+/. So, now we can match a triple word. First, the part in the first parenthesis pair matches the first occurrence, then the part in the second parenthesis pair can twice match some whitespace followed by that same word. When we try it out, it matches all of our sentences with doubled words, so we happily put it into our program and move on to the next project.

    Then, the next week, we get a bug report! The pattern reports a match on the sentence This is a test, even though there's clearly no doubled word there. In moments, we've fired up the pattern test program[396] to see what part of the string is matching: |Th<is is> a test|. There it is, a doubled word is, hidden in an ordinary string.

    [396]We told you that it would come in handy, and we weren't kidding.

    Clearly, this is a job for a word boundary anchor; we can't have our word start in the middle of another word. So we fix the program to use /\b(\w+)(\s+\1)+/, and sit back, confident that we've got it right this time.

    And then, just when you got started on another project, another bug report comes in. This time, we've matched the doubled word the in the phrase the theory. Yes, we need a word boundary at the end of the pattern to keep from matching a partial word there: /\b(\w+)(\s+\1)+\b/. Now we've finally gotten it right.

    What you've just read is a true story. The regular expression has been changed, but the bug reports are real. It does happen, more often than we'd like to admit, that even after you've been writing these patterns for years, you can make a pattern which has a bug, you can test it with a number of test cases, you can put it into a long-running program, the Perl documentation, or even a best-selling Perl book, and not realize that the bug is there until much later.

    The moral of the story is that regular expressions can be challenging. If you're serious about learning about regular expressions, though (and all Perl programmers should be), we highly recommend the book Mastering Regular Expressions, by Jeffry Friedl (O'Reilly & Associates, Inc.).

Previous | Home | Next
A.6. Answers to Chapter 7 Exercises | Book Index | A.8. Answers to Chapter 9 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.8. Answers to Chapter 9 Exercises

  1. Here's one way to do it:

    /($what){3}/

    Once $what has been interpolated, this gives a pattern resembling /(fred|barney){3}/. Without the parentheses, the pattern would be something like /fred|barney{3}/, which is the same as /fred|barneyyy/. So, the parentheses are required.

  2. Here's one way to do it:

    @ARGV = '/path/to/perlfunc.pod';  # or mentioned on the command line

while (<>) {
  if (/^=item\s+([a-z_]\w*)/i) {
    print "$1\n";                 # print out that identifier name
  }
}

    With what we've shown you so far, the only way to open an arbitrary file for input is to use the diamond operator (or to use input redirection, perhaps). So we put the path to perlfunc.pod into @ARGV.

    The heart of this program is the pattern, which looks for an identifier name on an =item line. The exercise description was ambiguous, in that it didn't say whether =item had to be in lower case; the author of this pattern seems to have decided that it should be a case-insensitive pattern. If you interpreted it otherwise, you could have used the pattern /^=item\s+([a-zA-Z_]\w*)/.

  3. Here's one way to do it:

    @ARGV = '/path/to/perlfunc.pod';  # or mentioned on the command line

my %seen;                         # (optionally) declaring the hash

while (<>) {
  if (/^=item\s+([a-z_]\w*)/i) {
    $seen{$1} += 1;               # a tally for each item
  }
}

foreach (sort keys %seen) {
  if ($seen{$_} > 2) {            # more than twice
    print "$_ was seen $seen{$_} times.\n";
  }
}

    This one starts out much like the previous one, but declares the hash %seen (in case use strict might be in effect). This is called %seen because it tells us which identifier names we've seen so far in the program, and how many times. This is a common use of a hash. The first loop now counts each identifier name, as an entry in %seen, instead of printing it out.

    The second loop goes through the keys of %seen, which are the different identifier names we've seen. It sorts the list, which (although not specified in the exercise description) is a courtesy to the user, who might otherwise have to search for the desired item in a long list.

    Although it may not be obvious, this program is pretty close to a real-world problem that most of us are likely to see. Imagine that your webserver's 400-megabyte logfile has some information you need. There's no way you're going to read that file on your own; you'll want a program to match the information you need (with a pattern) and then print it out in some nice report format. Perl is good for putting together quick programs to do that sort of thing.

Previous | Home | Next
A.7. Answers to Chapter 8 Exercises | Book Index | A.9. Answer to Chapter 10 Exercise
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.9. Answer to Chapter 10 Exercise

  1. Here's one way to do it:

    my $secret = int(1 + rand 100);
# This next line may be un-commented 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";
  }
}

    The first line picks out our secret number from 1 to 100. Here's how it works. First, rand is Perl's random number function, so rand 100 gives us a random number in the range from zero up to (but not including) 100. That is, the largest possible value of that expression is something like 99.999.[397] Adding one gives a number from 1 to 100.999, then the int function truncates that, giving a result from 1 to 100, as we needed.

    [397]The actual largest possible value depends upon your system; see http://www.cpan.org/doc/FMTEYEWTK/random if you really need to know.

    The commented-out line can be helpful during development and debugging, or if you like to cheat. The main body of this program is the infinite while loop. That will keep asking for guesses until we execute last.

    It's important that we test the possible strings before the numbers. If we didn't, do you see what would happen when the user types quit? That would be interpreted as a number (probably giving a warning message, if warnings were turned on), and since the value as a number would be zero, the poor user would get the message that their guess was too small. We might never get to the string tests, in that case.

    Another way to make the infinite loop here would be to use a naked block with redo. It's no more or less efficient; merely another way to write it. Generally, if you expect to mostly loop, it's good to write while, since that loops by default. If looping will be the exception, a naked block may be a better choice.

Previous | Home | Next
A.8. Answers to Chapter 9 Exercises | Book Index | A.10. Answers to Chapter 11 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.10. Answers to Chapter 11 Exercises

  1. Here's one way to do it:

    sub get_line {
  # prompts for, reads, chomps, and returns a line of input
  print $_[0];
  chomp(my $line = <STDIN>);
  $line;
}

my $source = &get_line("Which source file? ");
open IN, $source
  or die "Can't open '$source' for input: $!";

my $dest = &get_line("What destination file? ");
die "Won't overwrite existing file"
  if -e $dest;  # optional safety test
open OUT, ">$dest"
  or die "Can't open '$dest' for output: $!";

my $pattern = &get_line("What search pattern: ");
my $replace = &get_line("What replacement string: ");

while (<IN>) {
  s/$pattern/$replace/g;
  print OUT $_;
}

    This one needs to ask the user for several things, so we decided to make a subroutine to take care of some of the work. The subroutine prints out the prompt, which is the first (and only) parameter to the subroutine. Then it reads a line of input, chomps it, and returns it. That makes it easy to ask for each parameter, one after the other.

    Once we know what the user wants for the source file, we try opening it. An earlier version of this program asked for all of the parameters first, but if the source file name is incorrect, there's no point in having the user type more parameters. This way can save the user some time and trouble. Note that the die message reports the file name inside quote marks; this can be helpful in diagnosing a problem when a string has whitespace characters. If you opened "<$source" instead of just plain $source, that's fine, too. (There's no reason to worry that the user of this program will do something nefarious, since anything they can do with this program, they could accomplish just as well without it. If this program were made to run over the web, to give one example, we'd need to be much more cautious about opening the user's choice of file.)

    As we hope you discovered when you tried it, it's easy to overwrite an existing file simply by opening it for output. So we put in a safety test using the -e file test. The corresponding die message doesn't include $! because we're not reporting a failed request of the system. By the way, this test for overwrite is fine here, but it would be insufficient in an environment where many copies of the same program (or different programs all working with the same files) might be running at once. This typically happens with programs on the web: Two processes check the same filename for existence at approximately the same time, and both see that it doesn't exist. So one of them creates the file, and an instant later the other one overwrites it with a file of its own. This kind of concurrency problem can't be solved with the -e file test; some kind of file locking (which is beyond the scope of this book) is needed.

    With that safety test, the user won't accidentally overwrite an existing file. Is that test a good idea? Well, if the user comes to see you next week and says, "Golly, I'm glad you put in that safety test. It kept me from accidentally overwriting my file!", then you know that it was the right thing to do. But if the user says, "Dagnabit, your program is hard to use! I told it what filename I wanted to use for output, and it wouldn't let me use it until I first deleted that file!", then it was the wrong thing to do. Making decisions like this is often the toughest part of a programmer's job. Perhaps we should make the program ask something like, "Are you sure you want to overwrite the existing file `barney'?" by default, but have a command-line option for the power user that says to overwrite without asking. Next version.

    Once we've asked for everything and opened the files, the rest of the program is pretty simple. The heart of the program is the loop at the end, which reads lines, updates them, and prints them out. Note that the substitution uses the /g option -- if you left that out, your program is broken, since the exercise asked that the program replace every occurrence of the search pattern, not just the first one on each line.

    Were you able to use regular expression metacharacters in the search pattern? Sure; the substitution interpolates $pattern to make the search pattern. Were you able to use memory variables and backslash escapes in the replacement string? Nope; $replace is interpolated to make the replacement string, but it's not re-interpolated to interpret any magical characters. If $replace holds $1, that's a dollar sign and a numeral one in the replacement string. If Perl always kept re-interpolating, you could never put a dollar sign or backslash into the replacement string, since they'd always make something magical happen. (Actually, though, if you need one additional level of interpolation, it is possible. See the perlfaq manpages for some suggestions on how to do this.)

  2. Here's one way to do it:

    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
}

    In this one, once again it's convenient to use a subroutine. The main loop prints one line of attributes for each file, perhaps telling us that 'cereal-killer' is executable or that 'sasquatch' does not exist.

    The subroutine tells us the attributes of the given filename. Of course, if the file doesn't even exist, there's no need for the other tests, so we test for that first. If there's no file, we'll return early.

    If the file does exist, we'll build a list of attributes. (Give yourself extra credit points if you used the special _ filehandle instead of $file on these tests, to keep from calling the system separately for each new attribute.) It would be easy to add additional tests like the three we show here. But what happens if none of the attributes is true? Well, if we can't say anything else, at least we can say that the file exists, so we do. The unless clause uses the fact that @attrib will be true (in a Boolean context, which is a special case of a scalar context) if it's got any elements.

    But if we've got some attributes, we'll join them with " and " and put "is " in front, to make a description like is readable and writable. This isn't perfect however; if there are three attributes, it says that the file is readable and writable and executable, which has too many ands, but we can get away with it. If you wanted to add more attributes to the ones this program checks for, you should probably fix it to say something like is readable, writable, executable, and nonempty. If that matters to you.

    Note that if you somehow didn't put any filenames on the command line, this produces no output. This makes sense; if you ask for information on zero files, you should get zero lines of output. But let's compare that to what the next program does in a similar case, in the discussion below.

  3. Here's one way to do it:

    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;

    This one starts right out by complaining if it didn't get any filenames on the command line. That's because it's supposed to tell us the oldest filename -- and there ain't one if there aren't any files to check.

    Once again, we're using the "high-water-mark" algorithm. The first file is certainly the oldest one seen so far. We have to keep track of its age as well, so that's in $oldest_age.

    For each of the remaining files, we'll determine the age with the -M file test, just as we did for the first one (except that here, we'll use the default argument of $_ for the file test). The last-modified time is generally what people mean by the "age" of a file, although you could make a case for using a different one. If the age is more than $oldest_age, we'll use a list assignment to update both the name and age. We didn't have to use a list assignment, but it's a convenient way to update several variables at once.

    We stored the age from -M into the temporary variable $age. What would have happened if we had simply used -M each time, rather than using a variable? Well, first, unless we used the special _ filehandle, we would have been asking the operating system for the age of the file each time, a potentially slow operation (not that you'd notice unless you have hundreds or thousands of files, and maybe not even then). More importantly, though, we should consider what would happen if someone updated a file while we're checking it. That is, first we see the age of some file, and it's the oldest one seen so far. But before we can get back to use -M a second time, someone modifies the file and resets the timestamp to the current time. Now the age that we save into $oldest_age is actually the youngest age possible. The result would be that we'd get the oldest file among the files tested from that point on, rather than the oldest overall; this would be a tough problem to debug!

    Finally, at the end of the program, we use printf to print out the name and age, with the age rounded off to the nearest tenth of a day. Give yourself extra credit if you went to the trouble to convert the age to a number of days, hours, and minutes.

Previous | Home | Next
A.9. Answer to Chapter 10 Exercise | Book Index | A.11. Answers to Chapter 12 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.11. Answers to Chapter 12 Exercises

  1. Here's one way to do it, with a glob:

    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";
}

    First, we show a simple prompt, and read the desired directory, chomping it as needed. (Without a chomp, we'd be trying to head for a directory that ends in a newline -- legal in Unix, and therefore cannot be presumed to simply be extraneous by the chdir function.)

    Then, if the directory name is nonempty, we'll change to that directory, aborting on a failure. If empty, the home directory is selected instead.

    Finally, a glob on "star" pulls up all the names in the (new) working directory, automatically sorted to alphabetical order, and they're printed one at a time.

  2. Here's one way to do it:

    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";
}

    Two differences from previous one: first, the glob now includes "dot star", which matches all the names that do begin with a dot. And second, we now must sort the resulting list, because some of the names that begin with a dot must be interleaved appropriately either before or after the list of things without a beginning dot.

  3. Here's one way to do it:

    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': $!";
}

opendir DOT, "." or die "Can't opendir dot: $!";
foreach (sort readdir DOT) {
  # next if /^\./; ##   if we were skipping dot files
  print "$_\n";
}

    Again, same structure as the previous two programs, but now we've chosen to open a directory handle. Once we've changed the working directory, we want to open the current directory, and we've shown that as the DOT directory handle.

    Why DOT? Well, if the user asks for an absolute directory name, like /etc, there's no problem opening it. But if the name is relative, like fred, let's see what would happen. First, we chdir to fred, and then we want to use opendir to open it. But that would open fred in the new directory, not fred in the original directory. The only name we can be sure will mean "the current directory" is ".", which always has that meaning (on Unix and similar systems, at least).

    The readdir function pulls up all the names of the directory, which are then sorted, and displayed. If we had done the first exercise this way, we would have skipped over the dot files, and that's handled by the uncommenting the commented-out line in the foreach loop.

    You may find yourself asking, "Why did we chdir first? You can use readdir and friends on any directory, not merely on the current directory." Primarily, we wanted to give the user the convenience of being able to get to their home directory with a single keystroke. But this could be the start of a general file-management utility program; maybe the next step would be to ask the user which of the files in this directory should be moved to offline tape storage, say.

Previous | Home | Next
A.10. Answers to Chapter 11 Exercises | Book Index | A.12. Answers to Chapter 13 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.12. Answers to Chapter 13 Exercises

  1. Here's one way to do it:

    unlink @ARGV;

    ...or, if you want to warn the user of any problems:

    foreach (@ARGV) {
  unlink $_ or warn "Can't unlink '$_': $!, continuing...\n";
}

    Here, each item from the command-invocation line is placed individually into $_, which is then used as the argument to unlink. If something goes wrong, the warning gives the clue about why.

  2. Here's one way to do it:

    use File::Basename;
use File::Spec;

my($source, $dest) = @ARGV;

if (-d $dest) {
  my $basename = basename $source;
  $dest = File::Spec->catfile($dest, $basename);
}

rename $source, $dest
  or die "Can't rename '$source' to '$dest': $!\n";

    The workhorse in this program is the last statement, but the remainder of the program is necessary when we are renaming into a directory. First, after declaring the modules we're using, we name the command-line arguments sensibly. If $dest is a directory, we need to extract the basename from the $source name and append it to the directory ($dest). Finally, once $dest is patched up if needed, the rename does the deed.

  3. Here's one way to do it:

    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";

    As the hint in the exercise description said, this program is much like the previous one. The difference is that we'll link rather than rename. If your system doesn't support hard links, you might have written this as the last line:

    print "Would link '$source' to '$dest'.\n";

  4. Here's one way to do it:

    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 {
  link $source, $dest
    or die "Can't make hard link from '$source' to '$dest': $!\n";
}

    The first few lines of code (after the two use declarations) look at the first command-line argument, and if it's "-s", we're making a symbolic link, so we note that as a true value for $symlink. If we saw that "-s", we then need to get rid of it (in the next line). The next few lines are cut-and-pasted from the previous exercise answers. Finally, based on the truth of $symlink, we'll choose either to create a symbolic link or a hard link. We also updated the dying words to make it clear which kind of link we were attempting.

  5. Here's one way to do it:

    foreach (<.* *>) {
  my $dest = readlink $_;
  print "$_ -> $dest\n" if defined $dest;
}

    Each item resulting from the glob ends up in $_ one by one. If the item is a symbolic link, then readlink returns a defined value, and the location is displayed. If not, then the condition fails, and we skip over it.

Previous | Home | Next
A.11. Answers to Chapter 12 Exercises | Book Index | A.13. Answers to Chapter 14 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.13. Answers to Chapter 14 Exercises

  1. Here's one way to do it:

    chdir "/" or die "Can't chdir to root directory: $!";
exec "ls", "-l" or die "Can't exec ls: $!";

    The first line changes the current working directory to the root directory, as our particular hard-coded directory. The second line uses the multiple-argument exec function to send the result to standard output. We could have used the single-argument form just as well, but it doesn't hurt to do it this way.

  2. Here's one way to do it:

    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: $!";

    The first and second lines reopen STDOUT and STDERR to a file in the current directory (before we change directories). Then, after the directory change, the directory listing command executes, sending the data back to the files opened in the original directory.

    Where would the message from the last die go? Why, it would go into ls.err, of course, since that's where STDERR is going at that point. The die from chdir would go there, too. But where would the message go if we can't re-open STDERR on the second line? It goes to the old STDERR. For the three standard filehandles, STDIN, STDOUT, and STDERR, if re-opening them fails, the old filehandle is still open.

  3. Here's one way to do it:

    if (`date` =~ /^S/) {
  print "go play!\n";
} else {
  print "get to work!\n";
}

    Well, since both Saturday and Sunday start with an S, and the day of the week is the first part of the output of the date command, this is pretty simple. Just check the output of the date command to see if it starts with S. There are many harder ways to do this program, and we've seen most of them in our classes.

    If we had to use this in a real-world program, though, we'd probably use the pattern /^(Sat|Sun)/. It's a tiny bit less efficient, but that hardly matters; besides, it's so much easier for the maintenance programmer to understand.

Previous | Home | Next
A.12. Answers to Chapter 13 Exercises | Book Index | A.14. Answers to Chapter 15 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.14. Answers to Chapter 15 Exercises

  1. Here's one way to do it:

    my @numbers;
push @numbers, split while <>;
foreach (sort { $a <=> $b } @numbers) {
  printf "%20g\n", $_;
}

    That second line of code is too confusing, isn't it? Well, we did that on purpose. Although we recommend that you write clear code, some people like writing code that's as hard to understand as possible,[398] so we want you to be prepared for the worst. Someday, you'll need to maintain confusing code like this.

    [398]Well, we don't recommend it for normal coding purposes, but it can be a fun game to write confusing code, and it can be educational to take someone else's obfuscated code examples and spend a weekend or two figuring out just what they do. If you want to see some fun snippets of such code and maybe get a little help with decoding them, ask around at the next Perl Mongers' meeting. Or search for JAPHs on the Web, or see how well you can decipher the example obfuscated code block near the end of this chapter's answers.

    Since that line uses the while modifier, it's the same as if it were written in a loop like this:

    while (<>) {
  push @numbers, split;
}

    That's better, but maybe it's still a little unclear. (Nevertheless, we don't have a quibble about writing it this way. This one is on the correct side of the "too hard to understand at a glance" line.) The while loop is reading the input a line at a time (from the user's choice of input sources, as shown by the diamond operator), and split is, by default, splitting that on whitespace to make a list of words -- or, in this case, a list of numbers. The input is just a stream of numbers separated by whitespace, after all. Either way that you write it, then, that while loop will put all of the numbers from the input into @numbers.

    The foreach loop takes the sorted list and prints each one on its own line, using the %20g numeric format to put them in a right-justified column. You could have used %20s instead. What difference would that make? Well, that's a string format, so it would have left the strings untouched in the output. Did you notice that our sample data included both 1.50 and 1.5, and both 04 and 4? If you printed those as strings, the extra zero characters will still be in the output; but %20g is a numeric format, so equal numbers will appear identically in the output. Either format could potentially be correct, depending upon what you're trying to do.

  2. Here's one way to do it:

    # 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
}

    There's not much to say about this one; we put the keys in order as needed, then print them out. We chose to print them in last-name-comma-first-name order just for fun; the exercise description left that up to you.

  3. Here's one way to do it:

    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";

    This one starts out simply enough, asking the user for the strings and declaring an array to hold the list of substring positions. But once again, as we see in the for loop, the code seems to have been "optimized for cleverness", which should be done only for fun, never in production code. But this actually shows a valid technique which could be useful in some cases, so let's see how it works.

    The my variable $pos is declared private to the scope of the for loop, and it starts with a value of -1. So as not to keep you in suspense about this variable, we'll tell you right now that it's going to hold a position of the substring in the larger string. The test and increment sections of the for loop are empty, so this is an infinite loop. (Of course, we'll eventually break out of it, in this case with last).

    The first statement of the loop body looks for the first occurrence of the substring at or after position $pos + 1. That means that on the first iteration, when $pos is still -1, the search will start at position 0, the start of the string. The location of the substring is stored back into $pos. Now, if that was -1, we're done with the for loop, so last breaks out of the loop in that case. If it wasn't -1, then we save the position into @places and go around the loop again. This time, $pos + 1 means that we'll start looking for the substring just after the previous place where we found it. And so we get the answers we wanted and the world is once again a happy place.

    If you didn't want that tricky use of the for loop, you could accomplish the same result as shown here:

    {
  my $pos = -1;
  while (1) {
    ... # Same loop body as the for loop used above
  }
}

    The naked block on the outside restricts the scope of $pos. You don't have to do that, but it's often a good idea to declare each variable in the smallest possible scope. This means we have fewer variables "alive" at any given point in the program, making it less likely that we'll accidentally reuse the name $pos for some new purpose. For the same reason, if you don't declare a variable in a small scope, you should generally give it a longer name that's thereby less likely to be reused by accident. Maybe something like $substring_position would be appropriate in this case.

    On the other hand, if you were trying to obfuscate your code (shame on you!), you could create a monster like this (shame on us!):

    for (my $pos = -1; -1 !=
  ($pos = index
    +$string,
    +$sub,
    +$pos
    +1
  );
push @places, ((((+$pos))))) {
    'for ($pos != 1; # ;$pos++) {
      print "position $pos\n";#;';#' } pop @places;
}

    That even trickier code works in place of the original tricky for loop. By now, you should know enough to be able to decipher that one on your own, or to obfuscate code in order to amaze your friends and confound your enemies. Be sure to use these powers only for good, never for evil.

    Oh, and what did you get when you searched for t in This is a test.? It's at positions 10 and 13. It's not at position 0; since the capitalization doesn't match, the substring doesn't match.

Previous | Home | Next
A.13. Answers to Chapter 14 Exercises | Book Index | A.15. Answers to Chapter 16 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.15. Answers to Chapter 16 Exercises

  1. Here's one way to do it:

    open PF, '/path/to/perlfunc.pod' or die "Can't open perlfunc.pod: $!";
dbmopen my %DB, "pf_data", 0644 or die "Can't create dbm file: $!";

%DB = ( );  # wipe existing data, if any

while (<PF>) {
  if (/^=item\s+([a-z_]\w*)/i) {
    $DB{$1} = $DB{$1} || $.;
  }
}

print "Done!\n";

    This one is similar to the previous ones with perlfunc.pod. Here, though, we open a DBM file called pf_data as the DBM hash %DB. In case that file had any leftover data, we set the hash to an empty list. That's normally a rare thing to do, but we want to wipe out the entire database, in case a previous run of this program left incorrect or out-of-date data in the file. (After all, there's a new perlfunc.pod with each new release of Perl.)

    When we find an identifier, we need to store its line number (from $.) into the database. The statement that does that uses the high-precedence short-circuit || operator. If the database entry already has a value, that value is true, so the old value is used. If the database entry is empty, that's false, so the value on the right ($.) is used instead. We could have written that line in a shorter way, like this:

    $DB{$1} ||= $.;

    When the program is done, it says so. That's not required by the exercise description, but it lets us know that the program did something; without that line, there would be no output at all. But how can we tell that it worked correctly? That's the next exercise.

  2. Here's one way to do it:

    dbmopen my %DB, "pf_data", undef or die "Can't open dbm file: $!";
my $line = $DB{$ARGV[0]} || "not found";

print "$ARGV[0]: $line\n";

    Once we have the database, it's simple to look something up in it. Note that in this program, the third argument to dbmopen is undef, since that file must already exist for this program to work.

    If the entry for $ARGV[0] (the first command-line parameter) isn't found in the database, we'll say it's not found, using the high-precedence short-circuit ||.

  3. Here's one way to do it:

    dbmopen my %DB, "pf_data", undef or die "Can't open dbm file: $!";

if (my $line = $DB{$ARGV[0]}) {
  exec 'less', "+$line", '/path/to/perlfunc.pod'
    or die "Can't exec pager: $!";
} else {
  die "Entry unknown: '$ARGV[0]'.\n";
}

    This starts out like the previous one, but uses exec to start up a pager program if it can, and dies if it can't.

Previous | Home | Next
A.14. Answers to Chapter 15 Exercises | Book Index | A.16. Answer to Chapter 17 Exercises
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


A.16. Answer to Chapter 17 Exercises

  1. Here's one way to do it:

    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";
}

    This one uses an eval block to trap any failure that might occur when using the regular expression. Inside that block, a grep pulls the matching strings from the list of strings.

    Once the eval is finished, we can report either the error message or the matching strings. Note that we "unchomped" the strings for output by using map to add a newline to each string .

Previous | Home | Next
A.15. Answers to Chapter 16 Exercises | Book Index | B. Beyond the Llama
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Appendix B. Beyond the Llama

Contents:

Further Documentation
Regular expressions
Packages
Extending Perl's Functionality
Some Important Modules
Pragmas
Databases
Other Operators and Functions
Mathematics
Lists and Arrays
Bits and Pieces
Formats
Networking and IPC
Security
Debugging
The Common Gateway Interface (CGI)
Command-Line Options
Built in Variables
Syntax Extensions
References
Tied Variables
Operator Overloading
Dynamic Loading
Embedding
Converting Other Languages to Perl
Converting find Command Lines to Perl
Command-line Options in Your Programs
Embedded Documentation
More Ways to Open Filehandles
Locales and Unicode
Threads and Forking
Graphical User Interfaces (GUIs)
And More...

We've covered a lot in this book, but there's even more. In this appendix, we'll tell about a little more of what Perl can do, and give some references on where to learn the details. Some of what we mention here is on the bleeding edge and may have changed by the time that you're reading this book, which is one reason why we frequently send you to the documentation for the full story. We don't expect many readers to read every word of this appendix, but we hope you'll at least skim the headings so that you'll be prepared to fight back when someone tells you "You just can't use Perl for project X, because Perl can't do Y."

B.1. Further Documentation

The documentation that comes with Perl may seem overwhelming at first. Fortunately, you can use your computer to search for keywords in the documentation. When searching for a particular topic, it's often good to start with the perltoc (table of contents) and perlfaq (frequently asked questions) sections. On most systems, the perldoc command should be able to track down the documentation for Perl, installed modules, and related programs (including perldoc itself).

Previous | Home | Next
A.16. Answer to Chapter 17 Exercises | Book Index | B.2. Regular expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.2. Regular expressions

Yes, there's even more about regular expressions than we mentioned. Mastering Regular Expressions by Jeffrey Friedl is one of the best technical books we've ever read.[399] It's half about regular expressions in general, and half about Perl's regular expressions. It goes into good detail about how the regular expression engine works internally, and why one way of writing a pattern may be much more efficient than another. Anyone who is serious about Perl should read this book. Also see the perlre manpage (and its companion perlretut and perlrequick manpages in newer versions of Perl).

[399]And we're not just saying that because it's also published by O'Reilly & Associates, Inc. It's really a great book.

Previous | Home | Next
B. Beyond the Llama | Book Index | B.3. Packages
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.3. Packages

Packages[400] allow you to compartmentalize the namespaces. Imagine that you have ten programmers all working on one big project. If you use the global names $fred, @barney, %betty, and &wilma in your part of the project, what happens when I accidentally use one of those same names in my part? Packages let us keep these separate; I can access your $fred, and you can access mine, but not by accident. Packages are needed to make Perl scalable, so that we can manage large programs.

[400]The name "package" is perhaps an unfortunate choice, in that it makes many people think of a packaged-up chunk of code (in Perl, that's a module or a library). All that a package does is define a namespace (a collection of global symbol names, like $fred or &wilma). A namespace is not a chunk of code.

Previous | Home | Next
B.2. Regular expressions | Book Index | B.4. Extending Perl's Functionality
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.4. Extending Perl's Functionality

One of the most common pieces of good advice heard in the Perl discussion forums is that you shouldn't reinvent the wheel. Other folks have written code that you can put to use. The most frequent way to add to what Perl can do is by using a library or module. Many of these come with Perl, while others are available from CPAN. Of course, you can even write your own libraries and modules.

B.4.1. Libraries

Many programming languages offer support for libraries much as Perl does. Libraries are collections of (mostly) subroutines for a given purpose. In modern Perl, though, it's more common to use modules than libraries.

B.4.2. Modules

A module is a "smart library". A module will typically offer a collection of subroutines that act as if they were built in functions, for the most part. Modules are smart in that they keep their details in a separate package, only importing what you request. This keeps a module from stomping on your code's symbols.

Although many useful modules are written in pure Perl, others are written using a language like C. For example, the MD5 algorithm is sort of like a high-powered checksum.[401] It uses a lot of low-level bit-twiddling that could be done in Perl, but hundreds of times more slowly;[402] it's an algorithm that was designed to be efficiently implemented in C. So, the Digest::MD5 module is made to use the compiled C code. When you use that module, it's as if your Perl had a built in function to calculate MD5 digests.

[401]It's not really a checksum, but that's good enough for this explanation.

[402]The module Digest::Perl::MD5 is a pure Perl implementation of the MD5 algorithm. Although your mileage may vary, we found it to be about 280 times slower than the Digest::MD5 module on one sample dataset. Remember that many of the bit-twiddling operations in the C algorithm compile down to a single machine instruction; thus, entire lines of code can take a mere handful of clock cycles to run. Perl is fast, but let's not be unrealistic.

B.4.3. Finding and Installing Modules

Maybe your system already has the module you need. But how can you find out which modules are installed? You can use the program inside, which should be available for download from CPAN in the directory http://www.cpan.org/authors/id/P/PH/PHOENIX/.

If none of the modules already available on your system suits your needs, you can search for Perl modules on CPAN at http://search.cpan.org/. To install a module on your system, see the perlmodinstall manpage.

When using a module, you'll generally put the required use directives at the top of your program. That makes it easy for someone who is installing your program on a new system to see at a glance which modules it needs.

B.4.4. Writing Your Own Modules

In the rare case that there's no module to do what you need, an advanced programmer can write a new one, either in Perl or in another language (often C). See the perlmod and perlmodlib manpages for more information.

Previous | Home | Next
B.3. Packages | Book Index | B.5. Some Important Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.5. Some Important Modules

We describe some of the most important features[403] of the most important modules[404] in this section. These modules that we discuss here should generally be found on every machine that has Perl, except where mentioned. You can always get the latest ones from CPAN.

[403]We're including here merely the most important features of each module; see the module's own documentation to learn more.

[404]To be sure, there are other important modules whose use is too complex for most readers of this book, typically because using the module requires understanding Perl's references or objects.

B.5.1. The CGI and CGI_Lite Modules

Many people use Perl to write programs that a web server will run, generally called CGI programs. The CGI module comes with Perl, while the CGI_Lite module is available separately from CPAN. See Section B.16, "The Common Gateway Interface (CGI)" later in this appendix.

B.5.2. The Cwd Module

Sometimes you need to know what the current working directory's name is. (Well, you could often use ".", but maybe you need to save the name so that you can change back to this directory later.) The Cwd module, which comes with Perl, provides the cwd function, which you can use to determine the current working directory.

use Cwd;

my $directory = cwd;

B.5.3. The Fatal Module

If you get tired of writing "or die" after every invocation of open or chdir, then maybe the Fatal module is for you. Just tell it which functions to work with, and those will be automatically checked for failure, as if you'd written "or die" and a suitable message after each one. This won't affect such calls in someone else's package (that is, code contained within a module you're using, for example), so don't use this to fix up poorly written code. It's just a timesaver, mostly for simple programs in which you don't need direct control over the error message itself. For example:

use Fatal qw/ open chdir /;

chdir '/home/merlyn';  # "or die" is now supplied automatically

B.5.4. The File::Basename Module

We covered this module in Chapter 13, "Manipulating Files and Directories". It's primary uses are to portably pull the basename or directory name from a full filename:

use File::Basename;

for (@ARGV) {
  my $basename = basename $_;
  my $dirname = dirname $_;
  print "That's file $basename in directory $dirname.\n";
}

B.5.5. The File::Copy Module

When you need to copy or move files, the File::Copy module is for you. (It's often tempting to simply call a system program to do these things, but that's not portable.) This module provides the functions move and copy, which may be used much as the corresponding system programs would be used:

use File::Copy;

copy("source", "destination")
  or die "Can't copy 'source' to 'destination': $!";

B.5.6. The File::Spec Module

When you need to manipulate a filename (more formally called a "file specification"), it's generally more portable and reliable to use the File::Spec module than to do the work yourself from Perl. For example, you can use the catfile function to put together a directory name and a filename to produce a long filename (as we saw in Chapter 13, "Manipulating Files and Directories"), but you don't have to know whether the system your program is running on uses a forward slash or some other character to separate those. Or you could use the curdir function to get the name of the current directory (".", on Unix systems).

The File::Spec module is object-oriented, but you don't need to understand objects to use it. Just call each function ("method", really) by using File::Spec and a small arrow before the function's name, like this:

use File::Spec;

my $current_directory = File::Spec->curdir;
opendir DOT, $current_directory
  or die "Can't open current directory '$current_directory': $!";

B.5.7. The Image::Size Module

When you have an image file, you'll often want to know what its height and width are. (This is handy for making programs that write HTML, if you wish for an IMG tag to indicate the image's dimensions.) The Image::Size module, which is available from CPAN, understands the common GIF, JFIF (JPEG), and PNG image types, and some others. For example:

use Image::Size;

# Get the size of fred.png
my($fred_height, $fred_width) = imgsize("fred.png");
die "Couldn't get the size of the image"
  unless defined $fred_height;

B.5.8. The Net::SMTP Module

If you want your program to be able to send email through an SMTP server (which is the way most of us send email these days, whether you knew that or not), you may use the Net::SMTP module to do the work.[405] This module, which is available from CPAN, is object-oriented, but you may simply follow the syntax to use it. You will need to change the name of your SMTP host and the other items to make this work on your system. Your system administrator or local expert can tell you what to use. For example:

[405]Yes, this means that you are now able to use Perl to send spam. Please don't.

use Net::SMTP;

my $from = 'YOUR_ADDRESS_GOES_HERE';         # maybe fred@bedrock.edu
my $site = 'YOUR_SITE_NAME_GOES_HERE';       # maybe bedrock.edu
my $smtp_host = 'YOUR_SMTP_HOST_GOES_HERE';  # maybe mail or mailhost
my $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;

B.5.9. The POSIX Module

If you need access to the POSIX (IEEE Std 1003.1) functions, the POSIX module is for you. It provides many functions that C programmers may be used to, such as trigonometric functions (asin, cosh), general mathematical functions (floor, frexp), character-identification functions (isupper, isalpha), low-level IO functions (creat, open), and some others (asctime, clock). You'll probably want to call each of these with its "full" name; that is, with POSIX and a pair of colons as a prefix to the function's name:

use POSIX;

print "Please enter a number: ";
chomp(my $str = <STDIN>);

$! = 0;  # Clear out the error indicator
my($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";
}

B.5.10. The Sys::Hostname Module

The Sys::Hostname module provides the hostname function, which will be the network name of your machine, if that can be determined. (If it can't be determined, perhaps because your machine is not on the Internet or not properly configured, the function will die automatically; there's no point in using or die here.) For example:

use Sys::Hostname;
my $host = hostname;
print "This machine is known as '$host'.\n";

B.5.11. The Text::Wrap Module

The Text::Wrap module supplies the wrap function, which lets you implement simple word-wrapping. The first two parameters specify the indentation of the first line and the others, respectively; the remaining parameters make up the paragraph's text:

use Text::Wrap;

my $message = "This is some sample text which may be longer " .
  "than the width of your output device, so it needs to " .
  "be wrapped to fit properly as a paragraph. ";
$message x= 5;

print wrap("\t", "", "$message\n");

B.5.12. The Time::Local Module

If you have a time (for example, from the time function) that needs to be converted to a list of year, month, day, hour, minute, and second values, you can do that with Perl's built-in localtime function in a list context.[406] (In a scalar context, that gives a nicely formatted string representing the time, which is more often what you'd want.) But if you need to go in the other direction, you may use the timelocal function from the Time::Local module instead. It's important to note that the value of $mon and $year for January 2004 are not 1 and 2004 as you might expect, so be sure to read the documentation before you use this module. For example:

[406]The actual return value of localtime in a list context is a little different than you might expect; see the documentation.

use Time::Local;

my $time = timelocal($sec, $min, $hr, $day, $mon, $year);
Previous | Home | Next
B.4. Extending Perl's Functionality | Book Index | B.6. Pragmas
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.6. Pragmas

Pragmas are special modules that come with each release of Perl and tell Perl's internal compiler something about your code. You've already used the strict pragma. The pragmas available for your release of Perl should be listed in the perlmodlib manpage.

You use pragmas much like you'd use ordinary modules, with a use directive. Some pragmas are lexically scoped, like lexical ("my") variables are, and they therefore apply to the smallest enclosing block or file. Others may apply to the entire program or to the current package. (If you don't use any packages, the pragmas apply to your entire program.) Pragmas should generally appear near the top of your source code. The documentation for each pragma should tell you how it's scoped.

B.6.1. The constant Pragma

If you've used other languages, you've probably seen the ability to declare constants in one way or another. Constants are handy for making a setting just once, near the beginning of a program, but that can be easily updated if the need arises. Perl can do this with the package-scoped constant pragma, which tells the compiler that a given identifier has a constant value, which may thus be optimized wherever it appears. For example:

use constant DEBUGGING => 0;
use constant ONE_YEAR => 365.2425 * 24 * 60 * 60;

if (DEBUGGING) {
  # This code will be optimized away unless DEBUGGING is turned on
  ...
}

B.6.2. The diagnostics Pragma

Perl's diagnostic messages often seem somewhat cryptic, at least the first time you see them. But you can always look them up in the perldiag manpage to find out what they mean, and often a little about what's likely to be the problem and how to fix it. But you can save yourself the trouble of searching that manpage if you use the diagnostics pragma, which tells Perl to track down and print out the related information for any message. Unlike most pragmas, though, this one is not intended for everyday use, as it makes your program read the entire perldiag manpage just to get started. (This is potentially a significant amount of overhead, both in terms of time and memory.) Use this pragma only when you're debugging and expecting to get error message you don't yet understand. It affects your entire program. The syntax is:

use diagnostics;

B.6.3. The lib Pragma

It's nearly always best to install modules in the standard directories, so that they're available for everyone, but only the system administrator can do that. If you install your own modules, you'll have to store them in your own directories -- so, how will Perl know where to find them? That's what the lib pragma is all about. It tells Perl that the given directory is the first place to look for modules. (That means that it's also useful for trying out a new release of a given module.) It affects all modules loaded from this point on. The syntax is:

use lib '/home/rootbeer/experimental';

Be sure to use a nonrelative pathname as the argument, since there's no telling what will be the current working directory when your program is run. This is especially important for CGI programs (that is, programs run by a web server).

B.6.4. The strict Pragma

You've been using use strict for a while already without having to understand that it's a pragma. It's lexically scoped, and it enforces some good programming rules. See its documentation to learn what restrictions are available in your release of Perl.

B.6.5. The vars Pragma

In the rare case that you truly need a global variable while use strict is in effect, you may declare it with the vars pragma.[407] This package-scoped pragma tells Perl that you are intentionally using one or more global variables:

[407]If your program will never be used with a version of Perl prior to 5.6, you should use the our keyword instead of the vars pragma.

use strict;
use vars qw/ $fred $barney /;

$fred = "This is a global variable, but that's all right.\n";

B.6.6. The warnings Pragma

Starting in Perl version 5.6, you may choose to have lexically scoped warnings with the warnings pragma.[408] That is, rather than using the -w option crudely to turn warnings on or off for the entire program at once, you may specify that you want no warnings about undefined values in just one section of code, while other warnings should be available. This also serves as a signal to the maintenance programmer that says, "I know that this code would produce warnings, but I know what I'm doing anyway." See the documentation for this pragma to learn about the categories of warnings available in your release of Perl.

[408]If your program may be used with a version of Perl prior to 5.6, you should not use the warnings pragma.

Previous | Home | Next
B.5. Some Important Modules | Book Index | B.7. Databases
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.7. Databases

If you've got a database, Perl can work with it. This section describes some of the common types of databases.

B.7.1. Direct System Database Access

Perl can directly access some system databases, sometimes with the help of a module. These are databases like the Windows Registry (which holds machine-level settings), or the Unix password database (which lists which username corresponds to which number, and related information), as well as the domain-name database (which lets you translate an IP number into a machine name, and vice versa).

B.7.2. Flat-file Database Access

If you'd like to access your own flat-file databases from Perl, there are modules to help you with doing that (seemingly a new one every month or two, so any list here would be out of date). You can even do quite a bit without a module, with what we give in Chapter 16, "Simple Databases".

B.7.3. Relational Database Access

Relational databases include Sybase, Oracle, Informix, mysql, and others. These are complex enough that you generally do need to know about modules to use them. But if you use the DBI module, whose name stands for "database-independent," you can minimize your dependence upon any one type of database -- then, if you have to move from mysql to Oracle, say, you might not even need to change anything at all in your program.

Previous | Home | Next
B.6. Pragmas | Book Index | B.8. Other Operators and Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.8. Other Operators and Functions

Yes, there are more operators and functions than we can fit here, from the scalar .. operator to the scalar , operator, from wantarray to goto(!), from caller to chr. See the perlop and perlfunc manpages.

B.8.1. Transliteration with tr///

The tr/// operator looks like a regular expression, but it's really for transliterating one group of characters into another. It can also efficiently count selected characters. See the perlop manpage.

B.8.2. Here documents

Here documents are a useful form of multiline string quoting; see the perldata manpage.

Previous | Home | Next
B.7. Databases | Book Index | B.9. Mathematics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.9. Mathematics

Perl can do just about any kind of mathematics you can dream up.

B.9.1. Advanced Math Functions

All of the basic mathematical functions (square root, cosine, logarithm, absolute value, and many others) are available as built in functions; see the perlfunc manpage for details. Some others (like tangent or base-10 logarithm) are omitted, but those may be easily created from the basic ones, or loaded from a simple module that does so. (See the POSIX module for many common math functions.)

B.9.2. Imaginary and Complex Numbers

Although the core of Perl doesn't directly support them, there are modules available for working with complex numbers. These overload the normal operators and functions, so that you can still multiply with * and get a square root with sqrt, even when using complex numbers. See the Math::Complex module.

B.9.3. Large and High-Precision Numbers

You can do math with arbitrarily large numbers with an arbitrary number of digits of accuracy. For example, you could calculate the factorial of two thousand, or determine [image] to ten-thousand digits. See the Math::BigInt and Math::BigFloat modules.

Previous | Home | Next
B.8. Other Operators and Functions | Book Index | B.10. Lists and Arrays
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.10. Lists and Arrays

Perl has a number of features that make it easy to manipulate an entire list or array.

B.10.1. map and grep

We mentioned (in Chapter 17, "Some Advanced Perl Techniques") the map and grep list-processing operators. They can do more than we could include here; see the perlfunc manpage for more information and examples.

B.10.2. The splice Operator

With the splice operator, you can add items to the middle of an array, or remove them, letting the array grow or shrink as needed. (Roughly, this is like what substr lets you do with strings.) This effectively eliminates the need for linked lists in Perl. See the perlfunc manpage.

Previous | Home | Next
B.9. Mathematics | Book Index | B.11. Bits and Pieces
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.11. Bits and Pieces

You can work with an array of bits (a bitstring) with the vec operator, setting bit number 123, clearing bit number 456, and checking to see the state of bit 789. Bitstrings may be of arbitrary size. The vec operator can also work with chunks of other sizes, as long as the size is a small power of two, so it's useful if you need to view a string as a compact array of nybbles, say. See the perlfunc manpage.

Previous | Home | Next
B.10. Lists and Arrays | Book Index | B.12. Formats
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.12. Formats

Perl's formats are an easy way to make fixed-format template-driven reports with automatic page headers. In fact, they are one of the main reasons Larry developed Perl in the first place, as a Practical Extraction and Report Language. But, alas, they're limited. The heartbreak of formats happens when someone discovers that he or she needs a little more than what formats provide. This usually means ripping out the program's entire output section and replacing it with code that doesn't use formats. Still, if you're sure that formats do what you need, all that you'll need, and all that you'll ever need, they are pretty cool. See the perlform manpage.

Previous | Home | Next
B.11. Bits and Pieces | Book Index | B.13. Networking and IPC
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.13. Networking and IPC

If there's a way that programs on your machine can talk with others, Perl can probably do it. This section shows some common ways.

B.13.1. System V IPC

The standard functions for System V IPC (interprocess communication) are all supported by Perl, so you can use message queues, semaphores, and shared memory. Of course, an array in Perl isn't stored in a chunk of memory in the same way[409] that an array is stored in C, so shared memory can't share Perl data as-is. But there are modules that will translate data, so that you can pretend that your Perl data is in shared memory. See the perlfunc manpage and the perlipc module.

[409]In fact, it would generally be a lie to say that a Perl array is stored in "a chunk of memory" at all, as it's almost certainly spread among many separate chunks.

B.13.2. Sockets

Perl has full support for TCP/IP sockets, which means that you could write a web server in Perl, or a web browser, Usenet news server or client, finger daemon or client, FTP daemon or client, SMTP or POP or SOAP server or client, or either end of pretty much any other kind of protocol in use on the Internet. Of course, there's no need to get into the low-level details yourself; there are modules available for all of the common protocols. For example, you can make a web server or client with the LWP module and one or two lines of additional code.[410] The LWP module (actually, a tightly integrated set of modules, which together implement nearly everything that happens on the Web) is also a great example of high-quality Perl code, if you'd like to copy from the best. For other protocols, search for a module with the protocol's name.

[410]Although LWP makes it easy to make a simple "web browser" that pulls down a page or image, actually rendering that to the user is another problem. You can drive an X11 display with Tk or Gtk widgets though, or use curses to draw on a character terminal. It's all a matter of downloading and installing the right modules from CPAN.

Previous | Home | Next
B.12. Formats | Book Index | B.14. Security
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.14. Security

Perl has a number of strong security-related features that can make a program written in Perl more secure than the corresponding program written in C. Probably the most important of these is data-flow analysis, better known as taint checking. When this is enabled, Perl keeps track of which pieces of data seem to have come from the user or environment (and are therefore untrustworthy). Generally, if any such piece of so-called "tainted" data is used to affect another process, file, or directory, Perl will prohibit the operation and abort the program. It's not perfect, but it's a powerful way to prevent some security-related mistakes. There's more to the story; see the perlsec manpage.

Previous | Home | Next
B.13. Networking and IPC | Book Index | B.15. Debugging
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.15. Debugging

There's a very good debugger that comes with Perl and supports breakpoints, watchpoints, single-stepping, and generally everything you'd want in a command-line Perl debugger. It's actually written in Perl (so, if there are bugs in the debugger, we're not sure how they get those out). But that means that, in addition to all of the usual debugger commands, you can actually run Perl code from the debugger -- calling your subroutines, changing variables, even redefining subroutines -- while your program is running. See the perldebug manpage for the latest details.

Another debugging tactic is to use the B::Lint module, which is still preliminary as of this writing.

Previous | Home | Next
B.14. Security | Book Index | B.16. The Common Gateway Interface
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.16. The Common Gateway Interface (CGI)

One of the most popular uses for Perl on the Web is in writing CGI programs. These run on a web server to process the results of a form, perform a search, produce dynamic web content, or count the number of accesses to a web page.

The CGI module, which comes with Perl, provides an easy way to access the form parameters and to generate some HTML in responses. (If you don't want the overhead of the full CGI module, the CGI_Lite module provides access to the form parameters without all the rest.) It may be tempting to skip the module and simply copy-and-paste one of the snippets of code that purport to give access to the form parameters, but nearly all of these are buggy.[411]

[411]There are some details of the interface that these snippets don't support. Trust us; it's better to use a module.

When writing CGI programs, though, there are several big issues to keep in mind. These make this topic one too broad to fully include in this book:[412]

[412]Several of the reviewers who looked over a draft of this book for us wished we could cover more about CGI programming. We agree, but it wouldn't be fair to the reader to give just enough knowledge to be dangerous. A proper discussion of the problems inherent in CGI programming would probably add at least 50% to the size (and cost) of this book.

Security, security, security
We can't overemphasize security. Somewhere around half of the successful attacks on computers around the world involve a security-related bug in a CGI program.

Concurrency issues
It's easy to have several processes that are concurrently trying to access a single file or resource.

Standards compliance
No matter how hard you try, you probably won't be able to test your program thoroughly with more than about 1 or 2% of the web browsers and servers that are in use today.[413] That's because there are literally thousands of different programs available, with new ones popping up every week. The solution is to follow the standards, so your program will work with all of them.[414]

[413]Remember that every new release of each brand of browser on each different platform counts as a new one that you're probably not going to be able to test. We really chuckle when we hear someone tested a web site with "both browsers" or when they say "I don't know if it works with the other one."

[414]At the very least, following the standards lets you put the blame squarely on the other programmer, who didn't.

Troubleshooting and debugging
Since the CGI program runs in a different environment than you're likely to be able to access directly, you'll have to learn new techniques for troubleshooting and debugging.

Security, security, security!
There, we've said it again. Don't forget security -- it's the first and last thing to think about when your program is going to be available to everyone in the world who wants to try breaking it.

And that list didn't even mention URI-encoding, HTML entities, HTTP and response codes, Secure Sockets Layer (SSL), Server-side Includes (SSI), here documents, creating graphics on the fly, programmatically generating HTML tables, forms, and widgets, hidden form elements, getting and setting cookies, path info, error trapping, redirection, taint checking, internationalization and localization, embedding Perl into HTML (or the other way around), working with Apache and mod_perl, and using the LWP module.[415] Most or all of those topics should be covered in any good book on using Perl with the Web. CGI Programming with Perl by Scott Guelich, et al. (O'Reilly & Associates, Inc.) is mighty nice here, as is Lincoln Stein's Network Programming with Perl (Addison-Wesley).

[415]Do you see why we didn't try to fit all of that into this book?

Previous | Home | Next
B.15. Debugging | Book Index | B.17. Command-Line Options
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.17. Command-Line Options

There are many different command-line options available in Perl; many let you write useful programs directly from the command line. See the perlrun manpage.

Previous | Home | Next
B.16. The Common Gateway Interface | Book Index | B.18. Built in Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.18. Built in Variables

Perl has dozens of built-in variables (like @ARGV and $0), which provide useful information or control the operation of Perl itself. See the perlvar manpage.

Previous | Home | Next
B.17. Command-Line Options | Book Index | B.19. Syntax Extensions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.19. Syntax Extensions

There are more tricks you could do with Perl syntax, including the continue block and the BEGIN block. See the perlsyn and perlmod manpages.

Previous | Home | Next
B.18. Built in Variables | Book Index | B.20. References
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.20. References

Perl's references are similar to C's pointers, but in operation, they're more like what you have in Pascal or Ada. A reference "points" to a memory location, but because there's no pointer arithmetic or direct memory allocation and deallocation, you can be sure that any reference you have is a valid one. References allow object-oriented programming and complex data structures, among other nifty tricks. See the perlreftut and perlref manpages.

B.20.1. Complex Data Structures

References allow us to make complex data structures in Perl. For example, suppose you want a two-dimensional array? You can do that,[416] or you can do something much more interesting, like have an array of hashes, a hash of hashes, or a hash of arrays of hashes.[417] See the perldsc (data-structures cookbook) and perllol (lists of lists) manpages.

[416]Well, not really, but you can fake it so well that you'll hardly remember that there's a difference.

[417]Actually, you can't make any of these things; these are just verbal shorthands for what's really happening. What we call "an array of arrays" in Perl is really an array of references to arrays.

B.20.2. Object-Oriented Programming

Yes, Perl has objects; it's buzzword-compatible with all of those other languages. Object-oriented (OO) programming lets you create your own user-defined datatypes with associated abilities, using inheritance, overriding, and dynamic method lookup.[418]

[418]OO has its own set of jargon words. In fact, the terms used in any one OO language aren't even the same ones that are typically used in another.

Unlike some object-oriented languages, though, Perl doesn't force you to use objects. (Even many object-oriented modules can be used without understanding objects.) But if your program is going to be larger than N lines of code, it may be more efficient for the programmer (if a tiny bit slower at runtime) to make it object-oriented. No one knows the precise value of N, but we estimate it's around a few thousand or so. See the perlobj and perlboot manpages for a start, and Damian Conway's excellent Object-Oriented Perl (Manning Press) for more advanced information.

B.20.3. Anonymous Subroutines and Closures

Odd as it may sound at first, it can be useful to have a subroutine without a name. Such subroutines can be passed as parameters to other subroutines, or they can be accessed via arrays or hashes to make jump tables.

Closures are a powerful concept that comes to Perl from the world of Lisp. A closure is (roughly speaking) an anonymous subroutine with its own private data.

Previous | Home | Next
B.19. Syntax Extensions | Book Index | B.21. Tied Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.21. Tied Variables

Do you remember how the DBM hash (in Chapter 16, "Simple Databases") is "magically" connected to a file, so that accesses to the hash are really working with the corresponding DBM file? You can actually make any variable magical in that way. A tied variable may be accessed like any other, but using your own code behind the scenes. So you could make a scalar that is really stored on a remote machine, or an array that always stays sorted. See the perltie manpage.

Previous | Home | Next
B.20. References | Book Index | B.22. Operator Overloading
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.22. Operator Overloading

You can redefine operators like addition, concatenation, comparison, or even the implicit string-to-number conversion with the overload module. This is how a module implementing complex numbers (for example) can let you multiply a complex number by 8 to get a complex number as a result.

Previous | Home | Next
B.21. Tied Variables | Book Index | B.23. Dynamic Loading
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.23. Dynamic Loading

The basic idea of dynamic loading is that your program decides at runtime that it needs more functionality than what's currently available, so it loads it up and keeps running. You can always dynamically load Perl code, but it's even more interesting to dynamically load a binary extension.[419] This is how non-Perl modules are made.

[419]Dynamic loading of binary extensions is generally available if your system supports that. If it doesn't, you can compile the extensions statically -- that is, you can make a Perl binary with the extension built in, ready for use.

Previous | Home | Next
B.22. Operator Overloading | Book Index | B.24. Embedding
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.24. Embedding

The reverse of dynamic loading (in a sense) is embedding.

Suppose you want to make a really cool word processor, and you start writing it in (say) C++.[420] Now, you decide you want the users to be able to use Perl's regular expressions for an extra-powerful search-and-replace feature, so you embed Perl into your program. Then you realize that you could open up some of the power of Perl to your users. A power user could write a subroutine in Perl that could become a menu item in your program. Users can customize the operation of your word processor by writing a little Perl. Now you open up a little space on your website where users can share and exchange these Perl snippets, and you've got thousands of new programmers extending what your program can do at no extra cost to your company. And how much do you have to pay Larry for all this? Nothing -- see the licenses that come with Perl. Larry is a really nice guy. You should at least send him a thank-you note.

[420]That's probably the language we'd use for writing a word processor. Hey, we love Perl, but we didn't swear an oath in blood to use no other language. When language X is the best choice, use language X. But often, X equals Perl.

Although we don't know of such a word processor, some folks have already used this technique to make other powerful programs. One such example is Apache's mod_perl, which embeds Perl into an already-powerful web server. If you're thinking about embedding Perl, you should check out mod_perl; since it's all open source, you can see just how it works.

Previous | Home | Next
B.23. Dynamic Loading | Book Index | B.25. Converting Other Languages to Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.25. Converting Other Languages to Perl

If you've got old sed and awk programs that you wish were written in Perl, you're in luck. Not only can Perl do everything that those can do, there's also a conversion program available, and it's probably already installed on your system. Check the documentation for s2p (for converting from sed) or a2p (for converting from awk).[421] Since programs don't write programs as well as people do, the results won't necessarily be the best Perl -- but it's a start, and it's easy to tweak. The translated program may be faster or slower than the original, too. But after you've fixed up any gross inefficiencies in the machine-written Perl code, it should be comparable.

[421]If you're using gawk or nawk or some other variant, a2p may not be able to convert it. Both of these conversion programs were written long ago and have had few updates except when needed to keep working with new releases of Perl.

Do you have C algorithms you want to use from Perl? Well, you've still got some luck on your side; it's not too hard to put C code into a compiled module that can be used from Perl. In fact, any language that compiles to make object code can generally be used to make a module. See the perlxs manpage, and the Inline module, as well as the SWIG system.

Do you have a shell script that you want to convert to Perl? Your luck just ran out. There's no automatic way to convert shell to Perl. That's because the shell hardly does anything by itself; it spends all of its time running other programs. Sure, we could make a program that would mostly just call system for each line of the shell, but that would be much slower than just letting the shell do things in the first place. It really takes a human-level of intelligence to see how the shell's use of cut, rm, sed, awk, and grep can be turned into efficient Perl code. It's better to rewrite the shell script from scratch.

Previous | Home | Next
B.24. Embedding | Book Index | B.26. Converting find Command Lines to Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.26. Converting find Command Lines to Perl

A common task for a system administrator is to recursively search the directory tree for certain items. On Unix, this is typically done with the find command. We can do that directly from Perl, too.

The find2perl command, which comes with Perl, takes the same arguments that find does. Instead of finding the requested items, however, the output of find2perl is a Perl program that finds them. Since it's a program, you can edit it for your own needs. (The program is written in a somewhat odd style.)

One useful argument that's available in find2perl but not in the standard find is the -eval option. This says that what follows it is actual Perl code that should be run each time that a file is found. When it's run, the current directory will be the directory in which some item is found, and $_ will contain the item's name.

Here's an example of how you might use find2perl. Suppose that you're a system administrator on a Unix machine, and you want to find and remove all of the old files in the /tmp directory.[422] Here's the command that writes the program to do that:

[422]This is a task typically done by a cron job at some early-morning hour each day.

$ find2perl /tmp -atime +14 -eval unlink >Perl-program

That command says to search in /tmp (and recursively in subdirectories) for items whose atime (last access time) is at least 14 days ago. For each item, the program should run the Perl code unlink, which will use $_ by default as the name of a file to remove. The output (redirected to go into the file Perl-program) is the program that does all of this. Now you merely need to arrange for it to be run as needed.

Previous | Home | Next
B.25. Converting Other Languages to Perl | Book Index | B.27. Command-line Options in Your Programs
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.27. Command-line Options in Your Programs

If you'd like to make programs that take command-line options (like Perl's own -w for warnings, for example), there are modules that let you do this in a standard way. See the documentation for the Getopt::Long and Getopt::Std modules.

Previous | Home | Next
B.26. Converting find Command Lines to Perl | Book Index | B.28. Embedded Documentation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.28. Embedded Documentation

Perl's own documentation is written in pod (plain-old documentation) format. You can embed this documentation in your own programs, and it can then be translated to text, HTML, or many other formats as needed. See the perlpod manpage.

Previous | Home | Next
B.27. Command-line Options in Your Programs | Book Index | B.29. More Ways to Open Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.29. More Ways to Open Filehandles

There are other modes to use in opening a filehandle; see the perlopentut manpage.

Previous | Home | Next
B.28. Embedded Documentation | Book Index | B.30. Locales and Unicode
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.30. Locales and Unicode

It's a small world, after all. In order to work properly in places where even the alphabet is different, Perl has support for locales and Unicode.

Locales tell Perl how things are done locally. For example, does the character æ sort at the end of the alphabet, or between ä and å? And what's the local name for the third month? See the perllocale manpage (not to be confused with the perllocal manpage).

See the perlunicode manpage for the latest on how your version of Perl deals with Unicode. As of this writing, each new release of Perl has many new Unicode-related changes, but we hope things will settle down soon.

Previous | Home | Next
B.29. More Ways to Open Filehandles | Book Index | B.31. Threads and Forking
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.31. Threads and Forking

Perl now has support for threads. Although this is experimental (as of this writing), it can be a useful tool for some applications. Using fork (where it's available) is better supported; see the perlfork and perlthrtut manpages.

Previous | Home | Next
B.30. Locales and Unicode | Book Index | B.32. Graphical User Interfaces
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.32. Graphical User Interfaces (GUIs)

A large and powerful module set is Tk, which lets you make on screen interfaces that work on more than one platform. See Learning Perl/Tk by Nancy Walsh or the upcoming Mastering Perl/Tk by Nancy Walsh and Steve Lidie (O'Reilly & Associates, Inc.).

Previous | Home | Next
B.31. Threads and Forking | Book Index | B.33. And More...
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


B.33. And More...

If you check out the module list on CPAN, you'll find modules for even more purposes, from generating graphs and other images to downloading email, from figuring the amortization of a loan to figuring the time of sunset. New modules are added all the time, so Perl is even more powerful today than it was when we wrote this book. We can't keep up with it all, so we'll stop here.

Larry himself says he no longer keeps up with all of the development of Perl, because the Perl universe is big and keeps expanding. And he can't get bored with Perl, because he can always find another corner of this ever-expanding universe. And we suspect, neither will we. Thank you, Larry!

Previous | Home | Next
B.32. Graphical User Interfaces | Book Index | Index
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal featured on the cover of Learning Perl, Third Edition, is the llama, a relation of the camel native to the Andean range. Also included in this llamoid group is the domestic alpaca and their wild ancestors, the guanaco and the vicuna. Bones found in ancient human settlements suggest that domestication of the alpaca and llama dates back 4,500 years. In 1531, when Spanish conquistadors overran the Inca Empire in the high Andes, they found both animals present in great numbers. These llamas are suited for high mountain life; their hemoglobin can take in more oxygen than that of other mammals.

Llamas can weigh up to 300 pounds and are mainly used as beasts of burden. A packtrain may contain several hundred animals and can travel up to twenty miles per day. Llamas will carry loads up to fifty pounds, but have a tendency to be short-tempered and resort to spitting and biting to demonstrate displeasure. To the people of the Andes, llamas also provide meat, wool for clothing, hides for leather, and fat for candles. Their wool can also be braided into rope and rugs, and their dried dung is used for fuel.

Sarah Jane Shangraw and Ann Schirmer were the production editors for Learning Perl, Third Edition. Nicole Arigo copyedited the text. Sarah Jane Shangraw, Ann Schirmer, and Claire Cloutier provided quality control. Kimo Carter, Claire Cloutier, Ann Schirmer, and Sarah Jane Shangraw did interior page composition. Brenda Miller wrote the index.

Edie Freedman designed the cover of this book. The cover image is a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

Melanie Wang designed the interior layout based on a series design by Nancy Priest. The text and heading fonts are ITC Garamond Light and Garamond Book; the code font is Constant Willison. The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand 9 and Adobe Photoshop 6.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Learning Perl: Index

Learning Perl
Previous Next

Index

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Symbols & Numbers

-- autodecrement operator: 10.6. Autoincrement and Autodecrement
` ` backquotes/backticks: 1.5. A Whirlwind Tour of Perl
14.4. Using Backquotes to Capture Output
{ } curly braces (see curly braces)
- hyphen: 6.2. Input from the Diamond Operator
8.1. Character Classes
( ) parentheses (see parentheses)
' ' single quotes: 2.3.1. Single-Quoted String Literals
[ ] square brackets: 7.3. A Pattern Test Program
8.1. Character Classes
- subtraction operator: 2.2.5. Numeric Operators
+ addition operator: 2.2.5. Numeric Operators
.= append operator: 2.5.3. Binary Assignment Operators
@_ array variable: 4.5. Arguments
= assignment operator: 2.5.2. Scalar Assignment
@ at-sign: 3.4. List Assignment
++ autoincrement operator: 10.6. Autoincrement and Autodecrement
\\\\ backslash: 2.3.1. Single-Quoted String Literals
8.4.1. Backreferences
=~ binding operator: 9.3. The Binding Operator, =~
^ caret anchor: 8.3. Anchors
, comma: 5.2.3. The Big Arrow
$_ default variable (see default variable)
/ division operator: 2.2.5. Numeric Operators
$ dollar sign (see dollar sign)
. dot (see dot)
./ dot and slash: 1.4.1. A Simple Program
.. dot-dot: 13.3. Links and Files
-e command-line option: 16.4.1. In-place Editing from the Command Line
-eval option, find2perl command and: B.26. Converting find Command Lines to Perl
** exponentiation operator: 2.2.5. Numeric Operators
_ _FILE_ _ and _ _LINE_ _ tokens: 11.3. Fatal Errors with die
_ filehandle: 11.6.5. Using the Special Underscore Filehandle
-> little arrow: 5.2.3. The Big Arrow
13.8.3. The File::Spec Module
-i.bak command-line option: 16.4.1. In-place Editing from the Command Line
#! line: 1.4.2. What's Inside That Program?
1.5. A Whirlwind Tour of Perl
% modulus operator: 2.2.5. Numeric Operators
17.2. Picking Items from a List with grep
* multiplication operator: 2.2.5. Numeric Operators
-n command-line option: 16.4.1. In-place Editing from the Command Line
! negation operator (see negation operator)
. operator: 2.3.3. String Operators
-p command-line option: 16.4.1. In-place Editing from the Command Line
% percent sign (see percent sign)
| pipe: 11.1. What Is a Filehandle?
14.5. Processes as Filehandles
+ plus sign: 7.2.2. Simple Quantifiers
# pound sign: 1.4.2. What's Inside That Program?
? question mark: 7.2.2. Simple Quantifiers
**= raise to the power of operator: 2.5.3. Binary Assignment Operators
.. range operator: 3.3. List Literals
; semicolon (see semicolon)
* star: 7.2.2. Simple Quantifiers
. string concatenate operator: 2.5.3. Binary Assignment Operators
?\: ternary operator: 10.9.2. The Ternary Operator, ?:
~ tilde: 16.4. Variable-length (Text) Databases
~ tilde-prefix: 12.1. Moving Around the Directory Tree
_ underscore: 2.2.3. Integer Literals
4.10. The use strict Pragma
$! variable: 11.3. Fatal Errors with die
\\| vertical bar: 7.2.4. Alternatives
-w option: 2.4. Perl's Built-in Warnings
16.4.1. In-place Editing from the Command Line
vs. warnings pragma: B.6.6. The warnings Pragma
& ampersand: 4.3. Invoking a Subroutine
4.11.1. Omitting the Ampersand
$& variable: 9.5.2. The Automatic Match Variables
&& operator: 10.9. Logical Operators
10.9.3. Control Structures Using Partial-Evaluation Operators
&max subroutine: 4.5. Arguments
4.8.1. A Better &max Routine
@ARGV array: 6.3. The Invocation Arguments
$ARGV variable: 6.2. Input from the Diamond Operator
$atime (timestamp): 11.6.1. The stat and lstat Functions
changing: 13.7. Changing Timestamps
\\\\B nonword-boundary anchor: 8.3.1. Word Anchors
\\\\b word-boundary anchor: 8.3.1. Word Anchors
$ctime (timestamp): 11.6.1. The stat and lstat Functions
changing: 13.7. Changing Timestamps
%d conversion: 6.5. Formatted Output with printf
\\\\d shortcut: 8.1.1. Character Class Shortcuts
$dev (device number): 11.6.1. The stat and lstat Functions
\\\\E shortcut: 9.6.5. Case Shifting
__END__ marker: 10.8.1. The last Operator
%ENV hash: 14.3. The Environment Variables
%f conversion: 6.5. Formatted Output with printf
%g conversion: 6.5. Formatted Output with printf
/g modifier, s/// substitution operator and: 9.6.1. Global Replacements with /g
$gid (see group-ID)
=> big arrow: 5.2.3. The Big Arrow
17.4. Unquoted Hash Keys
> greater-than sign: 11.2. Opening a Filehandle
`Hello, world' program: 1.4.1. A Simple Program
/i modifier: 9.2.1. Case-insensitive Matching with /i
s/// substitution operator and: 9.6.3. Option Modifiers
$^I variable: 16.4. Variable-length (Text) Databases
$ino (inode number): 11.6.1. The stat and lstat Functions
\\\\l shortcut: 9.6.5. Case Shifting
@lines array variable: 1.5. A Whirlwind Tour of Perl
< less-than sign: 11.2. Opening a Filehandle
/m option: 17.5.2. Matching Multiple-line Text
$mode: 11.6.1. The stat and lstat Functions
$mtime (timestamp): 11.6.1. The stat and lstat Functions
changing: 13.7. Changing Timestamps
\\\\n shortcut: 1.4.2. What's Inside That Program?
within a single-quoted string: 2.3.1. Single-Quoted String Literals
.new files, renaming from .old files: 13.2. Renaming Files
$nlink (number of links): 11.6.1. The stat and lstat Functions
$now variable: 14.4. Using Backquotes to Capture Output
.old files, renaming to .new files: 13.2. Renaming Files
.plx file extension: 1.4.1. A Simple Program
.pm files: 7.1. What Are Regular Expressions?
$" variable: 3.5. Interpolating Arrays into Strings
"money numbers" (see decimals)
"" double quotes (see double quotes)
"short-circuit" logical operators: 10.9. Logical Operators
%s conversion: 6.5. Formatted Output with printf
/s modifier: 9.2.2. Matching Any Character with /s
s/// substitution operator and: 9.6.3. Option Modifiers
\\\\s shortcut: 8.1.1. Character Class Shortcuts
$size: 11.6.1. The stat and lstat Functions
\\\\u shortcut: 9.6.5. Case Shifting
$uid (see user-ID, numeric)
/usr/bin/perl: 1.4.2. What's Inside That Program?
/usr/local/bin/perl: 1.4.2. What's Inside That Program?
\\\\w characters: 8.3.1. Word Anchors
\\\\w shortcut: 8.1.1. Character Class Shortcuts
`wimla,' diamond operator and: 6.2. Input from the Diamond Operator
Ú Ú forward slashes: 7.2. Using Simple Patterns
9.1. Matches with m//

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

absolute value: B.9.1. Advanced Math Functions
addition operator (+): 2.2.5. Numeric Operators
ampersand (&)
in subroutine names: 4.3. Invoking a Subroutine
omitting: 4.11.1. Omitting the Ampersand
anchors: 8.3. Anchors
multiple-line text and: 17.5.2. Matching Multiple-line Text
AND operator (&&): 10.9. Logical Operators
10.9.3. Control Structures Using Partial-Evaluation Operators
angle brackets: 1.5. A Whirlwind Tour of Perl
12.3. An Alternate Syntax for Globbing
angle brackets (): 1.5. A Whirlwind Tour of Perl
filename globbing and: 12.3. An Alternate Syntax for Globbing
anonymous subroutines: B.20.3. Anonymous Subroutines and Closures
answers to exercises in this book: A. Exercise Answers
AnyDBM_file manpage: 16.1. DBM Files and DBM Hashes
a2p conversion program: B.25. Converting Other Languages to Perl
append operator (.=): 2.5.3. Binary Assignment Operators
argc: 6.3. The Invocation Arguments
argument lists (see parameter lists)
arguments: 4.5. Arguments
array elements: 3.1. Accessing Elements of an Array
array indices: 3.2. Special Array Indices
arrays: 3. Lists and Arrays
B.10. Lists and Arrays
interpolating vs. printing: 6.4. Output to Standard Output
printf function and: 6.5.1. Arrays and printf
slices and: 17.6.1. Array Slice
splice operator for: B.10.2. The splice Operator
arrows: 5.2.3. The Big Arrow
17.4. Unquoted Hash Keys
ASCII mode: 1.4. How Do I Make a Perl Program?
ASCIIbetical order, sort operator for: 3.7.2. The sort Operator
assigning
hashes: 5.2.2. Hash Assignment
lists: 3.4. List Assignment
scalars: 2.5.2. Scalar Assignment
assignment operator (=): 2.5.2. Scalar Assignment
associative arrays (see hashes)
associativity: 2.6.2. Operator Precedence and Associativity
chart of: 2.6.2. Operator Precedence and Associativity
at-sign(@) indicating arrays: 3.4. List Assignment
autodecrement operator (--): 10.6. Autoincrement and Autodecrement
autoincrement operator (++): 10.6. Autoincrement and Autodecrement
automatic match variables: 9.5.2. The Automatic Match Variables

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

backquotes/backticks (` `)
capturing output with: 14.4. Using Backquotes to Capture Output
enclosing external commands: 1.5. A Whirlwind Tour of Perl
backreferences: 8.4.1. Backreferences
backslash (\\\\): 2.3.1. Single-Quoted String Literals
in backreferences: 8.4.1. Backreferences
backslash escapes: 1.4.2. What's Inside That Program?
5.4.3. Hash Element Interpolation
list of: 2.3.2. Double-Quoted String Literals
backup files, text databases and: 16.4. Variable-length (Text) Databases
bad filehandles: 11.2.2. Bad Filehandles
barewords: 17.4. Unquoted Hash Keys
basenames: 13.8. Using Simple Modules
File::Basename module for: 13.8.1. The File::Basename Module
B.5.4. The File::Basename Module
BEGIN block: B.19. Syntax Extensions
big arrow (=>): 5.2.3. The Big Arrow
17.4. Unquoted Hash Keys
binary assignment operators: 2.5.3. Binary Assignment Operators
binary extensions, dynamic loading and: B.23. Dynamic Loading
binary mode: 1.4. How Do I Make a Perl Program?
binding operator (=~): 9.3. The Binding Operator, =~
s/// substitution operator and: 9.6.4. The Binding Operator
bitstrings: 11.6.4. Using Bitstrings
vec operator for: B.11. Bits and Pieces
bitwise operators: 11.6.3. Bitwise Operators
B::Lint module: B.15. Debugging
block comments: 1.4.2. What's Inside That Program?
block curly braces (see curly braces, block)
body of subroutine: 4.2. Defining a Subroutine
Boolean values
as handled by Perl: 2.7.1. Boolean Values
logical operators for: 10.9. Logical Operators
buffer
flushing of: 6.4. Output to Standard Output
11.4.1. Changing the Default Output Filehandle
stat: 11.6.5. Using the Special Underscore Filehandle
buffered output: 6.4. Output to Standard Output
bugs in Perl: 1.3.2. How Can I Get Support for Perl?
reporting: 1.3.4. What If I Find a Bug in Perl?
builtin functions
ampersand and: 4.11.1. Omitting the Ampersand
mathematical functions and: B.9.1. Advanced Math Functions
builtin variables: 9.5.2. The Automatic Match Variables
B.18. Built in Variables
bytecodes: 1.4.3. But How Do I Compile Perl?

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C programming language
DBM files and: 16.1.2. Using a DBM Hash
operators and: 10.9.2. The Ternary Operator, ?:
caller function: 11.3. Fatal Errors with die
Camel book: 1.2.1. Why Didn't Larry Just Use Some Other Language?
1.3.3. Are There Any Other Kinds of Support?
capitalization
case shifting and: 9.6.5. Case Shifting
vs. lowercase in variable names: 2.5.1. Choosing Good Variable Names
caret anchor (^) indicating beginning of string: 8.3. Anchors
case-insensitive matching, /i modifier for: 9.2.1. Case-insensitive Matching with /i
case shifting: 9.6.5. Case Shifting
cd command (Unix): 12.1. Moving Around the Directory Tree
CGI module: B.5.1. The CGI and CGI_Lite Modules
B.16. The Common Gateway Interface (CGI)
CGI_Lite module: B.5.1. The CGI and CGI_Lite Modules
B.16. The Common Gateway Interface (CGI)
character classes: 8.1. Character Classes
characters: 2.3. Strings
case shifting and: 9.6.5. Case Shifting
matching with /s modifier: 9.2.2. Matching Any Character with /s
transliterating/counting with tr/// operator: B.8.1. Transliteration with tr///
chdir operator: 12.1. Moving Around the Directory Tree
child processes, managing: 14. Process Management
chmod command (Unix): 1.4.1. A Simple Program
13.5. Modifying Permissions
chmod function (Unix): 13.5. Modifying Permissions
chomp operator: 2.9. The chomp Operator
chown function: 13.6. Changing Ownership
chunk number, die function and: 11.3. Fatal Errors with die
classes: 13.8.3. The File::Spec Module
close operator: 11.2.1. Closing a Filehandle
closedir operator: 12.4. Directory Handles
closures: B.20.3. Anonymous Subroutines and Closures
cmp (three-way comparison operator): 15.4. Advanced Sorting
code: 10.8.1. The last Operator
compiling: 1.4.3. But How Do I Compile Perl?
curly braces enclosing: 2.7. The if Control Structure
2.10. The while Control Structure
dynamic loading and: B.23. Dynamic Loading
embedding: B.24. Embedding
last operator for exiting early: 10.8.1. The last Operator
reading: 10.3. Expression Modifiers
used in this book, web site for: 0.3. Code Examples
while control structure for repeating blocks of: 2.10. The while Control Structure
comma (,): 5.2.3. The Big Arrow
command line, in-place editing from: 16.4.1. In-place Editing from the Command Line
command-line options: B.17. Command-Line Options
modules for: B.27. Command-line Options in Your Programs
comments: 1.4.2. What's Inside That Program?
comparison operators: 2.6.3. Comparison Operators
15.4. Advanced Sorting
compiling code: 1.4.3. But How Do I Compile Perl?
comp.lang.perl.moderated newsgroup: 1.3.3. Are There Any Other Kinds of Support?
complex data structures: B.20.1. Complex Data Structures
complex numbers: B.9.2. Imaginary and Complex Numbers
Comprehensive Perl Archive Network (see CPAN)
constant pragma: B.6.1. The constant Pragma
context: 3.8. Scalar and List Context
3.8. Scalar and List Context
void: 4.4. Return Values
continue block: 10.7. The for Control Structure
10.8.2. The next Operator
B.19. Syntax Extensions
control structures: 10. More Control Structures
loop controls for: 10.8. Loop Controls
partial-evaluation operators for: 10.9.3. Control Structures Using Partial-Evaluation Operators
stopping endless loops created by: 2.10. The while Control Structure
conversion programs: B.25. Converting Other Languages to Perl
conversions: 6.5. Formatted Output with printf
cosine: B.9.1. Advanced Math Functions
CPAN (Comprehensive Perl Archive Network): 1.3.1. What Is CPAN?
inside utility available from: B.4.3. Finding and Installing Modules
libraries available from: B.4.3. Finding and Installing Modules
modules available from: 13.8. Using Simple Modules
B.4.3. Finding and Installing Modules
curly braces ({ })
block, enclosing code: 2.7. The if Control Structure
2.10. The while Control Structure
enclosing hash keys: 5.2. Hash Element Access
enclosing variable names: 2.6.1. Interpolation of Scalar Variables into Strings
following hash names: 5.2. Hash Element Access
indicating quantifier: 8.2. General Quantifiers
current working directory: B.5.2. The Cwd Module
cwd function: B.5.2. The Cwd Module
Cwd module: B.5.2. The Cwd Module

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

data
formatting with sprintf function: 15.3. Formatting Data with sprintf
manipulating with pack and unpack functions: 16.2. Manipulating Data with pack and unpack
data-flow analysis: B.14. Security
data structures, complex: B.20.1. Complex Data Structures
databases: 16. Simple Databases
B.7. Databases
DBI module and: B.7.3. Relational Database Access
files for, read/write access to: 16.3. Fixed-length Random-access Databases
fixed-length random-access: 16.3. Fixed-length Random-access Databases
hashes and: 5.1.1. Why Use a Hash?
variable-length text: 16.4. Variable-length (Text) Databases
date command (Unix): 14.1. The system Function
16.4. Variable-length (Text) Databases
capturing output and: 14.4. Using Backquotes to Capture Output
DBI module: B.7.3. Relational Database Access
DBM files: 16.1. DBM Files and DBM Hashes
B.21. Tied Variables
DBM hashes: 16.1. DBM Files and DBM Hashes
B.21. Tied Variables
dbmclose function: 16.1.1. Opening and Closing DBM Hashes
dbmopen function: 16.1.1. Opening and Closing DBM Hashes
debugger for Perl: B.15. Debugging
decimal integer conversion: 6.5. Formatted Output with printf
decimals
formatting for output: 17.3. Transforming Items from a List with map
rounding
printf function and: 6.5. Formatted Output with printf
sprintf function and: 15.3.1. Using sprintf with "Money Numbers"
default variable ($_): 3.7. Perl's Favorite Default: $_
=~ binding operator and: 9.3. The Binding Operator, =~
input stored in: 6.1. Input from Standard Input
defaults: 1.2.2. Is Perl Easy or Hard?
output filehandle: 11.4.1. Changing the Default Output Filehandle
defined function: 2.12. The defined Function
13.6. Changing Ownership
delete function: 5.4.2. The delete Function
delimiters
changing for s/// substitution operator: 9.6.2. Different Delimiters
in lists: 3.3.1. The qw Shortcut
nonpaired: 9.1. Matches with m//
diagnostic messages, from diamond operator\\: 6.2. Input from the Diamond Operator
diagnostics pragma: B.6.2. The diagnostics Pragma
diamond operator (see diamond operator)
diamond operator (): 6.2. Input from the Diamond Operator
@ARGV array and: 6.3. The Invocation Arguments
in-place editing of text files and: 16.4. Variable-length (Text) Databases
die function: 11.3. Fatal Errors with die
digits, \\\\d shortcut for: 8.1.1. Character Class Shortcuts
directories: 13.3. Links and Files
making/removing: 13.4. Making and Removing Directories
manipulating: 12. Directory Operations
directory handles: 12.4. Directory Handles
dirname function, File::Basename module and: 13.8.1. The File::Basename Module
division operator (/): 2.2.5. Numeric Operators
documentation for Perl: 1.3.3. Are There Any Other Kinds of Support?
B.1. Further Documentation
embedding: B.28. Embedded Documentation
dollar sign ($)
in regular text: 2.6.1. Interpolation of Scalar Variables into Strings
in scalar variable names: 2.5. Scalar Variables
indicating end of string: 8.3. Anchors
preceding hash names: 5.2. Hash Element Access
domain-name databases: B.7.1. Direct System Database Access
dot (.)
as wildcard character: 7.2.1. About Metacharacters
/s modifier and: 9.2.2. Matching Any Character with /s
indicating current directory: 13.3. Links and Files
dot and slash (./): 1.4.1. A Simple Program
dot-dot (..) indicating parent directory: 13.3. Links and Files
double-precision floating-point values: 2.2.1. All Numbers Are the Same Format Internally
double-quote interpolation (see variable interpolation)
double-quoted string literals: 2.3.2. Double-Quoted String Literals
arrays, interpolating into: 3.5. Interpolating Arrays into Strings
hash elements, interpolating into: 5.4.3. Hash Element Interpolation
scalar variables, interpolating into: 2.6.1. Interpolation of Scalar Variables into Strings
variable interpolation and: 2.3.2. Double-Quoted String Literals
double quotes ("")
arrays and: 6.4. Output to Standard Output
enclosing strings: 2.3.2. Double-Quoted String Literals
omitting from hash keys: 17.4. Unquoted Hash Keys
downloading pattern test program: 7.4. Exercises
dynamic loading: B.23. Dynamic Loading

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

each function: 5.3.2. The each Function
DBM hashes and: 16.1.2. Using a DBM Hash
echo command: 12.2. Globbing
elements: 3. Lists and Arrays
of an array: 3.1. Accessing Elements of an Array
pop and push operators for: 3.4.1. The pop and push Operators
else clause, using with unless control structure: 10.1.1. The else Clause with unless
else keyword: 2.7. The if Control Structure
elsif clause: 10.5. The elsif Clause
emacs text editor: 1.4. How Do I Make a Perl Program?
email addresses, compile time errors and: 3.5. Interpolating Arrays into Strings
email, Net::SMTP module for: B.5.8. The Net::SMTP Module
embedding code: B.24. Embedding
end-of-file/end-of-input: 3.9. <STDIN> in List Context
bad filehandles and: 11.2.2. Bad Filehandles
endless loop, stopping: 2.10. The while Control Structure
environment variables: 14.3. The Environment Variables
Epoch: 11.6.1. The stat and lstat Functions
error messages: 2.4. Perl's Built-in Warnings
printed by die function: 11.3. Fatal Errors with die
sending to a file: 11.5. Reopening a Standard Filehandle
standard output and: 14.4. Using Backquotes to Capture Output
errors (see fatal errors)
eval block: 17.1. Trapping Errors with eval
caution with: 17.1. Trapping Errors with eval
exec function: 14.2. The exec Function
exercises in this book: 1.1.3. What About the Exercises and Their Answers?
answers to: A. Exercise Answers
exists function: 5.4.1. The exists Function
exit status: 11.3. Fatal Errors with die
exponentiation operator (**): 2.2.5. Numeric Operators
expressions
context and: 3.8. Scalar and List Context
modifiers for: 10.3. Expression Modifiers

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

fatal errors
die function for: 11.3. Fatal Errors with die
trapping with eval block: 17.1. Trapping Errors with eval
Fatal module: B.5.3. The Fatal Module
file extensions: 1.4.1. A Simple Program
File::Basename module: 13.8.1. The File::Basename Module
B.5.4. The File::Basename Module
File::Copy module: B.5.5. The File::Copy Module
File::Find library: 12.5. Recursive Directory Listing
filehandles: 11.1. What Is a Filehandle?
bad: 11.2.2. Bad Filehandles
default for output, changing: 11.4.1. Changing the Default Output Filehandle
opening/closing: 11.2. Opening a Filehandle
processes as: 14.5. Processes as Filehandles
reading, vs. globbing: 12.3. An Alternate Syntax for Globbing
reopening: 11.5. Reopening a Standard Filehandle
tests for: 11.6. File Tests
list of: 11.6. File Tests
underscore: 11.6.5. Using the Special Underscore Filehandle
using: 11.4. Using Filehandles
filename extensions: 1.4.1. A Simple Program
filenames, File::Spec module for manipulating: B.5.6. The File::Spec Module
files
database, in-place editing of: 16.4. Variable-length (Text) Databases
from command line: 16.4.1. In-place Editing from the Command Line
File::Copy module for copying/moving: B.5.5. The File::Copy Module
image, Image::Size module for: B.5.7. The Image::Size Module
links to, finding with stat function: 11.6.1. The stat and lstat Functions
manipulating: 13. Manipulating Files and Directories
names of, directory handles for reading: 12.4. Directory Handles
ownership of, changing: 13.6. Changing Ownership
removing: 13.1. Removing Files
renaming: 13.2. Renaming Files
size of, scalar variable for finding: 11.6.1. The stat and lstat Functions
specifications of, File::Spec module for manipulating: 13.8.3. The File::Spec Module
B.5.6. The File::Spec Module
tests for: 11.6. File Tests
list of: 11.6. File Tests
File::Spec module: 13.8.3. The File::Spec Module
B.5.6. The File::Spec Module
find command (Unix): 14.5. Processes as Filehandles
B.26. Converting find Command Lines to Perl
find2perl command: B.26. Converting find Command Lines to Perl
first found occurrence of a substring, index function for: 15.1. Finding a Substring with index
fixed-length random-access databases: 16.3. Fixed-length Random-access Databases
flags: 9.2. Option Modifiers
flat-file databases: B.7.2. Flat-file Database Access
Flintstones
anchors and: 8.3.1. Word Anchors
illustrating backreferences: 8.4.1. Backreferences
illustrating hash names: 5.2. Hash Element Access
illustrating Unix grep command: 7.1. What Are Regular Expressions?
precedence and: 8.5.1. Examples of Precedence
floating-point conversion: 6.5. Formatted Output with printf
floating-point literals: 2.2.2. Floating-Point Literals
flushed buffer: 6.4. Output to Standard Output
footnotes in this book: 1.1.2. Why Are There So Many Footnotes?
for control structure: 10.7. The for Control Structure
vs. foreach control structure: 10.7.1. The Secret Connection Between foreach and for
foreach control structure: 3.6. The foreach Control Structure
naked block control structure and: 10.4. The Naked Block Control Structure
vs. for control structure: 10.7.1. The Secret Connection Between foreach and for
foreach modifier: 10.3. Expression Modifiers
10.3. Expression Modifiers
fork system call: 14.6. Getting Down and Dirty with Fork
using instead of threads: B.31. Threads and Forking
format letters: 16.2. Manipulating Data with pack and unpack
format strings: 16.2. Manipulating Data with pack and unpack
formats: B.12. Formats
formatted output: 6.5. Formatted Output with printf
forward slashes (Ú Ú)
enclosing a pattern: 7.2. Using Simple Patterns
vs. m// operator: 9.1. Matches with m//
Friedl, Jeffrey: B.2. Regular expressions
function calls, parentheses and: 6.4. Output to Standard Output
functions
builtin, ampersand and: 4.11.1. Omitting the Ampersand
defaults for: 1.2.2. Is Perl Easy or Hard?

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

general numeric conversion: 6.5. Formatted Output with printf
getgrnam function: 13.6. Changing Ownership
Getopt::Long module: B.27. Command-line Options in Your Programs
Getopt::Std module: B.27. Command-line Options in Your Programs
getpwnam function: 13.6. Changing Ownership
glob operator: 12.2. Globbing
combining with unlink operator: 13.1. Removing Files
global replacements: 9.6.1. Global Replacements with /g
globbing: 12.2. Globbing
vs. directory handles: 12.4. Directory Handles
vs. filehandle reading: 12.3. An Alternate Syntax for Globbing
globs: 7.1. What Are Regular Expressions?
gmtime function: 11.6.2. The localtime Function
graphical user interfaces (GUIs): B.32. Graphical User Interfaces (GUIs)
greater-than sign (>) for creating files: 11.2. Opening a Filehandle
Greenwich Mean Time: 11.6.2. The localtime Function
grep command (Unix)
regular expressions and: 7.1. What Are Regular Expressions?
writing Perl program resembling: 9.4. Interpolating into Patterns
grep operator
perlfunc manpage and: B.10.1. map and grep
picking items from a list with: 17.2. Picking Items from a List with grep
vs. map operator: 17.3. Transforming Items from a List with map
vs. Unix's grep command: 17.2. Picking Items from a List with grep
group-ID ($gid): 11.6.1. The stat and lstat Functions
changing group membership and: 13.6. Changing Ownership
GUIs (graphical user interfaces): B.32. Graphical User Interfaces (GUIs)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

hard links: 13.3. Links and Files
13.3. Links and Files
hash elements, accessing: 5.2. Hash Element Access
hash functions: 5.3. Hash Functions
hash keys: 5.1. What Is a Hash?
delete function for removing: 5.4.2. The delete Function
exists function for checking: 5.4.1. The exists Function
omitting quotes from: 17.4. Unquoted Hash Keys
sorting: 15.4.1. Sorting a Hash by Value
hashes: 5. Hashes
accessing elements of: 5.2. Hash Element Access
assigning: 5.2.2. Hash Assignment
autoincrements/autodecrements and: 10.6.1. The Value of Autoincrement
elements of, interpolating into double-quoted string literals: 5.4.3. Hash Element Interpolation
functions for: 5.3. Hash Functions
names of: 5.2. Hash Element Access
reasons for using: 5.1.1. Why Use a Hash?
slices and: 17.6.2. Hash Slice
unwinding: 5.2.1. The Hash as a Whole
here documents: B.8.2. Here documents
hexadecimal literals: 2.2.4. Nondecimal Integer Literals
high-level programming languages: 1.2.1. Why Didn't Larry Just Use Some Other Language?
1.2.2. Is Perl Easy or Hard?
high-precision numbers: B.9.3. Large and High-Precision Numbers
home directory: 12.1. Moving Around the Directory Tree
hostname function: B.5.10. The Sys::Hostname Module
hyphen (-)
indicating standard input stream: 6.2. Input from the Diamond Operator
specifying range of characters: 8.1. Character Classes

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

if control structure: 2.7. The if Control Structure
else clause and: 10.1.1. The else Clause with unless
unless control structure and: 10.1. The unless Control Structure
if modifier: 10.3. Expression Modifiers
if-then-else test, ternary operator for: 10.9.2. The Ternary Operator, ?:
image files, Image::Size module for: B.5.7. The Image::Size Module
Image::Size module: B.5.7. The Image::Size Module
imaginary numbers: B.9.2. Imaginary and Complex Numbers
import lists: 13.8.2. Using Only Some Functions from a Module
index function: 15.1. Finding a Substring with index
using with substr operator: 15.2. Manipulating a Substring with substr
indexing elements: 3. Lists and Arrays
indirect filehandle read: 12.3. An Alternate Syntax for Globbing
inodes: 13.3. Links and Files
input: 6. I/O Basics
reading with diamond operator: 6.2. Input from the Diamond Operator
while control structure shortcut for: 6.1. Input from Standard Input
input/output (I/O): 6. I/O Basics
6. I/O Basics
filehandles and: 11.1. What Is a Filehandle?
inside utility: B.4.3. Finding and Installing Modules
integer literals: 2.2.3. Integer Literals
integer pragma: 2.2.1. All Numbers Are the Same Format Internally
integers: 2.2.1. All Numbers Are the Same Format Internally
internal integers: 2.2.1. All Numbers Are the Same Format Internally
Internet (see Web)
interprocess communication: B.13.1. System V IPC
invocation arguments: 6.2. Input from the Diamond Operator
6.3. The Invocation Arguments
invoking subroutines: 4.3. Invoking a Subroutine
I/O (input/output): 6. I/O Basics
6. I/O Basics
filehandles and: 11.1. What Is a Filehandle?
IP addresses, hashes and: 5.1.1. Why Use a Hash?
IPC: B.13. Networking and IPC
iterations, next and redo operators for: 10.8.2. The next Operator

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

join function: 9.8. The join Function

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

key-value pairs: 5.1. What Is a Hash?
keys (see hash keys)
keys function: 5.3.1. The keys and values Functions

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

labels: 10.8.4. Labeled Blocks
large numbers: B.9.3. Large and High-Precision Numbers
Larry (see Wall, Larry)
last found occurrence of a substring, rindex function for: 15.1. Finding a Substring with index
last operator: 10.8.1. The last Operator
leading zero: 2.2.4. Nondecimal Integer Literals
length function: 16.3. Fixed-length Random-access Databases
less-than sign (<) for opening files: 11.2. Opening a Filehandle
lexical variables: 4.6. Private Variables in Subroutines
4.9. Notes on Lexical (my) Variables
lexical warnings: 2.4. Perl's Built-in Warnings
lib pragma: B.6.3. The lib Pragma
libraries: B.4.1. Libraries
licenses for Perl: 1.3. How Can I Get Perl?
embedding code snippets and: B.24. Embedding
line-input operators: 2.8. Getting User Input
2.8. Getting User Input
6.2. Input from the Diamond Operator
11.4. Using Filehandles
line number
die function and: 11.3. Fatal Errors with die
warn function and: 11.3.1. Warning Messages with warn
link count: 13.3. Links and Files
link function: 13.3. Links and Files
links: 13.3. Links and Files
number of ($nlink): 11.6.1. The stat and lstat Functions
list context: 3.8. Scalar and List Context
return values and: 4.4. Return Values
using backquotes in: 14.4.1. Using Backquotes in a List Context
list literals: 3.3. List Literals
lists: 3. Lists and Arrays
B.10. Lists and Arrays
qw shortcut for: 3.3.1. The qw Shortcut
literal strings (see string literals)
literals: 2.2.2. Floating-Point Literals
little arrow (->): 5.2.3. The Big Arrow
in method names: 13.8.3. The File::Spec Module
Llama book: 1. Introduction
1.3.3. Are There Any Other Kinds of Support?
local operator: 4.7. The local Operator
locales: B.30. Locales and Unicode
localtime function: 11.6.2. The localtime Function
text databases and: 16.4. Variable-length (Text) Databases
log files, filehandles and: 11.2. Opening a Filehandle
11.4.1. Changing the Default Output Filehandle
logarithm: B.9.1. Advanced Math Functions
logical operators: 10.9. Logical Operators
loop blocks: 10.8.1. The last Operator
10.8.2. The next Operator
labels for: 10.8.4. Labeled Blocks
loop controls: 10.8. Loop Controls
loops: 2.10. The while Control Structure
endless, stopping: 2.10. The while Control Structure
low-level programming languages: 1.2.1. Why Didn't Larry Just Use Some Other Language?
lowercase
case shifting and: 9.6.5. Case Shifting
vs. capitalization in variable names: 2.5.1. Choosing Good Variable Names
lstat function: 11.6.1. The stat and lstat Functions
underscore filehandle and: 11.6.5. Using the Special Underscore Filehandle
LWP module: B.13.2. Sockets

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

m// operator: 9.1. Matches with m//
vs. s/// substitution operator: 9.6. Substitutions with s///
mailing lists for Perl: 1.3.3. Are There Any Other Kinds of Support?
main program: 1.4.2. What's Inside That Program?
maintenance programmers
partial-evaluation operators and: 10.9.3. Control Structures Using Partial-Evaluation Operators
writing intelligible code for: 2.6.2. Operator Precedence and Associativity
10.1.1. The else Clause with unless
make utility, exit status and: 11.3. Fatal Errors with die
manpages: 1.3.3. Are There Any Other Kinds of Support?
map operator: 17.3. Transforming Items from a List with map
perlfunc manpage and: B.10.1. map and grep
match variables: 9.5. The Match Variables
matching
with =~ binding operator: 9.3. The Binding Operator, =~
with dot wildcard character: 7.2.1. About Metacharacters
with /i modifier: 9.2.1. Case-insensitive Matching with /i
with m// operator: 9.1. Matches with m//
with /s modifier: 9.2.2. Matching Any Character with /s
with s/// substitution operator: 9.6. Substitutions with s///
Math::BigFloat module: B.9.3. Large and High-Precision Numbers
Math::BigInt module: B.9.3. Large and High-Precision Numbers
Math::Complex module: B.9.2. Imaginary and Complex Numbers
mathematical functions: B.9.1. Advanced Math Functions
mathematics: B.9. Mathematics
memory parentheses: 8.4. Memory Parentheses
memory, persistence of: 9.5.1. The Persistence of Memory
memory variables: 8.4.2. Memory Variables
metacharacters: 7.2.1. About Metacharacters
methods: 13.8.3. The File::Spec Module
mkdir function: 13.4. Making and Removing Directories
mod_perl software: B.24. Embedding
modules: 4.11.1. Omitting the Ampersand
13.8. Using Simple Modules
B.4.2. Modules
B.33. And More...
lib pragma for: B.6.3. The lib Pragma
using only some functions from: 13.8.2. Using Only Some Functions from a Module
modulus operator (%): 2.2.5. Numeric Operators
used with grep operator: 17.2. Picking Items from a List with grep
money, sprintf function for: 15.3.1. Using sprintf with "Money Numbers"
mounted volume: 13.3. Links and Files
multiline string quoting: B.8.2. Here documents
multiplication operator (*): 2.2.5. Numeric Operators
mv command (Unix): 13.2. Renaming Files
my operator: 4.9. Notes on Lexical (my) Variables
creating lexical variables with: 4.6. Private Variables in Subroutines
using instead of local operator: 4.7.1. The Difference Between local and my

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

naked block control structure: 10.4. The Naked Block Control Structure
names
hashes and: 5.1.1. Why Use a Hash?
of hashes: 5.2. Hash Element Access
of variables
choosing: 2.5.1. Choosing Good Variable Names
enclosed in curly braces: 2.6.1. Interpolation of Scalar Variables into Strings
namespaces, packages for: B.3. Packages
negating shortcuts: 8.1.2. Negating the Shortcuts
negation (not) operator (!): 2.7.1. Boolean Values
10.1. The unless Control Structure
10.9.3. Control Structures Using Partial-Evaluation Operators
negative array indices: 3.2. Special Array Indices
Net::SMTP module: B.5.8. The Net::SMTP Module
networking: B.13. Networking and IPC
newlines
print function and: 6.4. Output to Standard Output
trailing
chomp operator for removing: 2.9. The chomp Operator
die function and: 11.3. Fatal Errors with die
newsgroups for Perl: 1.3.3. Are There Any Other Kinds of Support?
next operator: 10.8.2. The next Operator
nondecimal integer literals: 2.2.4. Nondecimal Integer Literals
nonpaired delimiters: 9.1. Matches with m//
not operator (see negation operator)
NUL character: 2.3. Strings
DBM hashes and: 16.1.2. Using a DBM Hash
numbers: 2.2. Numbers
2.2. Numbers
comma-separated: 8.2. General Quantifiers
comparison operators for: 2.6.3. Comparison Operators
complex/imaginary and: B.9.2. Imaginary and Complex Numbers
converted automatically to strings: 2.3.4. Automatic Conversion Between Numbers and Strings
high-precision/large: B.9.3. Large and High-Precision Numbers
spaceship operator for comparing: 15.4. Advanced Sorting
sprintf function for: 15.3.1. Using sprintf with "Money Numbers"
numeric comparison operators: 2.6.3. Comparison Operators
numeric operators: 2.2.5. Numeric Operators
numeric user-ID (see user-ID, numeric)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

object-oriented (OO) programming: B.20.2. Object-Oriented Programming
octal literals: 2.2.4. Nondecimal Integer Literals
OO (object-oriented) programming: B.20.2. Object-Oriented Programming
open function: 16.3. Fixed-length Random-access Databases
open operator: 11.2. Opening a Filehandle
opendir operator: 12.4. Directory Handles
operator: 2.8. Getting User Input
context and: 3.9. <STDIN> in List Context
defined function and: 2.12. The defined Function
while loop shortcut and: 6.1. Input from Standard Input
operator precedence (see precedence)
operators
associativity and: 2.6.2. Operator Precedence and Associativity
comparison: 2.6.3. Comparison Operators
15.4. Advanced Sorting
numeric: 2.2.5. Numeric Operators
overload module for: B.22. Operator Overloading
perlfunc manpage and: B.8. Other Operators and Functions
perlop manpage and: B.8. Other Operators and Functions
precedence and: 2.6.2. Operator Precedence and Associativity
option modifiers: 9.2. Option Modifiers
OR operator (||): 10.9. Logical Operators
10.9.3. Control Structures Using Partial-Evaluation Operators
die function and: 11.3. Fatal Errors with die
output: 6.4. Output to Standard Output
buffered: 6.4. Output to Standard Output
capturing using backquotes: 14.4. Using Backquotes to Capture Output
formatted with printf function: 6.5. Formatted Output with printf
overload module: B.22. Operator Overloading

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

pack function: 16.2. Manipulating Data with pack and unpack
packages: B.3. Packages
parameter lists: 4.5. Arguments
empty: 4.8.2. Empty Parameter Lists
variable-length: 4.8. Variable-length Parameter Lists
parent processes, managing: 14. Process Management
parentheses
file tests and: 11.6. File Tests
grouping patterns with: 7.2.3. Grouping in Patterns
indicating precedence: 2.6.2. Operator Precedence and Associativity
optional use of: 3.4.1. The pop and push Operators
with print function: 6.4. Output to Standard Output
with memory function: 8.4. Memory Parentheses
partial-evaluation operators: 10.9.3. Control Structures Using Partial-Evaluation Operators
password databases (Unix): B.7.1. Direct System Database Access
PATH environment variable: 14.3. The Environment Variables
pattern match operator (m//): 9.1. Matches with m//
patterns: 7.1. What Are Regular Expressions?
7.1. What Are Regular Expressions?
7.2. Using Simple Patterns
manpages for: 8.5.2. And There's More
split operator and: 9.7. The split Operator
test program for: 7.3. A Pattern Test Program
percent sign (%): 6.5. Formatted Output with printf
indicating conversion: 6.5. Formatted Output with printf
indicating entire hash: 5.2.1. The Hash as a Whole
printing: 6.5. Formatted Output with printf
performance, slowed by automatic match variables: 9.5.2. The Automatic Match Variables
period (see dot)
Perl: 1.2. What Does "Perl" Stand For?
advanced techniques for: 17. Some Advanced Perl Techniques
bugs in: 1.3.2. How Can I Get Support for Perl?
reporting: 1.3.4. What If I Find a Bug in Perl?
converting other programming languages to: B.25. Converting Other Languages to Perl
current trends in: 1.2.4. What's Happening with Perl Now?
documentation for: 1.3.3. Are There Any Other Kinds of Support?
B.1. Further Documentation
libraries and modules for: B.4. Extending Perl's Functionality
licenses for: 1.3. How Can I Get Perl?
mailing lists and newsgroups for: 1.3.3. Are There Any Other Kinds of Support?
obtaining: 1.3. How Can I Get Perl?
portability and: 1.1.2. Why Are There So Many Footnotes?
1.2.2. Is Perl Easy or Hard?
reasons for using/not using: 1.2.5. What's Perl Really Good For?
security and: B.14. Security
B.16. The Common Gateway Interface (CGI)
support for: 1.3.2. How Can I Get Support for Perl?
Perl identifiers: 2.5. Scalar Variables
Perl Monastery: 1.3.3. Are There Any Other Kinds of Support?
perlboot manpage, object-oriented programming and: B.20.2. Object-Oriented Programming
perlbug utility: 1.3.4. What If I Find a Bug in Perl?
perldata manpage, here documents and: B.8.2. Here documents
perldebug manpage: B.15. Debugging
perldiag manpage: 1.4.2. What's Inside That Program?
errors and: 17.1. Trapping Errors with eval
warnings explained in: 2.4. Perl's Built-in Warnings
perldoc command: 1.5. A Whirlwind Tour of Perl
perldoc manpage: B.1. Further Documentation
perldsc manpage, data structures and: B.20.1. Complex Data Structures
perlfaq manpage: 10.5. The elsif Clause
B.1. Further Documentation
perlfork manpage: B.31. Threads and Forking
perlform manpage, formats and: B.12. Formats
perlfunc manpage: 10.4. The Naked Block Control Structure
format letters and: 16.2. Manipulating Data with pack and unpack
grep operator and: B.10.1. map and grep
map operator and: B.10.1. map and grep
mathematical functions and: B.9.1. Advanced Math Functions
operators and: B.8. Other Operators and Functions
splice operator and: B.10.2. The splice Operator
System V IPC and: B.13.1. System V IPC
vec operator and: B.11. Bits and Pieces
perlipc manpage: 14.6. Getting Down and Dirty with Fork
perlipc module, System V IPC and: B.13.1. System V IPC
perllexwarn manpage: 2.4. Perl's Built-in Warnings
perllocale manpage: B.30. Locales and Unicode
perllol manpage, data structures and: B.20.1. Complex Data Structures
perlmod manpage
syntax extensions and: B.19. Syntax Extensions
writing modules and: B.4.4. Writing Your Own Modules
perlmodinstall manpage: B.4.3. Finding and Installing Modules
perlmodlib manpage
pragmas and: B.6. Pragmas
writing modules and: B.4.4. Writing Your Own Modules
perlobj manpage, object-oriented programming and: B.20.2. Object-Oriented Programming
perlop manpage
bitwise operators and: 11.6.4. Using Bitstrings
operators and: B.8. Other Operators and Functions
perlopentut manpage, filehandles and: B.29. More Ways to Open Filehandles
perlpod manpage: B.28. Embedded Documentation
perlport manpage, standard input/output and: 11.1. What Is a Filehandle?
perlre manpage: 8.5.2. And There's More
B.2. Regular expressions
perlref manpage, references and: B.20. References
perlreftut manpage, references and: B.20. References
perlrequick manpage: 8.5.2. And There's More
B.2. Regular expressions
perlretut manpage: 8.5.2. And There's More
B.2. Regular expressions
perlrun manpage, command-line options and: 16.4.1. In-place Editing from the Command Line
B.17. Command-Line Options
perlsec manpage: B.14. Security
perlsyn manpage: 10.7. The for Control Structure
continue block and: 10.8.2. The next Operator
syntax extensions and: B.19. Syntax Extensions
perlthrtut manpage: B.31. Threads and Forking
perltie manpage, tied variables and: B.21. Tied Variables
perltoc manpage: B.1. Further Documentation
perlvar manpage, builtin variables and: B.18. Built in Variables
permissions
changing: 13.5. Modifying Permissions
Unix and: 13.1. Removing Files
pipe (|): 11.1. What Is a Filehandle?
processes and: 14.5. Processes as Filehandles
plain-old documentation format: B.28. Embedded Documentation
plus sign (+), as quantifier: 7.2.2. Simple Quantifiers
pod format: B.28. Embedded Documentation
pointers (C programming language): B.20. References
pop operator: 3.4.1. The pop and push Operators
portability: 1.1.2. Why Are There So Many Footnotes?
1.2.2. Is Perl Easy or Hard?
modules and: 13.8.3. The File::Spec Module
POSIX module: B.5.9. The POSIX Module
math functions and: B.9.1. Advanced Math Functions
postincrements/postdecrements: 10.6.1. The Value of Autoincrement
pound sign (#) in comments: 1.4.2. What's Inside That Program?
Practical Extraction and Report Language (see Perl)
pragmas: 4.10. The use strict Pragma
B.6. Pragmas
integer: 2.2.1. All Numbers Are the Same Format Internally
precedence: 2.6.2. Operator Precedence and Associativity
8.5. Precedence
partial-evaluation operators and: 10.9.3. Control Structures Using Partial-Evaluation Operators
table of: 2.6.2. Operator Precedence and Associativity
preincrements/predecrements: 10.6.1. The Value of Autoincrement
print function: 2.6. Output with print
databases records and: 16.3. Fixed-length Random-access Databases
filehandles and: 11.4. Using Filehandles
newlines and: 6.4. Output to Standard Output
optional parentheses and: 6.4. Output to Standard Output
output and: 6.4. Output to Standard Output
printf function: 6.5. Formatted Output with printf
filehandles and: 11.4. Using Filehandles
private variables (see lexical variables)
processes
as filehandles: 14.5. Processes as Filehandles
managing: 14. Process Management
programming: 1.4. How Do I Make a Perl Program?
10.1.1. The else Clause with unless
automatic match variables and: 9.5.2. The Automatic Match Variables
text editor for: 1.4. How Do I Make a Perl Program?
programming languages
C, operators and: 10.9.2. The Ternary Operator, ?:
converting to Perl: B.25. Converting Other Languages to Perl
low-level vs. high-level: 1.2.1. Why Didn't Larry Just Use Some Other Language?
structured: 10.8. Loop Controls
Programming Perl: 1.2.1. Why Didn't Larry Just Use Some Other Language?
as documentation for Perl: 1.3.3. Are There Any Other Kinds of Support?
programs: 10.8.1. The last Operator
example of in a nutshell: 1.5. A Whirlwind Tour of Perl
exit status and: 11.3. Fatal Errors with die
last operator for exiting early: 10.8.1. The last Operator
name of
die function and: 11.3. Fatal Errors with die
warn function and: 11.3.1. Warning Messages with warn
running over the Web: 1.4.3. But How Do I Compile Perl?
prototypes: 4.11.1. Omitting the Ampersand
push operator: 3.4.1. The pop and push Operators

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

quantifiers: 7.2.2. Simple Quantifiers
8.2. General Quantifiers
greedy/non-greedy: 17.5.1. Non-greedy Quantifiers
question mark (?) as quantifier: 7.2.2. Simple Quantifiers
quick reference to Perl: 1.3.3. Are There Any Other Kinds of Support?
quoting
multiline string: B.8.2. Here documents
qw shortcut form of: 3.3.1. The qw Shortcut
qw shortcut: 3.3.1. The qw Shortcut

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

raise to the power of operator (**=): 2.5.3. Binary Assignment Operators
range operator (..): 3.3. List Literals
read function, database records and: 16.3. Fixed-length Random-access Databases
readdir operator: 12.4. Directory Handles
readline operator: 12.3. An Alternate Syntax for Globbing
recursive directory listing: 12.5. Recursive Directory Listing
redo operator: 10.8.3. The redo Operator
references: 3.4. List Assignment
B.20. References
Registry (Windows): B.7.1. Direct System Database Access
regular expression engines: 17.5. More Powerful Regular Expressions
resources for further information: B.2. Regular expressions
regular expression memories: 8.4. Memory Parentheses
regular expressions: 7. Concepts of Regular Expressions
17.5. More Powerful Regular Expressions
resources for further reading: B.2. Regular expressions
using: 9. Using Regular Expressions
relational databases: B.7.3. Relational Database Access
removing
directories: 13.4. Making and Removing Directories
files: 13.1. Removing Files
rename function: 13.2. Renaming Files
reports, formats for: B.12. Formats
resources for further reading
auxiliary lock files: 16.1.2. Using a DBM Hash
bitwise operators: 11.6.4. Using Bitstrings
file tests: 11.6. File Tests
Perl
object-oriented programming and: B.20.2. Object-Oriented Programming
using with the Web: B.16. The Common Gateway Interface (CGI)
Programming Perl: 1.2.1. Why Didn't Larry Just Use Some Other Language?
regular expressions: 17.5.1. Non-greedy Quantifiers
B.2. Regular expressions
Tk: B.32. Graphical User Interfaces (GUIs)
restrictions: 4.10. The use strict Pragma
return operator: 4.11. The return Operator
return values: 4.4. Return Values
reverse operator: 3.7.1. The reverse Operator
15.4. Advanced Sorting
rindex function: 15.1. Finding a Substring with index
rm command (Unix): 13.1. Removing Files
rmdir operator: 13.4. Making and Removing Directories
rmtree function: 13.4. Making and Removing Directories
runtime: 1.4.3. But How Do I Compile Perl?

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

s/// substitution operator: 9.6. Substitutions with s///
vs. m// operator: 9.6. Substitutions with s///
scalar context: 3.8. Scalar and List Context
forcing: 3.8.3. Forcing Scalar Context
scalar variables
autoincrements/autodecrements for: 10.6. Autoincrement and Autodecrement
stat function and: 11.6.1. The stat and lstat Functions
scalars: 2.1. What Is Scalar Data?
values of, assigning to variables: 2.5.2. Scalar Assignment
scope of variables: 4.9. Notes on Lexical (my) Variables
naked block control structure and: 10.4. The Naked Block Control Structure
scoped variables (see lexical variables)
security: B.14. Security
CGI programs and: B.16. The Common Gateway Interface (CGI)
seek function: 16.3. Fixed-length Random-access Databases
select operator: 11.4.1. Changing the Default Output Filehandle
semicolon (;)
ending expressions: 1.4.2. What's Inside That Program?
in for/foreach control structures: 10.7.1. The Secret Connection Between foreach and for
return value expressions and: 4.6. Private Variables in Subroutines
shell, avoiding: 14.1.1. Avoiding the Shell
shift operator: 3.4.2. The shift and unshift Operators
shortcuts: 1.2.2. Is Perl Easy or Hard?
character class: 8.1.1. Character Class Shortcuts
negating: 8.1.2. Negating the Shortcuts
SIGINT: 14.7. Sending and Receiving Signals
signals, sending/receiving: 14.7. Sending and Receiving Signals
single-quoted string literals: 2.3.1. Single-Quoted String Literals
single quotes (' ') enclosing strings: 2.3.1. Single-Quoted String Literals
slash with dot (./): 1.4.1. A Simple Program
slices: 17.6. Slices
SMTP servers, Net::SMTP module for: B.5.8. The Net::SMTP Module
sockets (TCP/IP): B.13.2. Sockets
soft links: 13.3. Links and Files
13.3. Links and Files
sort subroutines (sort-definition subroutines): 15.4. Advanced Sorting
sorting
advanced: 15.4. Advanced Sorting
sort operator for: 3.7.2. The sort Operator
s2p conversion program: B.25. Converting Other Languages to Perl
spaces: 8.1.1. Character Class Shortcuts
\\s shortcut for: 8.1.1. Character Class Shortcuts
spaceship operator: 15.4. Advanced Sorting
spaceship operator (): 15.4. Advanced Sorting
splice operator: B.10.2. The splice Operator
split operator: 9.7. The split Operator
17.6. Slices
vs. join function: 9.8. The join Function
sports scores, sorting: 15.4.1. Sorting a Hash by Value
sprintf function: 15.3. Formatting Data with sprintf
sqrt function: 10.4. The Naked Block Control Structure
square brackets ([ ])
in character classes: 8.1. Character Classes
in pattern test program results: 7.3. A Pattern Test Program
square root: B.9.1. Advanced Math Functions
stacks: 4.7. The local Operator
standard error stream: 11.1. What Is a Filehandle?
standard input: 2.8. Getting User Input
6. I/O Basics
standard input stream: 11.1. What Is a Filehandle?
standard output: 6.4. Output to Standard Output
6.4. Output to Standard Output
standard output stream: 11.1. What Is a Filehandle?
star (*) as quantifier: 7.2.2. Simple Quantifiers
Star Wars, spaceship operator and: 15.4. Advanced Sorting
stat buffer: 11.6.5. Using the Special Underscore Filehandle
stat function: 11.6.1. The stat and lstat Functions
underscore filehandle and: 11.6.5. Using the Special Underscore Filehandle
stat(2) manpage: 11.6.1. The stat and lstat Functions
STDERR filehandle: 11.1. What Is a Filehandle?
11.5. Reopening a Standard Filehandle
STDIN filehandle: 11.1. What Is a Filehandle?
STDOUT filehandle: 11.1. What Is a Filehandle?
11.4.1. Changing the Default Output Filehandle
strict pragma: B.6.4. The strict Pragma
string accumulator: 2.11. The undef Value
string comparison operators: 2.6.3. Comparison Operators
string concatenate operator (.): 2.5.3. Binary Assignment Operators
string escapes (see backslash escapes)
string literals: 2.3. Strings
double-quoted (see double-quoted string literals)
string repetition operator (x): 2.3.3. String Operators
6.5.1. Arrays and printf
strings: 2.3. Strings
2.3. Strings
15. Strings and Sorting
converted automatically to numbers: 2.3.4. Automatic Conversion Between Numbers and Strings
finding substrings within: 15.1. Finding a Substring with index
operators for: 2.3.3. String Operators
comparison operators for: 2.6.3. Comparison Operators
sub keyword: 4.2. Defining a Subroutine
subroutines: 4.1. System and User Functions
anonymous: B.20.3. Anonymous Subroutines and Closures
calling: 4.3. Invoking a Subroutine
defining: 4.2. Defining a Subroutine
invoking: 4.3. Invoking a Subroutine
lexical variables in: 4.6. Private Variables in Subroutines
subscripts: 3.1. Accessing Elements of an Array
substr operator: 15.2. Manipulating a Substring with substr
substrings: 15.1. Finding a Substring with index
subtraction operator (-): 2.2.5. Numeric Operators
support for Perl: 1.3.2. How Can I Get Support for Perl?
symbolic links: 11.6. File Tests
11.6.1. The stat and lstat Functions
13.3. Links and Files
13.3. Links and Files
symlink function: 13.3. Links and Files
syntax extensions: B.19. Syntax Extensions
Sys::Hostname module: B.5.10. The Sys::Hostname Module
system databases: B.7.1. Direct System Database Access
system function: 14.1. The system Function
using vs. exec function: 14.2. The exec Function
system functions: 4.1. System and User Functions
system time: 11.6.1. The stat and lstat Functions
System V IPC: B.13.1. System V IPC

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

taint checking: B.14. Security
TCP/IP sockets: B.13.2. Sockets
temporary files, cleaning up: 14.7. Sending and Receiving Signals
B.26. Converting find Command Lines to Perl
ternary operator (?\:): 10.9.2. The Ternary Operator, ?:
text
matching multiple lines of: 17.5.2. Matching Multiple-line Text
regular dollar sign in: 2.6.1. Interpolation of Scalar Variables into Strings
Text::Wrap module for: B.5.11. The Text::Wrap Module
text databases: 16.4. Variable-length (Text) Databases
text editors: 1.4. How Do I Make a Perl Program?
text mode: 1.4. How Do I Make a Perl Program?
Text::Wrap module: B.5.11. The Text::Wrap Module
threads: B.31. Threads and Forking
three-way comparison operator (cmp): 15.4. Advanced Sorting
tie interface: 16.1.1. Opening and Closing DBM Hashes
tied variables: B.21. Tied Variables
tilde-prefix (~): 12.1. Moving Around the Directory Tree
tilde ("~"), as value for $^I variable: 16.4. Variable-length (Text) Databases
time function: 11.6.2. The localtime Function
timelocal function: B.5.12. The Time::Local Module
Time::Local module: B.5.12. The Time::Local Module
timestamps: 11.6.1. The stat and lstat Functions
changing: 13.7. Changing Timestamps
number for, converting: 11.6.2. The localtime Function
Tk module set: B.32. Graphical User Interfaces (GUIs)
tr/// operator: B.8.1. Transliteration with tr///
trailing newlines (see newlines, trailing)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

uid (user-ID): 11.6.1. The stat and lstat Functions
undef operator: 2.12. The defined Function
slices and: 17.6. Slices
undef value: 2.11. The undef Value
underscore (_)
in integer literals: 2.2.3. Integer Literals
in variable names: 4.10. The use strict Pragma
underscore filehandle: 11.6.5. Using the Special Underscore Filehandle
Unicode: B.30. Locales and Unicode
Universal Time: 11.6.2. The localtime Function
Unix
input/output and: 11.1. What Is a Filehandle?
model of files/directories and: 13.3. Links and Files
portability and: 1.1.2. Why Are There So Many Footnotes?
utilities for
diamond operator and: 6.2. Input from the Diamond Operator
regular expressions and: 7. Concepts of Regular Expressions
Unix password databases: B.7.1. Direct System Database Access
Unix signals, sending/receiving: 14.7. Sending and Receiving Signals
unless control structure: 10.1. The unless Control Structure
unless modifier: 10.3. Expression Modifiers
10.3. Expression Modifiers
unlink operator: 13.1. Removing Files
unpack function: 16.2. Manipulating Data with pack and unpack
unquoted hash keys: 17.4. Unquoted Hash Keys
unshift operator: 3.4.2. The shift and unshift Operators
until control structure: 10.2. The until Control Structure
until modifier: 10.3. Expression Modifiers
10.3. Expression Modifiers
unwinding hashes: 5.2.1. The Hash as a Whole
uppercase
case shifting and: 9.6.5. Case Shifting
vs. lowercase in variable names: 2.5.1. Choosing Good Variable Names
URLs
code in this book: 0.3. Code Examples
CPAN: 1.3.1. What Is CPAN?
B.4.3. Finding and Installing Modules
Perl Monastery: 1.3.3. Are There Any Other Kinds of Support?
search interfaces for Perl: 1.3.1. What Is CPAN?
use directives: B.4.3. Finding and Installing Modules
pragmas and: B.6. Pragmas
use strict pragma: 4.10. The use strict Pragma
B.6.4. The strict Pragma
user functions (see subroutines)
user-ID, numeric ($uid): 11.6.1. The stat and lstat Functions
changing file ownership and: 13.6. Changing Ownership
user-ID (uid): 11.6.1. The stat and lstat Functions
utilities
inside: B.4.3. Finding and Installing Modules
perlbug: 1.3.4. What If I Find a Bug in Perl?
Unix (see Unix, utilities for)
which_dbm: 16.1. DBM Files and DBM Hashes
utime function: 13.7. Changing Timestamps

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

values
list, assigning to variables: 3.4. List Assignment
of short-circuit logical operators: 10.9.1. The Value of a Short-Circuit Operator
saving using local operator: 4.7. The local Operator
scalar, assigning to variables: 2.5.2. Scalar Assignment
values function: 5.3.1. The keys and values Functions
variable interpolation: 2.3.2. Double-Quoted String Literals
2.6.1. Interpolation of Scalar Variables into Strings
2.6.1. Interpolation of Scalar Variables into Strings
variable-length parameter lists: 4.8. Variable-length Parameter Lists
variable-length text databases: 16.4. Variable-length (Text) Databases
variables: 2.5. Scalar Variables
altering: 2.5.3. Binary Assignment Operators
assigning list values to: 3.4. List Assignment
assigning scalar values to: 2.5.2. Scalar Assignment
builtin: 9.5.2. The Automatic Match Variables
declaring: 1.4.2. What's Inside That Program?
environment: 14.3. The Environment Variables
match: 9.5. The Match Variables
names of enclosed in curly braces: 2.6.1. Interpolation of Scalar Variables into Strings
tied: B.21. Tied Variables
undef value and: 2.11. The undef Value
value of, saving: 4.7. The local Operator
vars pragma: B.6.5. The vars Pragma
vec operator: B.11. Bits and Pieces
vertical bar (\\|): 7.2.4. Alternatives
vi text editor: 1.4. How Do I Make a Perl Program?
void context: 4.4. Return Values
Vromans, Johan: 1.3.3. Are There Any Other Kinds of Support?

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

waitpid function: 14.6. Getting Down and Dirty with Fork
Wall, Heidi: 6.2. Input from the Diamond Operator
Wall, Larry: 0.4. History of This Book
1.2. What Does "Perl" Stand For?
wantarray function: 4.4. Return Values
warn function: 11.3.1. Warning Messages with warn
warnings: 2.4. Perl's Built-in Warnings
bad filehandles and: 11.2.2. Bad Filehandles
warn function for: 11.3.1. Warning Messages with warn
warnings pragma: B.6.6. The warnings Pragma
Web
CGI programs and: B.16. The Common Gateway Interface (CGI)
running programs over: 1.4.3. But How Do I Compile Perl?
socket-support and: B.13.2. Sockets
which_dbm utility: 16.1. DBM Files and DBM Hashes
while control structure: 2.10. The while Control Structure
for control structure and: 10.7. The for Control Structure
naked block control structure and: 10.4. The Naked Block Control Structure
shortcut for: 6.1. Input from Standard Input
until control structure for reversing: 10.2. The until Control Structure
using each function with: 5.3.2. The each Function
while modifier: 10.3. Expression Modifiers
10.3. Expression Modifiers
15.3.1. Using sprintf with "Money Numbers"
whitespace: 1.4.2. What's Inside That Program?
3.3.1. The qw Shortcut
global replacements and: 9.6.1. Global Replacements with /g
greater-than sign and: 11.2. Opening a Filehandle
in format strings: 16.2. Manipulating Data with pack and unpack
\\\\s shortcut for: 8.1.1. Character Class Shortcuts
split operator and: 9.7. The split Operator
who command (Unix): 14.4.1. Using Backquotes in a List Context
Windows Registry: B.7.1. Direct System Database Access
word-boundary anchors: 8.3.1. Word Anchors
word count, hashes and: 5.1.1. Why Use a Hash?
word processor, using instead of a text editor: 1.4. How Do I Make a Perl Program?
word-wrapping, Text::Wrap module for: B.5.11. The Text::Wrap Module
words, \w shortcut for: 8.1.1. Character Class Shortcuts
working directory
chdir operator for changing: 12.1. Moving Around the Directory Tree
current, cwd function for determining: B.5.2. The Cwd Module
wrap function: B.5.11. The Text::Wrap Module

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x string repetition: 2.3.3. String Operators
6.5.1. Arrays and printf
xor operator: 10.9.3. Control Structures Using Partial-Evaluation Operators

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

There are no index entries for this letter.

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

There are no index entries for this letter.

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


 Programming Perl

by Larry Wall, Tom Christiansen, and Jon Orwant
ISBN 0-596-00027-8
Third Edition, published July 2000.
(See the catalog page for this book.)

Table of Contents

Copyright Page
Preface

Part I: Overview
Chapter 1: An Overview of Perl

Part II: The Gory Details
Chapter 2: Bits and Pieces
Chapter 3: Unary and Binary Operators
Chapter 4: Statements and Declarations
Chapter 5: Pattern Matching
Chapter 6: Subroutines
Chapter 7: Formats
Chapter 8: References
Chapter 9: Data Structures
Chapter 10: Packages
Chapter 11: Modules
Chapter 12: Objects
Chapter 13: Overloading
Chapter 14: Tied Variables

Part III: Perl as Technology
Chapter 15: Unicode
Chapter 16: Interprocess Communication
Chapter 17: Threads
Chapter 18: Compiling
Chapter 19: The Command-Line Interface
Chapter 20: The Perl Debugger
Chapter 21: Internals and Externals

Part IV: Perl as Culture
Chapter 22: CPAN
Chapter 23: Security
Chapter 24: Common Practices
Chapter 25: Portable Perl
Chapter 26: Plain Old Documentation
Chapter 27: Perl Culture

Part V: Reference Material
Chapter 28: Special Names
Chapter 29: Functions
Chapter 30: The Standard Perl Library
Chapter 31: Pragmatic Modules
Chapter 32: Standard Modules
Chapter 33: Diagnostic Messages

Glossary
 Index
Colophon

Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


(Perl and XML)

 Perl & XML
Previous Next

Copyright © 2000, 1996, 1991 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com). For more information contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com.

Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The association between the image of a camel and the Perl language is a trademark of O'Reilly & Associates, Inc. Permission may be granted for non-commercial use; please inquire by sending mail to camel@oreilly.com

While every precaution has been taken in the preparation of this book, the publisher and the author(s) assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Preface

0.1. The Pursuit of Happiness

Perl is a language for getting your job done.

Of course, if your job is programming, you can get your job done with any "complete" computer language, theoretically speaking. But we know from experience that computer languages differ not so much in what they make possible, but in what they make easy. At one extreme, the so-called fourth-generation languages make it easy to do some things, but nearly impossible to do other things. At the other extreme, so-called industrial-strength languages make it equally difficult to do almost everything.

Perl is different. In a nutshell, Perl is designed to make the easy jobs easy, without making the hard jobs impossible.

And what are these "easy jobs" that ought to be easy? The ones you do every day, of course. You want a language that makes it easy to manipulate numbers and text, files and directories, computers and networks, and especially programs. It should be easy to run external programs and scan their output for interesting tidbits. It should be easy to send those same tidbits off to other programs that can do special things with them. It should be easy to develop, modify, and debug your own programs too. And, of course, it should be easy to compile and run your programs, and do it portably, on any modern operating system.

Perl does all that, and a whole lot more.

Initially designed as a glue language for Unix, Perl has long since spread to most other operating systems. Because it runs nearly everywhere, Perl is one of the most portable programming environments available today. To program C or C++ portably, you have to put in all those strange #ifdef markings for different operating systems. To program Java portably, you have to understand the idiosyncrasies of each new Java implementation. To program a shell script portably, you have to remember the syntax for each operating system's version of each command and somehow find the common factor that (you hope) works everywhere. And to program Visual Basic portably, you just need a more flexible definition of the word "portable". :-)

Perl happily avoids such problems while retaining many of the benefits of these other languages, with some additional magic of its own. Perl's magic comes from many sources: the utility of its feature set, the inventiveness of the Perl community, and the exuberance of the open source movement in general. But much of this magic is simply hybrid vigor; Perl has a mixed heritage and has always viewed diversity as a strength rather than a weakness. Perl is a "give me your tired, your poor" language. If you feel like a huddled mass longing to be free, Perl is for you.

Perl reaches out across cultures. Much of the explosive growth of Perl has been fueled by the hankerings of former Unix systems programmers who wanted to take along with them as much of the "old country" as they could. For them, Perl is the portable distillation of Unix culture, an oasis in the desert of "can't get there from here". On the other hand, it also works in the other direction: Windows-based web designers are often delighted to discover that they can take their Perl programs and run them unchanged on the company's Unix server.

Although Perl is especially popular with systems programmers and web developers, that's just because they discovered it first; Perl appeals to a much broader audience. From its small start as a text-processing language, Perl has grown into a sophisticated, general-purpose programming language with a rich software development environment complete with debuggers, profilers, cross-referencers, compilers, libraries, syntax-directed editors, and all the rest of the trappings of a "real" programming language--if you want them. But those are all about making hard things possible, and lots of languages can do that. Perl is unique in that it never lost its vision for keeping easy things easy.

Because Perl is both powerful and accessible, it is being used daily in every imaginable field, from aerospace engineering to molecular biology, from mathematics to linguistics, from graphics to document processing, from database manipulation to network management. Perl is used by people who are desperate to analyze or convert lots of data quickly, whether you're talking DNA sequences, web pages, or pork belly futures. Indeed, one of the jokes in the Perl community is that the next big stock market crash will probably be triggered by a bug in someone's Perl script. (On the brighter side, any unemployed stock analysts will still have a marketable skill, so to speak.)

There are many reasons for the success of Perl. Perl was a successful open source project long before the open source movement got its name. Perl is free, and will always be free. You can use Perl however you see fit, subject only to a very liberal licensing policy. If you are in business and want to use Perl, go right ahead. You can embed Perl in the commercial applications you write without fee or restriction. And if you have a problem that the Perl community can't fix, you have the ultimate backstop: the source code itself. The Perl community is not in the business of renting you their trade secrets in the guise of "upgrades". The Perl community will never "go out of business" and leave you with an orphaned product.

It certainly helps that Perl is free software. But that's not enough to explain the Perl phenomenon since many freeware packages fail to thrive. Perl is not just free; it's also fun. People feel like they can be creative in Perl because they have freedom of expression: they get to choose what to optimize for, whether that's computer speed or programmer speed, verbosity or conciseness, readability or maintainability or reusability or portability or learnability or teachability. You can even optimize for obscurity, if you're entering an Obfuscated Perl Contest.

Perl can give you all these degrees of freedom because it's a language with a split personality. It's simultaneously a very simple language and a very rich language. Perl has taken good ideas from nearly everywhere and installed them into an easy-to-use mental framework. To those who merely like it, Perl is the Practical Extraction and Report Language. To those who love it, Perl is the Pathologically Eclectic Rubbish Lister. And to the minimalists in the crowd, Perl seems like a pointless exercise in redundancy. But that's okay. The world needs a few reductionists (mainly as physicists). Reductionists like to take things apart. The rest of us are just trying to get it together.

There are many ways in which Perl is a simple language. You don't have to know many special incantations to compile a Perl program--you can just execute it like a batch file or shell script. The types and structures used by Perl are easy to use and understand. Perl doesn't impose arbitrary limitations on your data--your strings and arrays can grow as large as they like (as long as you have memory), and they're designed to scale well as they grow. Instead of forcing you to learn new syntax and semantics, Perl borrows heavily from other languages you may already be familiar with (such as C, and awk, and BASIC, and Python, and English, and Greek). In fact, just about any programmer can read a well-written piece of Perl code and have some idea of what it does.

Most important, you don't have to know everything there is to know about Perl before you can write useful programs. You can learn Perl "small end first". You can program in Perl Baby-Talk, and we promise not to laugh. Or more precisely, we promise not to laugh any more than we'd giggle at a child's creative way of putting things. Many of the ideas in Perl are borrowed from natural language, and one of the best ideas is that it's okay to use a subset of the language as long as you get your point across. Any level of language proficiency is acceptable in Perl culture. We won't send the language police after you. A Perl script is "correct" if it gets the job done before your boss fires you.

Though simple in many ways, Perl is also a rich language, and there is much to learn about it. That's the price of making hard things possible. Although it will take some time for you to absorb all that Perl can do, you will be glad that you have access to the extensive capabilities of Perl when the time comes that you need them.

Because of its heritage, Perl was a rich language even when it was "just" a data-reduction language, designed for navigating files, scanning large amounts of text, creating and obtaining dynamic data, and printing easily formatted reports based on that data. But somewhere along the line, Perl started to blossom. It also became a language for filesystem manipulation, process management, database administration, client-server programming, secure programming, web-based information management, and even for object-oriented and functional programming. These capabilities were not just slapped onto the side of Perl--each new capability works synergistically with the others because Perl was designed to be a glue language from the start.

But Perl can glue together more than its own features. Perl is designed to be modularly extensible. Perl allows you to rapidly design, program, debug, and deploy applications, and it also allows you to easily extend the functionality of these applications as the need arises. You can embed Perl in other languages, and you can embed other languages in Perl. Through the module importation mechanism, you can use these external definitions as if they were built-in features of Perl. Object-oriented external libraries retain their object-orientedness in Perl.

Perl helps you in other ways, too. Unlike strictly interpreted languages such as command files or shell scripts, which compile and execute a program one command at a time, Perl first compiles your whole program quickly into an intermediate format. Like any other compiler, it performs various optimizations and gives you instant feedback on everything from syntax and semantic errors to library binding mishaps. Once Perl's compiler frontend is happy with your program, it passes off the intermediate code to the interpreter to execute (or optionally to any of several modular back ends that can emit C or bytecode). This all sounds complicated, but the compiler and interpreter are quite efficient, and most of us find that the typical compile-run-fix cycle is measured in mere seconds. Together with Perl's many fail-soft characteristics, this quick turnaround capability makes Perl a language in which you really can do rapid prototyping. Then later, as your program matures, you can tighten the screws on yourself and make yourself program with less flair but more discipline. Perl helps you with that, too, if you ask nicely.

Perl also helps you to write programs more securely. In addition to all the typical security interfaces provided by other languages, Perl also guards against accidental security errors through a unique data-tracing mechanism that automatically determines which data came from insecure sources and prevents dangerous operations before they can happen. Finally, Perl lets you set up specially protected compartments in which you can safely execute Perl code of dubious origin, disallowing dangerous operations.

But, paradoxically, the way in which Perl helps you the most has almost nothing to do with Perl and everything to do with the people who use Perl. Perl folks are, frankly, some of the most helpful folks on earth. If there's a religious quality to the Perl movement, then this is at the heart of it. Larry wanted the Perl community to function like a little bit of heaven, and by and large he seems to have gotten his wish, so far. Please do your part to keep it that way.

Whether you are learning Perl because you want to save the world, or just because you are curious, or because your boss told you to, this handbook will lead you through both the basics and the intricacies. And although we don't intend to teach you how to program, the perceptive reader will pick up some of the art, and a little of the science, of programming. We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris. Along the way, we hope you find the book mildly amusing in some spots (and wildly amusing in others). And if none of this is enough to keep you awake, just keep reminding yourself that learning Perl will increase the value of your resume. So keep reading.

Home | Next
Book Index | 0.2. What's New in This Edition
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.2. What's New in This Edition

Well, almost everything.

Even where we kept the good bits from the previous edition (and there were quite a few good bits, we'll admit), we've heavily revised and reorganized the current edition with several goals in mind. First, we wanted to increase the accessibility of the book to people coming from backgrounds other than computer science. We've made fewer assumptions about what the reader will know in advance. At the same time, we've kept the exposition lively in the hope that people who are already familiar with some of the material will not fall asleep reading it.

Second, we wanted to present the very latest developments in Perl itself. To that end, we have not been shy about presenting the current state of the work, even where we feel that it is still experimental. While the core of Perl has been rock solid for years, the pace of development for some of the experimental extensions can be quite torrid at times. We'll tell you honestly when we think the online documentation will be more reliable than what we have written here. Perl is a blue-collar language, so we're not afraid to call a spade a shovel.

Third, we wanted you to be able to find your way around in the book more easily, so we've broken this edition up into smaller, more coherent chapters and reorganized them into meaningful parts. Here's how the new edition is laid out:

Part 1, "Overview"

Getting started is always the hardest part. This part presents the fundamental ideas of Perl in an informal, curl-up-in-your-favorite-chair fashion. Not a full tutorial, it merely offers a quick jump-start, which may not serve everyone's need. See Section 0.5, "Offline Documentation" for books that might better suit your learning style.

Part 2, "The Gory Details"

This part consists of an in-depth, no-holds-barred discussion of the guts of the language at every level of abstraction, from data types, variables, and regular expressions to subroutines, modules, and objects. You'll gain a good sense of how the language works and, in the process, pick up a few hints on good software design. (And if you've never used a language with pattern matching, you're in for a special treat.)

Part 3, "Perl as Technology"

You can do a lot with Perl all by itself, but this part will take you to a higher level of wizardry. Here you'll learn how to make Perl jump through whatever hoops your computer sets up for it, from dealing with Unicode, interprocess communication, and multithreading, through compiling, invoking, debugging, and profiling Perl, on up to writing your own external extensions in C or C++ or interfaces to any existing API you feel like. Perl will be quite happy to talk to any interface on your computer, or for that matter, on any other computer on the Internet, weather permitting.

Part 4, "Perl as Culture"

Everyone understands that a culture must have a language, but the Perl community has always understood that a language must have a culture. This part is where we view Perl programming as a human activity, embedded in the real world of people. We'll cover how you can improve the way you deal with both good people and bad people. We'll also dispense a great deal of advice on how you can become a better person yourself and on how to make your programs more useful to other people.

Part 5, "Reference Material"

Here we've put together all the chapters in which you might want to look something up alphabetically, from special variables and functions to standard modules and pragmas. The Glossary will be particularly helpful to those who are unfamiliar with the jargon of computer science. For example, if you don't know what the meaning of "pragma" is, you could look it up right now. (If you don't know what the meaning of "is" is, we can't help you with that.)

Previous | Home | Next
0.1. The Pursuit of Happiness | Book Index | 0.3. The Standard Distribution
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.3. The Standard Distribution

Most operating system vendors these days include Perl as a standard component of their systems. As of this writing, AIX, BeOS, BSDI, Debian, DG/UX, DYNIX/ptx, FreeBSD, IRIX, LynxOS, Mac OS X, OpenBSD, OS390, RedHat, SINIX, Slackware, Solaris, SuSE, and Tru64 all came with Perl as part of their standard distributions. Some companies provide Perl on separate CDs of contributed freeware or through their customer service groups. Third-party companies like ActiveState offer prebuilt Perl distributions for a variety of different operating systems, including those from Microsoft.

Even if your vendor does ship Perl as standard, you'll probably eventually want to compile and install Perl on your own. That way you'll know you have the latest version, and you'll be able to choose where to install your libraries and documentation. You'll also be able to choose whether to compile Perl with support for optional extensions such as multithreading, large files, or the many low-level debugging options available through the -D command-line switch. (The user-level Perl debugger is always supported.)

The easiest way to download a Perl source kit is probably to point your web browser to Perl's home page at www.perl.com, where you'll find download information prominently featured on the start-up page, along with links to precompiled binaries for platforms that have misplaced their C compilers.

You can also head directly to CPAN (the Comprehensive Perl Archive Network, described in Chapter 22, "CPAN"), using http://www.perl.com/CPAN or http://www.cpan.org. If those are too slow for you (and they might be because they're very popular), you should find a mirror close to you. The following URLs are just a few of the CPAN mirrors around the world, now numbering over one hundred:

http://www.funet.fi/pub/languages/perl/CPAN/
ftp://ftp.funet.fi/pub/languages/perl/CPAN/

ftp://ftp.cs.colorado.edu/pub/perl/CPAN/
ftp://ftp.cise.ufl.edu/pub/perl/CPAN/
ftp://ftp.perl.org/pub/perl/CPAN/
http://www.perl.com/CPAN-local
http://www.cpan.org/
http://www.perl.org/CPAN/
http://www.cs.uu.nl/mirror/CPAN/
http://CPAN.pacific.net.hk/
The first pair in that list, those at the funet.fi site, point to the master CPAN repository. The MIRRORED.BY file there contains a list of all other CPAN sites, so you can just get that file and then pick your favorite mirror. Some of them are available through FTP, others through HTTP (which makes a difference behind some corporate firewalls). The http://www.perl.com/CPAN multiplexor attempts to make this selection for you. You can change your selection if you like later.

Once you've fetched the source code and unpacked it into a directory, you should read the README and the INSTALL files to learn how to build Perl. There may also be an INSTALL.platform file for you to read there, where platform represents your operating system platform.

If your platform happens to be some variety of Unix, then your commands to fetch, configure, build, and install Perl might resemble what follows. First, you must choose a command to fetch the source code. You can fetch with ftp:

% ftp ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/latest.tar.gz
(Again, feel free to substitute a nearby CPAN mirror. Of course, if you live in Finland, that is your nearby CPAN mirror.) If you can't use ftp, you can download via the Web using a browser or a command-line tool:
% wget http://www.funet.fi/pub/languages/perl/CPAN/src/latest.tar.gz
Now unpack, configure, build, and install:
% tar zxf latest.tar.gz         Or gunzip first, then tar xf.
% cd perl-5.6.0                 Or 5.* for whatever number.
% sh Configure -des             Assumes default answers.
% make test && make install     Install typically requires superuser.
This uses a conventional C development environment, so if you don't have a C compiler, you can't compile Perl. See the CPAN ports directory for up-to-date status on each platform to learn whether Perl comes bundled (and if so, what version), whether you can get by with the standard source kit, or whether you need a special port. Download links are given for those systems that typically require special ports or for systems from vendors who normally don't provide a C compiler (or rather, who abnormally don't provide a C compiler).

Previous | Home | Next
0.2. What's New in This Edition | Book Index | 0.4. Online Documentation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.4. Online Documentation

Perl's extensive online documentation comes as part of the standard Perl distribution. (See the next section for offline documentation.) Additional documentation shows up whenever you install a module from CPAN.

When we refer to a "Perl manpage" in this book, we're talking about this set of online Perl manual pages, sitting on your computer. The term manpage is purely a convention meaning a file containing documentation--you don't need a Unix-style man program to read one. You may even have the Perl manpages installed as HTML pages, especially on non-Unix systems.

The online manpages for Perl have been divided into separate sections, so you can easily find what you are looking for without wading through hundreds of pages of text. Since the top-level manpage is simply called perl, the Unix command man perl should take you to it.[1] That page in turn directs you to more specific pages. For example, man perlre will display the manpage for Perl's regular expressions. The perldoc command often works on systems when the man command won't. On Macs, you need to use the Shuck program. Your port may also provide the Perl manpages in HTML format or your system's native help format. Check with your local sysadmin--unless you're the local sysadmin.

[1] If you still get a truly humongous page when you do that, you're probably picking up the ancient release 4 manpage. Check your MANPATH for archeological sites. (Say perldoc perl to find out how to configure your MANPATH based on the output of perl -V:man.dir.)

0.4.1. Navigating the Standard Manpages

In the Beginning (of Perl, that is, back in 1987), the perl manpage was a terse document, filling about 24 pages when typeset and printed. For example, its section on regular expressions was only two paragraphs long. (That was enough, if you knew egrep.) In some ways, nearly everything has changed since then. Counting the standard documentation, the various utilities, the per-platform porting information, and the scads of standard modules, we're now up over 1,500 typeset pages of documentation spread across many separate manpages. (And that's not even counting any CPAN modules you install, which is likely to be quite a few.)

But in other ways, nothing has changed: there's still a perl manpage kicking around. And it's still the right place to start when you don't know where to start. The difference is that once you arrive, you can't just stop there. Perl documentation is no longer a cottage industry; it's a supermall with hundreds of stores. When you walk in the door, you need to find the YOU ARE HERE to figure out which shop or department store sells what you're shopping for. Of course, once you get familiar with the mall, you'll usually know right where to go.

Here are a few of the store signs you'll see:

Manpage | Covers
perl | What Perl manpages are available
perldata | Data types
perlsyn | Syntax
perlop | Operators and precedence
perlre | Regular expressions
perlvar | Predefined variables
perlsub | Subroutines
perlfunc | Built-in functions
perlmod | How to make Perl modules work
perlref | References
perlobj | Objects
perlipc | Interprocess communication
perlrun | How to run Perl commands, plus switches
perldebug | Debugging
perldiag | Diagnostic messages

That's just a small excerpt, but it has the important parts. You can tell that if you want to learn about an operator, perlop is apt to have what you're looking for. And if you want to find something out about predefined variables, you'd check in perlvar. If you got a diagnostic message you didn't understand, you'd go to perldiag. And so on.

Part of the standard Perl manual is the frequently asked questions (FAQ) list. It's split up into these nine different pages:

Manpage | Covers
perlfaq1 | General questions about Perl
perlfaq2 | Obtaining and learning about Perl
perlfaq3 | Programming tools
perlfaq4 | Data manipulation
perlfaq5 | Files and formats
perlfaq6 | Regular expressions
perlfaq7 | General Perl language issues
perlfaq8 | System interaction
perlfaq9 | Networking

Some manpages contain platform-specific notes:

Manpage | Covers
perlamiga | The Amiga port
perlcygwin | The Cygwin port
perldos | The MS-DOS port
perlhpux | The HP-UX port
perlmachten | The Power MachTen port
perlos2 | The OS/2 port
perlos390 | The OS/390 port
perlvms | The DEC VMS port
perlwin32 | The MS-Windows port

(See also Chapter 25, "Portable Perl", and the CPAN ports directory described earlier for porting information.)

0.4.2. Searching the Manpages

Nobody expects you to read through all 1,500 typeset pages just to find a needle in a haystack. There's an old saying that you can't grep [2] dead trees. Besides the customary search capabilities inherent in most document-viewing programs, as of the 5.6.1 release of Perl, each main Perl manpage has its own search and display capability. You can search individual pages by using the name of the manpage as the command and passing a Perl regular expression (see Chapter 5, "Pattern Matching") as the search pattern:

% perlop comma

% perlfunc split

% perlvar ARGV

% perldiag 'assigned to typeglob'
When you don't quite know where something is in the documentation, you can expand your search. For example, to search all the FAQs, use the perlfaq command (which is also a manpage):
% perlfaq round
The perltoc command (which is also a manpage) searches all the manpages' collective tables of contents:
% perltoc typeglob
perl5005delta: Undefined value assigned to typeglob
perldata: Typeglobs and Filehandles
perldiag: Undefined value assigned to typeglob
Or to search the complete online Perl manual, including all headers, descriptions, and examples, for any instances of the string, use the perlhelp command:
% perlhelp CORE::GLOBAL
See the perldoc manpage for details.

[2]Don't forget there's a Glossary if you need it.

0.4.3. Non-Perl Manpages

When we refer to non-Perl documentation, as in getitimer(2), this refers to the getitimer manpage from section 2 of the Unix Programmer's Manual.[3] Manpages for syscalls such as getitimer may not be available on non-Unix systems, but that's probably okay, because you couldn't use the Unix syscall there anyway. If you really do need the documentation for a Unix command, syscall, or library function, many organizations have put their manpages on the web--a quick search of AltaVista for "+crypt(3) +manual" will find many copies.

[3]Section 2 is only supposed to contain direct calls into the operating system. (These are often called "system calls", but we'll consistently call them syscalls in this book to avoid confusion with the system function, which has nothing to do with syscalls). However, systems vary somewhat in which calls are implemented as syscalls and which are implemented as C library calls, so you could conceivably find getitimer(2) in section 3 instead.

Although the top-level Perl manpages are typically installed in section 1 of the standard man directories, we will omit appending a (1) to those manpage names in this book. You can recognize them anyway because they are all of the form "perl mumble".

Previous | Home | Next
0.3. The Standard Distribution | Book Index | 0.5. Offline Documentation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.5. Offline Documentation

If you'd like to learn more about Perl, here are some related publications that we recommend:

  • Perl 5 Pocket Reference, 3d ed., by Johan Vromans (O'Reilly, 2000). This small booklet serves as a convenient quick reference for Perl.

  • Perl Cookbook, by Tom Christiansen and Nathan Torkington (O'Reilly, 1998). This is the companion volume to the book you have in your hands right now.

  • Elements of Programming with Perl, by Andrew L. Johnson (Manning, 1999). This book aims to teach non-programmers how to program from the ground up, and to do so using Perl.

  • Learning Perl, 2d ed., by Randal Schwartz and Tom Christiansen (O'Reilly, 1997). This book teaches Unix sysadmins and Unix programmers the 30% of basic Perl that they'll use 70% of the time. Erik Olson retargeted a version of this book for Perl programmers on Microsoft systems; it is called Learning Perl for Win32 Systems.

  • Perl: The Programmer's Companion, by Nigel Chapman (Wiley, 1997). This fine book is geared for professional computer scientists and programmers without regard to platform. It covers Perl quickly but completely.

  • Mastering Regular Expressions, by Jeffrey Friedl (O'Reilly, 1997). Although it doesn't cover the latest additions to Perl regular expressions, this book is an invaluable reference for anyone seeking to learn how regular expressions really work.

  • Object Oriented Perl, by Damian Conway (Manning, 1999). For beginning as well as advanced OO programmers, this astonishing book explains common and esoteric techniques for writing powerful object systems in Perl.

  • Mastering Algorithms with Perl, by Jon Orwant, Jarkko Hietaniemi, and John Macdonald (O'Reilly, 1999). All the useful techniques from a computer science algorithms course, but without the painful proofs. This book covers fundamental and useful algorithms in the fields of graphs, text, sets, and much more.

  • Writing Apache Modules with Perl and C, by Lincoln Stein and Doug MacEachern (O'Reilly, 1999). This guide to web programming teaches you how to extend the capabilities of the Apache web server, especially using the turbo-charged mod_perl for fast CGI scripts and via the Perl-accessible Apache API.

  • The Perl Journal, edited by Jon Orwant. This quarterly magazine by programmers and for programmers regularly features programming insights, techniques, the latest news, and more.

There are many other Perl books and publications out there, and out of senility, we have undoubtedly forgotten to mention some good ones. (Out of mercy, we have neglected to mention some bad ones.)

In addition to the Perl-related publications listed above, we recommend the following books. They aren't about Perl directly but still come in handy for reference, consultation, and inspiration.

  • The Art of Computer Programming, by Donald Knuth, vol. 1, Fundamental Algorithms; vol. 2, Seminumerical Algorithms; and vol. 3, Sorting and Searching (Addison-Wesley, 1998).

  • Introduction to Algorithms, by Cormen, Leiserson, and Rivest (MIT Press and McGraw-Hill, 1990).

  • Algorithms in C: Fundamental Data Structures, Sorting, Searching, 3d ed., by Robert Sedgewick (Addison-Wesley, 1997).

  • The Elements of Programming Style, by Kernighan and Plauger (Prentiss-Hall, 1988).

  • The Unix Programming Environment, by Kernighan and Pike (Prentiss-Hall, 1984).

  • POSIX Programmer's Guide, by Donald Lewine (O'Reilly, 1991).

  • Advanced Programming in the UNIX Environment, by W. Richard Stevens (Addison-Wesley, 1992).

  • TCP/IP Illustrated, vols. 1-3, by W. Richard Stevens, (Addison-Wesley, 1994-1996).

  • The Lord of the Rings by J.R.R. Tolkien (most recent printing: Houghton Mifflin, 1999).

Previous | Home | Next
0.4. Online Documentation | Book Index | 0.6. Additional Resources
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.6. Additional Resources

The Internet is a wonderful invention, and we're all still discovering how to use it to its full potential. (Of course, some people prefer to "discover" the Internet the way Tolkien discovered Middle Earth.)

0.6.1. Perl on the Web

Visit the Perl home page at http://www.perl.com/. It tells what's new in the Perl world and contains source code and ports, feature articles, documentation, conference schedules, and a lot more.

Also visit the Perl Mongers' web page at http://www.perl.org for a grassroots-level view of Perl's, er, grass roots, which grow quite thickly in every part of the world, except at the South Pole, where they have to be kept indoors. Local PM groups hold regular small meetings where you can exchange Perl lore with other Perl hackers who live in your part of the world.

0.6.2. Usenet Newsgroups

The Perl newsgroups are a great, if sometimes cluttered, source of information about Perl. Your first stop might be comp.lang.perl.moderated, a moderated, low-traffic newsgroup that includes announcements and technical discussions. Because of the moderation, the newsgroup is quite readable.

The high-traffic comp.lang.perl.misc group discusses everything from technical issues to Perl philosophy to Perl games and Perl poetry. Like Perl itself, comp.lang.perl.misc is meant to be useful, and no question is too silly to ask.[4]

[4] Of course, some questions are too silly to answer. (Especially those already answered in the online manpages and FAQs. Why ask for help on a newsgroup when you could find the answer by yourself in less time than it takes to type in the question?)

The comp.lang.perl.tk group discusses how to use the popular Tk toolkit from Perl. The comp.lang.perl.modules group is about the development and use of Perl modules, which are the best way to get reusable code. There may be other comp.lang.perl.whatever newsgroups by the time you read this; look around.

If you aren't using a regular newsreader to access Usenet, but a web browser instead, prepend "news:" to the newsgroup name to get at one of these named newsgroups. (This only works if you have a news server.) Alternatively, if you use a Usenet searching service like Alta Vista or Deja, specify "*perl*" as the newsgroups to search for.

One other newsgroup you might want to check out, at least if you're doing CGI programming on the Web, is comp.infosystems.www.authoring.cgi. While it isn't strictly speaking a Perl group, most of the programs discussed there are written in Perl. It's the right place to go for web-related Perl issues, unless you're using mod_perl under Apache, in which case you might check out comp.infosystems.www.servers.unix.

0.6.3. Bug Reports

In the unlikely event that you should encounter a bug that's in Perl proper and not just in your own program, you should try to reduce it to a minimal test case and then report it with the perlbug program that comes with Perl. See http://bugs.perl.org for more info.

Previous | Home | Next
0.5. Offline Documentation | Book Index | 0.7. Conventions Used in This Book
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.7. Conventions Used in This Book

Some of our conventions get larger sections of their very own. Coding conventions are discussed in Section 0.3, "Programming with Style" in Chapter 24, "Common Practices". In a sense, our lexical conventions are given in the Glossary (our lexicon).

The following typographic conventions are used in this book:

Italic

is used for URLs, manpages, pathnames, and programs. New terms are also italicized when they first appear in the text. Many of these terms will have alternative definitions in the Glossary if the one in the text doesn't do it for you.

Constant width

is used in examples and in regular text to show any literal code. Data values are represented by constant width in quotes (""), which are not part of the value.

Constant width bold

is used for command-line switches. This allows one to distinguish for example, between the -w warnings switch and the -w filetest operator. It is also used in the examples to indicate the text you type in literally.

Constant width italic

is used for generic code terms for which you must substitute particular values.

We give lots of examples, most of which are pieces of code that should go into a larger program. Some examples are complete programs, which you can recognize because they begin with a #! line. We start nearly all of our longer programs with:

#!/usr/bin/perl
Still other examples are things to be typed on a command line. We've used % to indicate a generic shell prompt:
% perl -e 'print "Hello, world.\n"'
Hello, world.
This style is representative of a standard Unix command line, where single quotes represent the "most quoted" form. Quoting and wildcard conventions on other systems vary. For example, many command-line interpreters under MS-DOS and VMS require double quotes instead of single quotes when you need to group arguments with spaces or wildcards in them.

Previous | Home | Next
0.6. Additional Resources | Book Index | 0.8. Acknowledgments
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.8. Acknowledgments

Here we say nice things in public about our reviewers to make up for all the rude things we said to them in private: Todd Miller, Sharon Hopkins Rauenzahn, Rich Rauenzahn, Paul Marquess, Paul Grassie, Nathan Torkington, Johan Vromans, Jeff Haemer, Gurusamy Sarathy, Gloria Wall, Dan Sugalski, and Abigail.

We'd like to express our special gratitude to Tim O'Reilly (and his Associates) for encouraging authors to write the sort of books people might enjoy reading.

Previous | Home | Next
0.7. Conventions Used in This Book | Book Index | 0.9. We'd Like to Hear from You
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


0.9. We'd Like to Hear from You

We have tested and verified all of the information in this book to the best of our ability, but you may find that features have changed (or even that we have made mistakes!). Please let us know about any errors you find, as well as your suggestions for future editions, by writing:

O'Reilly & Associates, Inc.
1005 Gravenstein Hwy North
Sebastopol, CA 95472
1-800-998-9938 (in the US or Canada)
1-707-829-0515 (international/local)
1-707-829-0104 (fax)
You can also send messages electronically. To be put on the O'Reilly mailing list or request a catalog, send mail to info@oreilly.com.

To ask technical questions or comment on this book, send mail to bookquestions@oreilly.com.

We have a web site for the book, where we'll list any errata and other Camel-related information:

http://www.oreilly.com/catalog/pperl3
Here you'll also find all the example code from the book available for download so you don't have to type it all in, like we did.

Previous | Home | Next
0.8. Acknowledgments | Book Index | Part 1. Overview
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part I. Overview

Chapter 1: An Overview of Perl

Previous | Home | Next
0.9. We'd Like to Hear from You | Book Index | 1. An Overview of Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 1. An Overview of Perl

Contents:

Getting Started
Natural and Artificial Languages
An Average Example
Filehandles
Operators
Control Structures
Regular Expressions
List Processing
What You Don't Know Won't Hurt You (Much)

1.1. Getting Started

We think that Perl is an easy language to learn and use, and we hope to convince you that we're right. One thing that's easy about Perl is that you don't have to say much before you say what you want to say. In many programming languages, you have to declare the types, variables, and subroutines you are going to use before you can write the first statement of executable code. And for complex problems demanding complex data structures, declarations are a good idea. But for many simple, everyday problems, you'd like a programming language in which you can simply say:

print "Howdy, world!\n";
and expect the program to do just that.

Perl is such a language. In fact, this example is a complete program,[1] and if you feed it to the Perl interpreter, it will print "Howdy, world!" on your screen. (The \n in the example produces a newline at the end of the output.)

[1] Or script, or application, or executable, or doohickey. Whatever.

And that's that. You don't have to say much after you say what you want to say, either. Unlike many languages, Perl thinks that falling off the end of your program is just a normal way to exit the program. You certainly may call the exit function explicitly if you wish, just as you may declare some of your variables, or even force yourself to declare all your variables. But it's your choice. With Perl you're free to do The Right Thing, however you care to define it.

There are many other reasons why Perl is easy to use, but it would be pointless to list them all here, because that's what the rest of the book is for. The devil may be in the details, as they say, but Perl tries to help you out down there in the hot place too. At every level, Perl is about helping you get from here to there with minimum fuss and maximum enjoyment. That's why so many Perl programmers go around with a silly grin on their face.

This chapter is an overview of Perl, so we're not trying to present Perl to the rational side of your brain. Nor are we trying to be complete, or logical. That's what the following chapters are for. Vulcans, androids, and like-minded humans should skip this overview and go straight to Chapter 2, "Bits and Pieces", for maximum information density. If, on the other hand, you're looking for a carefully paced tutorial, you should probably get Randal's nice book, Learning Perl (published by O'Reilly & Associates). But don't throw this book out just yet.

This chapter presents Perl to the other side of your brain, whether you prefer to call it associative, artistic, passionate, or merely spongy. To that end, we'll be presenting various views of Perl that will give you as clear a picture of Perl as the blind men had of the elephant. Well, okay, maybe we can do better than that. We're dealing with a camel here (see the cover). Hopefully, at least one of these views of Perl will help get you over the hump.

Previous | Home | Next
 | 1.2. Natural and Artificial Languages
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.2. Natural and Artificial Languages

Languages were first invented by humans, for the benefit of humans. In the annals of computer science, this fact has occasionally been forgotten.[2] Since Perl was designed (loosely speaking) by an occasional linguist, it was designed to work smoothly in the same ways that natural language works smoothly. Naturally, there are many aspects to this, since natural language works well at many levels simultaneously. We could enumerate many of these linguistic principles here, but the most important principle of language design is that easy things should be easy, and hard things should be possible. (Actually, that's two principles.) They may seem obvious to you, but many computer languages fail at one or the other.

[2] More precisely, this fact has occasionally been remembered.

Natural languages are good at both because people are continually trying to express both easy things and hard things, so the language evolves to handle both. Perl was designed first of all to evolve, and indeed it has evolved. Many people have contributed to the evolution of Perl over the years. We often joke that a camel is a horse designed by a committee, but if you think about it, the camel is pretty well adapted for life in the desert. The camel has evolved to be relatively self-sufficient. (On the other hand, the camel has not evolved to smell good. Neither has Perl.) This is one of the many strange reasons we picked the camel to be Perl's mascot, but it doesn't have much to do with linguistics.

Now when someone utters the word "linguistics", many folks focus in on one of two things. Either they think of words, or they think of sentences. But words and sentences are just two handy ways to "chunk" speech. Either may be broken down into smaller units of meaning or combined into larger units of meaning. And the meaning of any unit depends heavily on the syntactic, semantic, and pragmatic context in which the unit is located. Natural language has words of various sorts: nouns and verbs and such. If someone says "dog" in isolation, you think of it as a noun, but you can also use the word in other ways. That is, a noun can function as a verb, an adjective, or an adverb when the context demands it. If you dog a dog during the dog days of summer, you'll be a dog tired dogcatcher.[3]

[3] And you're probably dog tired of all this linguistics claptrap. But we'd like you to understand why Perl is different from the typical computer language, doggone it!

Perl also evaluates words differently in various contexts. We will see how it does that later. Just remember that Perl is trying to understand what you're saying, like any good listener does. Perl works pretty hard to try to keep up its end of the bargain. Just say what you mean, and Perl will usually "get it". (Unless you're talking nonsense, of course--the Perl parser understands Perl a lot better than either English or Swahili.)

But back to nouns. A noun can name a particular object, or it can name a class of objects generically without specifying which one is currently being referred to. Most computer languages make this distinction, only we call the particular one a value and the generic one a variable. A value just exists somewhere, who knows where, but a variable gets associated with one or more values over its lifetime. So whoever is interpreting the variable has to keep track of that association. That interpreter may be in your brain or in your computer.

1.2.1. Variable Syntax

A variable is just a handy place to keep something, a place with a name, so you know where to find your special something when you come back looking for it later. As in real life, there are various kinds of places to store things, some of them rather private, and some of them out in public. Some places are temporary, and other places are more permanent. Computer scientists love to talk about the "scope" of variables, but that's all they mean by it. Perl has various handy ways of dealing with scoping issues, which you'll be happy to learn later when the time is right. Which is not yet. (Look up the adjectives local, my, and our in Chapter 29, "Functions", when you get curious, or see "Scoped Declarations" in Chapter 4, "Statements and Declarations".)

But a more immediately useful way of classifying variables is by what sort of data they can hold. As in English, Perl's primary type distinction is between singular and plural data. Strings and numbers are singular pieces of data, while lists of strings or numbers are plural. (And when we get to object-oriented programming, you'll find that the typical object looks singular from the outside but plural from the inside, like a class of students.) We call a singular variable a scalar, and a plural variable an array. Since a string can be stored in a scalar variable, we might write a slightly longer (and commented) version of our first example like this:

$phrase = "Howdy, world!\n";          # Set a variable.
print $phrase;                        # Print the variable.
Note that we did not have to predefine what kind of variable $phrase is. The $ character tells Perl that phrase is a scalar variable, that is, one containing a singular value. An array variable, by contrast, would start with an @ character. (It may help you to remember that a $ is a stylized "s", for "scalar", while @ is a stylized "a", for "array".)

Perl has some other variable types, with unlikely names like "hash", "handle", and "typeglob". Like scalars and arrays, these types of variables are also preceded by funny characters. For completeness, here are all the funny characters you'll encounter:

Type | Character | Example | Is a name for:
Scalar | $ | $cents | An individual value (number or string)
Array | @ | @large | A list of values, keyed by number
Hash | % | %interest | A group of values, keyed by string
Subroutine | & | &how | A callable chunk of Perl code
Typeglob | * | *struck | Everything named struck

Some language purists point to these funny characters as a reason to abhor Perl. This is superficial. These characters have many benefits, not least of which is that variables can be interpolated into strings with no additional syntax. Perl scripts are also easy to read (for people who have bothered to learn Perl!) because the nouns stand out from verbs. And new verbs can be added to the language without breaking old scripts. (We told you Perl was designed to evolve.) And the noun analogy is not frivolous--there is ample precedent in English and other languages for requiring grammatical noun markers. It's how we think! (We think.)

1.2.1.1. Singularities

From our earlier example, you can see that scalars may be assigned a new value with the = operator, just as in many other computer languages. Scalar variables can be assigned any form of scalar value: integers, floating-point numbers, strings, and even esoteric things like references to other variables, or to objects. There are many ways of generating these values for assignment.

As in the Unix[4]shell, you can use different quoting mechanisms to make different kinds of values. Double quotation marks (double quotes) do variable interpolation [5] and backslash interpolation (such as turning \n into a newline) while single quotes suppress interpolation. And backquotes (the ones leaning to the left) will execute an external program and return the output of the program, so you can capture it as a single string containing all the lines of output.

$answer = 42;                # an integer
$pi = 3.14159265;            # a "real" number
$avocados = 6.02e23;         # scientific notation
$pet = "Camel";              # string
$sign = "I love my $pet";    # string with interpolation
$cost = 'It costs $100';     # string without interpolation
$thence = $whence;           # another variable's value
$salsa = $moles * $avocados; # a gastrochemical expression
$exit = system("vi $file");  # numeric status of a command
$cwd = `pwd`;                # string output from a command
And while we haven't covered fancy values yet, we should point out that scalars may also hold references to other data structures, including subroutines and objects.
$ary = \@myarray;            # reference to a named array
$hsh = \%myhash;             # reference to a named hash
$sub = \&mysub;              # reference to a named subroutine

$ary = [1,2,3,4,5];          # reference to an unnamed array
$hsh = {Na => 19, Cl => 35}; # reference to an unnamed hash
$sub = sub { print $state }; # reference to an unnamed subroutine

$fido = new Camel "Amelia";  # reference to an object

[4]Here and elsewhere, when we say Unix, we mean any operating system resembling Unix, including BSD, Linux, and, of course, Unix.

[5]Sometimes called "substitution" by shell programmers, but we prefer to reserve that word for something else in Perl. So please call it interpolation. We're using the term in the textual sense ("this passage is a Gnostic interpolation") rather than in the mathematical sense ("this point on the graph is an interpolation between two other points").

If you use a variable that has never been assigned a value, the uninitialized variable automatically springs into existence as needed. Following the principle of least surprise, the variable is created with a null value, either "" or 0. Depending on where you use them, variables will be interpreted automatically as strings, as numbers, or as "true" and "false" values (commonly called Boolean values). Remember how important context is in human languages. In Perl, various operators expect certain kinds of singular values as parameters, so we will speak of those operators as "providing" or "supplying" a scalar context to those parameters. Sometimes we'll be more specific, and say it supplies a numeric context, a string context, or a Boolean context to those parameters. (Later we'll also talk about list context, which is the opposite of scalar context.) Perl will automatically convert the data into the form required by the current context, within reason. For example, suppose you said this:

$camels = '123';
print $camels + 1, "\n";
The original value of $camels is a string, but it is converted to a number to add 1 to it, and then converted back to a string to be printed out as 124. The newline, represented by "\n", is also in string context, but since it's already a string, no conversion is necessary. But notice that we had to use double quotes there--using single quotes to say '\n' would result in a two-character string consisting of a backslash followed by an "n", which is not a newline by anybody's definition.

So, in a sense, double quotes and single quotes are yet another way of specifying context. The interpretation of the innards of a quoted string depends on which quotes you use. (Later, we'll see some other operators that work like quotes syntactically but use the string in some special way, such as for pattern matching or substitution. These all work like double-quoted strings too. The double-quote context is the "interpolative" context of Perl, and is supplied by many operators that don't happen to resemble double quotes.)

Similarly, a reference behaves as a reference when you give it a "dereference" context, but otherwise acts like a simple scalar value. For example, we might say:

$fido = new Camel "Amelia";
if (not $fido) { die "dead camel"; }
$fido->saddle();
Here we create a reference to a Camel object and put it into the variable $fido. On the next line, we test $fido as a scalar Boolean to see if it is "true", and we throw an exception (that is, we complain) if it is not true, which in this case would mean that the new Camel constructor failed to make a proper Camel object. But on the last line, we treat $fido as a reference by asking it to look up the saddle() method for the object held in $fido, which happens to be a Camel, so Perl looks up the saddle() method for Camel objects. More about that later. For now, just remember that context is important in Perl because that's how Perl knows what you want without your having to say it explicitly, as many other computer languages force you to do.

1.2.1.2. Pluralities

Some kinds of variables hold multiple values that are logically tied together. Perl has two types of multivalued variables: arrays and hashes. In many ways, these behave like scalars--they spring into existence with nothing in them when needed, for instance. But they are different from scalars in that, when you assign to them, they supply a list context to the right side of the assignment rather than a scalar context.

Arrays and hashes also differ from each other. You'd use an array when you want to look something up by number. You'd use a hash when you want to look something up by name. The two concepts are complementary. You'll often see people using an array to translate month numbers into month names, and a corresponding hash to translate month names back into month numbers. (Though hashes aren't limited to holding only numbers. You could have a hash that translates month names to birthstone names, for instance.)

1.2.1.2.1. Arrays.

An array is an ordered list of scalars, accessed[6] by the scalar's position in the list. The list may contain numbers, or strings, or a mixture of both. (It might also contain references to subarrays or subhashes.) To assign a list value to an array, you simply group the values together (with a set of parentheses):

@home = ("couch", "chair", "table", "stove");
Conversely, if you use @home in a list context, such as on the right side of a list assignment, you get back out the same list you put in. So you could set four scalar variables from the array like this:
($potato, $lift, $tennis, $pipe) = @home;
These are called list assignments. They logically happen in parallel, so you can swap two variables by saying:
($alpha,$omega) = ($omega,$alpha);
As in C, arrays are zero-based, so while you would talk about the first through fourth elements of the array, you would get to them with subscripts 0 through 3.[7] Array subscripts are enclosed in square brackets [like this], so if you want to select an individual array element, you would refer to it as $home[n], where n is the subscript (one less than the element number) you want. See the example that follows. Since the element you are dealing with is a scalar, you always precede it with a $.

[6] Or keyed, or indexed, or subscripted, or looked up. Take your pick.

[7] If this seems odd to you, just think of the subscript as an offset, that is, the count of how many array elements come before it. Obviously, the first element doesn't have any elements before it, and so has an offset of 0. This is how computers think. (We think.)

If you want to assign to one array element at a time, you could write the earlier assignment as:

$home[0] = "couch";
$home[1] = "chair";
$home[2] = "table";
$home[3] = "stove";
Since arrays are ordered, you can do various useful operations on them, such as the stack operations push and pop. A stack is, after all, just an ordered list, with a beginning and an end. Especially an end. Perl regards the end of your array as the top of a stack. (Although most Perl programmers think of an array as horizontal, with the top of the stack on the right.)

1.2.1.2.2. Hashes.

A hash is an unordered set of scalars, accessed[8] by some string value that is associated with each scalar. For this reason hashes are often called associative arrays. But that's too long for lazy typists to type, and we talk about them so often that we decided to name them something short and snappy. The other reason we picked the name "hash" is to emphasize the fact that they're disordered. (They are, coincidentally, implemented internally using a hash-table lookup, which is why hashes are so fast, and stay so fast no matter how many values you put into them.) You can't push or pop a hash though, because it doesn't make sense. A hash has no beginning or end. Nevertheless, hashes are extremely powerful and useful. Until you start thinking in terms of hashes, you aren't really thinking in Perl. Figure 1-1 shows the ordered elements of an array and the unordered (but named) elements of a hash.

[8] Or keyed, or indexed, or subscripted, or looked up. Take your pick.

Figure 1.1. An array and a hash

Since the keys to a hash are not automatically implied by their position, you must supply the key as well as the value when populating a hash. You can still assign a list to it like an ordinary array, but each pair of items in the list will be interpreted as a key and a value. Since we're dealing with pairs of items, hashes use the funny character % to mark hash names. (If you look carefully at the % character, you can see the key and the value with a slash between them. It may help to squint.)

Suppose you wanted to translate abbreviated day names to the corresponding full names. You could write the following list assignment:

%longday = ("Sun", "Sunday", "Mon", "Monday", "Tue", "Tuesday",
            "Wed", "Wednesday", "Thu", "Thursday", "Fri",
            "Friday", "Sat", "Saturday");
But that's rather difficult to read, so Perl provides the => (equals sign, greater-than sign) sequence as an alternative separator to the comma. Using this syntactic sugar (and some creative formatting), it is much easier to see which strings are the keys and which strings are the associated values.
%longday = (
    "Sun" => "Sunday",
    "Mon" => "Monday",
    "Tue" => "Tuesday",
    "Wed" => "Wednesday",
    "Thu" => "Thursday",
    "Fri" => "Friday",
    "Sat" => "Saturday",
);
Not only can you assign a list to a hash, as we did above, but if you mention a hash in list context, it'll convert the hash back to a list of key/value pairs, in a weird order. This is occasionally useful. More often people extract a list of just the keys, using the (aptly named) keys function. The key list is also unordered, but can easily be sorted if desired, using the (aptly named) sort function. Then you can use the ordered keys to pull out the corresponding values in the order you want.

Because hashes are a fancy kind of array, you select an individual hash element by enclosing the key in braces (those fancy brackets also known as "curlies"). So, for example, if you want to find out the value associated with Wed in the hash above, you would use $longday{"Wed"}. Note again that you are dealing with a scalar value, so you use $ on the front, not %, which would indicate the entire hash.

Linguistically, the relationship encoded in a hash is genitive or possessive, like the word "of" in English, or like "'s". The wife of Adam is Eve, so we write:

$wife{"Adam"} = "Eve";

1.2.1.3. Complexities

Arrays and hashes are lovely, simple, flat data structures. Unfortunately, the world does not always cooperate with our attempts to oversimplify. Sometimes you need to build not-so-lovely, not-so-simple, not-so-flat data structures. Perl lets you do this by pretending that complicated values are really simple ones. To put it the other way around, Perl lets you manipulate simple scalar references that happen to refer to complicated arrays and hashes. We do this all the time in natural language when we use a simple singular noun like "government" to represent an entity that is completely convoluted and inscrutable. Among other things.

To extend our previous example, suppose we want to switch from talking about Adam's wife to Jacob's wife. Now, as it happens, Jacob had four wives. (Don't try this at home.) In trying to represent this in Perl, we find ourselves in the odd situation where we'd like to pretend that Jacob's four wives were really one wife. (Don't try this at home, either.) You might think you could write it like this:

$wife{"Jacob"} = ("Leah", "Rachel", "Bilhah", "Zilpah");        # WRONG
But that wouldn't do what you want, because even parentheses and commas are not powerful enough to turn a list into a scalar in Perl. (Parentheses are used for syntactic grouping, and commas for syntactic separation.) Rather, you need to tell Perl explicitly that you want to pretend that a list is a scalar. It turns out that square brackets are powerful enough to do that:
$wife{"Jacob"} = ["Leah", "Rachel", "Bilhah", "Zilpah"];        # ok
That statement creates an unnamed array and puts a reference to it into the hash element $wife{"Jacob"}. So we have a named hash containing an unnamed array. This is how Perl deals with both multidimensional arrays and nested data structures. As with ordinary arrays and hashes, you can also assign individual elements, like this:
$wife{"Jacob"}[0] = "Leah";
$wife{"Jacob"}[1] = "Rachel";
$wife{"Jacob"}[2] = "Bilhah";
$wife{"Jacob"}[3] = "Zilpah";
You can see how that looks like a multidimensional array with one string subscript and one numeric subscript. To see something that looks more tree-structured, like a nested data structure, suppose we wanted to list not only Jacob's wives but all the sons of each of his wives. In this case we want to treat a hash as a scalar. We can use braces for that. (Inside each hash value we'll use square brackets to represent arrays, just as we did earlier. But now we have an array in a hash in a hash.)
$kids_of_wife{"Jacob"} = {
    "Leah"   => ["Reuben", "Simeon", "Levi", "Judah", "Issachar", "Zebulun"],
    "Rachel" => ["Joseph", "Benjamin"],
    "Bilhah" => ["Dan", "Naphtali"],
    "Zilpah" => ["Gad", "Asher"],
};
That would be more or less equivalent to saying:
$kids_of_wife{"Jacob"}{"Leah"}[0]   = "Reuben";
$kids_of_wife{"Jacob"}{"Leah"}[1]   = "Simeon";
$kids_of_wife{"Jacob"}{"Leah"}[2]   = "Levi";
$kids_of_wife{"Jacob"}{"Leah"}[3]   = "Judah";
$kids_of_wife{"Jacob"}{"Leah"}[4]   = "Issachar";
$kids_of_wife{"Jacob"}{"Leah"}[5]   = "Zebulun";
$kids_of_wife{"Jacob"}{"Rachel"}[0] = "Joseph";
$kids_of_wife{"Jacob"}{"Rachel"}[1] = "Benjamin";
$kids_of_wife{"Jacob"}{"Bilhah"}[0] = "Dan";
$kids_of_wife{"Jacob"}{"Bilhah"}[1] = "Naphtali";
$kids_of_wife{"Jacob"}{"Zilpah"}[0] = "Gad";
$kids_of_wife{"Jacob"}{"Zilpah"}[1] = "Asher";
You can see from this that adding a level to a nested data structure it is like adding another dimension to a multidimensional array. Perl lets you think of it either way, but the internal representation is the same.

The important point here is that Perl lets you pretend that a complex data structure is a simple scalar. On this simple kind of encapsulation, Perl's entire object-oriented structure is built. When we earlier invoked the Camel constructor like this:

$fido = new Camel "Amelia";
we created a Camel object that is represented by the scalar $fido. But the inside of the Camel is more complicated. As well-behaved object-oriented programmers, we're not supposed to care about the insides of Camels (unless we happen to be the people implementing the methods of the Camel class). But generally, an object like a Camel would consist of a hash containing the particular Camel's attributes, such as its name ("Amelia" in this case, not "fido"), and the number of humps (which we didn't specify, but probably defaults to 1; check the front cover).

1.2.1.4. Simplicities

If your head isn't spinning a bit from reading that last section, then you have an unusual head. People don't generally like to deal with complex data structures, whether governmental or genealogical. So in our natural languages, we have many ways of sweeping complexity under the carpet. Many of these fall into the category of topicalization, which is just a fancy linguistics term for agreeing with someone about what you're going to talk about (and by exclusion, what you're probably not going to talk about). This happens on many levels in language. On a high level, we divide ourselves up into various subcultures that are interested in various subtopics and establish sublanguages that talk primarily about those subtopics. The lingo of the doctor's office ("indissoluable asphyxiant") is different from the lingo of the chocolate factory ("everlasting gobstopper"). Most of us automatically switch contexts as we go from one lingo to another.

On a conversational level, the context switch has to be more explicit, so our language gives us many ways of saying what we're about to say. We put titles on our books and headers on our sections. On our sentences, we put quaint phrases like "In regard to your recent query" or "For all X". Usually, though, we just say things like, "You know that dangley thingy that hangs down in the back of your throat?"

Perl also has several ways of topicalizing. One important topicalizer is the package declaration. Suppose you want to talk about Camels in Perl. You'd likely start off your Camel module by saying:

package Camel;
This has several notable effects. One of them is that Perl will assume from this point on that any unspecified verbs or nouns are about Camels. It does this by automatically prefixing any global name with the module name "Camel::". So if you say:
package Camel;
$fido = &fetch();
then the real name of $fido is $Camel::fido (and the real name of &fetch is &Camel::fetch, but we're not talking about verbs yet). This means that if some other module says:
package Dog;
$fido = &fetch();
Perl won't get confused, because the real name of this $fido is $Dog::fido, not $Camel::fido. A computer scientist would say that a package establishes a namespace. You can have as many namespaces as you like, but since you're only in one of them at a time, you can pretend that the other namespaces don't exist. That's how namespaces simplify reality for you. Simplification is based on pretending. (Of course, so is oversimplification, which is what we're doing in this chapter.)

Now it's important to keep your nouns straight, but it's just as important to keep your verbs straight. It's nice that &Camel::fetch is not confused with &Dog::fetch within the Camel and Dog namespaces, but the really nice thing about packages is that they classify your verbs so that other packages can use them. When we said:

$fido = new Camel "Amelia";
we were actually invoking the &new verb in the Camel package, which has the full name of &Camel::new. And when we said:
$fido->saddle();
we were invoking the &Camel::saddle routine, because $fido remembers that it is pointing to a Camel. This is how object-oriented programming works.

When you say package Camel, you're starting a new package. But sometimes you just want to borrow the nouns and verbs of an existing package. Perl lets you do that with a use declaration, which not only borrows verbs from another package, but also checks that the module you name is loaded in from disk. In fact, you must say something like:

use Camel;
before you say:
$fido = new Camel "Amelia";
because otherwise Perl wouldn't know what a Camel is.

The interesting thing is that you yourself don't really need to know what a Camel is, provided you can get someone else to write the Camel module for you. Even better would be if someone had already written the Camel module for you. It could be argued that the most powerful thing about Perl is not Perl itself, but CPAN (Comprehensive Perl Archive Network), which contains myriads of modules that accomplish many different tasks that you don't have to know how to do. You just have to download it and know how to say:

use Some::Cool::Module;
and then use the verbs from that module in a manner appropriate to the topic under discussion.

So, like topicalization in a natural language, topicalization in Perl "warps" the language that you'll use from there to the end of the program. In fact, some of the built-in modules don't actually introduce verbs at all, but simply warp the Perl language in various useful ways. These special modules we call pragmas. For instance, you'll often see people use the pragma strict, like this:

use strict;
What the strict module does is tighten up some of the rules so that you have to be more explicit about various things that Perl would otherwise guess about, such as how you want your variables to be scoped. Making things explicit is helpful when you're working on large projects. By default Perl is optimized for small projects, but with the strict pragma, Perl is also good for large projects that need to be more maintainable. Since you can add the strict pragma at any time, Perl is also good for evolving small projects into large ones, even when you didn't expect that to happen. Which is usually.

1.2.2. Verbs

As is typical of your typical imperative computer language, many of the verbs in Perl are commands: they tell the Perl interpreter to do something. On the other hand, as is typical of a natural language, the meanings of Perl verbs tend to mush off in various directions depending on the context. A statement starting with a verb is generally purely imperative and evaluated entirely for its side effects. (We sometimes call these verbs procedures, especially when they're user-defined.) A frequently seen built-in command (in fact, you've seen it already) is the print command:

print "Adam's wife is $wife{'Adam'}.\n";
This has the side effect of producing the desired output:
Adam's wife is Eve.

But there are other "moods" besides the imperative mood. Some verbs are for asking questions and are useful in conditionals such as if statements. Other verbs translate their input parameters into return values, just as a recipe tells you how to turn raw ingredients into something (hopefully) edible. We tend to call these verbs functions, in deference to generations of mathematicians who don't know what the word "functional" means in normal English.

An example of a built-in function would be the exponential function:

$e = exp(1);   # 2.718281828459 or thereabouts
But Perl doesn't make a hard distinction between procedures and functions. You'll find the terms used interchangeably. Verbs are also sometimes called operators (when built-in), or subroutines (when user-defined).[9] But call them whatever you like--they all return a value, which may or may not be a meaningful value, which you may or may not choose to ignore.

[9] Historically, Perl required you to put an ampersand character (&) on any calls to user-defined subroutines (see $fido = &fetch(); earlier). But with Perl version 5, the ampersand became optional, so that user-defined verbs can now be called with the same syntax as built-in verbs ($fido = fetch();). We still use the ampersand when talking about the name of the routine, such as when we take a reference to it ($fetcher = \&fetch;). Linguistically speaking, you can think of the ampersand form &fetch as an infinitive, "to fetch", or the similar form "do fetch". But we rarely say "do fetch" when we can just say "fetch". That's the real reason we dropped the mandatory ampersand in Perl 5.

As we go on, you'll see additional examples of how Perl behaves like a natural language. But there are other ways to look at Perl too. We've already sneakily introduced some notions from mathematical language, such as subscripts, addition, and the exponential function. But Perl is also a control language, a glue language, a prototyping language, a text-processing language, a list-processing language, and an object-oriented language. Among other things.

But Perl is also just a plain old computer language. And that's how we'll look at it next.

Previous | Home | Next
1.1. Getting Started | Book Index | 1.3. An Average Example
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.3. An Average Example

Suppose you've been teaching a Perl class, and you're trying to figure out how to grade your students. You have a set of exam scores for each member of a class, in random order. You'd like a combined list of all the grades for each student, plus their average score. You have a text file (imaginatively named grades) that looks like this:

Noël 25
Ben 76
Clementine 49
Norm 66
Chris 92
Doug 42
Carol 25
Ben 12
Clementine 0
Norm 66
...
You can use the following script to gather all their scores together, determine each student's average, and print them all out in alphabetical order. This program assumes rather naively that you don't have two Carols in your class. That is, if there is a second entry for Carol, the program will assume it's just another score for the first Carol (not to be confused with the first Noël).

By the way, the line numbers are not part of the program, any other resemblances to BASIC notwithstanding.

 1  #!/usr/bin/perl
 2
 3  open(GRADES, "grades") or die "Can't open grades: $!\n";
 4  while ($line = <GRADES>) {
 5      ($student, $grade) = split(" ", $line);
 6      $grades{$student} .= $grade . " ";
 7  }
 8
 9  foreach $student (sort keys %grades) {
10      $scores = 0;
11      $total = 0;
12      @grades = split(" ", $grades{$student});
13      foreach $grade (@grades) {
14          $total += $grade;
15          $scores++;
16      }
17      $average = $total / $scores;
18      print "$student: $grades{$student}\tAverage: $average\n";
19  }
Now before your eyes cross permanently, we'd better point out that this example demonstrates a lot of what we've covered so far, plus quite a bit more that we'll explain presently. But if you let your eyes go just a little out of focus, you may start to see some interesting patterns. Take some wild guesses now as to what's going on, and then later on we'll tell you if you're right.

We'd tell you to try running it, but you may not know how yet.

1.3.1. How to Do It

Gee, right about now you're probably wondering how to run a Perl program. The short answer is that you feed it to the Perl language interpreter program, which coincidentally happens to be named perl. The long answer starts out like this: There's More Than One Way To Do It.[10]

[10] That's the Perl Slogan, and you'll get tired of hearing it, unless you're the Local Expert, in which case you'll get tired of saying it. Sometimes it's shortened to TMTOWTDI, pronounced "tim-toady". But you can pronounce it however you like. After all, TMTOWTDI.

The first way to invoke perl (and the way most likely to work on any operating system) is to simply call perl explicitly from the command line.[11] If you are doing something fairly simple, you can use the -e switch (% in the following example represents a standard shell prompt, so don't type it). On Unix, you might type:

% perl -e 'print "Hello, world!\n";'

[11] Assuming that your operating system provides a command-line interface. If you're running an older Mac, you might need to upgrade to a version of BSD such as Mac OS X.

On other operating systems, you may have to fiddle with the quotes some. But the basic principle is the same: you're trying to cram everything Perl needs to know into 80 columns or so.[12]

[12] These types of scripts are often referred to as "one-liners". If you ever end up hanging out with other Perl programmers, you'll find that some of us are quite fond of creating intricate one-liners. Perl has occasionally been maligned as a write-only language because of these shenanigans.

For longer scripts, you can use your favorite text editor (or any other text editor) to put all your commands into a file and then, presuming you named the script gradation (not to be confused with graduation), you'd say:

% perl gradation
You're still invoking the Perl interpreter explicitly, but at least you don't have to put everything on the command line every time. And you no longer have to fiddle with quotes to keep the shell happy.

The most convenient way to invoke a script is just to name it directly (or click on it), and let the operating system find the interpreter for you. On some systems, there may be ways of associating various file extensions or directories with a particular application. On those systems, you should do whatever it is you do to associate the Perl script with the perl interpreter. On Unix systems that support the #! "shebang" notation (and most Unix systems do, nowadays), you can make the first line of your script be magical, so the operating system will know which program to run. Put a line resembling line 1 of our example into your program:

#!/usr/bin/perl
(If perl isn't in /usr/bin, you'll have to change the #! line accordingly.) Then all you have to say is:
% gradation
Of course, this didn't work because you forgot to make sure the script was executable (see the manpage for chmod(1)) and in your PATH. If it isn't in your PATH, you'll have to provide a complete filename so that the operating system knows how to find your script. Something like:
% /home/sharon/bin/gradation
Finally, if you are unfortunate enough to be on an ancient Unix system that doesn't support the magic #! line, or if the path to your interpreter is longer than 32 characters (a built-in limit on many systems), you may be able to work around it like this:
#!/bin/sh -- # perl, to stop looping
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if 0;
Some operating systems may require variants of this to deal with /bin/csh, DCL, COMMAND.COM, or whatever happens to be your default command interpreter. Ask your Local Expert.

Throughout this book, we'll just use #!/usr/bin/perl to represent all these notions and notations, but you'll know what we really mean by it.

A random clue: when you write a test script, don't call your script test. Unix systems have a built-in test command, which will likely be executed instead of your script. Try try instead.

A not-so-random clue: while learning Perl, and even after you think you know what you're doing, we suggest using the -w switch, especially during development. This option will turn on all sorts of useful and interesting warning messages, not necessarily in that order. You can put the -w switch on the shebang line, like this:

#!/usr/bin/perl -w
Now that you know how to run your own Perl program (not to be confused with the perl program), let's get back to our example.

Previous | Home | Next
1.2. Natural and Artificial Languages | Book Index | 1.4. Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.4. Filehandles

Unless you're using artificial intelligence to model a solipsistic philosopher, your program needs some way to communicate with the outside world. In lines 3 and 4 of our Average Example you'll see the word GRADES, which exemplifies another of Perl's data types, the filehandle. A filehandle is just a name you give to a file, device, socket, or pipe to help you remember which one you're talking about, and to hide some of the complexities of buffering and such. (Internally, filehandles are similar to streams from a language like C++ or I/O channels from BASIC.)

Filehandles make it easier for you to get input from and send output to many different places. Part of what makes Perl a good glue language is that it can talk to many files and processes at once. Having nice symbolic names for various external objects is just part of being a good glue language.[13]

[13] Some of the other things that make Perl a good glue language are: it's 8-bit clean, it's embeddable, and you can embed other things in it via extension modules. It's concise, and it "networks" easily. It's environmentally conscious, so to speak. You can invoke it in many different ways (as we saw earlier). But most of all, the language itself is not so rigidly structured that you can't get it to "flow" around your problem. It comes back to that TMTOWTDI thing again.

You create a filehandle and attach it to a file by using open. The open function takes at least two parameters: the filehandle and filename you want to associate it with. Perl also gives you some predefined (and preopened) filehandles. STDIN is your program's normal input channel, while STDOUT is your program's normal output channel. And STDERR is an additional output channel that allows your program to make snide remarks off to the side while it transforms (or attempts to transform) your input into your output.[14]

[14] These filehandles are typically attached to your terminal, so you can type to your program and see its output, but they may also be attached to files (and such). Perl can give you these predefined handles because your operating system already provides them, one way or another. Under Unix, processes inherit standard input, output, and error from their parent process, typically a shell. One of the duties of a shell is to set up these I/O streams so that the child process doesn't need to worry about them.

Since you can use the open function to create filehandles for various purposes (input, output, piping), you need to be able to specify which behavior you want. As you might do on the command line, you simply add characters to the filename.

open(SESAME, "filename")               # read from existing file
open(SESAME, "<filename")              #   (same thing, explicitly)
open(SESAME, ">filename")              # create file and write to it
open(SESAME, ">>filename")             # append to existing file
open(SESAME, "| output-pipe-command")  # set up an output filter
open(SESAME, "input-pipe-command |")   # set up an input filter
As you can see, the name you pick for the filehandle is arbitrary. Once opened, the filehandle SESAME can be used to access the file or pipe until it is explicitly closed (with, you guessed it, close(SESAME)), or until the filehandle is attached to another file by a subsequent open on the same filehandle.[15]

[15]Opening an already opened filehandle implicitly closes the first file, making it inaccessible to the filehandle, and opens a different file. You must be careful that this is what you really want to do. Sometimes it happens accidentally, like when you say open($handle,$file), and $handle happens to contain a constant string. Be sure to set $handle to something unique, or you'll just open a new file on the same filehandle. Or you can leave $handle undefined, and Perl will fill it in for you.

Once you've opened a filehandle for input, you can read a line using the line reading operator, <>. This is also known as the angle operator because it's made of angle brackets. The angle operator encloses the filehandle (<SESAME>) you want to read lines from. The empty angle operator, <>, will read lines from all the files specified on the command line, or STDIN, if none were specified. (This is standard behavior for many filter programs.) An example using the STDIN filehandle to read an answer supplied by the user would look something like this:

print STDOUT "Enter a number: ";          # ask for a number
$number = <STDIN>;                        # input the number
print STDOUT "The number is $number.\n";  # print the number
Did you see what we just slipped by you? What's that STDOUT doing there in those print statements? Well, that's just one of the ways you can use an output filehandle. A filehandle may be supplied as the first argument to the print statement, and if present, tells the output where to go. In this case, the filehandle is redundant, because the output would have gone to STDOUT anyway. Much as STDIN is the default for input, STDOUT is the default for output. (In line 18 of our Average Example, we left it out to avoid confusing you up till now.)

If you try the previous example, you may notice that you get an extra blank line. This happens because the line-reading operation does not automatically remove the newline from your input line (your input would be, for example, "9\n"). For those times when you do want to remove the newline, Perl provides the chop and chomp functions. chop will indiscriminately remove (and return) the last character of the string, while chomp will only remove the end of record marker (generally, "\n") and return the number of characters so removed. You'll often see this idiom for inputting a single line:

chop($number = <STDIN>);    # input number and remove newline
which means the same thing as:
$number = <STDIN>;          # input number
chop($number);              # remove newline

Previous | Home | Next
1.3. An Average Example | Book Index | 1.5. Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.5. Operators

As we alluded to earlier, Perl is also a mathematical language. This is true at several levels, from low-level bitwise logical operations, up through number and set manipulation, on up to larger predicates and abstractions of various sorts. And as we all know from studying math in school, mathematicians love strange symbols. What's worse, computer scientists have come up with their own versions of these strange symbols. Perl has a number of these strange symbols too, but take heart, most are borrowed directly from C, FORTRAN, sed(1) or awk(1), so they'll at least be familiar to users of those languages.

The rest of you can take comfort in knowing that, by learning all these strange symbols in Perl, you've given yourself a head start on all those other strange languages.

Perl's built-in operators may be classified by number of operands into unary, binary, and trinary (or ternary) operators. They may be classified by whether they're prefix operators (which go in front of their operands) or infix operators (which go in between their operands). They may also be classified by the kinds of objects they work with, such as numbers, strings, or files. Later, we'll give you a table of all the operators, but first here are some handy ones to get you started.

1.5.1. Some Binary Arithmetic Operators

Arithmetic operators do what you would expect from learning them in school. They perform some sort of mathematical function on numbers. For example:

Example | Name | Result
$a + $b | Addition | Sum of $a and $b
$a * $b | Multiplication | Product of $a and $b
$a % $b | Modulus | Remainder of $a divided by $b
$a ** $b | Exponentiation | $a to the power of $b

Yes, we left out subtraction and division--we suspect you can figure out how they should work. Try them and see if you're right. (Or cheat and look in Chapter 3, "Unary and Binary Operators".) Arithmetic operators are evaluated in the order your math teacher taught you (exponentiation before multiplication; multiplication before addition). You can always use parentheses to make it come out differently.

1.5.2. String Operators

There is also an "addition" operator for strings that performs concatenation (that is, joining strings end to end). Unlike some languages that confuse this with numeric addition, Perl defines a separate operator (.) for string concatenation:

$a = 123;
$b = 456;
print $a + $b;     # prints 579
print $a . $b;     # prints 123456

There's also a "multiply" operator for strings, called the repeat operator. Again, it's a separate operator (x) to keep it distinct from numeric multiplication:

$a = 123;
$b = 3;
print $a * $b;     # prints 369
print $a x $b;     # prints 123123123
These string operators bind as tightly as their corresponding arithmetic operators. The repeat operator is a bit unusual in taking a string for its left argument but a number for its right argument. Note also how Perl is automatically converting from numbers to strings. You could have put all the literal numbers above in quotes, and it would still have produced the same output. Internally though, it would have been converting in the opposite direction (that is, from strings to numbers).

A couple more things to think about. String concatenation is also implied by the interpolation that happens in double-quoted strings. And when you print out a list of values, you're also effectively concatenating strings. So the following three statements produce the same output:

print $a . ' is equal to ' . $b . ".\n";    # dot operator
print $a, ' is equal to ', $b, ".\n";       # list
print "$a is equal to $b.\n";               # interpolation
Which of these you use in any particular situation is entirely up to you. (But bear in mind that interpolation is often the most readable.)

The x operator may seem relatively worthless at first glance, but it is quite useful at times, especially for things like this:

print "-" x $scrwid, "\n";
which draws a line across your screen, presuming $scrwid contains your screen width, and not your screw identifier.

1.5.3. Assignment Operators

Although it's not exactly a mathematical operator, we've already made extensive use of the simple assignment operator, =. Try to remember that = means "gets set to" rather than "equals". (There is also a mathematical equality operator == that means "equals", and if you start out thinking about the difference between them now, you'll save yourself a lot of headache later. The == operator is like a function that returns a Boolean value, while = is more like a procedure that is evaluated for the side effect of modifying a variable.)

Like the operators described earlier, assignment operators are binary infix operators, which means they have an operand on either side of the operator. The right operand can be any expression you like, but the left operand must be a valid lvalue (which, when translated to English, means a valid storage location like a variable, or a location in an array). The most common assignment operator is simple assignment. It determines the value of the expression on its right side, and then sets the variable on the left side to that value:

$a = $b;
$a = $b + 5;
$a = $a * 3;
Notice the last assignment refers to the same variable twice; once for the computation, once for the assignment. There's nothing wrong with that, but it's a common enough operation that there's a shortcut for it (borrowed from C). If you say:
lvalue operator= expression
it is evaluated as if it were:
lvalue = lvalue operator expression
except that the lvalue is not computed twice. (This only makes a difference if evaluation of the lvalue has side effects. But when it does make a difference, it usually does what you want. So don't sweat it.)

So, for example, you could write the previous example as:

$a *= 3;
which reads "multiply $a by 3". You can do this with almost any binary operator in Perl, even some that you can't do it with in C:
$line .= "\n";  # Append newline to $line.
$fill x= 80;    # Make string $fill into 80 repeats of itself.
$val ||= "2";   # Set $val to 2 if it isn't already "true".
Line 6 of our Average Example[16] contains two string concatenations, one of which is an assignment operator. And line 14 contains a +=.

[16]Thought we'd forgotten it, didn't you?

Regardless of which kind of assignment operator you use, the final value of the variable on the left is returned as the value of the assignment as a whole.[17] This will not surprise C programmers, who will already know how to use this idiom to zero out variables:

$a = $b = $c = 0;
You'll also frequently see assignment used as the condition of a while loop, as in line 4 of our average example.

[17] This is unlike, say, Pascal, in which assignment is a statement and returns no value. We said earlier that assignment is like a procedure, but remember that in Perl, even procedures return values.

What will surprise C programmers is that assignment in Perl returns the actual variable as an lvalue, so that you can modify the same variable more than once in a statement. For instance, you could say:

($temp -= 32) *= 5/9;
to do an in-place conversion from Fahrenheit to Celsius. This is also why earlier in this chapter we could say:
chop($number = <STDIN>);
and have it chop the final value of $number. Generally speaking, you can use this feature whenever you want to copy something and at the same time do something else with it.

1.5.4. Unary Arithmetic Operators

As if $variable += 1 weren't short enough, Perl borrows from C an even shorter way to increment a variable. The autoincrement (and autodecrement) operators simply add (or subtract) one from the value of the variable. They can be placed on either side of the variable, depending on when you want them to be evaluated:

Example | Name | Result
++$a, $a++ | Autoincrement | Add 1 to $a
--$a, $a-- | Autodecrement | Subtract 1 from $a

If you place one of these "auto" operators before the variable, it is known as a pre-incremented (pre-decremented) variable. Its value will be changed before it is referenced. If it is placed after the variable, it is known as a post-incremented (post-decremented) variable, and its value is changed after it is used. For example:

$a = 5;        # $a is assigned 5
$b = ++$a;     # $b is assigned the incremented value of $a, 6
$c = $a--;     # $c is assigned 6, then $a is decremented to 5
Line 15 of our Average Example increments the number of scores by one, so that we'll know how many scores we're averaging. It uses a post-increment operator ($scores++), but in this case it doesn't matter, since the expression is in a void context, which is just a funny way of saying that the expression is being evaluated only for the side effect of incrementing the variable. The value returned is being thrown away.[18]

[18] The optimizer will notice this and optimize the post-increment into a pre-increment, because that's a bit faster to execute. (You didn't need to know that, but we hoped it would cheer you up.)

1.5.5. Logical Operators

Logical operators, also known as "short-circuit" operators, allow the program to make decisions based on multiple criteria without using nested if statements. They are known as short-circuit operators because they skip (short circuit) the evaluation of their right argument if they decide the left argument has already supplied enough information to decide the overall value. This is not just for efficiency. You are explicitly allowed to depend on this short-circuiting behavior to avoid evaluating code in the right argument that you know would blow up if the left argument were not "guarding" it. You can say "California or bust!" in Perl without busting (presuming you do get to California).

Perl actually has two sets of logical operators, a traditional set borrowed from C and a newer (but even more traditional) set of ultralow-precedence operators borrowed from BASIC. Both sets contribute to readability when used appropriately. C's punctuational operators work well when you want your logical operators to bind more tightly than commas, while BASIC's word-based operators work well when you want your commas to bind more tightly than your logical operators. Often they work the same, and which set you use is a matter of personal preference. (For contrastive examples, see Section 1.20, "Logical and, or, not, and xor" in Chapter 3, "Unary and Binary Operators".) Although the two sets of operators are not interchangeable due to precedence, once they're parsed, the operators themselves behave identically; precedence merely governs the extent of their arguments. Table 1-1 lists logical operators.

Table 1.1. Logical Operators

Example | Name | Result
$a && $b | And | $a if $a is false, $b otherwise
$a || $b | Or | $a if $a is true, $b otherwise
! $a | Not | True if $a is not true
$a and $b | And | $a if $a is false, $b otherwise
$a or $b | Or | $a if $a is true, $b otherwise
not $a | Not | True if $a is not true
$a xor $b | Xor | True if $a or $b is true, but not both

Since the logical operators "short-circuit" the way they do, they're often used in Perl to conditionally execute code. The following line (line 3 from our Average Example) tries to open the file grades:

open(GRADES, "grades") or die "Can't open file grades: $!\n";
If it opens the file, it will jump to the next line of the program. If it can't open the file, it will provide us with an error message and then stop execution.

Literally, this line means "Open grades or bust!" Besides being another example of natural language, the short-circuit operators preserve the visual flow. Important actions are listed down the left side of the screen, and secondary actions are hidden off to the right. (The $! variable contains the error message returned by the operating system--see Chapter 28, "Special Names".) Of course, these logical operators can also be used within the more traditional kinds of conditional constructs, such as the if and while statements.

1.5.6. Some Numeric and String Comparison Operators

Comparison, or relational, operators tell us how two scalar values (numbers or strings) relate to each other. There are two sets of operators; one does numeric comparison and the other does string comparison. (In either case, the arguments will be "coerced" to have the appropriate type first.) Assuming left and right arguments of $a and $b, we have:

Comparison | Numeric | String | Return Value
Equal | == | eq | True if $a is equal to $b
Not equal | != | ne | True if $a is not equal to $b
Less than | < | lt | True if $a is less than $b
Greater than | > | gt | True if $a is greater than $b
Less than or equal | <= | le | True if $a not greater than $b
Comparison | <=> | cmp | 0 if equal, 1 if $a greater, -1 if $b greater

The last pair of operators (<=> and cmp) are entirely redundant. However, they're incredibly useful in sort subroutines (see Chapter 29, "Functions").[19]

[19] Some folks feel that such redundancy is evil because it keeps a language from being minimalistic, or orthogonal. But Perl isn't an orthogonal language; it's a diagonal language. By this we mean that Perl doesn't force you to always go at right angles. Sometimes you just want to follow the hypotenuse of the triangle to get where you're going. TMTOWTDI is about shortcuts. Shortcuts are about efficiency.

1.5.7. Some File Test Operators

The file test operators allow you to test whether certain file attributes are set before you go and blindly muck about with the files. The most basic file attribute is, of course, whether the file exists. For example, it would be very nice to know whether your mail aliases file already exists before you go and open it as a new file, wiping out everything that was in there before. Here are a few of the file test operators:

Example | Name | Result
-e $a | Exists | True if file named in $a exists
-r $a | Readable | True if file named in $a is readable
-w $a | Writable | True if file named in $a is writable
-d $a | Directory | True if file named in $a is a directory
-f $a | File | True if file named in $a is a regular file
-T $a | Text File | True if file named in $a is a text file

You might use them like this:

-e "/usr/bin/perl" or warn "Perl is improperly installed\n";
-f "/vmlinuz" and print "I see you are a friend of Linus\n";
Note that a regular file is not the same thing as a text file. Binary files like /vmlinuz are regular files, but they aren't text files. Text files are the opposite of binary files, while regular files are the opposite of "irregular" files like directories and devices.

There are a lot of file test operators, many of which we didn't list. Most of the file tests are unary Boolean operators, which is to say they take only one operand (a scalar that evaluates to a filename or a filehandle), and they return either a true or false value. A few of them return something fancier, like the file's size or age, but you can look those up when you need them in the section Section 1.10, "Named Unary and File Test Operators" in Chapter 3, "Unary and Binary Operators".

Previous | Home | Next
1.4. Filehandles | Book Index | 1.6. Control Structures
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.6. Control Structures

So far, except for our one large example, all of our examples have been completely linear; we executed each command in order. We've seen a few examples of using the short-circuit operators to cause a single command to be (or not to be) executed. While you can write some very useful linear programs (a lot of CGI scripts fall into this category), you can write much more powerful programs if you have conditional expressions and looping mechanisms. Collectively, these are known as control structures. So you can also think of Perl as a control language.

But to have control, you have to be able to decide things, and to decide things, you have to know the difference between what's true and what's false.

1.6.1. What Is Truth?

We've bandied about the term truth,[20] and we've mentioned that certain operators return a true or a false value. Before we go any further, we really ought to explain exactly what we mean by that. Perl treats truth a little differently than most computer languages, but after you've worked with it a while, it will make a lot of sense. (Actually, we hope it'll make a lot of sense after you've read the following.)

[20] Strictly speaking, this is not true.

Basically, Perl holds truths to be self-evident. That's a glib way of saying that you can evaluate almost anything for its truth value. Perl uses practical definitions of truth that depend on the type of thing you're evaluating. As it happens, there are many more kinds of truth than there are of nontruth.

Truth in Perl is always evaluated in a scalar context. Other than that, no type coercion is done. So here are the rules for the various kinds of values a scalar can hold:

  1. Any string is true except for "" and "0".

  2. Any number is true except for 0.

  3. Any reference is true.

  4. Any undefined value is false.

Actually, the last two rules can be derived from the first two. Any reference (rule 3) would point to something with an address and would evaluate to a number or string containing that address, which is never 0 because it's always defined. And any undefined value (rule 4) would always evaluate to 0 or the null string.

And in a way, you can derive rule 2 from rule 1 if you pretend that everything is a string. Again, no string coercion is actually done to evaluate truth, but if the string coercion were done, then any numeric value of 0 would simply turn into the string "0" and be false. Any other number would not turn into the string "0", and so would be true. Let's look at some examples so we can understand this better:

0          # would become the string "0", so false.
1          # would become the string "1", so true.
10 - 10    # 10 minus 10 is 0, would convert to string "0", so false.
0.00       # equals 0, would convert to string "0", so false.
"0"        # is the string "0", so false.
""         # is a null string, so false.
"0.00"     # is the string "0.00", neither "" nor "0", so true!
"0.00" + 0 # would become the number 0 (coerced by the +), so false.
\$a        # is a reference to $a, so true, even if $a is false.
undef()    # is a function returning the undefined value, so false.
Since we mumbled something earlier about truth being evaluated in a scalar context, you might be wondering what the truth value of a list is. Well, the simple fact is, none of the operations in Perl will return a list in a scalar context. They'll all notice they're in a scalar context and return a scalar value instead, and then you apply the rules of truth to that scalar. So there's no problem, as long as you can figure out what any given operator will return in a scalar context. As it happens, both arrays and hashes return scalar values that conveniently happen to be true if the array or hash contains any elements. More on that later.

1.6.1.1. The if and unless statements

We saw earlier how a logical operator could function as a conditional. A slightly more complex form of the logical operators is the if statement. The if statement evaluates a truth condition (that is, a Boolean expression) and executes a block if the condition is true:

if ($debug_level > 0) {
    # Something has gone wrong.  Tell the user.
    print "Debug: Danger, Will Robinson, danger!\n";
    print "Debug: Answer was '54', expected '42'.\n";
}
A block is one or more statements grouped together by a set of braces. Since the if statement executes a block, the braces are required by definition. If you know a language like C, you'll notice that this is different. Braces are optional in C if you have a single statement, but the braces are not optional in Perl.

Sometimes, just executing a block when a condition is met isn't enough. You may also want to execute a different block if that condition isn't met. While you could certainly use two if statements, one the negation of the other, Perl provides a more elegant solution. After the block, if can take an optional second condition, called else, to be executed only if the truth condition is false. (Veteran computer programmers will not be surprised at this point.)

At times you may even have more than two possible choices. In this case, you'll want to add an elsif truth condition for the other possible choices. (Veteran computer programmers may well be surprised by the spelling of "elsif", for which nobody here is going to apologize. Sorry.)

if ($city eq "New York") {
    print "New York is northeast of Washington, D.C.\n";
}
elsif ($city eq "Chicago") {
    print "Chicago is northwest of Washington, D.C.\n";
}
elsif ($city eq "Miami") {
    print "Miami is south of Washington, D.C.  And much warmer!\n";
}
else {
    print "I don't know where $city is, sorry.\n";
}

The if and elsif clauses are each computed in turn, until one is found to be true or the else condition is reached. When one of the conditions is found to be true, its block is executed and all remaining branches are skipped. Sometimes, you don't want to do anything if the condition is true, only if it is false. Using an empty if with an else may be messy, and a negated if may be illegible; it sounds weird in English to say "if not this is true, do something". In these situations, you would use the unless statement:

unless ($destination eq $home) {
    print "I'm not going home.\n";
}
There is no elsunless though. This is generally construed as a feature.

1.6.2. Iterative (Looping) Constructs

Perl has four main iterative statement types: while, until, for, and foreach. These statements allow a Perl program to repeatedly execute the same code.

1.6.2.1. The while and until statements

The while and until statements behave just like the if and unless statements, except that they'll execute the block repeatedly. That is, they loop. First, the conditional part of the statement is checked. If the condition is met (if it is true for a while or false for an until), the block of the statement is executed.

while ($tickets_sold < 10000) {
    $available = 10000 - $tickets_sold;
    print "$available tickets are available.  How many would you like: ";
    $purchase = <STDIN>;
    chomp($purchase);
    $tickets_sold += $purchase;
}
Note that if the original condition is never met, the loop will never be entered at all. For example, if we've already sold 10,000 tickets, we might want to have the next line of the program say something like:
print "This show is sold out, please come back later.\n";
In our Average Example earlier, line 4 reads:
while ($line = <GRADES>) {
This assigns the next line to the variable $line and, as we explained earlier, returns the value of $line so that the condition of the while statement can evaluate $line for truth. You might wonder whether Perl will get a false negative on blank lines and exit the loop prematurely. The answer is that it won't. The reason is clear if you think about everything we've said. The line input operator leaves the newline on the end of the string, so a blank line has the value "\n". And you know that "\n" is not one of the canonical false values. So the condition is true, and the loop continues even on blank lines.

On the other hand, when we finally do reach the end of the file, the line input operator returns the undefined value, which always evaluates to false. And the loop terminates, just when we wanted it to. There's no need for an explicit test of the eof function in Perl, because the input operators are designed to work smoothly in a conditional context.

In fact, almost everything is designed to work smoothly in a conditional (Boolean) context. If you mention an array in a scalar context, the length of the array is returned. So you often see command-line arguments processed like this:

while (@ARGV) {
    process(shift @ARGV);
}
The shift operator removes one element from the argument list each time through the loop (and returns that element). The loop automatically exits when array @ARGV is exhausted, that is, when its length goes to 0. And 0 is already false in Perl. In a sense, the array itself has become "false".[21]

[21] This is how Perl programmers think. So there's no need to compare 0 to 0 to see if it's false. Despite the fact that other languages force you to, don't go out of your way to write explicit comparisons like while (@ARGV != 0). That's just inefficient for both you and the computer. And anyone who has to maintain your code.

1.6.2.2. The for statement

Another iterative statement is the for loop. The for loop runs exactly like the while loop, but looks a good deal different. (C programmers will find it very familiar though.)

for ($sold = 0; $sold < 10000; $sold += $purchase) {
    $available = 10000 - $sold;
    print "$available tickets are available.  How many would you like: ";
    $purchase = <STDIN>;
    chomp($purchase);
}
This for loop takes three expressions within the loop's parentheses: an expression to set the initial state of the loop variable, a condition to test the loop variable, and an expression to modify the state of the loop variable. When a for loop starts, the initial state is set and the truth condition is checked. If the condition is true, the block is executed. When the block finishes, the modification expression is executed, the truth condition is again checked, and if true, the block is rerun with the next value. As long as the truth condition remains true, the block and the modification expression will continue to be executed. (Note that only the middle expression is evaluated for its value. The first and third expressions are evaluated only for their side effects, and the resulting values are thrown away!)

1.6.2.3. The foreach statement

The last of Perl's iterative statements is the foreach statement, which is used to execute the same code for each of a known set of scalars, such as an array:

foreach $user (@users) {
    if (-f "$home{$user}/.nexrc") {
        print "$user is cool... they use a perl-aware vi!\n";
    }
}
Unlike the if and while statements, which provide scalar context to a conditional expression, the foreach statement provides a list context to the expression in parentheses. So the expression is evaluated to produce a list (not a scalar, even if there's only one scalar in the list). Then each element of the list is aliased to the loop variable in turn, and the block of code is executed once for each list element. Note that the loop variable refers to the element itself, rather than a copy of the element. Hence, modifying the loop variable also modifies the original array.

You'll find many more foreach loops in the typical Perl program than for loops, because it's very easy in Perl to generate the kinds of lists that foreach wants to iterate over. One idiom you'll often see is a loop to iterate over the sorted keys of a hash:

foreach $key (sort keys %hash) {
In fact, line 9 of our Average Example does precisely that.

1.6.2.4. Breaking out: next and last

The next and last operators allow you to modify the flow of your loop. It is not at all uncommon to have a special case; you may want to skip it, or you may want to quit when you encounter it. For example, if you are dealing with Unix accounts, you may want to skip the system accounts (like root or lp). The next operator would allow you to skip to the end of your current loop iteration, and start the next iteration. The last operator would allow you to skip to the end of your block, as if your loop's test condition had returned false. This might be useful if, for example, you are looking for a specific account and want to quit as soon as you find it.

foreach $user (@users) {
    if ($user eq "root" or $user eq "lp") {
        next;
    }
    if ($user eq "special") {
        print "Found the special account.\n";
        # do some processing
        last;
    }
}
It's possible to break out of multilevel loops by labeling your loops and specifying which loop you want to break out of. Together with statement modifiers (another form of conditional which we'll talk about later), this can make for extremely readable loop exits (if you happen to think English is readable):
LINE: while ($line = <ARTICLE>) {
    last LINE if $line eq "\n"; # stop on first blank line
    next LINE if $line =~ /^#/; # skip comment lines
    # your ad here
}

You may be saying, "Wait a minute, what's that funny ^# thing there inside the leaning toothpicks? That doesn't look much like English." And you're right. That's a pattern match containing a regular expression (albeit a rather simple one). And that's what the next section is about. Perl is the best text processing language in the world, and regular expressions are at the heart of Perl's text processing.

Previous | Home | Next
1.5. Operators | Book Index | 1.7. Regular Expressions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.7. Regular Expressions

Regular expressions (a.k.a. regexes, regexps, or REs) are used by many search programs such as grep and findstr, text-munging programs like sed and awk, and editors like vi and emacs. A regular expression is a way of describing a set of strings without having to list all the strings in your set.[22]

[22] A good source of information on regular expression concepts is Jeffrey Friedl's book, Mastering Regular Expressions (O'Reilly & Associates).

Many other computer languages incorporate regular expressions (some of them even advertise "Perl5 regular expressions"!), but none of these languages integrates regular expressions into the language the way Perl does. Regular expressions are used several ways in Perl. First and foremost, they're used in conditionals to determine whether a string matches a particular pattern, because in a Boolean context they return true and false. So when you see something that looks like /foo/ in a conditional, you know you're looking at an ordinary pattern-matching operator:

if (/Windows 95/) { print "Time to upgrade?\n" }

Second, if you can locate patterns within a string, you can replace them with something else. So when you see something that looks like s/foo/bar/, you know it's asking Perl to substitute "bar" for "foo", if possible. We call that the substitution operator. It also happens to return true or false depending on whether it succeeded, but usually it's evaluated for its side effect:

s/Windows/Linux/;

Finally, patterns can specify not only where something is, but also where it isn't. So the split operator uses a regular expression to specify where the data isn't. That is, the regular expression defines the separators that delimit the fields of data. Our Average Example has a couple of trivial examples of this. Lines 5 and 12 each split strings on the space character in order to return a list of words. But you can split on any separator you can specify with a regular expression:

($good, $bad, $ugly) = split(/,/, "vi,emacs,teco");
(There are various modifiers you can use in each of these situations to do exotic things like ignore case when matching alphabetic characters, but these are the sorts of gory details that we'll cover later when we get to the gory details.)

The simplest use of regular expressions is to match a literal expression. In the case of the split above, we matched on a single comma character. But if you match on several characters in a row, they all have to match sequentially. That is, the pattern looks for a substring, much as you'd expect. Let's say we want to show all the lines of an HTML file that contain HTTP links (as opposed to FTP links). Let's imagine we're working with HTML for the first time, and we're being a little naïve. We know that these links will always have "http:" in them somewhere. We could loop through our file with this:

while ($line = <FILE>) {
    if ($line =~ /http:/) {
        print $line;
    }
}
Here, the =~ (pattern-binding operator) is telling Perl to look for a match of the regular expression "http:" in the variable $line. If it finds the expression, the operator returns a true value and the block (a print statement) is executed.[23]

[23] This is very similar to what the Unix command grep 'http:' file would do. On MS-DOS you could use the find command, but it doesn't know how to do more complicated regular expressions. (However, the misnamed findstr program of Windows NT does know about regular expressions.)

By the way, if you don't use the =~ binding operator, Perl will search a default string instead of $line. It's like when you say, "Eek! Help me find my contact lens!" People automatically know to look around near you without your actually having to tell them that. Likewise, Perl knows that there is a default place to search for things when you don't say where to search for them. This default string is actually a special scalar variable that goes by the odd name of $_. In fact, it's not the default just for pattern matching; many operators in Perl default to using the $_ variable, so a veteran Perl programmer would likely write the last example as:

while (<FILE>) {
    print if /http:/;
}
(Hmm, another one of those statement modifiers seems to have snuck in there. Insidious little beasties.)

This stuff is pretty handy, but what if we wanted to find all of the link types, not just the HTTP links? We could give a list of link types, like "http:", "ftp:", "mailto:", and so on. But that list could get long, and what would we do when a new kind of link was added?

while (<FILE>) {
    print if /http:/;
    print if /ftp:/;
    print if /mailto:/;
    # What next?
}

Since regular expressions are descriptive of a set of strings, we can just describe what we are looking for: a number of alphabetic characters followed by a colon. In regular expression talk (Regexese?), that would be /[a-zA-Z]+:/, where the brackets define a character class. The a-z and A-Z represent all alphabetic characters (the dash means the range of all characters between the starting and ending character, inclusive). And the + is a special character that says "one or more of whatever was before me". It's what we call a quantifier, meaning a gizmo that says how many times something is allowed to repeat. (The slashes aren't really part of the regular expression, but rather part of the pattern-match operator. The slashes are acting like quotes that just happen to contain a regular expression.)

Because certain classes like the alphabetics are so commonly used, Perl defines shortcuts for them:

Name | ASCII Definition | Code
Whitespace | [ \t\n\r\f] | \s
Word character | [a-zA-Z_0-9] | \w
Digit | [0-9] | \d

Note that these match single characters. A \w will match any single word character, not an entire word. (Remember that + quantifier? You can say \w+ to match a word.) Perl also provides the negation of these classes by using the uppercased character, such as \D for a nondigit character.

We should note that \w is not always equivalent to [a-zA-Z_0-9] (and \d is not always [0-9]). Some locales define additional alphabetic characters outside the ASCII sequence, and \w respects them. Newer versions of Perl also know about Unicode letter and digit properties and treat Unicode characters with those properties accordingly. (Perl also considers ideographs to be \w characters.)

There is one other very special character class, written with a ".", that will match any character whatsoever.[24] For example, /a./ will match any string containing an "a" that is not the last character in the string. Thus it will match "at" or "am" or even "a!", but not "a", since there's nothing after the "a" for the dot to match. Since it's searching for the pattern anywhere in the string, it'll match "oasis" and "camel", but not "sheba". It matches "caravan" on the first "a". It could match on the second "a", but it stops after it finds the first suitable match, searching from left to right.

[24] Except that it won't normally match a newline. When you think about it, a "." doesn't normally match a newline in grep(1) either.

1.7.1. Quantifiers

The characters and character classes we've talked about all match single characters. We mentioned that you could match multiple "word" characters with \w+. The + is one kind of quantifier, but there are others. All of them are placed after the item being quantified.

The most general form of quantifier specifies both the minimum and maximum number of times an item can match. You put the two numbers in braces, separated by a comma. For example, if you were trying to match North American phone numbers, the sequence \d{7,11} would match at least seven digits, but no more than eleven digits. If you put a single number in the braces, the number specifies both the minimum and the maximum; that is, the number specifies the exact number of times the item can match. (All unquantified items have an implicit {1} quantifier.)

If you put the minimum and the comma but omit the maximum, then the maximum is taken to be infinity. In other words, it will match at least the minimum number of times, plus as many as it can get after that. For example, \d{7} will match only the first seven digits (a local North American phone number, for instance, or the first seven digits of a longer number), while \d{7,} will match any phone number, even an international one (unless it happens to be shorter than seven digits). There is no special way of saying "at most" a certain number of times. Just say .{0,5}, for example, to find at most five arbitrary characters.

Certain combinations of minimum and maximum occur frequently, so Perl defines special quantifiers for them. We've already seen +, which is the same as {1,}, or "at least one of the preceding item". There is also *, which is the same as {0,}, or "zero or more of the preceding item", and ?, which is the same as {0,1}, or "zero or one of the preceding item" (that is, the preceding item is optional).

You need to be careful of a couple things about quantification. First of all, Perl quantifiers are by default greedy. This means that they will attempt to match as much as they can as long as the whole pattern still matches. For example, if you are matching /\d+/ against "1234567890", it will match the entire string. This is something to watch out for especially when you are using ".", any character. Often, someone will have a string like:

larry:JYHtPh0./NJTU:100:10:Larry Wall:/home/larry:/bin/tcsh
and will try to match "larry:" with /.+:/. However, since the + quantifier is greedy, this pattern will match everything up to and including "/home/larry:", because it matches as much as possible before the last colon, including all the other colons. Sometimes you can avoid this by using a negated character class, that is, by saying /[^:]+:/, which says to match one or more noncolon characters (as many as possible), up to the first colon. It's that little caret in there that negates the Boolean sense of the character class.[25] The other point to be careful about is that regular expressions will try to match as early as possible. This even takes precedence over being greedy. Since scanning happens left-to-right, this means that the pattern will match as far left as possible, even if there is some other place where it could match longer. (Regular expressions may be greedy, but they aren't into delayed gratification.) For example, suppose you're using the substitution command (s///) on the default string (variable $_, that is), and you want to remove a string of x's from the middle of the string. If you say:
$_ = "fred xxxxxxx barney";
s/x*//;
it will have absolutely no effect! This is because the x* (meaning zero or more "x" characters) will be able to match the "nothing" at the beginning of the string, since the null string happens to be zero characters wide and there's a null string just sitting there plain as day before the "f" of "fred".[26]

[25] Sorry, we didn't pick that notation, so don't blame us. That's just how negated character classes are customarily written in Unix culture.

[26] Don't feel bad. Even the authors get caught by this from time to time.

There's one other thing you need to know. By default, quantifiers apply to a single preceding character, so /bam{2}/ will match "bamm" but not "bambam". To apply a quantifier to more than one character, use parentheses. So to match "bambam", use the pattern /(bam){2}/.

1.7.2. Minimal Matching

If you were using an ancient version of Perl and you didn't want greedy matching, you had to use a negated character class. (And really, you were still getting greedy matching of a constrained variety.)

In modern versions of Perl, you can force nongreedy, minimal matching by placing a question mark after any quantifier. Our same username match would now be /.*?:/. That .*? will now try to match as few characters as possible, rather than as many as possible, so it stops at the first colon rather than at the last.

1.7.3. Nailing Things Down

Whenever you try to match a pattern, it's going to try to match in every location till it finds a match. An anchor allows you to restrict where the pattern can match. Essentially, an anchor is something that matches a "nothing", but a special kind of nothing that depends on its surroundings. You could also call it a rule, or a constraint, or an assertion. Whatever you care to call it, it tries to match something of zero width, and either succeeds or fails. (Failure merely means that the pattern can't match that particular way. The pattern will go on trying to match some other way, if there are any other ways left to try.)

The special symbol \b matches at a word boundary, which is defined as the "nothing" between a word character (\w) and a nonword character (\W), in either order. (The characters that don't exist off the beginning and end of your string are considered to be nonword characters.) For example,

/\bFred\b/
would match "Fred" in both "The Great Fred" and "Fred the Great", but not in "Frederick the Great" because the "d" in "Frederick" is not followed by a nonword character.

In a similar vein, there are also anchors for the beginning of the string and the end of the string. If it is the first character of a pattern, the caret (^) matches the "nothing" at the beginning of the string. Therefore, the pattern /^Fred/ would match "Fred" in "Frederick the Great" but not in "The Great Fred", whereas /Fred^/ wouldn't match either. (In fact, it doesn't even make much sense.) The dollar sign ($) works like the caret, except that it matches the "nothing" at the end of the string instead of the beginning.[27]

[27] This is a bit oversimplified, since we're assuming here that your string contains no newlines; ^ and $ are actually anchors for the beginnings and endings of lines rather than strings. We'll try to straighten this all out in Chapter 5, "Pattern Matching" (to the extent that it can be straightened out).

So now you can probably figure out that when we said:

next LINE if $line =~ /^#/;
we meant "Go to the next iteration of LINE loop if this line happens to begin with a # character."

Earlier we said that the sequence \d{7,11} would match a number from seven to eleven digits long. While strictly true, the statement is misleading: when you use that sequence within a real pattern match operator such as /\d{7,11}/, it does not preclude there being extra unmatched digits after the 11 matched digits! You often need to anchor quantified patterns on either or both ends to get what you expect.

1.7.4. Backreferences

We mentioned earlier that you can use parentheses to group things for quantifiers, but you can also use parentheses to remember bits and pieces of what you matched. A pair of parentheses around a part of a regular expression causes whatever was matched by that part to be remembered for later use. It doesn't change what the part matches, so /\d+/ and /(\d+)/ will still match as many digits as possible, but in the latter case they will be remembered in a special variable to be backreferenced later.

How you refer back to the remembered part of the string depends on where you want to do it from. Within the same regular expression, you use a backslash followed by an integer. The integer corresponding to a given pair of parentheses is determined by counting left parentheses from the beginning of the pattern, starting with one. So for example, to match something similar to an HTML tag like "<B>Bold</B>", you might use /<(.*?)>.*?<\/\1>/. This forces the two parts of the pattern to match the exact same string, such as the "B" in this example.

Outside the regular expression itself, such as in the replacement part of a substitution, you use a $ followed by an integer, that is, a normal scalar variable named by the integer. So, if you wanted to swap the first two words of a string, for example, you could use:

s/(\S+)\s+(\S+)/$2 $1/

The right side of the substitution (between the second and third slashes) is mostly just a funny kind of double-quoted string, which is why you can interpolate variables there, including backreference variables. This is a powerful concept: interpolation (under controlled circumstances) is one of the reasons Perl is a good text-processing language. The other reason is the pattern matching, of course. Regular expressions are good for picking things apart, and interpolation is good for putting things back together again. Perhaps there's hope for Humpty Dumpty after all.

Previous | Home | Next
1.6. Control Structures | Book Index | 1.8. List Processing
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.8. List Processing

Much earlier in this chapter, we mentioned that Perl has two main contexts, scalar context (for dealing with singular things) and list context (for dealing with plural things). Many of the traditional operators we've described so far have been strictly scalar in their operation. They always take singular arguments (or pairs of singular arguments for binary operators) and always produce a singular result, even in list context. So if you write this:

@array = (1 + 2, 3 - 4, 5 * 6, 7 / 8);
you know that the list on the right side contains exactly four values, because the ordinary math operators always produce scalar values, even in the list context provided by the assignment to an array.

However, other Perl operators can produce either a scalar or a list value, depending on their context. They just "know" whether a scalar or a list is expected of them. But how will you know that? It turns out to be pretty easy to figure out, once you get your mind around a few key concepts.

First, list context has to be provided by something in the "surroundings". In the previous example, the list assignment provides it. Earlier we saw that the list of a foreach loop provides it. The print operator also provides it. But you don't have to learn these one by one.

If you look at the various syntax summaries scattered throughout the rest of the book, you'll see various operators that are defined to take a LIST as an argument. Those are the operators that provide a list context. Throughout this book, LIST is used as a specific technical term to mean "a syntactic construct that provides a list context". For example, if you look up sort, you'll find the syntax summary:

sort LIST
That means that sort provides a list context to its arguments.

Second, at compile time (that is, while Perl is parsing your program and translating to internal opcodes), any operator that takes a LIST provides a list context to each syntactic element of that LIST. So every top-level operator or entity in the LIST knows at compile time that it's supposed to produce the best list it knows how to produce. This means that if you say:

sort @dudes, @chicks, other();
then each of @dudes, @chicks, and other() knows at compile time that it's supposed to produce a list value rather than a scalar value. So the compiler generates internal opcodes that reflect this.

Later, at run time (when the internal opcodes are actually interpreted), each of those LIST elements produces its list in turn, and then (this is important) all the separate lists are joined together, end to end, into a single list. And that squashed-flat, one-dimensional list is what is finally handed off to the function that wanted the LIST in the first place. So if @dudes contains (Fred,Barney), @chicks contains (Wilma,Betty), and the other() function returns the single-element list (Dino), then the LIST that sort sees is:

(Fred,Barney,Wilma,Betty,Dino)
and the LIST that sort returns is:
(Barney,Betty,Dino,Fred,Wilma)

Some operators produce lists (like keys), while some consume them (like print), and others transform lists into other lists (like sort). Operators in the last category can be considered filters, except that, unlike in the shell, the flow of data is from right to left, since list operators operate on arguments passed in from the right. You can stack up several list operators in a row:

print reverse sort map {lc} keys %hash;
That takes the keys of %hash and returns them to the map function, which lowercases all the keys by applying the lc operator to each of them, and passes them to the sort function, which sorts them, and passes them to the reverse function, which reverses the order of the list elements, and passes them to the print function, which prints them.

As you can see, that's much easier to describe in Perl than in English.

There are many other ways in which list processing produces more natural code. We can't enumerate all the ways here, but for an example, let's go back to regular expressions for a moment. We talked about using a pattern in a scalar context to see whether it matched, but if instead you use a pattern in a list context, it does something else: it pulls out all the backreferences as a list. Suppose you're searching through a log file or a mailbox, and you want to parse a string containing a time of the form "12:59:59 am". You might say this:

($hour, $min, $sec, $ampm) = /(\d+):(\d+):(\d+) *(\w+)/;
That's a convenient way to set several variables simultaneously. But you could just as easily say
@hmsa = /(\d+):(\d+):(\d+) *(\w+)/;
and put all four values into one array. Oddly, by decoupling the power of regular expressions from the power of Perl expressions, list context increases the power of the language. We don't often admit it, but Perl is actually an orthogonal language in addition to being a diagonal language. Have your cake, and eat it too.

Previous | Home | Next
1.7. Regular Expressions | Book Index | 1.9. What You Don't Know Won't Hurt You (Much)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


1.9. What You Don't Know Won't Hurt You (Much)

Finally, allow us to return once more to the concept of Perl as a natural language. Speakers of a natural language are allowed to have differing skill levels, to speak different subsets of the language, to learn as they go, and generally, to put the language to good use before they know the whole language. You don't know all of Perl yet, just as you don't know all of English. But that's Officially Okay in Perl culture. You can work with Perl usefully, even though we haven't even told you how to write your own subroutines yet. We've scarcely begun to explain how to view Perl as a system management language, or a rapid prototyping language, or a networking language, or an object-oriented language. We could write entire chapters about some of these things. (Come to think of it, we already did.)

But in the end, you must create your own view of Perl. It's your privilege as an artist to inflict the pain of creativity on yourself. We can teach you how we paint, but we can't teach you how you paint. There's More Than One Way To Do It.

Have the appropriate amount of fun.

Previous | Home | Next
1.8. List Processing | Book Index | Part 2. The Gory Details
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part II. The Gory Details

Chapter 2: Bits and Pieces
Chapter 3: Unary and Binary Operators
Chapter 4: Statements and Declarations
Chapter 5: Pattern Matching
Chapter 6: Subroutines
Chapter 7: Formats
Chapter 8: References
Chapter 9: Data Structures
Chapter 10: Packages
Chapter 11: Modules
Chapter 12: Objects
Chapter 13: Overloading
Chapter 14: Tied Variables

Previous | Home | Next
1.9. What You Don't Know Won't Hurt You (Much) | Book Index | 2. Bits and Pieces
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 2. Bits and Pieces

Contents:

Atoms
Molecules
Built-in Data Types
Variables
Names
Scalar Values
Context
List Values and Arrays
Hashes
Typeglobs and Filehandles
Input Operators

We're going to start small, so this chapter is about the elements of Perl.

Since we're starting small, the progression through the next several chapters is necessarily from small to large. That is, we take a bottom-up approach, beginning with the smallest components of Perl programs and building them into more elaborate structures, much like molecules are built out of atoms. The disadvantage of this approach is that you don't necessarily get the Big Picture before getting lost in a welter of details. The advantage is that you can understand the examples as we go along. (If you're a top-down person, just turn the book over and read the chapters backward.)

Each chapter does build on the preceding chapter (or the subsequent chapter, if you're reading backward), so you'll need to be careful if you're the sort of person who skips around.

You're certainly welcome to peek at the reference materials toward the end of the book as we go along. (That doesn't count as skipping around.) In particular, any isolated word in typewriter font is likely to be found in Chapter 29, "Functions". And although we've tried to stay operating-system neutral, if you are unfamiliar with Unix terminology and run into a word that doesn't seem to mean what you think it ought to mean, you should check whether the word is in the Glossary. If the Glossary doesn't work, the index probably will.

2.1. Atoms

Although there are various invisible things going on behind the scenes that we'll explain presently, the smallest things you generally work with in Perl are individual characters. And we do mean characters; historically, Perl freely confused bytes with characters and characters with bytes, but in this new era of global networking, we must be careful to distinguish the two.

Perl may, of course, be written entirely in the 7-bit ASCII character set. Perl also allows you to write in any 8-bit or 16-bit character set, whether it's a national character set or some other legacy character set. However, if you choose to write in one of these older, non-ASCII character sets, you may use non-ASCII characters only within string literals. You are responsible for making sure that the semantics of your program are consistent with the particular national character set you've chosen. For instance, if you're using a 16-bit encoding for an Asian national character set, keep in mind that Perl will generally think of each of your characters as two bytes, not as one character.

As described in Chapter 15, "Unicode", we've recently added support for Unicode to Perl.[1] This support is pervasive throughout the language: you can use Unicode characters in identifiers (variable names and such) as well as within literal strings. When you are using Unicode, you don't need to worry about how many bits or bytes it takes to represent a character. Perl just pretends all Unicode characters are the same size (that is, size 1), even though any given character might be represented by multiple bytes internally. Perl normally represents Unicode internally as UTF-8, a variable-length encoding. (For instance, a Unicode smiley character, U-263A, would be represented internally as a three-byte sequence.)

[1] As excited as we are about Unicode support, most of our examples will be in ASCII, since not everyone has a decent Unicode editor yet.

If you'll let us drive our analogy of the physical elements a bit further, characters are atomic in the same sense as the individual atoms of the various elements. Yes, they're composed of smaller particles known as bits and bytes, but if you break a character apart (in a character accelerator, no doubt), the individual bits and bytes lose the distinguishing chemical properties of the character as a whole. Just as neutrons are an implementation detail of the U-238 atom, so too bytes are an implementation detail of the U-263A character.

So we'll be careful to say "characters" when we mean characters, and "bytes" when we mean bytes. But we don't mean to scare you--you can still do the good old-fashioned byte processing easily enough. All you have to do is tell Perl that you still want to think of bytes as characters. You can do that with a use bytes pragma (see Chapter 31, "Pragmatic Modules"). But even if you don't do that, Perl will still do a pretty good job of keeping small characters in 8 bits when you expect it to.

So don't sweat the small stuff. Let's move on to bigger and better things.

Previous | Home | Next
 | 2.2. Molecules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.2. Molecules

Perl is a free-form language, but that doesn't mean that Perl is totally free of form. As computer folks usually use the term, a free-form language is one in which you can put spaces, tabs, and newlines anywhere you like--except where you can't.

One obvious place you can't put a whitespace character is in the middle of a token. A token is what we call a sequence of characters with a unit of meaning, much like a simple word in natural language. But unlike the typical word, a token might contain other characters besides letters, just as long as they hang together to form a unit of meaning. (In that sense, they're more like molecules, which don't have to be composed of only one particular kind of atom.) For example, numbers and mathematical operators are considered tokens. An identifier is a token that starts with a letter or underscore and contains only letters, digits, and underscores. A token may not contain whitespace characters because this would split the token into two tokens, just as a space in an English word turns it into two words.[2]

[2] The astute reader will point out that literal strings may contain whitespace characters. But strings can get away with it only because they have quotes on both ends to keep the spaces from leaking out.

Although whitespace is allowed between any two tokens, whitespace is required only between tokens that would otherwise be confused as a single token. All whitespace is equivalent for this purpose. Newlines are distinguished from spaces and tabs only within quoted strings, formats, and certain line-oriented forms of quoting. Specifically, newlines do not terminate statements as they do in certain other languages (such as FORTRAN or Python). Statements in Perl are terminated with semicolons, just as they are in C and its various derivatives.

Unicode whitespace characters are allowed in a Unicode Perl program, but you need to be careful. If you use the special Unicode paragraph and line separators, be aware that Perl may count line numbers differently than your text editor does, so error messages may be more difficult to interpret. It's best to stick with good old-fashioned newlines.

Tokens are recognized greedily; if at a particular point the Perl parser has a choice between recognizing a short token or a long token, it will choose the long one. If you meant it to be two tokens, just insert some whitespace between the tokens. (We tend to put extra space around most operators anyway, just for readability.)

Comments are indicated by the # character and extend from there through the end of the line. A comment counts as whitespace for separating tokens. The Perl language attaches no special meaning to anything you might put into a comment.[3]

[3] Actually, that's a small fib. The Perl parser does look for command-line switches on an initial #! line (see Chapter 19, "The Command-Line Interface"). It can also interpret the line number directives that various preprocessors produce (see the section Section 2.5.2, "Generating Perl in Other Languages" in Chapter 24, "Common Practices").

One other oddity is that if a line begins with = anywhere a statement would be legal, Perl ignores everything from that line down to the next line that begins with =cut. The ignored text is assumed to be pod, or "plain old documentation". The Perl distribution has programs that will extract pod commentary from Perl modules and turn it into flat text, manpages, [LaTeX], HTML, or (someday soon) XML documents. In a complementary fashion, the Perl parser extracts the Perl code from Perl modules and ignores the pod. So you may consider this an alternate, multiline form of commenting. You may also consider it completely nuts, but Perl modules documented this way never lose track of their documentation. See Chapter 26, "Plain Old Documentation", for details on pod, including a description of how to effect multiline comments in Perl.

But don't look down on the normal comment character. There's something comforting about the visual effect of a nice row of # characters down the left side of a multiline comment. It immediately tells your eyes: "This is not code." You'll note that even in languages with a multiline quoting mechanisms like C, people often put a row of * characters down the left side of their comments anyway. Appearances are often more important than they appear.

In Perl, just as in chemistry and in language, you can build larger and larger structures out of the smaller ones. We already mentioned the statement; it's just a sequence of tokens that make up a command, that is, a sentence in the imperative mood. You can combine a sequence of statements into a block that is delimited by braces (also known affectionately as "curlies" by people who confuse braces with suspenders.) Blocks can in turn be combined into larger blocks. Some blocks function as subroutines, which can be combined into modules, which can be combined into programs. But we're getting ahead of ourselves--those are subjects for coming chapters. Let's build some more tokens out of characters.

Previous | Home | Next
2.1. Atoms | Book Index | 2.3. Built-in Data Types
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.3. Built-in Data Types

Before we start talking about various kinds of tokens you can build from characters, we need a few more abstractions. To be specific, we need three data types.

Computer languages vary in how many and what kinds of data types they provide. Unlike some commonly used languages that provide many confusing types for similar kinds of values, Perl provides just a few built-in data types. Consider C, in which you might run into char, short, int, long, long long, bool, wchar_t, size_t, off_t, regex_t, uid_t, u_longlong_t, pthread_key_t, fp_exception_field_type, and so on. That's just some of the integer types! Then there are floating-point numbers, and pointers, and strings.

All these complicated types correspond to just one type in Perl: the scalar. (Usually Perl's simple data types are all you need, but if not, you're free to define fancy dynamic types using Perl's object-oriented features--see Chapter 12, "Objects".) Perl's three basic data types are: scalars, arrays of scalars, and hashes of scalars (also known as associative arrays). Some people may prefer to call these data structures rather than types. That's okay.

Scalars are the fundamental type from which more complicated structures are built. A scalar stores a single, simple value--typically a string or a number. Elements of this simple type may be combined into either of the two aggregate types. An array is an ordered list of scalars that you access with an integer subscript (or index). All indexing in Perl starts at 0. Unlike many programming languages, however, Perl treats negative subscripts as valid: instead of counting from the beginning, negative subscripts count back from the end of whatever it is you're indexing into. (This applies to various substring and sublist operations as well as to regular subscripting.) A hash, on the other hand, is an unordered set of key/value pairs that you access using strings (the keys) as subscripts to look up the scalars (the values) corresponding to a given key. Variables are always one of these three types. (Other than variables, Perl also has other abstractions that you can think of as data types, such as filehandles, directory handles, formats, subroutines, symbol tables, and symbol table entries.)

Abstractions are wonderful, and we'll collect more of them as we go along, but they're also useless in a way. You can't do anything with an abstraction directly. That's why computer languages have syntax. We need to introduce you to the various kinds of syntactic terms you can use to pull your abstract data into expressions. We like to use the technical term term when we want to talk in terms of these syntactic units. (Hmm, this could get terminally confusing. Just remember how your math teacher used to talk about the terms of an equation, and you won't go terribly wrong.)

Just like the terms in a math equation, the purpose of most terms in Perl is to produce values for operators like addition and multiplication to operate on. Unlike in a math equation, however, Perl has to do something with the values it calculates, not just think with a pencil in its hand about whether the two sides of the equation are equal. One of the most common things to do with a value is to store it somewhere:

$x = $y;

That's an example of the assignment operator (not the numeric equality operator, which is spelled == in Perl). The assignment gets the value from $y and puts it into $x. Notice that we aren't using the term $x for its value; we're using it for its location. (The old value of $x gets clobbered by the assignment.) We say that $x is an lvalue, meaning it's the sort of storage location we can use on the left side of an assignment. We say that $y is an rvalue because it's used on the right side.

There's also a third kind of value, called a temporary value, that you need to understand if you want to know what Perl is really doing with your lvalues and rvalues. If we do some actual math and say:

$x = $y + 1;
Perl takes the rvalue $y and adds the rvalue 1 to it, which produces a temporary value that is eventually assigned to the lvalue $x. It may help you to visualize what is going on if we tell you that Perl stores these temporary values in an internal structure called a stack.[4] The terms of an expression (the ones we're talking about in this chapter) tend to push values onto the stack, while the operators of the expression (which we'll discuss in the next chapter) tend to pop them back off the stack, perhaps leaving another temporary result on the stack for the next operator to work with. The pushes and pops all balance out--by the time the expression is done, the stack is entirely empty (or as empty as it was when we started). More about temporary values later.

[4] A stack works just like one of those spring-loaded plate dispensers you see in a buffet restaurant--you can push plates onto the top of the stack, or you can pop them off again (to use the Comp. Sci. vernacular).

Some terms can only be rvalues, such as the 1 above, while others can serve as either lvalues or rvalues. In particular, as the assignments above illustrate, a variable may function as either. And that's what our next section is about.

Previous | Home | Next
2.2. Molecules | Book Index | 2.4. Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.4. Variables

Not surprisingly, there are three variable types corresponding to the three abstract data types we mentioned earlier. Each of these is prefixed by what we call a funny character.[5] Scalar variables are always named with an initial $, even when referring to a scalar that is part of an array or hash. It works a bit like the English word "the". Thus, we have:

[5] That's another technical term in computer science. (And if it wasn't before, it is now.)

Construct | Meaning
$days | Simple scalar value $days
$days[28] | 29th element of array @days
$days{'Feb'} | "Feb" value from hash %days

Note that we can use the same name for $days, @days, and %days without Perl getting confused.

There are other, fancier scalar terms, useful in specialized situations that we won't go into yet. They look like this:

Construct | Meaning
${days} | Same as $days but unambiguous before alphanumerics
$Dog::days | Different $days variable, in the Dog package
$#days | Last index of array @days
$days->[28] | 29th element of array pointed to by reference $days
$days[0][2] | Multidimensional array
$days{2000}{'Feb'} | Multidimensional hash
$days{2000,'Feb'} | Multidimensional hash emulation

Entire arrays (or slices of arrays and hashes) are named with the funny character @, which works much like the words "these" or "those":

Construct | Meaning
@days | Array containing ($days[0], $days[1],... $days[n])
@days[3, 4, 5] | Array slice containing ($days[3], $days[4], $days[5])
@days[3..5] | Array slice containing ($days[3], $days[4], $days[5])
@days{'Jan','Feb'} | Hash slice containing ($days{'Jan'},$days{'Feb'})

Entire hashes are named by %:

Construct | Meaning
%days | (Jan => 31, Feb => $leap ? 29 : 28, ...)

Any of these constructs may also serve as an lvalue, specifying a location you could assign a value to. With arrays, hashes, and slices of arrays or hashes, the lvalue provides multiple locations to assign to, so you can assign multiple values to them all at once:

@days = 1 .. 7;

Previous | Home | Next
2.3. Built-in Data Types | Book Index | 2.5. Names
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.5. Names

We've talked about storing values in variables, but the variables themselves (their names and their associated definitions) also need to be stored somewhere. In the abstract, these places are known as namespaces. Perl provides two kinds of namespaces, which are often called symbol tables and lexical scopes.[6] You may have an arbitrary number of symbol tables or lexical scopes, but every name you define gets stored in one or the other. We'll explain both kinds of namespaces as we go along. For now we'll just say that symbol tables are global hashes that happen to contain symbol table entries for global variables (including the hashes for other symbol tables). In contrast, lexical scopes are unnamed scratchpads that don't live in any symbol table, but are attached to a block of code in your program. They contain variables that can only be seen by the block. (That's what we mean by a scope). The lexical part just means, "having to do with text", which is not at all what a lexicographer would mean by it. Don't blame us.)

[6] We also call them packages and pads when we're talking about Perl's specific implementations, but those longer monikers are the generic industry terms, so we're pretty much stuck with them. Sorry.

Within any given namespace (whether global or lexical), every variable type has its own subnamespace, determined by the funny character. You can, without fear of conflict, use the same name for a scalar variable, an array, or a hash (or, for that matter, a filehandle, a subroutine name, a label, or your pet llama). This means that $foo and @foo are two different variables. Together with the previous rules, it also means that $foo[1] is an element of @foo totally unrelated to the scalar variable $foo. This may seem a bit weird, but that's okay, because it is weird.

Subroutines may be named with an initial &, although the funny character is optional when calling the subroutine. Subroutines aren't generally considered lvalues, though recent versions of Perl allow you to return an lvalue from a subroutine and assign to that, so it can look as though you're assigning to the subroutine.

Sometimes you just want a name for "everything named foo" regardless of its funny character. So symbol table entries can be named with an initial *, where the asterisk stands for all the other funny characters. These are called typeglobs, and they have several uses. They can also function as lvalues. Assignment to typeglobs is how Perl implements importing of symbols from one symbol table to another. More about that later too.

Like most computer languages, Perl has a list of reserved words that it recognizes as special keywords. However, because variable names always start with a funny character, reserved words don't actually conflict with variable names. Certain other kinds of names don't have funny characters, though, such as labels and filehandles. With these, you do have to worry (a little) about conflicting with reserved words. Since most reserved words are entirely lowercase, we recommend that you pick label and filehandle names that contain uppercase letters. For example, if you say open(LOG, logfile) rather than the regrettable open(log, "logfile"), you won't confuse Perl into thinking you're talking about the built-in log operator (which does logarithms, not tree trunks). Using uppercase filehandles also improves readability[7] and protects you from conflict with reserved words we might add in the future. For similar reasons, user-defined modules are typically named with initial capitals so that they'll look different from the built-in modules known as pragmas, which are named in all lowercase. And when we get to object-oriented programming, you'll notice that class names are usually capitalized for the same reason.

[7] One of the design principles of Perl is that different things should look different. Contrast this with languages that try to force different things to look the same, to the detriment of readability.

As you might deduce from the preceding paragraph, case is significant in identifiers--FOO, Foo, and foo are all different names in Perl. Identifiers start with a letter or underscore and may be of any length (for values of "any" ranging between 1 and 251, inclusive) and may contain letters, digits, and underscores. This includes Unicode letters and digits. Unicode ideographs also count as letters, but we don't recommend you use them unless you can read them. See Chapter 15, "Unicode".

Names that follow funny characters don't have to be identifiers, strictly speaking. They can start with a digit, in which case they may only contain more digits, as in $123. Names that start with anything other than a letter, digit, or underscore are (usually) limited to that one character (like $? or $$), and generally have a predefined significance to Perl. For example, just as in the Bourne shell, $$ is the current process ID and $? the exit status of your last child process.

As of version 5.6, Perl also has an extensible syntax for internal variables names. Any variable of the form ${^NAME} is a special variable reserved for use by Perl. All these non-identifier names are forced to be in the main symbol table. See Chapter 28, "Special Names", for some examples.

It's tempting to think of identifiers and names as the same thing, but when we say name, we usually mean a fully qualified name, that is, a name that says which symbol table it lives in. Such names may be formed of a sequence of identifiers separated by the :: token:

$Santa::Helper::Reindeer::Rudolph::nose
That works just like the directories and filenames in a pathname:
/Santa/Helper/Reindeer/Rudolph/nose
In the Perl version of that notion, all the leading identifiers are the names of nested symbol tables, and the last identifier is the name of the variable within the most deeply nested symbol table. For instance, in the variable above, the symbol table is named Santa::Helper::Reindeer::Rudolph::, and the actual variable within that symbol table is $nose. (The value of that variable is, of course, "red".)

A symbol table in Perl is also known as a package, so these are often called package variables. Package variables are nominally private to the package in which they exist, but are global in the sense that the packages themselves are global. That is, anyone can name the package to get at the variable; it's just hard to do this by accident. For instance, any program that mentions $Dog::bert is asking for the $bert variable within the Dog:: package. That is an entirely separate variable from $Cat::bert. See Chapter 10, "Packages".

Variables attached to a lexical scope are not in any package, so lexically scoped variable names may not contain the :: sequence. (Lexically scoped variables are declared with a my declaration.)

2.5.1. Name Lookups

So the question is, what's in a name? How does Perl figure out what you mean if you just say $bert? Glad you asked. Here are the rules the Perl parser uses while trying to understand an unqualified name in context:

  1. First, Perl looks earlier in the immediately enclosing block to see whether the variable is declared in that same block with a my (or our) declaration (see those entries in Chapter 29, "Functions", as well as the section Section 2.8, "Scoped Declarations" in Chapter 4, "Statements and Declarations"). If there is a my declaration, the variable is lexically scoped and doesn't exist in any package--it exists only in that lexical scope (that is, in the block's scratchpad). Because lexical scopes are unnamed, nobody outside that chunk of program can even name your variable.[8]

    [8]If you use an our declaration instead of a my declaration, this only declares a lexically scoped alias (a nickname) for a package variable, rather than declaring a true lexically scoped variable the way my does. Outside code can still get at the real variable through its package, but in all other respects an our declaration behaves like a my declaration. This is handy when you're trying to limit your own use of globals with the use strict pragma (see the strict pragma in Chapter 31, "Pragmatic Modules"). But you should always prefer my if you don't need a global.

  2. If that doesn't work, Perl looks for the block enclosing that block and tries again for a lexically scoped variable in the larger block. Again, if Perl finds one, the variable belongs only to the lexical scope from the point of declaration through the end of the block in which it is declared--including any nested blocks, like the one we just came from in step 1. If Perl doesn't find a declaration, it repeats step 2 until it runs out of enclosing blocks.

  3. When Perl runs out of enclosing blocks, it examines the whole compilation unit for declarations as if it were a block. (A compilation unit is just the entire current file, or the string currently being compiled by an eval STRING operator.) If the compilation unit is a file, that's the largest possible lexical scope, and Perl will look no further for lexically scoped variables, so we go to step 4. If the compilation unit is a string, however, things get fancier. A string compiled as Perl code at run time pretends that it's a block within the lexical scope from which the eval STRING is running, even though the actual boundaries of the lexical scope are the limits of the string containing the code rather than any real braces. So if Perl doesn't find the variable in the lexical scope of the string, we pretend that the eval STRING is a block and go back to step 2, only this time starting with the lexical scope of the eval STRING operator instead of the lexical scope inside its string.

  4. If we get here, it means Perl didn't find any declaration (either my or our) for your variable. Perl now gives up on lexically scoped variables and assumes that your variable is a package variable. If the strict pragma is in effect, you will now get an error, unless the variable is one of Perl's predefined variables or has been imported into the current package. This is because that pragma disallows the use of unqualified global names. However, we aren't done with lexical scopes just yet. Perl does the same search of lexical scopes as it did in steps 1 through 3, only this time it searches for package declarations instead of variable declarations. If it finds such a package declaration, it knows that the current code is being compiled for the package in question and prepends the declared package name to the front of the variable.

  5. If there is no package declaration in any surrounding lexical scope, Perl looks for the variable name in the unnamed top-level package, which happens to have the name main when it isn't going around without a name tag. So in the absence of any declarations to the contrary, $bert means the same as $::bert, which means the same as $main::bert. (But because main is just another package in the top-level unnamed package, it's also $::main::bert, and $main::main::bert, $::main::main::bert and so on. This could be construed as a useless fact. But see "Symbol Tables" in Chapter 10, "Packages".)

There are several implications to these search rules that might not be obvious, so we'll make them explicit.

  • Because the file is the largest possible lexical scope, a lexically scoped variable can never be visible outside the file in which it's declared. File scopes do not nest.

  • Any particular bit of Perl is compiled in at least one lexical scope and exactly one package scope. The mandatory lexical scope is, of course, the file itself. Additional lexical scopes are provided by each enclosing block. All Perl code is also compiled in the scope of exactly one package, and although the declaration of which package you're in is lexically scoped, packages themselves are not lexically constrained. That is, they're global.

  • An unqualified variable name may therefore be searched for in many lexical scopes, but only one package scope, whichever one is currently in effect (which is lexically determined).

  • A variable name may only attach to one scope. Although at least two different scopes (lexical and package) are active everywhere in your program, a variable can only exist in one of those scopes.

  • An unqualified variable name can therefore resolve to only a single storage location, either in the first enclosing lexical scope in which it is declared, or else in the current package--but not both. The search stops as soon as that storage location is resolved, and any storage location that it would have found had the search continued is effectively hidden.

  • The location of the typical variable name can be completely determined at compile time.

Now that you know all about how the Perl compiler deals with names, you sometimes have the problem that you don't know the name of what you want at compile time. Sometimes you want to name something indirectly; we call this the problem of indirection. So Perl provides a mechanism: you can always replace an alphanumeric variable name with a block containing an expression that returns a reference to the real data. For instance, instead of saying:

$bert
you might say:
${ some_expression() }
and if the some_expression() function returns a reference to variable $bert (or even the string, "bert"), it will work just as if you'd said $bert in the first place. On the other hand, if the function returns a reference to $ernie, you'll get his variable instead. The syntax shown is the most general (and least legible) form of indirection, but we'll cover several convenient variations in Chapter 8, "References".

Previous | Home | Next
2.4. Variables | Book Index | 2.6. Scalar Values
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.6. Scalar Values

Whether it's named directly or indirectly, and whether it's in a variable, or an array element, or is just a temporary value, a scalar always contains a single value. This value may be a number, a string, or a reference to another piece of data. Or, there might even be no value at all, in which case the scalar is said to be undefined. Although we might speak of a scalar as "containing" a number or a string, scalars are typeless: you are not required to declare your scalars to be of type integer or floating-point or string or whatever.[9]

[9] Future versions of Perl will allow you to insert int, num, and str type declarations, not to enforce strong typing, but only to give the optimizer hints about things that it might not figure out for itself. Generally, you'd only consider doing this in tight code that must run very fast, so we're not going to tell you how to do it yet. Optional types are also used by the pseudohash mechanism, in which case they can function as types do in a more strongly typed language. See Chapter 8, "References" for more.

Perl stores strings as sequences of characters, with no arbitrary constraints on length or content. In human terms, you don't have to decide in advance how long your strings are going to get, and you can include any characters including null bytes within your string. Perl stores numbers as signed integers if possible, or as double-precision floating-point values in the machine's native format otherwise. Floating-point values are not infinitely precise. This is important to remember because comparisons like (10/3 == 1/3*10) tend to fail mysteriously.

Perl converts between the various subtypes as needed, so you can treat a number as a string or a string as a number, and Perl will do the Right Thing. To convert from string to number, Perl internally uses something like the C library's atof(3) function. To convert from number to string, it does the equivalent of an sprintf(3) with a format of "%.14g" on most machines. Improper conversions of a nonnumeric string like foo to a number count as numeric 0; these trigger warnings if you have them enabled, but are silent otherwise. See Chapter 5, "Pattern Matching", for examples of detecting what sort of data a string holds.

Although strings and numbers are interchangeable for nearly all intents, references are a bit different. They're strongly typed, uncastable pointers with built-in reference-counting and destructor invocation. That is, you can use them to create complex data types, including user-defined objects. But they're still scalars, for all that, because no matter how complicated a data structure gets, you often want to treat it as a single value.

By uncastable, we mean that you can't, for instance, convert a reference to an array into a reference to a hash. References are not castable to other pointer types. However, if you use a reference as a number or a string, you will get a numeric or string value, which is guaranteed to retain the uniqueness of the reference even though the "referenceness" of the value is lost when the value is copied from the real reference. You can compare such values or extract their type. But you can't do much else with the values, since there's no way to convert numbers or strings back into references. Usually, this is not a problem, because Perl doesn't force you to do pointer arithmetic--or even allow it. See Chapter 8, "References" for more on references.

2.6.1. Numeric Literals

Numeric literals are specified in any of several customary[10] floating-point or integer formats:

$x = 12345;                # integer
$x = 12345.67;             # floating point
$x = 6.02e23;              # scientific notation
$x = 4_294_967_296;        # underline for legibility
$x = 0377;                 # octal
$x = 0xffff;               # hexadecimal
$x = 0b1100_0000;          # binary

[10]Customary in Unix culture, that is. If you're from a different culture, welcome to ours!

Because Perl uses the comma as a list separator, you cannot use it to separate the thousands in a large number. Perl does allow you to use an underscore character instead. The underscore only works within literal numbers specified in your program, not for strings functioning as numbers or data read from somewhere else. Similarly, the leading 0x for hexadecimal, 0b for binary, and 0 for octal work only for literals. The automatic conversion of a string to a number does not recognize these prefixes--you must do an explicit conversion[11] with the oct function--which works for hex and binary numbers, too, as it happens, provided you supply the 0x or 0b on the front.

[11]Sometimes people think Perl should convert all incoming data for them. But there are far too many decimal numbers with leading zeros in the world to make Perl do this automatically. For example, the Zip Code for the O'Reilly & Associates office in Cambridge, MA, is 02140. The postmaster would get confused if your mailing label program turned 02140 into 1120 decimal.

2.6.2. String Literals

String literals are usually surrounded by either single or double quotes. They work much like Unix shell quotes: double-quoted string literals are subject to backslash and variable interpolation, but single-quoted strings are not (except for \' and \\, so that you can embed single quotes and backslashes into single-quoted strings). If you want to embed any other backslash sequences such as \n (newline), you must use the double-quoted form. (Backslash sequences are also known as escape sequences, because you "escape" the normal interpretation of characters temporarily.)

A single-quoted string must be separated from a preceding word by a space because a single quote is a valid--though archaic--character in an identifier. Its use has been replaced by the more visually distinct :: sequence. That means that $main'var and $main::var are the same thing, but the second is generally considered easier to read for people and programs.

Double-quoted strings are subject to various forms of character interpolation, many of which will be familiar to programmers of other languages. These are listed in Table 2-1.

Table 2.1. Backslashed Character Escapes

Code | Meaning
\n | Newline (usually LF)
\r | Carriage return (usually CR)
\t | Horizontal tab
\f | Form feed
\b | Backspace
\a | Alert (bell)
\e | ESC character
\033 | ESC in octal
\x7f | DEL in hexadecimal
\cC | Control-C
\x{263a} | Unicode (smiley)
\N{NAME} | Named character

The \N{NAME} notation is usable only in conjunction with the use charnames pragma described in Chapter 31, "Pragmatic Modules". This allows you to specify character names symbolically, as in \N{GREEK SMALL LETTER SIGMA}, \N{greek:Sigma}, or \N{sigma}--depending on how you call the pragma. See also Chapter 15, "Unicode".

There are also escape sequences to modify the case or "meta-ness" of subsequent characters. See Table 2-2.

Table 2.2. Translation Escapes

Code | Meaning
\u | Force next character to uppercase ("titlecase" in Unicode).
\l | Force next character to lowercase.
\U | Force all following characters to uppercase.
\L | Force all following characters to lowercase.
\Q | Backslash all following nonalphanumeric characters.
\E | End \U, \L, or \Q.

You may also embed newlines directly in your strings; that is, they can begin and end on different lines. This is often useful, but it also means that if you forget a trailing quote, the error will not be reported until Perl finds another line containing the quote character, which may be much further on in the script. Fortunately, this usually causes an immediate syntax error on the same line, and Perl is then smart enough to warn you that you might have a runaway string where it thought the string started.

Besides the backslash escapes listed above, double-quoted strings are subject to variable interpolation of scalar and list values. This means that you can insert the values of certain variables directly into a string literal. It's really just a handy form of string concatenation.[12] Variable interpolation may be done for scalar variables, entire arrays (but not hashes), single elements from an array or hash, or slices (multiple subscripts) of an array or hash. Nothing else interpolates. In other words, you may only interpolate expressions that begin with $ or @, because those are the two characters (along with backslash) that the string parser looks for. Inside strings, a literal @ that is not part of an array or slice identifier but is followed by an alphanumeric character must be escaped with a backslash (\@), or else a compilation error will result. Although a complete hash specified with a % may not be interpolated into the string, single hash values or hash slices are okay, because they begin with $ and @ respectively.

[12]With warnings enabled, Perl may report undefined values interpolated into strings as using the concatenation or join operations, even though you don't actually use those operators there. The compiler created them for you anyway.

The following code segment prints out "The price is $100.":

$Price = '$100';                    # not interpolated
print "The price is $Price.\n";     # interpolated

As in some shells, you can put braces around the identifier to distinguish it from following alphanumerics: "How ${verb}able!". An identifier within such braces is forced to be a string, as is any single identifier within a hash subscript. For example:

$days{'Feb'}
can be written as:
$days{Feb}
and the quotes will be assumed. Anything more complicated in the subscript is interpreted as an expression, and then you'd have to put in the quotes:
$days{'February 29th'}   # Ok.
$days{"February 29th"}   # Also ok. "" doesn't have to interpolate.
$days{ February 29th }   # WRONG, produces parse error.
In particular, you should always use quotes in slices such as:
@days{'Jan','Feb'}       # Ok.
@days{"Jan","Feb"}       # Also ok.
@days{ Jan,  Feb }       # Kinda wrong (breaks under use strict)

Apart from the subscripts of interpolated array and hash variables, there are no multiple levels of interpolation. Contrary to the expectations of shell programmers, backticks do not interpolate within double quotes, nor do single quotes impede evaluation of variables when used within double quotes. Interpolation is extremely powerful but strictly controlled in Perl. It happens only inside double quotes, and in certain other "double-quotish" operations that we'll describe in the next section:

print "\n";              # Ok, print a newline.
print  \n ;              # WRONG, no interpolative context.

2.6.3. Pick Your Own Quotes

Although we usually think of quotes as literal values, in Perl they function more like operators, providing various kinds of interpolating and pattern-matching capabilities. Perl provides the customary quote characters for these behaviors, but also provides a more general way for you to choose your quote character for any of them. In Table 2-3, any nonalphanumeric, nonwhitespace delimiter may be used in place of /. (The newline and space characters are no longer allowed as delimiters, although ancient versions of Perl once allowed this.)

Table 2.3. Quote Constructs

Customary | Generic | Meaning | Interpolates
'' | q// | Literal string | No
"" | qq// | Literal string | Yes
`` | qx// | Command execution | Yes
() | qw// | Word list | No
// | m// | Pattern match | Yes
s/// | s/// | Pattern substitution | Yes
y/// | tr/// | Character translation | No
"" | qr// | Regular expression | Yes

Some of these are simply forms of "syntactic sugar" to let you avoid putting too many backslashes into quoted strings, particularly into pattern matches where your regular slashes and backslashes tend to get all tangled.

If you choose single quotes for delimiters, no variable interpolation is done even on those forms that ordinarily interpolate. If the opening delimiter is an opening parenthesis, bracket, brace, or angle bracket, the closing delimiter will be the corresponding closing character. (Embedded occurrences of the delimiters must match in pairs.) Examples:

$single = q!I said, "You said, 'She said it.'"!;

$double = qq(Can't we get some "good" $variable?);

$chunk_of_code = q {
    if ($condition) {
        print "Gotcha!";
    }
};
The last example demonstrates that you can use whitespace between the quote specifier and its initial bracketing character. For two-element constructs like s/// and tr///, if the first pair of quotes is a bracketing pair, the second part gets its own starting quote character. In fact, the second pair needn't be the same as the first pair. So you can write things like s<foo>(bar) or tr(a-f)[A-F]. Because whitespace is also allowed between the two inner quote characters, you could even write that last one as:
tr (a-f)
   [A-F];
Whitespace is not allowed, however, when # is being used as the quoting character. q#foo# is parsed as the string 'foo', while q #foo# is parsed as the quote operator q followed by a comment. Its delimiter will be taken from the next line. Comments can also be placed in the middle of two-element constructs, which allows you to write:
s {foo}   # Replace foo
  {bar};  #    with bar.

tr [a-f]  # Transliterate lowercase hex
   [A-F]; #            to uppercase hex

2.6.4. Or Leave the Quotes Out Entirely

A name that has no other interpretation in the grammar will be treated as if it were a quoted string. These are known as barewords.[13] As with filehandles and labels, a bareword that consists entirely of lowercase letters risks conflict with future reserved words. If you have warnings enabled, Perl will warn you about barewords. For example:

@days = (Mon,Tue,Wed,Thu,Fri);
print STDOUT hello, ' ', world, "\n";

[13] Variable names, filehandles, labels, and the like are not considered barewords because they have a meaning forced by a preceding token or a following token (or both). Predeclared names such as subroutines aren't barewords either. It's only a bareword when the parser has no clue.

sets the array @days to the short form of the weekdays and prints "hello world" followed by a newline on STDOUT. If you leave the filehandle out, Perl tries to interpret hello as a filehandle, resulting in a syntax error. Because this is so error-prone, some people may wish to avoid barewords entirely. The quoting operators listed earlier provide many convenient forms, including the qw// "quote words" construct which nicely quotes a list of space-separated words:

@days = qw(Mon Tue Wed Thu Fri);
print STDOUT "hello world\n";
You can go as far as to outlaw barewords entirely. If you say:
use strict 'subs';
then any bareword will produce a compile-time error. The restriction lasts through the end of the enclosing scope. An inner scope may countermand this by saying:
no strict 'subs';
Note that the bare identifiers in constructs like:
"${verb}able"
$days{Feb}
are not considered barewords since they're allowed by explicit rule rather than by having "no other interpretation in the grammar".

An unquoted name with a trailing double colon, such as main:: or Dog::, is always treated as the package name. Perl turns the would-be bareword Camel:: into the string "Camel" at compile time, so this usage is not subject to rebuke by use strict.

2.6.5. Interpolating Array Values

Array variables are interpolated into double-quoted strings by joining all elements of the array with the separator specified in the $" variable[14] (which contains a space by default). The following are equivalent:

$temp = join( $", @ARGV );
print $temp;

print "@ARGV";
Within search patterns, which also undergo double-quotish interpolation, there is an unfortunate ambiguity: is /$foo[bar]/ to be interpreted as /${foo}[bar]/ (where [bar] is a character class for the regular expression) or as /${foo[bar]}/ (where [bar] is the subscript to array @foo)? If @foo doesn't otherwise exist, it's obviously a character class. If @foo exists, Perl takes a good guess about [bar], and is almost always right.[15] If it does guess wrong, or if you're just plain paranoid, you can force the correct interpretation with braces as shown earlier. Even if you're merely prudent, it's probably not a bad idea.

[14]$LIST_SEPARATOR if you use the English module bundled with Perl.

[15]The guesser is too boring to describe in full, but basically takes a weighted average of all the things that look like character classes (a-z, \w, initial ^) versus things that look like expressions (variables or reserved words).

2.6.6. "Here" Documents

A line-oriented form of quoting is based on the Unix shell's here-document syntax. It's line-oriented in the sense that the delimiters are lines rather than characters. The starting delimiter is the current line, and the terminating delimiter is a line consisting of the string you specify. Following a <<, you specify the string to terminate the quoted material, and all lines following the current line down to but not including the terminating line are part of the string. The terminating string may be either an identifier (a word) or some quoted text. If quoted, the type of quote determines the treatment of the text, just as it does in regular quoting. An unquoted identifier works as though it were in double quotes. A backslashed identifier works as though it were in single quotes (for compatibility with shell syntax). There must be no space between the << and an unquoted identifier, although whitespace is permitted if you specify a quoted string instead of the bare identifier. (If you insert a space, it will be treated as a null identifier, which is valid but deprecated, and matches the first blank line--see the first Hurrah! example below.) The terminating string must appear by itself, unquoted and with no extra whitespace on either side, on the terminating line.

print <<EOF;    # same as earlier example
The price is $Price.
EOF

print <<"EOF";  # same as above, with explicit quotes
The price is $Price.
EOF

print <<'EOF';    # single-quoted quote
All things (e.g. a camel's journey through
A needle's eye) are possible, it's true.
But picture how the camel feels, squeezed out
In one long bloody thread, from tail to snout.
                                -- C.S. Lewis
EOF

print << x 10;    # print next line 10 times
The camels are coming!  Hurrah!  Hurrah!

print <<"" x 10;  # the preferred way to write that
The camels are coming!  Hurrah!  Hurrah!

print <<`EOC`;    # execute commands
echo hi there
echo lo there
EOC

print <<"dromedary", <<"camelid";   # you can stack them
I said bactrian.
dromedary
She said llama.
camelid

funkshun(<<"THIS", 23, <<'THAT');   # doesn't matter if they're in parens
Here's a line
or two.
THIS
And here's another.
THAT
Just don't forget that you have to put a semicolon on the end to finish the statement, because Perl doesn't know you're not going to try to do this:
print <<'odd'
2345
odd
    + 10000;   # prints 12345
If you want your here docs to be indented with the rest of the code, you'll need to remove leading whitespace from each line manually:
($quote = <<'QUOTE') =~ s/^\s+//gm;
    The Road goes ever on and on,
    down from the door where it began.
QUOTE
You could even populate an array with the lines of a here document as follows:
@sauces = <<End_Lines =~ m/(\S.*\S)/g;
   normal tomato
   spicy tomato
   green chile
   pesto
   white wine
End_Lines

2.6.7. V-String Literals

A literal that begins with a v and is followed by one or more dot-separated integers is treated as a string literal composed of characters with the specified ordinal values:

$crlf = v13.10;           # ASCII carriage return, line feed
These are called v-strings, short for "vector strings" or "version strings" or anything else you can think of that starts with "v" and deals with lists of integers. They provide an alternate and more legible way to construct strings when you want to specify the numeric values of each character. Thus, v1.20.300.4000 is a more winsome way to produce the same string value as any of:
"\x{1}\x{14}\x{12c}\x{fa0}"
pack("U*", 1, 20, 300, 4000)
chr(1) . chr(20) . chr(300) . chr(4000)
If such a literal has two or more dots (three or more integers), the leading v may be omitted.
print v9786;              # prints UTF-8 encoded SMILEY, "\x{263a}"
print v102.111.111;       # prints "foo"
print 102.111.111;        # same thing

use 5.6.0;                # require a particular Perl version (or later)

$ipaddr = 204.148.40.9;   # the IPv4 address of oreilly.com
V-strings are useful for representing IP address and version numbers. In particular, since characters can have an ordinal value larger than 255 these days, v-strings provide a way to represent version numbers of any size that can be correctly compared with a simple string comparison.

Version numbers and IP addresses stored in v-strings are not human readable, since the individual integers are stored as arbitrary characters. To produce something legible, use the v flag in a printf mask, like "%vd", as described under sprintf in Chapter 29, "Functions". For more on Unicode strings, see Chapter 15, "Unicode" and the use bytes pragma in Chapter 31, "Pragmatic Modules"; for comparing version strings using string comparison operators, see $^V in Chapter 28, "Special Names"; and for representing IPv4 addresses, see gethostbyaddr in Chapter 29, "Functions".

2.6.8. Other Literal Tokens

You should consider any identifier that both begins and ends with a double underscore to be reserved for special syntactic use by Perl. Two such special literals are __LINE__ and __FILE__, which represent the current line number and filename at that point in your program. They may only be used as separate tokens; they will not be interpolated into strings. Likewise, __PACKAGE__ is the name of the package the current code is being compiled into. If there is no current package (due to an empty package; directive), __PACKAGE__ is the undefined value. The token __END__ (or alternatively, a Control-D or Control-Z character) may be used to indicate the logical end of the script before the real end-of-file. Any following text is ignored, but may be read via the DATA filehandle.

The __DATA__ token functions similarly to the __END__ token, but opens the DATA filehandle within the current package's namespace, so that files you require can each have their own DATA filehandles open simultaneously. For more information, see DATA in Chapter 28, "Special Names".

Previous | Home | Next
2.5. Names | Book Index | 2.7. Context
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.7. Context

Until now we've seen several terms that can produce scalar values. Before we can discuss terms further, though, we must come to terms with the notion of context.

2.7.1. Scalar and List Context

Every operation[16] that you invoke in a Perl script is evaluated in a specific context, and how that operation behaves may depend on the requirements of that context. There are two major contexts: scalar and list. For example, assignment to a scalar variable, or to a scalar element of an array or hash, evaluates the righthand side in a scalar context:

$x         = funkshun();  # scalar context
$x[1]      = funkshun();  # scalar context
$x{"ray"}  = funkshun();  # scalar context
But assignment to an array or a hash, or to a slice of either, evaluates the righthand side in a list context, even if the slice picks out only one element:
@x         = funkshun();  # list context
@x[1]      = funkshun();  # list context
@x{"ray"}  = funkshun();  # list context
%x         = funkshun();  # list context
Assignment to a list of scalars also provides a list context to the righthand side, even if there's only one element in the list:
($x,$y,$z) = funkshun();  # list context
($x)       = funkshun();  # list context
These rules do not change at all when you declare a variable by modifying the term with my or our, so we have:
my $x      = funkshun();  # scalar context
my @x      = funkshun();  # list context
my %x      = funkshun();  # list context
my ($x)    = funkshun();  # list context

[16] Here we use the term "operation" loosely to mean either an operator or a term. The two concepts fuzz into each other when you start talking about functions that parse like terms but look like unary operators.

You will be miserable until you learn the difference between scalar and list context, because certain operators (such as our mythical funkshun() function above) know which context they are in, and return a list in contexts wanting a list but a scalar value in contexts wanting a scalar. (If this is true of an operation, it will be mentioned in the documentation for that operation.) In computer lingo, the operations are overloaded on their return type. But it's a very simple kind of overloading, based only on the distinction between singular and plural values, and nothing else.

If some operators respond to context, then obviously something around them has to supply the context. We've shown that assignment can supply a context to its right operand, but that's not terribly surprising, since all operators supply some kind of context to each of their operands. What you really want to know is which operators supply which context to their operands. As it happens, you can easily tell which ones supply a list context because they all have LIST in their syntactic descriptions. Everything else supplies a scalar context. Generally, it's quite intuitive.[17] If necessary, you can force a scalar context onto an argument in the middle of a LIST by using the scalar pseudofunction. Perl provides no way to force a list context in a scalar context, because anywhere you would want a list context it's already provided by the LIST of some controlling function.

[17] Note, however, that the list context of a LIST can propagate down through subroutine calls, so it's not always obvious from inspection whether a given statement is going to be evaluated in a scalar or list context. The program can find out its context within a subroutine by using the wantarray function.

Scalar context can be further classified into string context, numeric context, and don't-care context. Unlike the scalar versus list distinction we just made, operations never know or care which scalar context they're in. They simply return whatever kind of scalar value they want to and let Perl translate numbers to strings in string context, and strings to numbers in numeric context. Some scalar contexts don't care whether a string or a number or a reference is returned, so no conversion will happen. This happens, for example, when you are assigning the value to another variable. The new variable just takes on the same subtype as the old value.

2.7.2. Boolean Context

Another special don't-care scalar context is called Boolean context. Boolean context is simply any place where an expression is being evaluated to see whether it's true or false. When we say "true" and "false" in this book, we mean the technical definition that Perl uses: a scalar value is true if it is not the null string "" or the number 0 (or its string equivalent, "0"). A reference is always true because it represents an address which is never 0. An undefined value (often called undef) is always false because it looks like either "" or 0, depending on whether you treat it as a string or a number. (List values have no Boolean value because list values are never produced in a scalar context!)

Because Boolean context is a don't-care context, it never causes any scalar conversions to happen, though of course the scalar context itself is imposed on any operand that cares. And for many operands that care, the scalar they produce in scalar context represents a reasonable Boolean value. That is, many operators that would produce a list in list context can be used for a true/false test in Boolean context. For instance, in list context such as that provided by the unlink operator, an array name produces the list of its values:

unlink @files;      # Delete all files, ignoring errors.
But if you use the array in a conditional (that is, in a Boolean context), the array knows it's in a scalar context and returns the number of elements in the array, which conveniently is true as long as there are any elements left. So supposing you wanted to get warnings on each file that wasn't deleted properly, you might write a loop like this:
while (@files) {
    my $file = shift @files;
    unlink $file or warn "Can't delete $file: $!\n";
}
Here @files is evaluated in the Boolean context supplied by the while statement, so Perl evaluates the array itself to see whether it's a "true array" or a "false array". It's a true array as long as there are filenames in it, but it becomes a false array as soon as the last filename is shifted out. Note that what we earlier said still holds. Despite the fact that an array contains (and can produce) a list value, we are not evaluating a list value in scalar context. We are telling the array it's a scalar and asking what it thinks of itself.

Do not be tempted to use defined @files for this. It doesn't work because the defined function is asking whether a scalar is equal to undef, but an array is not a scalar. The simple Boolean test suffices.

2.7.3. Void Context

Another peculiar kind of scalar context is the void context. This context not only doesn't care what the return value's type is, it doesn't even want a return value. From the standpoint of how functions work, it's no different from an ordinary scalar context. But if you have warnings enabled, the Perl compiler will warn you if you use an expression with no side effects in a place that doesn't want a value, such as in a statement that doesn't return a value. For example, if you use a string as a statement:

"Camel Lot";
you may get a warning like this:
Useless use of a constant in void context in myprog line 123;

2.7.4. Interpolative Context

We mentioned earlier that double-quoted literal strings do backslash interpretation and variable interpolation, but that the interpolative context (often called "double-quote context" because nobody can pronounce "interpolative") applies to more than just double-quoted strings. Some other double-quotish constructs are the generalized backtick operator qx//, the pattern match operator m//, the substitution operator s///, and the quote regex operator, qr//. The substitution operator does interpolation on its left side before doing a pattern match, and then does interpolation on its right side each time the left side matches.

The interpolative context only happens inside quotes, or things that work like quotes, so perhaps it's not fair to call it a context in the same sense as scalar and list contexts. (Then again, maybe it is.)

Previous | Home | Next
2.6. Scalar Values | Book Index | 2.8. List Values and Arrays
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.8. List Values and Arrays

Now that we've talked about context, we can talk about list literals and how they behave in context. You've already seen some list literals. List literals are denoted by separating individual values by commas (and enclosing the list in parentheses where precedence requires it). Because it (almost) never hurts to use extra parentheses, the syntax diagram of a list value is usually indicated like this:

(LIST)
Earlier we said that LIST in a syntax description indicates something that supplies list context to its arguments, but a bare list literal itself is the one partial exception to that rule, in that it supplies a list context to its arguments only when the list as a whole is in list context. The value of a list literal in list context is just the values of the arguments in the order specified. As a fancy sort of term in an expression, a list literal merely pushes a series of temporary values onto Perl's stack, to be collected off the stack later by whatever operator wants the list.

In a scalar context, however, the list literal doesn't really behave like a LIST, in that it doesn't supply list context to its values. Instead, it merely evaluates each of its arguments in scalar context, and returns the value of the final element. That's because it's really just the C comma operator in disguise, which is a binary operator that always throws away the value on the left and returns the value on the right. In terms of what we discussed earlier, the left side of the comma operator really provides a void context. Because the comma operator is left associative, if you have a series of comma-separated values, you always end up with the last value because the final comma throws away whatever any previous commas produced. So, to contrast the two, the list assignment:

@stuff = ("one", "two", "three");
assigns the entire list value to array @stuff, but the scalar assignment:
$stuff = ("one", "two", "three");
assigns only the value "three" to variable $stuff. Like the @files array we mentioned earlier the comma operator knows whether it is in a scalar or list context, and chooses its behavior accordingly.

It bears repeating that a list value is different from an array. A real array variable also knows its context, and in a list context, it would return its internal list of values just like a list literal. But in a scalar context it returns only the length of the array. The following assigns to $stuff the value 3:

@stuff = ("one", "two", "three");
$stuff = @stuff;
If you expected it to get the value "three", you were probably making a false generalization by assuming that Perl uses the comma operator rule to throw away all but one of the temporary values that @stuff put on the stack. But that's not how it works. The @stuff array never put all its values on the stack. It never put any of its values on the stack, in fact. It only put one value, the length of the array, because it knew it was in scalar context. No term or operator in scalar context will ever put a list on the stack. Instead, it will put one scalar on the stack, whatever it feels like, which is unlikely to be the last value of the list it would have returned in list context, because the last value is not likely to be the most useful value in scalar context. Got that? (If not, you'd better reread this paragraph, because it's important.)

Now back to true LISTs, the ones that do list context. Until now we've pretended that list literals were just lists of literals. But just as a string literal might interpolate other substrings, a list literal can interpolate other sublists. Any expression that returns values may be used within a list. The values so used may be either scalar values or list values, but they all become part of the new list value because LISTs do automatic interpolation of sublists. That is, when a LIST is evaluated, each element of the list is evaluated in a list context, and the resulting list value is interpolated into LIST just as if each individual element were a member of LIST. Thus arrays lose their identity in a LIST.[18] The list:

(@stuff,@nonsense,funkshun())

[18]Some people seem to think this is a problem, but it's not. You can always interpolate a reference to an array if you do not want it to lose its identity. See Chapter 8, "References".

contains the elements of @stuff, followed by the elements of @nonsense, followed by whatever values the subroutine &funkshun decides to return when called in list context. Note that any or all of these might have interpolated a null (empty) list, in which case it's as if no array or function call had been interpolated at that point. The null list itself is represented by the literal (). As with a null array, which interpolates as a null list and is therefore effectively ignored, interpolating the null list into another list has no effect. Thus, ((),(),()) is equivalent to ().

A corollary to this rule is that you may place an optional comma at the end of any list value. This makes it easy to come back later and add more elements after the last one:

@releases = (
    "alpha",
    "beta",
    "gamma",
);

Or you can do away with the commas entirely: another way to specify a literal list is with the qw (quote words) syntax we mentioned earlier. This construct is equivalent to splitting a single-quoted string on whitespace. For example:

@froots = qw(
    apple       banana      carambola
    coconut     guava       kumquat
    mandarin    nectarine   peach
    pear        persimmon   plum
);
(Note that those parentheses are behaving as quote characters, not ordinary parentheses. We could just as easily have picked angle brackets or braces or slashes. But parens are pretty.)

A list value may also be subscripted like a normal array. You must put the list in parentheses (real ones) to avoid ambiguity. Though it's often used to fetch a single value out of a list, it's really a slice of the list, so the syntax is:

(LIST)[LIST]
Examples:
# Stat returns list value.
$modification_time = (stat($file))[9];

# SYNTAX ERROR HERE.
$modification_time = stat($file)[9];  # OOPS, FORGOT PARENS

# Find a hex digit.
$hexdigit = ('a','b','c','d','e','f')[$digit-10];

# A "reverse comma operator".
return (pop(@foo),pop(@foo))[0];

# Get multiple values as a slice.
($day, $month, $year) = (localtime)[3,4,5];

2.8.1. List Assignment

A list may be assigned to only if each element of the list is itself legal to assign to:

($a, $b, $c) = (1, 2, 3);

($map{red}, $map{green}, $map{blue}) = (0xff0000, 0x00ff00, 0x0000ff);
You may assign to undef in a list. This is useful for throwing away some of the return values of a function:
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
The final list element may be an array or a hash:
($a, $b, @rest) = split;
my ($a, $b, %rest) = @arg_list;
You can actually put an array or hash anywhere in the list you assign to, but the first array or hash in the list will soak up all the remaining values, and anything after it will be set to the undefined value. This may be useful in a local or my, where you probably want the arrays initialized to be empty anyway.

You can even assign to the empty list:

() = funkshun();
That ends up calling your function in list context, but discarding the return values. If you had just called the function without an assignment, it would have instead been called in void context, which is a kind of scalar context, and might have caused the function to behave completely differently.

List assignment in scalar context returns the number of elements produced by the expression on the right side of the assignment:

$x = ( ($a, $b) = (7,7,7) );    # set $x to 3, not 2
$x = ( ($a, $b) = funk() );     # set $x to funk()'s return count
$x = ( () = funk() );           # also set $x to funk()'s return count
This is handy when you want to do a list assignment in a Boolean context, because most list functions return a null list when finished, which when assigned produces a 0, which is interpreted as false. Here's how you might use it in a while statement:
while (($login, $password) = getpwent) {
    if (crypt($login, $password) eq $password) {
        print "$login has an insecure password!\n";
    }
}

2.8.2. Array Length

You may find the number of elements in the array @days by evaluating @days in a scalar context, such as:

@days + 0;      # implicitly force @days into a scalar context
scalar(@days)   # explicitly force @days into a scalar context
Note that this only works for arrays. It does not work for list values in general. As we mentioned earlier, a comma-separated list evaluated in scalar context returns the last value, like the C comma operator. But because you almost never actually need to know the length of a list in Perl, this is not a problem.

Closely related to the scalar evaluation of @days is $#days. This will return the subscript of the last element of the array, or one less than the length, since there is (ordinarily) a 0th element. Assigning to $#days changes the length of the array. Shortening an array by this method destroys intervening values. You can gain some measure of efficiency by pre-extending an array that is going to get big. (You can also extend an array by assigning to an element beyond the end of the array.) You can truncate an array down to nothing by assigning the null list () to it. The following two statements are equivalent:

@whatever = ();
$#whatever = -1;
And the following is always true:
scalar(@whatever) == $#whatever + 1;
Truncating an array does not recover its memory. You have to undef(@whatever) to free its memory back to your process's memory pool. You probably can't free it all the way back to your system's memory pool, because few operating systems support this.

Previous | Home | Next
2.7. Context | Book Index | 2.9. Hashes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.9. Hashes

As we said earlier, a hash is just a funny kind of array in which you look values up using key strings instead of numbers. A hash defines associations between keys and values, so hashes are often called associative arrays by people who are not lazy typists.

There really isn't any such thing as a hash literal in Perl, but if you assign an ordinary list to a hash, each pair of values in the list will be taken to indicate one key/value association:

%map = ('red',0xff0000,'green',0x00ff00,'blue',0x0000ff);
This has the same effect as:
%map = ();            # clear the hash first
$map{red}   = 0xff0000;
$map{green} = 0x00ff00;
$map{blue}  = 0x0000ff;

It is often more readable to use the => operator between key/value pairs. The => operator is just a synonym for a comma, but it's more visually distinctive and also quotes any bare identifiers to the left of it (just like the identifiers in braces above), which makes it convenient for several sorts of operation, including initializing hash variables:

%map = (
    red   => 0xff0000,
    green => 0x00ff00,
    blue  => 0x0000ff,
);
or initializing anonymous hash references to be used as records:
$rec = {
    NAME  => 'John Smith',
    RANK  => 'Captain',
    SERNO => '951413',
};

or using named parameters to invoke complicated functions:

$field = radio_group(
             NAME      => 'animals',
             VALUES    => ['camel', 'llama', 'ram', 'wolf'],
             DEFAULT   => 'camel',
             LINEBREAK => 'true',
             LABELS    => \%animal_names,
         );
But we're getting ahead of ourselves again. Back to hashes.

You can use a hash variable (%hash) in a list context, in which case it interpolates all its key/value pairs into the list. But just because the hash was initialized in a particular order doesn't mean that the values come back out in that order. Hashes are implemented internally using hash tables for speedy lookup, which means that the order in which entries are stored is dependent on the internal hash function used to calculate positions in the hash table, and not on anything interesting. So the entries come back in a seemingly random order. (The two elements of each key/value pair come out in the right order, of course.) For examples of how to arrange for an output ordering, see the keys function in Chapter 29, "Functions".

When you evaluate a hash variable in a scalar context, it returns a true value only if the hash contains any key/value pairs whatsoever. If there are any key/value pairs at all, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash. This is pretty much only useful to find out whether Perl's (compiled in) hashing algorithm is performing poorly on your data set. For example, you stick 10,000 things in a hash, but evaluating %HASH in scalar context reveals "1/8", which means only one out of eight buckets has been touched. Presumably that one bucket contains all 10,000 of your items. This isn't supposed to happen.

To find the number of keys in a hash, use the keys function in a scalar context: scalar(keys(%HASH)).

You can emulate a multidimensional hash by specifying more than one key within the braces, separated by commas. The listed keys are concatenated together, separated by the contents of $; ($SUBSCRIPT_SEPARATOR), which has a default value of chr(28). The resulting string is used as the actual key to the hash. These two lines do the same thing:

$people{ $state, $county } = $census_results;
$people{ join $; => $state, $county } = $census_results;

This feature was originally implemented to support a2p, the awk-to-Perl translator. These days, you'd usually just use a real (well, realer) multidimensional array as described in Chapter 9, "Data Structures". One place the old style is still useful is for hashes tied to DBM files (see DB_File in Chapter 32, "Standard Modules"), which don't support multidimensional keys.

Don't confuse multidimensional hash emulations with slices. The one represents a scalar value, and the other represents a list value:

$hash{ $x, $y, $z }      # a single value
@hash{ $x, $y, $z }      # a slice of three values

Previous | Home | Next
2.8. List Values and Arrays | Book Index | 2.10. Typeglobs and Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.10. Typeglobs and Filehandles

Perl uses an special type called a typeglob to hold an entire symbol table entry. (The symbol table entry *foo contains the values of $foo, @foo, %foo, &foo, and several interpretations of plain old foo.) The type prefix of a typeglob is a * because it represents all types.

One use of typeglobs (or references thereto) is for passing or storing filehandles. If you want to save away a filehandle, do it this way:

$fh = *STDOUT;
or perhaps as a real reference, like this:
$fh = \*STDOUT;

This is also the way to create a local filehandle. For example:

sub newopen {
    my $path = shift;
    local *FH;          # not my() nor our()
    open(FH, $path) or return undef;
    return *FH;         # not \*FH!
}
$fh = newopen('/etc/passwd');
See the open function for other ways to generate new filehandles.

The main use of typeglobs nowadays is to alias one symbol table entry to another symbol table entry. Think of an alias as a nickname. If you say:

*foo = *bar;
it makes everything named "foo" a synonym for every corresponding thing named "bar". You can alias just one variable from a typeglob by assigning a reference instead:
*foo = \$bar;
makes $foo an alias for $bar, but doesn't make @foo an alias for @bar, or %foo an alias for %bar. All these affect global (package) variables only; lexicals cannot be accessed through symbol table entries. Aliasing global variables like this may seem like a silly thing to want to do, but it turns out that the entire module export/import mechanism is built around this feature, since there's nothing that says the symbol you're aliasing has to be in your namespace. This:
local *Here::blue = \$There::green;
temporarily makes $Here::blue an alias for $There::green, but doesn't make @Here::blue an alias for @There::green, or %Here::blue an alias for %There::green. Fortunately, all these complicated typeglob manipulations are hidden away where you don't have to look at them. See the sections Section 2.2.4, "Handle References" and Section 2.2.5, "Symbol Table References" in Chapter 8, "References", the section Section 2.1, "Symbol Tables" in Chapter 10, "Packages", and Chapter 11, "Modules", for more discussion on typeglobs and importation.

Previous | Home | Next
2.9. Hashes | Book Index | 2.11. Input Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


2.11. Input Operators

There are several input operators we'll discuss here because they parse as terms. Sometimes we call them pseudoliterals because they act like quoted strings in many ways. (Output operators like print parse as list operators and are discussed in Chapter 29, "Functions".)

2.11.1. Command Input (Backtick) Operator

First of all, we have the command input operator, also known as the backtick operator, because it looks like this:

$info = `finger $user`;
A string enclosed by backticks (grave accents, technically) first undergoes variable interpolation just like a double-quoted string. The result is then interpreted as a command line by the system, and the output of that command becomes the value of the pseudoliteral. (This is modeled after a similar operator in Unix shells.) In scalar context, a single string consisting of all the output is returned. In list context, a list of values is returned, one for each line of output. (You can set $/ to use a different line terminator.)

The command is executed each time the pseudoliteral is evaluated. The numeric status value of the command is saved in $? (see Chapter 28, "Special Names" for the interpretation of $?, also known as $CHILD_ERROR). Unlike the csh version of this command, no translation is done on the return data--newlines remain newlines. Unlike in any of the shells, single quotes in Perl do not hide variable names in the command from interpretation. To pass a $ through to the shell you need to hide it with a backslash. The $user in our finger example above is interpolated by Perl, not by the shell. (Because the command undergoes shell processing, see Chapter 23, "Security", for security concerns.)

The generalized form of backticks is qx// (for "quoted execution"), but the operator works exactly the same way as ordinary backticks. You just get to pick your quote characters. As with similar quoting pseudofunctions, if you happen to choose a single quote as your delimiter, the command string doesn't undergo double-quote interpolation;

$perl_info  = qx(ps $$);            # that's Perl's $$
$shell_info = qx'ps $$';            # that's the shell's $$

2.11.2. Line Input (Angle) Operator

The most heavily used input operator is the line input operator, also known as the angle operator or the readline function (since that's what it calls internally). Evaluating a filehandle in angle brackets (STDIN, for example) yields the next line from the associated filehandle. (The newline is included, so according to Perl's criteria for truth, a freshly input line is always true, up until end-of-file, at which point an undefined value is returned, which is conveniently false.) Ordinarily, you would assign the input value to a variable, but there is one situation where an automatic assignment happens. If and only if the line input operator is the only thing inside the conditional of a while loop, the value is automatically assigned to the special variable $_. The assigned value is then tested to see whether it is defined. (This may seem like an odd thing to you, but you'll use the construct frequently, so it's worth learning.) Anyway, the following lines are equivalent:

while (defined($_ = <STDIN>)) { print $_; }   # the longest way
while ($_ = <STDIN>) { print; }               # explicitly to $_
while (<STDIN>) { print; }                    # the short way
for (;<STDIN>;) { print; }                    # while loop in disguise
print $_ while defined($_ = <STDIN>);         # long statement modifier
print while $_ = <STDIN>;                     # explicitly to $_
print while <STDIN>;                          # short statement modifier
Remember that this special magic requires a while loop. If you use the input operator anywhere else, you must assign the result explicitly if you want to keep the value:
while (<FH1> && <FH2>) { ... }          # WRONG: discards both inputs
if (<STDIN>)      { print; }            # WRONG: prints old value of $_
if ($_ = <STDIN>) { print; }            # suboptimal: doesn't test defined
if (defined($_ = <STDIN>)) { print; }   # best
When you're implicitly assigning to $_ in a $_ loop, this is the global variable by that name, not one localized to the while loop. You can protect an existing value of $_ this way:
while (local $_ = <STDIN>) { print; }   # use local $_
Any previous value is restored when the loop is done. $_ is still a global variable, though, so functions called from inside that loop could still access it, intentionally or otherwise. You can avoid this, too, by declaring a lexical variable:
while (my $line = <STDIN>) { print $line; } # now private
(Both of these while loops still implicitly test for whether the result of the assignment is defined, because my and local don't change how assignment is seen by the parser.) The filehandles STDIN, STDOUT, and STDERR are predefined and pre-opened. Additional filehandles may be created with the open or sysopen functions. See those functions' documentation in Chapter 29, "Functions" for details on this.

In the while loops above, we were evaluating the line input operator in a scalar context, so the operator returns each line separately. However, if you use the operator in a list context, a list consisting of all remaining input lines is returned, one line per list element. It's easy to make a large data space this way, so use this feature with care:

$one_line = <MYFILE>;   # Get first line.
@all_lines = <MYFILE>;  # Get the rest of the lines.
There is no while magic associated with the list form of the input operator, because the condition of a while loop always provides a scalar context (as does any conditional).

Using the null filehandle within the angle operator is special; it emulates the command-line behavior of typical Unix filter programs such as sed and awk. When you read lines from <>, it magically gives you all the lines from all the files mentioned on the command line. If no files were mentioned, it gives you standard input instead, so your program is easy to insert into the middle of a pipeline of processes.

Here's how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is null, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames. More explicitly, the loop:

while (<>) {
    ...                     # code for each line
}
is equivalent to the following Perl-like pseudocode:
@ARGV = ('-') unless @ARGV;     # assume STDIN iff empty
while (@ARGV) {
    $ARGV = shift @ARGV;        # shorten @ARGV each time
    if (!open(ARGV, $ARGV)) {
        warn "Can't open $ARGV: $!\n";
        next;
    }
    while (<ARGV>) {
        ...                     # code for each line
    }
}
except that it isn't so cumbersome to say, and will actually work. It really does shift array @ARGV and put the current filename into the global variable $ARGV. It also uses the special filehandle ARGV internally--<> is just a synonym for the more explicitly written <ARGV>, which is a magical filehandle. (The pseudocode above doesn't work because it treats <ARGV> as nonmagical.)

You can modify @ARGV before the first <> as long as the array ends up containing the list of filenames you really want. Because Perl uses its normal open function here, a filename of "-" counts as standard input wherever it is encountered, and the more esoteric features of open are automatically available to you (such as opening a "file" named "gzip -dc < file.gz|"). Line numbers ($.) continue as if the input were one big happy file. (But see the example under eof in Chapter 29, "Functions" for how to reset line numbers on each file.)

If you want to set @ARGV to your own list of files, go right ahead:

# default to README file if no args given
@ARGV = ("README") unless @ARGV;
If you want to pass switches into your script, you can use one of the Getopt::* modules or put a loop on the front like this:
while (@ARGV and $ARGV[0] =~ /^-/) {
    $_ = shift;
    last if /^--$/;
    if (/^-D(.*)/) { $debug = $1 }
    if (/^-v/)     { $verbose++  }
    ...             # other switches
}
while (<>) {
    ...             # code for each line
}
The <> symbol will return false only once. If you call it again after this, it will assume you are processing another @ARGV list, and if you haven't set @ARGV, it will input from STDIN.

If the string inside the angle brackets is a scalar variable (for example, <$foo>), that variable contains an indirect filehandle, either the name of the filehandle to input from or a reference to such a filehandle. For example:

$fh = \*STDIN;
$line = <$fh>;
or:
open($fh, "<data.txt");
$line = <$fh>;

2.11.3. Filename Globbing Operator

You might wonder what happens to a line input operator if you put something fancier inside the angle brackets. What happens is that it mutates into a different operator. If the string inside the angle brackets is anything other than a filehandle name or a scalar variable (even if there are just extra spaces), it is interpreted as a filename pattern to be "globbed".[19] The pattern is matched against the files in the current directory (or the directory specified as part of the fileglob pattern), and the filenames so matched are returned by the operator. As with line input, names are returned one at a time in scalar context, or all at once in list context. The latter usage is more common; you often see things like:

@files = <*.xml>;
As with other kinds of pseudoliterals, one level of variable interpolation is done first, but you can't say <$foo> because that's an indirect filehandle as explained earlier. In older versions of Perl, programmers would insert braces to force interpretation as a fileglob: <${foo}>. These days, it's considered cleaner to call the internal function directly as glob($foo), which is probably the right way to have invented it in the first place. So instead you'd write
@files = glob("*.xml");
if you despise overloading the angle operator for this. Which you're allowed to do.

[19]Fileglobs have nothing to do with the previously mentioned typeglobs, other than that they both use the * character in a wildcard fashion. The * character has the nickname "glob" when used like this. With typeglobs, you're globbing symbols with the same name from the symbol table. With a fileglob, you're doing wildcard matching on the filenames in a directory, just as the various shells do.

Whether you use the glob function or the old angle-bracket form, the fileglob operator also does while magic like the line input operator, assigning the result to $_. (That was the rationale for overloading the angle operator in the first place.) For example, if you wanted to change the permissions on all your C code files, you might say:

while (glob "*.c") {
    chmod 0644, $_;
}
which is equivalent to:
while (<*.c>) {
    chmod 0644, $_;
}
The glob function was originally implemented as a shell command in older versions of Perl (and in even older versions of Unix), which meant it was comparatively expensive to execute and, worse still, wouldn't work exactly the same everywhere. Nowadays it's a built-in, so it's more reliable and a lot faster. See the description of the File::Glob module in Chapter 32, "Standard Modules" for how to alter the default behavior of this operator, such as whether to treat spaces in its operand (argument) as pathname separators, whether to expand tildes or braces, whether to be case insensitive, and whether to sort the return values--amongst other things.

Of course, the shortest and arguably the most readable way to do the chmod command above is to use the fileglob as a list operator:

chmod 0644, <*.c>;
A fileglob evaluates its (embedded) operand only when starting a new list. All values must be read before the operator will start over. In a list context, this isn't important because you automatically get them all anyway. In a scalar context, however, the operator returns the next value each time it is called, or a false value if you've just run out. Again, false is returned only once. So if you're expecting a single value from a fileglob, it is much better to say:
($file) = <blurch*>;  # list context
than to say:
$file = <blurch*>;    # scalar context
because the former returns all matched filenames and resets the operator, whereas the latter alternates between returning filenames and returning false.

If you're trying to do variable interpolation, it's definitely better to use the glob operator because the older notation can cause confusion with the indirect filehandle notation. This is where it becomes apparent that the borderline between terms and operators is a bit mushy:

@files = <$dir/*.[ch]>;         # Works, but avoid.
@files = glob("$dir/*.[ch]");   # Call glob as function.
@files = glob $some_pattern;    # Call glob as operator.

We left the parentheses off of the last example to illustrate that glob can be used either as a function (a term) or as a unary operator; that is, a prefix operator that takes a single argument. The glob operator is an example of a named unary operator, which is just one kind of operator we'll talk about in the next chapter. Later, we'll talk about pattern-matching operators, which also parse like terms but behave like operators.

Previous | Home | Next
2.10. Typeglobs and Filehandles | Book Index | 3. Unary and Binary Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 3. Unary and Binary Operators

Contents:

Terms and List Operators (Leftward)
The Arrow Operator
Autoincrement and Autodecrement
Exponentiation
Ideographic Unary Operators
Binding Operators
Multiplicative Operators
Additive Operators
Shift Operators
Named Unary and File Test Operators
Relational Operators
Equality Operators
Bitwise Operators
C-Style Logical (Short-Circuit) Operators
Range Operator
Conditional Operator
Assignment Operators
Comma Operators
List Operators (Rightward)
Logical and, or, not, and xor
C Operators Missing from Perl

In the last chapter, we talked about the various kinds of terms you might use in an expression, but to be honest, isolated terms are a bit boring. Many terms are party animals. They like to have relationships with each other. The typical young term feels strong urges to identify with and influence other terms in various ways, but there are many different kinds of social interaction and many different levels of commitment. In Perl, these relationships are expressed using operators.

Sociology has to be good for something.

From a mathematical perspective, operators are just ordinary functions with special syntax. From a linguistic perspective, operators are just irregular verbs. But as any linguist will tell you, the irregular verbs in a language tend to be the ones you use most often. And that's important from an information theory perspective because the irregular verbs tend to be shorter and more efficient in both production and recognition.

In practical terms, operators are handy.

Operators come in various flavors, depending on their arity (how many operands they take), their precedence (how hard they try to take those operands away from surrounding operators), and their associativity (whether they prefer to do things right to left or left to right when associated with operators of the same precedence).

Perl operators come in three arities: unary, binary, and trinary (or ternary, if your native tongue is Shibboleth). Unary operators are always prefix operators (except for the postincrement and postdecrement operators).[1] The others are all infix operators--unless you count the list operators, which can prefix any number of arguments. But most people just think of list operators as normal functions that you can forget to put parentheses around. Here are some examples:

! $x                # a unary operator
$x * $y             # a binary operator
$x ? $y : $z        # a trinary operator
print $x, $y, $z    # a list operator
An operator's precedence controls how tightly it binds. Operators with higher precedence grab the arguments around them before operators with lower precedence. The archetypal example is straight out of elementary math, where multiplication takes precedence over addition:
2 + 3 * 4          # yields 14, not 20
The order in which two operators of the same precedence are executed depends on their associativity. These rules also follow math conventions to some extent:
2 * 3 * 4          # means (2 * 3) * 4, left associative
2 ** 3 ** 4        # means 2 ** (3 ** 4), right associative
2 != 3 != 4        # illegal, nonassociative
Table 3-1 lists the associativity and arity of the Perl operators from highest precedence to lowest.

[1]Though you can think of various quotes and brackets as circumfix operators that delimit terms.

Table 3.1. Operator Precedence

Associativity | Arity | Precedence Class
None | 0 | Terms, and list operators (leftward)
Left | 2 | ->
None | 1 | ++ --
Right | 2 | **
Right | 1 | ! ~ > and unary + and -
Left | 2 | =~ !~
Left | 2 | * / % x
Left | 2 | + - .
Left | 2 | << >>
Right | 0,1 | Named unary operators
None | 2 | < > <= >= lt gt le ge
None | 2 | == != <=> eq ne cmp
Left | 2 | &
Left | 2 | | ^
Left | 2 | &&
Left | 2 | ||
None | 2 | .. ...
Right | 3 | ?:
Right | 2 | = += -= *= and so on
Left | 2 | , =>
Right | 0+ | List operators (rightward)
Right | 1 | not
Left | 2 | and
Left | 2 | or xor

It may seem to you that there are too many precedence levels to remember. Well, you're right, there are. Fortunately, you've got two things going for you here. First, the precedence levels as they're defined usually follow your intuition, presuming you're not psychotic. And second, if you're merely neurotic, you can always put in extra parentheses to relieve your anxiety.

Another helpful hint is that any operators borrowed from C keep the same precedence relationship with each other, even where C's precedence is slightly screwy. (This makes learning Perl easier for C folks and C++ folks. Maybe even Java folks.)

The following sections cover these operators in precedence order. With very few exceptions, these all operate on scalar values only, not list values. We'll mention the exceptions as they come up.

Although references are scalar values, using most of these operators on references doesn't make much sense, because the numeric value of a reference is only meaningful to the internals of Perl. Nevertheless, if a reference points to an object of a class that allows overloading, you can call these operators on such objects, and if the class has defined an overloading for that particular operator, it will define how the object is to be treated under that operator. This is how complex numbers are implemented in Perl, for instance. For more on overloading, see Chapter 13, "Overloading".

3.1. Terms and List Operators (Leftward)

Any term is of highest precedence in Perl. Terms include variables, quote and quotelike operators, most expressions in parentheses, or brackets or braces, and any function whose arguments are parenthesized. Actually, there aren't really any functions in this sense, just list operators and unary operators behaving as functions because you put parentheses around their arguments. Nevertheless, the name of Chapter 29 is Functions.

Now listen carefully. Here are a couple of rules that are very important and simplify things greatly, but may occasionally produce counterintuitive results for the unwary. If any list operator (such as print) or any named unary operator (such as chdir) is followed by a left parenthesis as the next token (ignoring whitespace), the operator and its parenthesized arguments are given highest precedence, as if it were a normal function call. The rule is this: If it looks like a function call, it is a function call. You can make it look like a nonfunction by prefixing the parentheses with a unary plus, which does absolutely nothing, semantically speaking--it doesn't even coerce the argument to be numeric.

For example, since || has lower precedence than chdir, we get:

chdir $foo    || die;       # (chdir $foo) || die
chdir($foo)   || die;       # (chdir $foo) || die
chdir ($foo)  || die;       # (chdir $foo) || die
chdir +($foo) || die;       # (chdir $foo) || die
but, because * has higher precedence than chdir, we get:
chdir $foo * 20;            # chdir ($foo * 20)
chdir($foo) * 20;           # (chdir $foo) * 20
chdir ($foo) * 20;          # (chdir $foo) * 20
chdir +($foo) * 20;         # chdir ($foo * 20)
Likewise for any numeric operator that happens to be a named unary operator, such as rand:
rand 10 * 20;               # rand (10 * 20)
rand(10) * 20;              # (rand 10) * 20
rand (10) * 20;             # (rand 10) * 20
rand +(10) * 20;            # rand (10 * 20)
In the absence of parentheses, the precedence of list operators such as print, sort, or chmod is either very high or very low depending on whether you look at the left side or the right side of the operator. (That's what the "Leftward" is doing in the title of this section.) For example, in:
@ary = (1, 3, sort 4, 2);
print @ary;         # prints 1324
the commas on the right of the sort are evaluated before the sort, but the commas on the left are evaluated after. In other words, a list operator tends to gobble up all the arguments that follow it, and then act like a simple term with regard to the preceding expression. You still have to be careful with parentheses:
# These evaluate exit before doing the print:
print($foo, exit);  # Obviously not what you want.
print $foo, exit;   # Nor this.

# These do the print before evaluating exit:
(print $foo), exit; # This is what you want.
print($foo), exit;  # Or this.
print ($foo), exit; # Or even this.
The easiest place to get burned is where you're using parentheses to group mathematical arguments, and you forget that parentheses are also used to group function arguments:
print ($foo & 255) + 1, "\n";   # prints ($foo & 255)
That probably doesn't do what you expect at first glance. Fortunately, mistakes of this nature generally produce warnings like "Useless use of addition in a void context" when warnings are enabled.

Also parsed as terms are the do {} and eval {} constructs, as well as subroutine and method calls, the anonymous array and hash composers [] and {}, and the anonymous subroutine composer sub {}.

Previous | Home | Next
2.11. Input Operators | Book Index | 3.2. The Arrow Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.2. The Arrow Operator

Just as in C and C++, the binary -> operator is an infix dereference operator. If the right side is a [...] array subscript, a {...} hash subscript, or a (...) subroutine argument list, the left side must be a reference (either hard or symbolic) to an array, a hash, or a subroutine, respectively. In an lvalue (assignable) context, if the left side is not a reference, it must be a location capable of holding a hard reference, in which case such a reference will be autovivified for you. For more on this (and some warnings about accidental autovivification) see Chapter 8, "References".

$aref->[42]               # an array dereference
$href->{"corned beef"}    # a hash dereference
$sref->(1,2,3)            # a subroutine dereference
Otherwise, it's a method call of some kind. The right side must be a method name (or a simple scalar variable containing the method name), and the left side must evaluate to either an object (a blessed reference) or a class name (that is, a package name):
$yogi = Bear->new("Yogi");    # a class method call
$yogi->swipe($picnic);        # an object method call
The method name may be qualified with a package name to indicate in which class to start searching for the method, or with the special package name, SUPER::, to indicate that the search should start in the parent class. See Chapter 12, "Objects".

Previous | Home | Next
3.1. Terms and List Operators (Leftward) | Book Index | 3.3. Autoincrement and Autodecrement
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.3. Autoincrement and Autodecrement

The ++ and -- operators work as in C. That is, when placed before a variable, they increment or decrement the variable before returning the value, and when placed after, they increment or decrement the variable after returning the value. For example, $a++ increments the value of scalar variable $a, returning the value before it performs the increment. Similarly, --$b{(/(\w+)/)[0]} decrements the element of the hash %b indexed by the first "word" in the default search variable ($_) and returns the value after the decrement.[2]

[2]Okay, so that wasn't exactly fair. We just wanted to make sure you were paying attention. Here's how that expression works. First the pattern match finds the first word in $_ using the regular expression \w+. The parentheses around that cause the word to be returned as a single-element list value because the pattern match is in a list context. The list context is supplied by the list slice operator, (...)[0], which returns the first (and only) element of the list. That value is used as the key for the hash, and the hash entry (value) is decremented and returned. In general, when confronted with a complex expression, analyze it from the inside out to see what order things happen in.

The autoincrement operator has a little extra built-in magic. If you increment a variable that is numeric, or that has ever been used in a numeric context, you get a normal increment. If, however, the variable has only been used in string contexts since it was set, has a value that is not the null string, and matches the pattern /^[a-zA-Z]*[0-9]*$/, the increment is done as a string, preserving each character within its range, with carry:

print ++($foo = '99');      # prints '100'
print ++($foo = 'a0');      # prints 'b1'
print ++($foo = 'Az');      # prints 'Ba'
print ++($foo = 'zz');      # prints 'aaa'
As of this writing, magical autoincrement has not been extended to Unicode letters and digits, but it might be in the future.

The autodecrement operator, however, is not magical, and we have no plans to make it so.

Previous | Home | Next
3.2. The Arrow Operator | Book Index | 3.4. Exponentiation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.4. Exponentiation

Binary ** is the exponentiation operator. Note that it binds even more tightly than unary minus, so -2**4 is -(2**4), not (-2)**4. The operator is implemented using C's pow(3) function, which works with floating-point numbers internally. It calculates using logarithms, which means that it works with fractional powers, but you sometimes get results that aren't as exact as a straight multiplication would produce.

Previous | Home | Next
3.3. Autoincrement and Autodecrement | Book Index | 3.5. Ideographic Unary Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.5. Ideographic Unary Operators

Most unary operators just have names (see Section 3.10, "Named Unary and File Test Operators" later in this chapter), but some operators are deemed important enough to merit their own special symbolic representation. All of these operators seem to have something to do with negation. Blame the mathematicians.

Unary ! performs logical negation, that is, "not". See not for a lower precedence version of logical negation. The value of a negated operand is true (1) if the operand is false (numeric 0, string "0", the null string, or undefined) and false ("") if the operand is true.

Unary - performs arithmetic negation if the operand is numeric. If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. Otherwise, if the string starts with a plus or minus, a string starting with the opposite sign is returned. One effect of these rules is that -bareword is equivalent to "-bareword". This is most useful for Tk programmers.

Unary ~ performs bitwise negation, that is, 1's complement. By definition, this is somewhat nonportable when limited by the word size of your machine. For example, on a 32-bit machine, ~123 is 4294967172, while on a 64-bit machine, it's 18446744073709551492. But you knew that already.

What you perhaps didn't know is that if the argument to ~ happens to be a string instead of a number, a string of identical length is returned, but with all the bits of the string complemented. This is a fast way to flip a lot of bits all at once, and it's a way to flip those bits portably, since it doesn't depend on the word size of your computer. Later we'll also cover the bitwise logical operators, which have string-oriented variants as well.

Unary + has no semantic effect whatsoever, even on strings. It is syntactically useful for separating a function name from a parenthesized expression that would otherwise be interpreted as the complete list of function arguments. (See examples under the section Section 3.1, "Terms and List Operators (Leftward)".) If you think about it sideways, + negates the effect that parentheses have of turning prefix operators into functions.

Unary \ creates a reference to whatever follows it. Used on a list, it creates a list of references. See the section Section 3.2.1, "The Backslash Operator" in Chapter 8, "References" for details. Do not confuse this behavior with the behavior of backslash within a string, although both forms do convey the vaguely negational notion of protecting the next thing from interpretation. This resemblance is not entirely accidental.

Previous | Home | Next
3.4. Exponentiation | Book Index | 3.6. Binding Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.6. Binding Operators

Binary =~ binds a string expression to a pattern match, substitution, or transliteration (loosely called translation). These operations would otherwise search or modify the string contained in $_ (the default variable). The string you want to bind is put on the left, while the operator itself is put on the right. The return value indicates the success or failure of the operator on the right, since the binding operator doesn't really do anything on its own.

If the right argument is an expression rather than a pattern match, substitution, or transliteration, it will be interpreted as a search pattern at run time. That is to say, $_ =~ $pat is equivalent to $_ =~ /$pat/. This is less efficient than an explicit search, since the pattern must be checked and possibly recompiled every time the expression is evaluated. You can avoid this recompilation by precompiling the original pattern using the qr// (quote regex) operator.

Binary !~ is just like =~ except the return value is negated logically. The following expressions are functionally equivalent:

$string !~ /pattern/
not $string =~ /pattern/
We said that the return value indicates success, but there are many kinds of success. Substitutions return the number of successful matches, as do transliterations. (In fact, the transliteration operator is often used to count characters.) Since any nonzero result is true, it all works out. The most spectacular kind of true value is a list assignment of a pattern: in a list context, pattern matches can return substrings matched by the parentheses in the pattern. But again, according to the rules of list assignment, the list assignment itself will return true if anything matched and was assigned, and false otherwise. So you sometimes see things like:
if ( ($k,$v) = $string =~ m/(\w+)=(\w*)/ ) {
    print "KEY $k VALUE $v\n";
}
Let's pick that apart. The =~ has precedence over =, so =~ happens first. The =~ binds $string to the pattern match on the right, which is scanning for occurrences of things that look like KEY=VALUE in your string. It's in a list context because it's on the right side of a list assignment. If the pattern matches, it returns a list to be assigned to $k and $v. The list assignment itself is in a scalar context, so it returns 2, the number of values on the right side of the assignment. And 2 happens to be true, since our scalar context is also a Boolean context. When the match fails, no values are assigned, which returns 0, which is false.

For more on the politics of patterns, see Chapter 5, "Pattern Matching".

Previous | Home | Next
3.5. Ideographic Unary Operators | Book Index | 3.7. Multiplicative Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.7. Multiplicative Operators

Perl provides the C-like operators * (multiply), / (divide), and % (modulo). The * and / work exactly as you would expect, multiplying or dividing their two operands. Division is done in floating point, unless you've used the integer pragmatic module.

The % operator converts its operands to integers before finding the remainder according to integer division. (However, it does this integer division in floating point if necessary, so your operands can be up to 15 digits long on most 32-bit machines.) Assume that your two operands are called $a and $b. If $b is positive, then the result of $a % $b is $a minus the largest multiple of $b that is not greater than $a (which means the result will always be in the range 0 .. $b-1). If $b is negative, then the result of $a % $b is $a minus the smallest multiple of $b that is not less than $a (which means the result will be in the range $b+1 .. 0).

When use integer is in scope, % gives you direct access to the modulus operator as implemented by your C compiler. This operator is not well defined for negative operands, but will execute faster.

Binary x is the repetition operator. Actually, it's two operators. In scalar context, it returns a concatenated string consisting of the left operand repeated the number of times specified by the right operand. (For backward compatibility, it also does this in list context if the left argument is not in parentheses.)

print '-' x 80;                             # print row of dashes
print "\t" x ($tab/8), ' ' x ($tab%8);      # tab over
In list context, if the left operand is a list in parentheses, the x works as a list replicator rather than a string replicator. This is useful for initializing all the elements of an array of indeterminate length to the same value:
@ones = (1) x 80;           # a list of 80 1's
@ones = (5) x @ones;        # set all elements to 5
Similarly, you can also use x to initialize array and hash slices:
@keys = qw(perls before swine);
@hash{@keys} = ("") x @keys;
If this mystifies you, note that @keys is being used both as a list on the left side of the assignment and as a scalar value (returning the array length) on the right side of the assignment. The previous example has the same effect on %hash as:
$hash{perls}  = "";
$hash{before} = "";
$hash{swine}  = "";

Previous | Home | Next
3.6. Binding Operators | Book Index | 3.8. Additive Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.8. Additive Operators

Strangely enough, Perl also has the customary + (addition) and - (subtraction) operators. Both operators convert their arguments from strings to numeric values if necessary and return a numeric result.

Additionally, Perl provides the . operator, which does string concatenation. For example:

$almost = "Fred" . "Flintstone";    # returns FredFlintstone
Note that Perl does not place a space between the strings being concatenated. If you want the space, or if you have more than two strings to concatenate, you can use the join operator, described in Chapter 29, "Functions". Most often, though, people do their concatenation implicitly inside a double-quoted string:
$fullname = "$firstname $lastname";

Previous | Home | Next
3.7. Multiplicative Operators | Book Index | 3.9. Shift Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.9. Shift Operators

The bit-shift operators (<< and >>) return the value of the left argument shifted to the left (<<) or to the right (>>) by the number of bits specified by the right argument. The arguments should be integers. For example:

1 << 4;     # returns 16
32 >> 4;    # returns 2
Be careful, though. Results on large (or negative) numbers may vary depending on the number of bits your machine uses to represent integers.

Previous | Home | Next
3.8. Additive Operators | Book Index | 3.10. Named Unary and File Test Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.10. Named Unary and File Test Operators

Some of the "functions" described in Chapter 29, "Functions" are really unary operators. Table 3-2 lists all the named unary operators.

Table 3.2. Named Unary Operators

-X (file tests) | gethostbyname | localtime | return
alarm | getnetbyname | lock | rmdir
caller | getpgrp | log | scalar
chdir | getprotobyname | lstat | sin
chroot | glob | my | sleep
cos | gmtime | oct | sqrt
defined | goto | ord | srand
delete | hex | quotemeta | stat
do | int | rand | uc
eval | lc | readlink | ucfirst
exists | lcfirst | ref | umask
exit | length | require | undef

Unary operators have a higher precedence than some of the binary operators. For example:

sleep 4 | 3;
does not sleep for 7 seconds; it sleeps for 4 seconds and then takes the return value of sleep (typically zero) and bitwise ORs that with 3, as if the expression were parenthesized as:
(sleep 4) | 3;
Compare this with:
print 4 | 3;
which does take the value of 4 ORed with 3 before printing it (7 in this case), as if it were written:
print (4 | 3);
This is because print is a list operator, not a simple unary operator. Once you've learned which operators are list operators, you'll have no trouble telling unary operators and list operators apart. When in doubt, you can always use parentheses to turn a named unary operator into a function. Remember, if it looks like a function, it is a function.

Another funny thing about named unary operators is that many of them default to $_ if you don't supply an argument. However, if you omit the argument but the token following the named unary operator looks like it might be the start of an argument, Perl will get confused because it's expecting a term. Whenever the Perl tokener gets to one of the characters listed in Table 3-3, the tokener returns different token types depending on whether it expects a term or operator.

Table 3.3. Ambiguous Characters

Character | Operator | Term
+ | Addition | Unary plus
- | Subtraction | Unary minus
* | Multiplication | *typeglob
/ | Division | /pattern/
< | Less than, left shift | <HANDLE>, <<END
. | Concatenation | .3333
? | ?: | ?pattern?
% | Modulo | %assoc
& | &, && | &subroutine

So a typical boo-boo is:

next if length < 80;
in which the < looks to the parser like the beginning of the <> input symbol (a term) instead of the "less than" (an operator) you were thinking of. There's really no way to fix this and still keep Perl pathologically eclectic. If you're so incredibly lazy that you cannot bring yourself to type the two characters $_, then use one of these instead:
next if length() < 80;
next if (length) < 80;
next if 80 > length;
next unless length >= 80;
When a term is expected, a minus sign followed by a single letter will always be interpreted as a file test operator. A file test operator is a unary operator that takes one argument, either a filename or a filehandle, and tests the associated file to see whether something is true about it. If the argument is omitted, it tests $_, except for -t, which tests STDIN. Unless otherwise documented, it returns 1 for true and "" for false, or the undefined value if the file doesn't exist or is otherwise inaccessible. Currently implemented file test operators are listed in Table 3-4.

Table 3.4. File Test Operators

Operator | Meaning
-r | File is readable by effective UID/GID.
-w | File is writable by effective UID/GID.
-x | File is executable by effective UID/GID.
-o | File is owned by effective UID.
-R | File is readable by real UID/GID.
-W | File is writable by real UID/GID.
-X | File is executable by real UID/GID.
-O | File is owned by real UID.
-e | File exists.
-z | File has zero size.
-s | File has nonzero size (returns size).
-f | File is a plain file.
-d | File is a directory.
-l | File is a symbolic link.
-p | File is a named pipe (FIFO).
-S | File is a socket.
-b | File is a block special file.
-c | File is a character special file.
-t | Filehandle is opened to a tty.
-u | File has setuid bit set.
-g | File has setgid bit set.
-k | File has sticky bit set.
-T | File is a text file.
-B | File is a binary file (opposite of -T).
-M | Age of file (at startup) in days since modification.
-A | Age of file (at startup) in days since last access.
-C | Age of file (at startup) in days since inode change.

Note that -s/a/b/ does not do a negated substitution. Saying -exp($foo) still works as expected, however--only single letters following a minus are interpreted as file tests.

The interpretation of the file permission operators -r, -R, -w, -W, -x, and -X is based solely on the mode of the file and the user and group IDs of the user. There may be other reasons you can't actually read, write, or execute the file, such as Andrew File System (AFS) access control lists.[3] Also note that for the superuser, -r, -R, -w, and -W always return 1, and -x and -X return 1 if any execute bit is set in the mode. Thus, scripts run by the superuser may need to do a stat in order to determine the actual mode of the file or temporarily set the UID to something else.

[3]You may, however, override the built-in semantics with the use filetest pragma. See Chapter 31, "Pragmatic Modules".

The other file test operators don't care who you are. Anybody can use the test for "regular" files:

while (<>) {
    chomp;
    next unless -f $_;      # ignore "special" files
    ...
}

The -T and -B switches work as follows. The first block or so of the file is examined for strange characters such as control codes or bytes with the high bit set (that don't look like UTF-8). If more than a third of the bytes appear to be strange, it's a binary file; otherwise, it's a text file. Also, any file containing ASCII NUL (\0) in the first block is considered a binary file. If -T or -B is used on a filehandle, the current input (standard I/O or "stdio") buffer is examined rather than the first block of the file. Both -T and -B return true on an empty file, or on a file at EOF (end-of-file) when testing a filehandle. Because Perl has to read a file to do the -T test, you don't want to use -T on special files that might hang or give you other kinds of grief. So on most occasions you'll want to test with a -f first, as in:

next unless -f $file && -T $file;
If any of the file tests (or either the stat or lstat operator) are given the special filehandle consisting of a solitary underline, then the stat structure of the previous file test (or stat operator) is used, thereby saving a system call. (This doesn't work with -t, and you need to remember that lstat and -l will leave values in the stat structure for the symbolic link, not the real file. Likewise, -l _ will always be false after a normal stat.)

Here are a couple of examples:

print "Can do.\n" if -r $a || -w _ || -x _;

stat($filename);
print "Readable\n" if -r _;
print "Writable\n" if -w _;
print "Executable\n" if -x _;
print "Setuid\n" if -u _;
print "Setgid\n" if -g _;

print "Sticky\n" if -k _;
print "Text\n" if -T _;
print "Binary\n" if -B _;

File ages for -M, -A, and -C are returned in days (including fractional days) since the script started running. This time is stored in the special variable $^T ($BASETIME). Thus, if the file changed after the script started, you would get a negative time. Note that most time values (86,399 out of 86,400, on average) are fractional, so testing for equality with an integer without using the int function is usually futile. Examples:

next unless -M $file > .5;      # files are older than 12 hours
&newfile if -M $file < 0;       # file is newer than process
&mailwarning if int(-A) == 90;  # file ($_) was accessed 90 days ago today
To reset the script's start time to the current time, say this:
$^T = time;

Previous | Home | Next
3.9. Shift Operators | Book Index | 3.11. Relational Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.11. Relational Operators

Perl has two classes of relational operators. One class operates on numeric values, the other on string values, as shown in Table 3-5.

Table 3.5. Relational Operators

Numeric | String | Meaning
> | gt | Greater than
>= | ge | Greater than or equal to
< | lt | Less than
<= | le | Less than or equal to

These operators return 1 for true and "" for false. Note that relational operators are nonassociating, which means that $a < $b < $c is a syntax error.

In the absence of locale declarations, string comparisons are based on the ASCII/Unicode collating sequences, and, unlike in some computer languages, trailing spaces count in the comparison. With a locale declaration, the collation order specified by the locale is used. (Locale-based collation mechanisms may or may not interact well with the Unicode collation mechanisms currently in development.)

Previous | Home | Next
3.10. Named Unary and File Test Operators | Book Index | 3.12. Equality Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.12. Equality Operators

The equality operators listed in Table 3-6 are much like the relational operators.

Table 3.6. Equality Operators

Numeric | String | Meaning
== | eq | Equal to
!= | ne | Not equal to
<=> | cmp | Comparison, with signed result

The equal and not-equal operators return 1 for true and "" for false (just as the relational operators do). The <=> and cmp operators return -1 if the left operand is less than the right operand, 0 if they are equal, and +1 if the left operand is greater than the right. Although the equality operators appear to be similar to the relational operators, they do have a lower precedence level, so $a < $b <=> $c < $d is syntactically valid.

For reasons that are apparent to anyone who has seen Star Wars, the <=> operator is known as the "spaceship" operator.

Previous | Home | Next
3.11. Relational Operators | Book Index | 3.13. Bitwise Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.13. Bitwise Operators

Like C, Perl has bitwise AND, OR, and XOR (exclusive OR) operators: &, |, and ^. You'll have noticed from your painstaking examination of the table at the start of this chapter that bitwise AND has a higher precedence than the others, but we've cheated and combined them in this discussion.

These operators work differently on numeric values than they do on strings. (This is one of the few places where Perl cares about the difference.) If either operand is a number (or has been used as a number), both operands are converted to integers, and the bitwise operation is performed between the two integers. These integers are guaranteed to be at least 32 bits long, but can be 64 bits on some machines. The point is that there's an arbitrary limit imposed by the machine's architecture.

If both operands are strings (and have not been used as numbers since they were set), the operators do bitwise operations between corresponding bits from the two strings. In this case, there's no arbitrary limit, since strings aren't arbitrarily limited in size. If one string is longer than the other, the shorter string is considered to have a sufficient number of 0 bits on the end to make up the difference.

For example, if you AND together two strings:

"123.45" & "234.56"
you get another string:
"020.44"
But if you AND together a string and a number:
"123.45" & 234.56
The string is first converted to a number, giving:
123.45 & 234.56
The numbers are then converted to integers:
123 & 234
which evaluates to 106. Note that all bit strings are true (unless they result in the string "0"). This means if you want to see whether any byte came out to nonzero, instead of writing this:
if ( "fred" & "\1\2\3\4" ) { ... }
you need to write this:
if ( ("fred" & "\1\2\3\4") =~ /[^\0]/ ) { ... }

Previous | Home | Next
3.12. Equality Operators | Book Index | 3.14. C-Style Logical (Short-Circuit) Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.14. C-Style Logical (Short-Circuit) Operators

Like C, Perl provides the && (logical AND) and || (logical OR) operators. They evaluate from left to right (with && having slightly higher precedence than ||) testing the truth of the statement. These operators are known as short-circuit operators because they determine the truth of the statement by evaluating the fewest number of operands possible. For example, if the left operand of an && operator is false, the right operand is never evaluated because the result of the operator is false regardless of the value of the right operand.

Example | Name | Result
$a && $b | And | $a if $a is false, $b otherwise
$a || $b | Or | $a if $a is true, $b otherwise

Such short circuits not only save time, but are frequently used to control the flow of evaluation. For example, an oft-appearing idiom in Perl programs is:

open(FILE, "somefile") || die "Can't open somefile: $!\n";
In this case, Perl first evaluates the open function. If the value is true (because somefile was successfully opened), the execution of the die function is unnecessary, and so is skipped. You can read this literally as "Open some file or die!"

The && and || operators differ from C's in that, rather than returning 0 or 1, they return the last value evaluated. In the case of ||, this has the delightful result that you can select the first of a series of scalar values that happens to be true. Thus, a reasonably portable way to find out the user's home directory might be:

$home = $ENV{HOME}
     || $ENV{LOGDIR}
     || (getpwuid($<))[7]
     || die "You're homeless!\n";
On the other hand, since the left argument is always evaluated in scalar context, you can't use || for selecting between two aggregates for assignment:
@a = @b || @c;             # This doesn't do the right thing
@a = scalar(@b) || @c;     # because it really means this.
@a = @b ? @b : @c;         # This works fine, though.
Perl also provides lower precedence and and or operators that some people find more readable and don't force you to use parentheses on list operators. They also short-circuit. See Table 3-1 for a complete list.

Previous | Home | Next
3.13. Bitwise Operators | Book Index | 3.15. Range Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.15. Range Operator

The .. range operator is really two different operators depending on the context.

In scalar context, .. returns a Boolean value. The operator is bi-stable, like an electronic flip-flop, and emulates the line-range (comma) operator of sed, awk, and various editors. Each scalar .. operator maintains its own Boolean state. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, after which the range operator becomes false again. The operator doesn't become false until the next time it is evaluated. It can test the right operand and become false on the same evaluation as the one where it became true (the way awk's range operator behaves), but it still returns true once. If you don't want it to test the right operand until the next evaluation (which is how sed's range operator works), just use three dots (...) instead of two. With both .. and ..., the right operand is not evaluated while the operator is in the false state, and the left operand is not evaluated while the operator is in the true state.

The value returned is either the null string for false or a sequence number (beginning with 1) for true. The sequence number is reset for each range encountered. The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the endpoint. You can exclude the beginning point by waiting for the sequence number to be greater than 1. If either operand of scalar .. is a numeric literal, that operand implicitly compared to the $. variable, which contains the current line number for your input file. Examples:

if (101 .. 200) { print; }  # print 2nd hundred lines
next line if (1 .. /^$/);   # skip header lines
s/^/> / if (/^$/ .. eof()); # quote body
In list context, .. returns a list of values counting (by ones) from the left value to the right value. This is useful for writing for (1..10) loops and for doing slice operations on arrays:
for (101 .. 200) { print; }            # prints 101102...199200
@foo = @foo[0 .. $#foo];               # an expensive no-op
@foo = @foo[ -5 .. -1];                # slice last 5 items
If the left value is greater than the right value, a null list is returned. (To produce a list in reverse order, see the reverse operator.)

If its operands are strings, the range operator makes use of the magical autoincrement algorithm discussed earlier.[4] So you can say:

@alphabet = ('A' .. 'Z');
to get all the letters of the (English) alphabet, or:
$hexdigit = (0 .. 9, 'a' .. 'f')[$num & 15];
to get a hexadecimal digit, or:
@z2 = ('01' .. '31');  print $z2[$mday];
to get dates with leading zeros. You can also say:
@combos = ('aa' .. 'zz');
to get all combinations of two lowercase letters. However, be careful of something like:
@bigcombos = ('aaaaaa' .. 'zzzzzz');
since that will require lots of memory. More precisely, it'll need space to store 308,915,776 scalars. Let's hope you allocated a very large swap partition. Perhaps you should consider an iterative approach instead.

[4] If the final value specified is not in the sequence that the magical increment would produce, the sequence continues until the next value is longer than the final value specified.

Previous | Home | Next
3.14. C-Style Logical (Short-Circuit) Operators | Book Index | 3.16. Conditional Operator
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.16. Conditional Operator

As in C, ?: is the only trinary operator. It's often called the conditional operator because it works much like an if-then-else, except that, since it's an expression and not a statement, it can be safely embedded within other expressions and functions calls. As a trinary operator, its two parts separate three expressions:

COND ? THEN : ELSE
If the condition COND is true, only the THEN expression is evaluated, and the value of that expression becomes the value of the entire expression. Otherwise, only the ELSE expression is evaluated, and its value becomes the value of the entire expression.

Scalar or list context propagates downward into the second or third argument, whichever is selected. (The first argument is always in scalar context, since it's a conditional.)

$a = $ok ? $b : $c;  # get a scalar
@a = $ok ? @b : @c;  # get an array
$a = $ok ? @b : @c;  # get a count of an array's elements
You'll often see the conditional operator embedded in lists of values to format with printf, since nobody wants to replicate the whole statement just to switch between two related values.
printf "I have %d camel%s.\n",
               $n,     $n == 1 ? "" : "s";
Conveniently, the precedence of ?: is higher than a comma but lower than most operators you'd use inside (such as == in this example), so you don't usually have to parenthesize anything. But you can add parentheses for clarity if you like. For conditional operators nested within the THEN parts of other conditional operators, we suggest that you put in line breaks and indent as if they were ordinary if statements:
$leapyear =
    $year % 4 == 0
        ? $year % 100 == 0
            ? $year % 400 == 0
                ? 1
                : 0
            : 1
        : 0;
For conditionals nested within the ELSE parts of earlier conditionals, you can do a similar thing:
$leapyear =
    $year % 4
        ? 0
        : $year % 100
          ? 1
          : $year % 400
            ? 0
            : 1;
but it's usually better to line up all the COND and THEN parts vertically:
$leapyear =
    $year %   4 ? 0 :
    $year % 100 ? 1 :
    $year % 400 ? 0 : 1;
Lining up the question marks and colons can make sense of even fairly cluttered structures:
printf "Yes, I like my %s book!\n",
    $i18n eq "french"   ? "chameau"          :
    $i18n eq "german"   ? "Kamel"            :
    $i18n eq "japanese" ? "\x{99F1}\x{99DD}" :
                          "camel"
You can assign to the conditional operator[5] if both the second and third arguments are legal lvalues (meaning that you can assign to them), and both are scalars or both are lists (otherwise, Perl won't know which context to supply to the right side of the assignment):
($a_or_b ? $a : $b) = $c;  # sets either $a or $b to have the value of $c
Bear in mind that the conditional operator binds more tightly than the various assignment operators. Usually this is what you want (see the $leapyear assignments above, for example), but you can't have it the other way without using parentheses. Using embedded assignments without parentheses will get you into trouble, and you might not get a parse error because the conditional operator can be parsed as an lvalue. For example, you might write this:
$a % 2 ? $a += 10 : $a += 2        # WRONG
But that would be parsed like this:
(($a % 2) ? ($a += 10) : $a) += 2

[5] This is not necessarily guaranteed to contribute to the readability of your program. But it can be used to create some cool entries in an Obfuscated Perl contest.

Previous | Home | Next
3.15. Range Operator | Book Index | 3.17. Assignment Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.17. Assignment Operators

Perl recognizes the C assignment operators, as well as providing some of its own. There are quite a few of them:

=    **=    +=    *=    &=    <<=    &&=
            -=    /=    |=    >>=    ||=
            .=    %=    ^=
                  x=
Each operator requires a target lvalue (typically a variable or array element) on the left side and an expression on the right side. For the simple assignment operator:
TARGET = EXPR
the value of the EXPR is stored into the variable or location designated by TARGET. For the other operators, Perl evaluates the expression:
TARGET OP= EXPR
as if it were written:
TARGET = TARGET OP EXPR
That's a handy mental rule, but it's misleading in two ways. First, assignment operators always parse at the precedence level of ordinary assignment, regardless of the precedence that OP would have by itself. Second, TARGET is evaluated only once. Usually that doesn't matter unless there are side effects, such as an autoincrement:
$var[$a++] += $value;               # $a is incremented once
$var[$a++] = $var[$a++] + $value;   # $a is incremented twice
Unlike in C, the assignment operator produces a valid lvalue. Modifying an assignment is equivalent to doing the assignment and then modifying the variable to which it was assigned. This is useful for modifying a copy of something, like this:
($tmp = $global) += $constant;
which is the equivalent of:
$tmp = $global + $constant;
Likewise:
($a += 2) *= 3;
is equivalent to:
$a += 2;
$a *= 3;
That's not terribly useful, but here's an idiom you see frequently:
($new = $old) =~ s/foo/bar/g;
In all cases, the value of the assignment is the new value of the variable. Since assignment operators associate right-to-left, this can be used to assign many variables the same value, as in:
$a = $b = $c = 0;
which assigns 0 to $c, and the result of that (still 0) to $b, and the result of that (still 0) to $a.

List assignment may be done only with the plain assignment operator, =. In list context, list assignment returns the list of new values just as scalar assignment does. In scalar context, list assignment returns the number of values that were available on the right side of the assignment, as mentioned in Chapter 2, "Bits and Pieces". This makes it useful for testing functions that return a null list when unsuccessful (or no longer successful), as in:

while (($key, $value) = each %gloss) { ... }

next unless ($dev, $ino, $mode) = stat $file;

Previous | Home | Next
3.16. Conditional Operator | Book Index | 3.18. Comma Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.18. Comma Operators

Binary "," is the comma operator. In scalar context it evaluates its left argument in void context, throws that value away, then evaluates its right argument in scalar context and returns that value. This is just like C's comma operator. For example:

$a = (1, 3);
assigns 3 to $a. Do not confuse the scalar context use with the list context use. In list context, a comma is just the list argument separator, and inserts both its arguments into the LIST. It does not throw any values away.

For example, if you change the previous example to:

@a = (1, 3);
you are constructing a two-element list, while:
atan2(1, 3);
is calling the function atan2 with two arguments.

The => digraph is mostly just a synonym for the comma operator. It's useful for documenting arguments that come in pairs. It also forces any identifier to its immediate left to be interpreted as a string.

Previous | Home | Next
3.17. Assignment Operators | Book Index | 3.19. List Operators (Rightward)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.19. List Operators (Rightward)

The right side of a list operator governs all the list operator's arguments, which are comma separated, so the precedence of a list operator is lower than a comma if you're looking to the right. Once a list operator starts chewing up comma-separated arguments, the only things that will stop it are tokens that stop the entire expression (like semicolons or statement modifiers), or tokens that stop the current subexpression (like right parentheses or brackets), or the low precedence logical operators we'll talk about next.

Previous | Home | Next
3.18. Comma Operators | Book Index | 3.20. Logical and, or, not, and xor
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.20. Logical and, or, not, and xor

As lower precedence alternatives to &&, ||, and !, Perl provides the and, or, and not operators. The behavior of these operators is identical--in particular, and and or short-circuit like their counterparts, which makes them useful not only for logical expressions but also for control flow.

Since the precedence of these operators is much lower than the ones borrowed from C, you can safely use them after a list operator without the need for parentheses:

unlink "alpha", "beta", "gamma"
        or gripe(), next LINE;
With the C-style operators you'd have to write it like this:
unlink("alpha", "beta", "gamma")
        || (gripe(), next LINE);
But you can't just up and replace all instances of || with or. Suppose you change this:
$xyz = $x || $y || $z;
to this:
$xyz = $x or $y or $z;    # WRONG
That wouldn't do the same thing at all! The precedence of the assignment is higher than or but lower than ||, so it would always assign $x to $xyz, and then do the ors. To get the same effect as ||, you'd have to write:
$xyz = ( $x or $y or $z );

The moral of the story is that you still must learn precedence (or use parentheses) no matter which variety of logical operators you use.

There is also a logical xor operator that has no exact counterpart in C or Perl, since the only other exclusive-OR operator ((^)) works on bits. The xor operator can't short-circuit, since both sides must be evaluated. The best equivalent for $a xor $b is perhaps !$a != !$b. One could also write !$a ^ !$b or even $a ? !$b : !!$b, of course. The point is that both $a and $b have to evaluate to true or false in a Boolean context, and the existing bitwise operator doesn't provide a Boolean context without help.

Previous | Home | Next
3.19. List Operators (Rightward) | Book Index | 3.21. C Operators Missing from Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


3.21. C Operators Missing from Perl

Here is what C has that Perl doesn't:

unary &

The address-of operator. Perl's \ operator (for taking a reference) fills the same ecological niche, however:

$ref_to_var = \$var;
But Perl references are much safer than C pointers.

unary *

The dereference-address operator. Since Perl doesn't have addresses, it doesn't need to dereference addresses. It does have references though, so Perl's variable prefix characters serve as dereference operators, and indicate type as well: $, @, %, and &. Oddly enough, there actually is a * dereference operator, but since * is the funny character indicating a typeglob, you wouldn't use it the same way.

(TYPE)

The typecasting operator. Nobody likes to be typecast anyway.

Previous | Home | Next
3.20. Logical and, or, not, and xor | Book Index | 4. Statements and Declarations
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 4. Statements and Declarations

Contents:

Simple Statements
Compound Statements
if and unless Statements
Loop Statements
Bare Blocks
goto
Global Declarations
Scoped Declarations
Pragmas

A Perl program consists of a sequence of declarations and statements. A declaration may be placed anywhere a statement may be placed, but its primary effect occurs at compile time. A few declarations do double duty as ordinary statements, but most are totally transparent at run time. After compilation, the main sequence of statements is executed just once.

Unlike many programming languages, Perl doesn't require variables to be explicitly declared; they spring into existence upon their first use, whether you've declared them or not. If you try to use a value from a variable that's never had a value assigned to it, it's quietly treated as 0 when used as a number, as "" (the null string) when used as a string, or simply as false when used as a logical value. If you prefer to be warned about using undefined values as though they were real strings or numbers, or even to treat doing so as an error, the use warnings declaration will take care of that; see the section Section 4.9, "Pragmas" at the end of this chapter.

You may declare your variables though, if you like, using either my or our in front of the variable name. You can even make it an error to use an undeclared variable. This kind of discipline is fine, but you have to declare that you want the discipline. Normally, Perl minds its own business about your programming habits, but under the use strict declaration, the use of undeclared variables is apprehended at compile time. Again, see Section 4.9, "Pragmas".

4.1. Simple Statements

A simple statement is an expression evaluated for its side effects. Every simple statement must end in a semicolon, unless it is the final statement in a block. In that case, the semicolon is optional--Perl knows that you must be done with the statement, since you've finished the block. But put the semicolon in anyway if it's at the end of a multiline block, because you might eventually add another line.

Even though operators like eval {}, do {}, and sub {} all look like compound statements, they really aren't. True, they allow multiple statements on the inside, but that doesn't count. From the outside, those operators are just terms in an expression, and thus they need an explicit semicolon if used as the last item in a statement.

Any simple statement may optionally be followed by a single modifier, just before the terminating semicolon (or block ending). The possible modifiers are:

if EXPR
unless EXPR
while EXPR
until EXPR
foreach LIST
The if and unless modifiers work pretty much as they do in English:
$trash->take('out') if $you_love_me;
shutup() unless $you_want_me_to_leave;

The while and until modifiers evaluate repeatedly. As you might expect, a while modifier keeps executing the expression as long as its expression remains true, and an until modifier keeps executing only as long as it remains false:

$expression++ while -e "$file$expression";
kiss('me') until $I_die;

The foreach modifier (also spelled for) evaluates once for each element in its LIST, with $_ aliased to the current element:

s/java/perl/ for @resumes;
print "field: $_\n" foreach split /:/, $dataline;

The while and until modifiers have the usual while-loop semantics (conditional evaluated first), except when applied to a do BLOCK (or to the now-deprecated do SUBROUTINE statement), in which case the block executes once before the conditional is evaluated. This allows you to write loops like this:

do {
    $line = <STDIN>;
    ...
} until $line eq ".\n";
See the three different do entries in Chapter 29, "Functions". Note also that the loop-control operators described later will not work in this construct, since modifiers don't take loop labels. You can always place an extra block around it to terminate early, or inside it to iterate early, as described later in the section Section 4.5, "Bare Blocks". Or you could write a real loop with multiple loop controls inside. Speaking of real loops, we'll talk about compound statements next.

Previous | Home | Next
3.21. C Operators Missing from Perl | Book Index | 4.2. Compound Statements
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.2. Compound Statements

A sequence of statements within a scope[1] is called a block. Sometimes the scope is the entire file, such as a required file or the file containing your main program. Sometimes the scope is a string being evaluated with eval. But generally, a block is surrounded by braces ({}). When we say scope, we mean any of these three. When we mean a block with braces, we'll use the term BLOCK.

[1]Scopes and namespaces are described in Chapter 2, "Bits and Pieces", in Section 4.5, "Names".

Compound statements are built out of expressions and BLOCKs. Expressions are built out of terms and operators. In our syntax descriptions, we'll use the word EXPR to indicate a place where you can use any scalar expression. To indicate an expression evaluated in list context, we'll say LIST.

The following statements may be used to control conditional and repeated execution of BLOCKs. (The LABEL portion is optional.)

if (EXPR) BLOCK
if (EXPR) BLOCK else BLOCK
if (EXPR) BLOCK elsif (EXPR) BLOCK ...
if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK

unless (EXPR) BLOCK
unless (EXPR) BLOCK else BLOCK
unless (EXPR) BLOCK elsif (EXPR) BLOCK ...
unless (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK

LABEL while (EXPR) BLOCK
LABEL while (EXPR) BLOCK continue BLOCK

LABEL until (EXPR) BLOCK
LABEL until (EXPR) BLOCK continue BLOCK

LABEL for (EXPR; EXPR; EXPR) BLOCK

LABEL foreach (LIST) BLOCK
LABEL foreach VAR (LIST) BLOCK
LABEL foreach VAR (LIST) BLOCK continue BLOCK

LABEL BLOCK
LABEL BLOCK continue BLOCK
Note that unlike in C and Java, these are defined in terms of BLOCKs, not statements. This means that the braces are required--no dangling statements allowed. If you want to write conditionals without braces there are several ways to do so. The following all do the same thing:
unless (open(FOO, $foo))    { die "Can't open $foo: $!" }
if (!open(FOO, $foo))       { die "Can't open $foo: $!" }

die "Can't open $foo: $!"   unless open(FOO, $foo);
die "Can't open $foo: $!"   if !open(FOO, $foo);

open(FOO, $foo)             || die "Can't open $foo: $!";
open FOO, $foo              or die "Can't open $foo: $!";
Under most circumstances, we tend to prefer the last pair. These forms come with less eye-clutter than the others, especially the "or die" version. With the || form you need to get used to using parentheses religiously, but with the or version, it doesn't matter if you forget.

But the main reason we like the last versions better is because of how they pull the important part of the statement right up to the front of the line where you'll see it first. The error handling is shoved off to the side so that you don't have to pay attention to it unless you want to.[2] If you tab all your "or die" checks over to the same column on the right each time, it's even easier to read:

chdir $dir                  or die "chdir $dir: $!";
open FOO, $file             or die "open $file: $!";
@lines = <FOO>              or die "$file is empty?";
close FOO                   or die "close $file: $!";

[2] (Like this footnote.)

Previous | Home | Next
4.1. Simple Statements | Book Index | 4.3. if and unless Statements
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.3. if and unless Statements

The if statement is straightforward. Because BLOCKs are always bounded by braces, there is never any ambiguity regarding which particular if an else or elsif goes with. In any given sequence of if/elsif/else BLOCKs, only the first one whose condition evaluates to true is executed. If none of them is true, then the else BLOCK, if there is one, is executed. It's usually a good idea to put an else at the end of a chain of elsifs to guard against a missed case.

If you use unless in place of if, the sense of its test is reversed. That is:

unless ($x == 1) ...
is equivalent to:
if ($x != 1) ...
or even to the unsightly:
if (!($x == 1)) ...

The scope of a variable declared in the controlling condition extends from its declaration through the rest of that conditional only, including any elsifs and the final else clause if present, but not beyond:

if ((my $color = <STDIN>) =~ /red/i) {
    $value = 0xff0000;
}
elsif ($color =~ /green/i) {
    $value = 0x00ff00;
}
elsif ($color =~ /blue/i) {
    $value = 0x0000ff;
}
else {
    warn "unknown RGB component `$color', using black instead\n";
    $value = 0x000000;
}
After the else, the $color variable is no longer in scope. If you want the scope to extend further, declare the variable beforehand.

Previous | Home | Next
4.2. Compound Statements | Book Index | 4.4. Loop Statements
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.4. Loop Statements

All loop statements have an optional LABEL in their formal syntax. (You can put a label on any statement, but it has a special meaning to a loop.) If present, the label consists of an identifier followed by a colon. It's customary to make the label uppercase to avoid potential confusion with reserved words, and so it stands out better. And although Perl won't get confused if you use a label that already has a meaning like if or open, your readers might.

4.4.1. while and until Statements

The while statement repeatedly executes the block as long as EXPR is true. If the word while is replaced by the word until, the sense of the test is reversed; that is, it executes the block only as long as EXPR remains false. The conditional is still tested before the first iteration, though.

The while or until statement can have an optional extra block: the continue block. This block is executed every time the block is continued, either by falling off the end of the first block or by an explicit next (a loop-control operator that goes to the next iteration). The continue block is not heavily used in practice, but it's in here so we can define the for loop rigorously in the next section.

Unlike the foreach loop we'll see in a moment, a while loop never implicitly localizes any variables in its test condition. This can have "interesting" consequences when while loops use globals for loop variables. In particular, see the section Section 4.11.2, "Line Input (Angle) Operator" in Chapter 2, "Bits and Pieces" for how implicit assignment to the global $_ can occur in certain while loops, along with an example of how to deal with the problem by explicitly localizing $_. For other loop variables, however, it's best to declare them with my, as in the next example.

A variable declared in the test condition of a while or until statement is visible only in the block or blocks governed by that test. It is not part of the surrounding scope. For example:

while (my $line = <STDIN>) {
    $line = lc $line;
}
continue {
    print $line;   # still visible
}
# $line now out of scope here
Here the scope of $line extends from its declaration in the control expression throughout the rest of the loop construct, including the continue block, but not beyond. If you want the scope to extend further, declare the variable before the loop.

4.4.2. for Loops

The three-part for loop has three semicolon-separated expressions within its parentheses. These expressions function respectively as the initialization, the condition, and the re-initialization expressions of the loop. All three expressions are optional (but not the semicolons); if omitted, the condition is always true. Thus, the three-part for loop can be defined in terms of the corresponding while loop. This:

LABEL:
  for (my $i = 1; $i <= 10; $i++) {
      ...
  }
is like this:
{
    my $i = 1;
  LABEL:
    while ($i <= 10) {
        ...
    }

    continue {
        $i++;
    }
}
except that there's not really an outer block. (We just put one there to show how the scope of the my is limited.)

If you want to iterate through two variables simultaneously, just separate the parallel expressions with commas:

for ($i = 0, $bit = 0; $i < 32; $i++, $bit <<= 1) {
    print "Bit $i is set\n" if $mask & $bit;
}
# the values in $i and $bit persist past the loop

Or declare those variables to be visible only inside the for loop:

for (my ($i, $bit) = (0, 1); $i < 32; $i++, $bit <<= 1) {
    print "Bit $i is set\n" if $mask & $bit;
}
# loop's versions of $i and $bit now out of scope
Besides the normal looping through array indices, for can lend itself to many other interesting applications. It doesn't even need an explicit loop variable. Here's one example that avoids the problem you get when you explicitly test for end-of-file on an interactive file descriptor, causing your program to appear to hang.
$on_a_tty = -t STDIN && -t STDOUT;
sub prompt { print "yes? " if $on_a_tty }
for ( prompt(); <STDIN>; prompt() ) {
    # do something
}

Another traditional application for the three-part for loop results from the fact that all three expressions are optional, and the default condition is true. If you leave out all three expressions, you have written an infinite loop:

for (;;) {
    ...
}
This is the same as writing:
while (1) {
    ...
}

If the notion of infinite loops bothers you, we should point out that you can always fall out of the loop at any point with an explicit loop-control operator such as last. Of course, if you're writing the code to control a cruise missile, you may not actually need an explicit loop exit. The loop will be terminated automatically at the appropriate moment.[3]

[3] That is, the fallout from the loop tends to occur automatically.

4.4.3. foreach Loops

The foreach loop iterates over a list of values by setting the control variable (VAR) to each successive element of the list:

foreach VAR (LIST) {
    ...
}

The foreach keyword is just a synonym for the for keyword, so you can use foreach and for interchangeably, whichever you think is more readable in a given situation. If VAR is omitted, the global $_ is used. (Don't worry--Perl can easily distinguish for (@ARGV) from for ($i=0; $i<$#ARGV; $i++) because the latter contains semicolons.) Here are some examples:

$sum = 0; foreach $value (@array) { $sum += $value }

for $count (10,9,8,7,6,5,4,3,2,1,'BOOM') {  # do a countdown
    print "$count\n"; sleep(1);
}

for (reverse 'BOOM', 1 .. 10) {             # same thing
    print "$_\n"; sleep(1);
}

for $field (split /:/, $data) {             # any LIST expression
    print "Field contains: `$field'\n";
}

foreach $key (sort keys %hash) {
    print "$key => $hash{$key}\n";
}

That last one is the canonical way to print out the values of a hash in sorted order. See the keys and sort entries in Chapter 29, "Functions" for more elaborate examples.

There is no way with foreach to tell where you are in a list. You may compare adjacent elements by remembering the previous one in a variable, but sometimes you just have to break down and write a three-part for loop with subscripts. That's what the other kind of for loop is there for, after all.

If LIST consists entirely of assignable values (meaning variables, generally, not enumerated constants), you can modify each of those variables by modifying VAR inside the loop. That's because the foreach loop index variable is an implicit alias for each item in the list that you're looping over. Not only can you modify a single array in place, you can also modify multiple arrays and hashes in a single list:

foreach $pay (@salaries) {               # grant 8% raises
    $pay *= 1.08;
}

for (@christmas, @easter) {              # change menu
    s/ham/turkey/;
}
s/ham/turkey/ for @christmas, @easter;   # same thing

for ($scalar, @array, values %hash) {
    s/^\s+//;                            # strip leading  whitespace
    s/\s+$//;                            # strip trailing whitespace
}

The loop variable is valid only from within the dynamic or lexical scope of the loop and will be implicitly lexical if the variable was previously declared with my. This renders it invisible to any function defined outside the lexical scope of the variable, even if called from within that loop. However, if no lexical declaration is in scope, the loop variable will be a localized (dynamically scoped) global variable; this allows functions called from within the loop to access that variable. In either case, any previous value the localized variable had before the loop will be restored automatically upon loop exit.

If you prefer, you may explicitly declare which kind of variable (lexical or global) to use. This makes it easier for maintainers of your code to know what's really going on; otherwise, they'll need to search back up through enclosing scopes for a previous declaration to figure out which kind of variable it is:

for my  $i    (1 .. 10) { ... }         # $i always lexical
for our $Tick (1 .. 10) { ... }         # $Tick always global
When a declaration accompanies the loop variable, the shorter for spelling is preferred over foreach, since it reads better in English.

Here's how a C or Java programmer might first think to code up a particular algorithm in Perl:

for ($i = 0; $i < @ary1; $i++) {
    for ($j = 0; $j < @ary2; $j++) {
        if ($ary1[$i] > $ary2[$j]) {
            last;         # Can't go to outer loop. :-(
        }
        $ary1[$i] += $ary2[$j];
    }
    # this is where that last takes me
}
But here's how a veteran Perl programmer might do it:
WID: foreach $this (@ary1) {
    JET: foreach $that (@ary2) {
        next WID if $this > $that;
        $this += $that;
    }
}
See how much easier that was in idiomatic Perl? It's cleaner, safer, and faster. It's cleaner because it's less noisy. It's safer because if code gets added between the inner and outer loops later on, the new code won't be accidentally executed, since next (explained below) explicitly iterates the outer loop rather than merely breaking out of the inner one. And it's faster because Perl executes a foreach statement more rapidly than it would the equivalent for loop, since the elements are accessed directly instead of through subscripting.

But write it however you like. TMTOWTDI.

Like the while statement, the foreach statement can also take a continue block. This lets you execute a bit of code at the bottom of each loop iteration no matter whether you got there in the normal course of events or through a next.

Speaking of which, now we can finally say it: next is next.

4.4.4. Loop Control

We mentioned that you can put a LABEL on a loop to give it a name. The loop's LABEL identifies the loop for the loop-control operators next, last, and redo. The LABEL names the loop as a whole, not just the top of the loop. Hence, a loop-control operator referring to the loop doesn't actually "go to" the loop label itself. As far as the computer is concerned, the label could just as easily have been placed at the end of the loop. But people like things labeled at the top, for some reason.

Loops are typically named for the item the loop is processing on each iteration. This interacts nicely with the loop-control operators, which are designed to read like English when used with an appropriate label and a statement modifier. The archetypal loop works on lines, so the archetypal loop label is LINE:, and the archetypal loop-control operator is something like this:

next LINE if /^#/;      # discard comments

The syntax for the loop-control operators is:

last LABEL
next LABEL
redo LABEL
The LABEL is optional; if omitted, the operator refers to the innermost enclosing loop. But if you want to jump past more than one level, you must use a LABEL to name the loop you want to affect. That LABEL does not have to be in your lexical scope, though it probably ought to be. But in fact, the LABEL can be anywhere in your dynamic scope. If this forces you to jump out of an eval or subroutine, Perl issues a warning (upon request).

Just as you may have as many return operators in a function as you like, you may have as many loop-control operators in a loop as you like. This is not to be considered wicked or even uncool. During the early days of structured programming, some people insisted that loops and subroutines have only one entry and one exit. The one-entry notion is still a good idea, but the one-exit notion has led people to write a lot of unnatural code. Much of programming consists of traversing decision trees. A decision tree naturally starts with a single trunk but ends with many leaves. Write your code with the number of loop exits (and function returns) that is natural to the problem you're trying to solve. If you've declared your variables with reasonable scopes, everything gets automatically cleaned up at the appropriate moment, no matter how you leave the block.

The last operator immediately exits the loop in question. The continue block, if any, is not executed. The following example bombs out of the loop on the first blank line:

LINE: while (<STDIN>) {
    last LINE if /^$/;      # exit when done with mail header
    ...
}

The next operator skips the rest of the current iteration of the loop and starts the next one. If there is a continue clause on the loop, it is executed just before the condition is re-evaluated, just like the third component of a three-part for loop. Thus it can be used to increment a loop variable, even when a particular iteration of the loop has been interrupted by a next:

LINE: while (<STDIN>) {
    next LINE if /^#/;      # skip comments
    next LINE if /^$/;      # skip blank lines
    ...
} continue {
    $count++;
}

The redo operator restarts the loop block without evaluating the conditional again. The continue block, if any, is not executed. This operator is often used by programs that want to fib to themselves about what was just input. Suppose you were processing a file that sometimes had a backslash at the end of a line to continue the record on the next line. Here's how you could use redo for that:

while (<>) {
    chomp;
    if (s/\\$//) {
        $_ .= <>;
        redo unless eof;    # don't read past each file's eof
    }
    # now process $_
}
which is the customary Perl shorthand for the more explicitly (and tediously) written version:
LINE: while (defined($line = <ARGV>)) {
    chomp($line);
    if ($line =~ s/\\$//) {
        $line .= <ARGV>;
        redo LINE unless eof(ARGV);
    }
    # now process $line
}
Here's an example from a real program that uses all three loop-control operators. Although this particular strategy of parsing command-line arguments is less common now that we have the Getopts::* modules bundled with Perl, it's still a nice illustration of the use of loop-control operators on named, nested loops:
ARG: while (@ARGV && $ARGV[0] =~ s/^-(?=.)//) {
    OPT: for (shift @ARGV) {
         m/^$/       && do {                             next ARG; };
         m/^-$/      && do {                             last ARG; };
         s/^d//      && do { $Debug_Level++;             redo OPT; };
         s/^l//      && do { $Generate_Listing++;        redo OPT; };
         s/^i(.*)//  && do { $In_Place = $1 || ".bak";   next ARG; };
         say_usage("Unknown option: $_");
    }
}
One more point about loop-control operators. You may have noticed that we are not calling them "statements". That's because they aren't statements--although like any expression, they can be used as statements. You can almost think of them as unary operators that just happen to cause a change in control flow. So you can use them anywhere it makes sense to use them in an expression. In fact, you can even use them where it doesn't make sense. One sometimes sees this coding error:
open FILE, $file
     or warn "Can't open $file: $!\n", next FILE;   # WRONG
The intent is fine, but the next FILE is being parsed as one of the arguments to warn, which is a list operator. So the next executes before the warn gets a chance to emit the warning. In this case, it's easily fixed by turning the warn list operator into the warn function call with some suitably situated parentheses:
open FILE, $file
     or warn("Can't open $file: $!\n"), next FILE;   # okay
However, you might find it easier to read this:
unless (open FILE, $file) {
     warn "Can't open $file: $!\n";
     next FILE;
}

Previous | Home | Next
4.3. if and unless Statements | Book Index | 4.5. Bare Blocks
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.5. Bare Blocks

A BLOCK by itself (labeled or not) is semantically equivalent to a loop that executes once. Thus you can use last to leave the block or redo to restart the block.[4] Note that this is not true of the blocks in eval {}, sub {}, or, much to everyone's surprise, do {}. These three are not loop blocks because they're not BLOCKs by themselves; the keyword in front makes them mere terms in an expression that just happen to include a code block. Since they're not loop blocks, they cannot be given a label to apply loop controls to. Loop controls may only be used on true loops, just as a return may only be used within a subroutine (well, or an eval).

[4] For reasons that may (or may not) become clear upon reflection, a next also exits the once-through block. There is a slight difference, however: a next will execute a continue block, but a last won't.

Loop controls don't work in an if or unless, either, since those aren't loops. But you can always introduce an extra set of braces to give yourself a bare block, which does count as a loop:

if (/pattern/) {{
    last if /alpha/;
    last if /beta/;
    last if /gamma/;
    # do something here only if still in if()
}}

Here's how a block can be used to let loop-control operators work with a do{} construct. To next or redo a do, put a bare block inside:

do {{
    next if $x == $y;
    # do something here
}} until $x++ > $z;

For last, you have to be more elaborate:

{
    do {
        last if $x = $y ** 2;
        # do something here
    } while $x++ <= $z;
}
And if you want both loop controls available, you'll have put a label on those blocks so you can tell them apart:
DO_LAST: {
            do {
DO_NEXT:          {
                    next DO_NEXT if $x == $y;
                    last DO_LAST if $x =  $y ** 2;
                    # do something here
                  }
            } while $x++ <= $z;
         }
But certainly by that point (if not before), you'd be better off using an ordinary infinite loop with last at the end:
for (;;) {
    next if $x == $y;
    last if $x =  $y ** 2;
    # do something here
    last unless $x++ <= $z;
}

4.5.1. Case Structures

Unlike some other programming languages, Perl has no official switch or case statement. That's because Perl doesn't need one, having many ways to do the same thing. A bare block is particularly convenient for doing case structures (multiway switches). Here's one:

SWITCH: {
    if (/^abc/) { $abc = 1; last SWITCH; }
    if (/^def/) { $def = 1; last SWITCH; }
    if (/^xyz/) { $xyz = 1; last SWITCH; }
    $nothing = 1;
}
and here's another:
SWITCH: {
    /^abc/      && do { $abc = 1; last SWITCH; };
    /^def/      && do { $def = 1; last SWITCH; };
    /^xyz/      && do { $xyz = 1; last SWITCH; };
    $nothing = 1;
}
or, formatted so that each case stands out more:
SWITCH: {
    /^abc/      && do {
                        $abc = 1;
                        last SWITCH;
                   };
    /^def/      && do {
                        $def = 1;
                        last SWITCH;
                   };
    /^xyz/      && do {
                        $xyz = 1;
                        last SWITCH;
                    };
    $nothing = 1;
}
or even (horrors!):
if    (/^abc/) { $abc = 1 }
elsif (/^def/) { $def = 1 }
elsif (/^xyz/) { $xyz = 1 }
else           { $nothing = 1 }
In this next example, notice how the last operators ignore the do {} blocks, which aren't loops, and exit the for loop instead:
for ($very_nasty_long_name[$i++][$j++]->method()) {
    /this pattern/      and do { push @flags, '-e'; last; };
    /that one/          and do { push @flags, '-h'; last; };
    /something else/    and do {                    last; };
    die "unknown value: `$_'";
}
You might think it odd to loop over a single value, since you'll only go through the loop once. But it's convenient to use for/foreach's aliasing capability to make a temporary, localized assignment to $_. On repeated compares against the same long value, this makes it much easier to type and therefore harder to mistype. It avoids possible side effects from evaluating the expression again. And pertinent to this section, it's also one of the most commonly seen standard idioms for implementing a switch or case structure.

Cascading use of the ?: operator can also work for simple cases. Here we again use a for for its aliasing property to make repeated comparisons more legible:

for ($user_color_preference) {
    $value = /red/      ?   0xFF0000  :
             /green/    ?   0x00FF00  :
             /blue/     ?   0x0000FF  :
                            0x000000  ;   # black if all fail
}
For situations like this last one, it's sometimes better to build yourself a hash and quickly index into it to pull the answer out. Unlike the cascading conditionals we just looked at, a hash scales to an unlimited number of entries, and takes no more time to look up the first one than the last. The disadvantage is that you can only do an exact lookup, not a pattern match. If you have a hash like this:
%color_map = (
    azure       => 0xF0FFFF,
    chartreuse  => 0x7FFF00,
    lavender    => 0xE6E6FA,
    magenta     => 0xFF00FF,
    turquoise   => 0x40E0D0,
);
then exact string lookups run quickly:
$value = $color_map{ lc $user_color_preference } || 0x000000;
Even complicated multiway branching statements (with each case involving the execution of several different statements) can be turned into fast lookups. You just need to use a hash of references to functions. See the section Section 4.5, "Hashes of Functions" in Chapter 9, "Data Structures", for how to handle those.

Previous | Home | Next
4.4. Loop Statements | Book Index | 4.6. goto
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.6. goto

Although not for the faint of heart (nor for the pure of heart), Perl does support a goto operator. There are three forms: goto LABEL, goto EXPR, and goto &NAME.

The goto LABEL form finds the statement labeled with LABEL and resumes execution there. It cant be used to jump into any construct that requires initialization, such as a subroutine or a foreach loop. It also can't be used to jump into a construct that has been optimized away (see Chapter 18, "Compiling"). It can be used to go almost anywhere else within the current block or any block in your dynamic scope (that is, a block you were called from). You can even goto out of subroutines, but it's usually better to use some other construct. The author of Perl has never felt the need to use this form of goto (in Perl, that is--C is another matter).

The goto EXPR form is just a generalization of goto LABEL. It expects the expression to produce a label name, whose location obviously has to be resolved dynamically by the interpreter. This allows for computed gotos per FORTRAN, but isn't necessarily recommended if you're optimizing for maintainability:

goto(("FOO", "BAR", "GLARCH")[$i]);         # hope 0 <= i < 3

@loop_label = qw/FOO BAR GLARCH/;
goto $loop_label[rand @loop_label];         # random teleport
In almost all cases like this, it's usually a far, far better idea to use the structured control flow mechanisms of next, last, or redo instead of resorting to a goto. For certain applications, a hash of references to functions or the catch-and-throw pair of eval and die for exception processing can also be prudent approaches.

The goto &NAME form is highly magical and sufficiently removed from the ordinary goto to exempt its users from the opprobrium to which goto users are customarily subjected. It substitutes a call to the named subroutine for the currently running subroutine. This behavior is used by AUTOLOAD subroutines to load another subroutine and then pretend that the other subroutine was called in the first place. After the goto, not even caller will be able to tell that this routine was called first. The autouse, AutoLoader, and SelfLoader modules all use this strategy to define functions the first time they're called, and then to jump right to them without anyone ever knowing the functions weren't there all along.

Previous | Home | Next
4.5. Bare Blocks | Book Index | 4.7. Global Declarations
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.7. Global Declarations

Subroutine and format declarations are global declarations. No matter where you place them, what they declare is global (it's local to a package, but packages are global to the program, so everything in a package is visible from anywhere). A global declaration can be put anywhere a statement can, but it has no effect on the execution of the primary sequence of statements--the declarations take effect at compile time.

This means you can't conditionally declare subroutines or formats by hiding them from the compiler inside a run-time conditional like an if, since only the interpreter pays attention to those conditions. Subroutine and format declarations (and use and no declarations) are seen by the compiler no matter where they occur.

Global declarations are typically put at the beginning or the end of your program, or off in some other file. However, if you're declaring any lexically scoped variables (see the next section), you'll want to make sure your format or subroutine definition falls within the scope of the variable declarations if you expect it to be able to access those private variables.

Note that we sneakily switched from talking about declarations to definitions. Sometimes it helps to split the definition of the subroutine from its declaration. The only syntactic difference between the two is that the definition supplies a BLOCK containing the code to be executed, while the declaration doesn't. (A subroutine definition acts as its own declaration if no declaration has been seen.) Splitting the definition from the declaration allows you to put the subroutine declaration at the front of the file and the definition at the end (with your lexically scoped variable declarations happily in the middle):

sub count (@);       # Compiler now knows how to call count().
my $x;               # Compiler now knows about lexical variable.
$x = count(3,2,1);   # Compiler can validate function call.
sub count (@) { @_ } # Compiler now knows what count() means.
As this example shows, subroutines don't actually have to be defined before calls to them can be compiled (indeed, the definition can even by delayed until first use, if you use autoloading), but declaring subroutines helps the compiler in various ways and gives you more options in how you can call them.

Declaring a subroutine allows it to be used without parentheses, as if it were a built-in operator, from that point forward in the compilation. (We used parentheses to call count in the last example, but we didn't actually need to.) You can declare a subroutine without defining it just by saying:

sub myname;
$me = myname $0             or die "can't get myname";
A bare declaration like that declares the function to be a list operator, not a unary operator, so be careful to use or there instead of ||. The || operator binds too tightly to use after list operators, though you can always use parentheses around the list operators arguments to turn the list operator back into something that behaves more like a function call. Alternatively, you can use the prototype ($) to turn the subroutine into a unary operator:
sub myname ($);
$me = myname $0             || die "can't get myname";
That now parses as you'd expect, but you still ought to get in the habit of using or in that situation. For more on prototypes, see Chapter 6, "Subroutines".

You do need to define the subroutine at some point, or you'll get an error at run time indicating that you've called an undefined subroutine. Other than defining the subroutine yourself, there are several ways to pull in definitions from elsewhere.

You can load definitions from other files with a simple require statement; this was the best way to load files in Perl 4, but there are two problems with it. First, the other file will typically insert subroutine names into a package (a symbol table) of its own choosing, not your packages. Second, a require happens at run time, so it occurs too late to serve as a declaration in the file invoking the require. There are times, however, when delayed loading is what you want.

A more useful way to pull in declarations and definitions is with the use declaration, which effectively requires the module at compile time (because use counts as a BEGIN block) and then lets you import some of the module's declarations into your own program. Thus use can be considered a kind of global declaration, in that it imports names at compile time into your own (global) package just as if you'd declared them yourself. See the section Section 4.1, "Symbol Tables" in Chapter 10, "Packages", for low-level mechanics on how importation works between packages; Chapter 11, "Modules", for how to set up a module's imports and exports; and Chapter 18, "Compiling" for an explanation of BEGIN and its cousins, CHECK, INIT, and END, which are also global declarations of a sort because they're dealt with at compile time and can have global effects.

Previous | Home | Next
4.6. goto | Book Index | 4.8. Scoped Declarations
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.8. Scoped Declarations

Like global declarations, lexically scoped declarations have an effect at the time of compilation. Unlike global declarations, lexically scoped declarations only apply from the point of the declaration through the end of the innermost enclosing scope (block, file, or eval--whichever comes first). That's why we call them lexically scoped, though perhaps "textually scoped" would be more accurate, since lexical scoping has little to do with lexicons. But computer scientists the world over know what "lexically scoped" means, so we perpetuate the usage here.

Perl also supports dynamically scoped declarations. A dynamic scope also extends to the end of the innermost enclosing block, but in this case "enclosing" is defined dynamically at run time rather than textually at compile time. To put it another way, blocks nest dynamically by invoking other blocks, not by including them. This nesting of dynamic scopes may correlate somewhat to the nesting of lexical scopes, but the two are generally not identical, especially when any subroutines have been invoked.

We mentioned that some aspects of use could be considered global declarations, but other aspects of use are lexically scoped. In particular, use not only imports package symbols but also implements various magical compiler hints, known as pragmas (or if you're into classical forms, pragmata). Most pragmas are lexically scoped, including the use strict 'vars' pragma which forces you to declare your variables before you can use them. See the later section Section 4.9, "Pragmas".

A package declaration, oddly enough, is itself lexically scoped, despite the fact that a package is a global entity. But a package declaration merely declares the identity of the default package for the rest of the enclosing block. Undeclared, unqualified variable names[5] are looked up in that package. In a sense, a package is never declared at all, but springs into existence when you refer to something that belongs to that package. It's all very Perlish.

[5]Also unqualified names of subroutines, filehandles, directory handles, and formats.

4.8.1. Scoped Variable Declarations

Most of the rest of the chapter is about using global variables. Or rather, it's about not using global variables. There are various declarations that help you not use global variables--or at least, not use them foolishly.

We already mentioned the package declaration, which was introduced into Perl long ago to allow globals to be split up into separate packages. This works pretty well for certain kinds of variables. Packages are used by libraries, modules, and classes to store their interface data (and some of their semi-private data) to avoid conflicting with variables and functions of the same name in your main program or in other modules. If you see someone write $Some::stuff,[6] they're using the $stuff scalar variable from the package Some. See Chapter 10, "Packages".

[6] Or the archaic $Some'stuff, which probably shouldn't be encouraged outside of Perl poetry.

If this were all there were to the matter, Perl programs would quickly become unwieldy as they got longer. Fortunately, Perl's three scoping declarations make it easy to create completely private variables (using my), to give selective access to global ones (using our), and to provide temporary values to global variables (using local):

my $nose;
our $House;
local $TV_channel;
If more than one variable is listed, the list must be placed in parentheses. For my and our, the elements may only be simple scalar, array, or hash variables. For local, the constraints are somewhat more relaxed: you may also localize entire typeglobs and individual elements or slices of arrays and hashes:
my ($nose, @eyes, %teeth);
our ($House, @Autos, %Kids);
local (*Spouse, $phone{HOME});
Each of these modifiers offers a different sort of "confinement" to the variables they modify. To oversimplify slightly: our confines names to a scope, local confines values to a scope, and my confines both names and values to a scope.

Each of these constructs may be assigned to, though they differ in what they actually do with the values, since they have different mechanisms for storing values. They also differ somewhat if you don't (as we didn't above) assign any values to them: my and local cause the variables in question to start out with values of undef or (), as appropriate; our, on the other hand, leaves the current value of its associated global unchanged.

Syntactically, my, our, and local are simply modifiers (like adjectives) on an lvalue expression. When you assign to a modified lvalue, the modifier doesn't change whether the lvalue is viewed as a scalar or a list. To figure how the assignment will work, just pretend that the modifier isn't there. So either of:

my ($foo) = <STDIN>;
my @array = <STDIN>;
supplies a list context to the righthand side, while:
my $foo = <STDIN>;
supplies a scalar context.

Modifiers bind more tightly (with higher precedence) than the comma does. The following example erroneously declares only one variable, not two, because the list following the modifier is not enclosed in parentheses.

my $foo, $bar = 1;              # WRONG
This has the same effect as:
my $foo;
$bar = 1;
You'll get a warning about the mistake if warnings are enabled, whether via the -w or -W command-line switches, or, preferably, through the use warnings declaration explained later in Section 4.9, "Pragmas".

In general, it's best to declare a variable in the smallest possible scope that suits it. Since variables declared in a control-flow statement are visible only in the block governed by that statement, their visibility is reduced. It reads better in English this way, too.

sub check_warehouse {
    for my $widget (our @Current_Inventory) {
        print "I have a $widget in stock today.\n";
    }
}
The most frequently seen form of declaration is my, which declares lexically scoped variables for which both the names and values are stored in the current scope's temporary scratchpad and may not be accessed globally. Closely related is the our declaration, which enters a lexically scoped name in the current scope, just as my does, but actually refers to a global variable that anyone else could access if they wished. In other words, it's a global variable masquerading as a lexical.

The other form of scoping, dynamic scoping, applies to local variables, which despite the word "local" are really global variables and have nothing to do with the local scratchpad.

4.8.2. Lexically Scoped Variables: my

To help you avoid the maintenance headaches of global variables, Perl provides lexically scoped variables, often called lexicals for short. Unlike globals, lexicals guarantee you privacy. Assuming you don't hand out references to these private variables that would let them be fiddled with indirectly, you can be certain that every possible access to these private variables is restricted to code within one discrete and easily identifiable section of your program. That's why we picked the keyword my, after all.

A statement sequence may contain declarations of lexically scoped variables. Such declarations tend to be placed at the front of the statement sequence, but this is not a requirement. In addition to declaring variable names at compile time, the declarations act like ordinary run-time statements: each of them is elaborated within the sequence of statements as if it were an ordinary statement without the modifier:

my $name = "fred";
my @stuff = ("car", "house", "club");
my ($vehicle, $home, $tool) = @stuff;
These lexical variables are totally hidden from the world outside their immediately enclosing scope. Unlike the dynamic scoping effects of local (see the next section), lexicals are hidden from any subroutine called from their scope. This is true even if the same subroutine is called from itself or elsewhere--each instance of the subroutine gets its own "scratchpad" of lexical variables.

Unlike block scopes, file scopes don't nest; there's no "enclosing" going on, at least not textually. If you load code from a separate file with do, require, or use, the code in that file cannot access your lexicals, nor can you access lexicals from that file.

However, any scope within a file (or even the file itself) is fair game. It's often useful to have scopes larger than subroutine definitions, because this lets you share private variables among a limited set of subroutines. This is how you create variables that a C programmer would think of as "static":

{
    my $state = 0;

    sub on     { $state = 1 }
    sub off    { $state = 0 }
    sub toggle { $state = !$state }
}

The eval STRING operator also works as a nested scope, since the code in the eval can see its caller's lexicals (as long as the names aren't hidden by identical declarations within the eval's own scope). Anonymous subroutines can likewise access any lexical variables from their enclosing scopes; if they do so, they're what are known as closures.[7] Combining those two notions, if a block evals a string that creates an anonymous subroutine, the subroutine becomes a closure with full access to the lexicals of both the eval and the block, even after the eval and the block have exited. See the section Section 4.3.7, "Closures" in Chapter 8, "References".

[7]As a mnemonic, note the common element between "enclosing scope" and "closure". (The actual definition of closure comes from a mathematical notion concerning the completeness of sets of values and operations on those values.)

The newly declared variable (or value, in the case of local) does not show up until the statement after the statement containing the declaration. Thus you could mirror a variable this way:

my $x = $x;
That initializes the new inner $x with the current value $x, whether the current meaning of $x is global or lexical. (If you don't initialize the new variable, it starts out with an undefined or empty value.)

Declaring a lexical variable of a particular name hides any previously declared lexical of the same name. It also hides any unqualified global variable of the same name, but you can always get to the global variable by explicitly qualifying it with the name of the package the global is in, for example, $PackageName::varname.

4.8.3. Lexically Scoped Global Declarations: our

A better way to access globals, especially for programs and modules running under the use strict declaration, is the our declaration. This declaration is lexically scoped in that it applies only through the end of the current scope. But unlike the lexically scoped my or the dynamically scoped local, our does not isolate anything to the current lexical or dynamic scope. Instead, it provides access to a global variable in the current package, hiding any lexicals of the same name that would have otherwise hidden that global from you. In this respect, our variables act just like my variables.

If you place an our declaration outside any brace-delimited block, it lasts through the end of the current compilation unit. Often, though, people put it just inside the top of a subroutine definition to indicate that they're accessing a global variable:

sub check_warehouse {
    our @Current_Inventory;
    my  $widget;
    foreach $widget (@Current_Inventory) {
        print "I have a $widget in stock today.\n";
    }
}
Since global variables are longer in life and broader in visibility than private variables, we like to use longer and flashier names for them than for temporary variable. This practice alone, if studiously followed, can do as much as use strict can toward discouraging the use of global variables, especially in less prestidigitatorial typists.

Repeated our declarations do not meaningfully nest. Every nested my produces a new variable, and every nested local a new value. But every time you use our, you're talking about the same global variable, irrespective of nesting. When you assign to an our variable, the effects of that assignment persist after the scope of the declaration. That's because our never creates values; it just exposes a limited form of access to the global, which lives forever:

our $PROGRAM_NAME = "waiter";
{
    our $PROGRAM_NAME = "server";
    # Code called here sees "server".
    ...
}
# Code executed here still sees "server".

Contrast this with what happens under my or local, where after the block, the outer variable or value becomes visible again:

my $i = 10;
{
    my $i = 99;
    ...
}
# Code compiled here sees outer variable.

local $PROGRAM_NAME = "waiter";
{
    local $PROGRAM_NAME = "server";
    # Code called here sees "server".
    ...
}
# Code executed here sees "waiter" again.
It usually only makes sense to assign to an our declaration once, probably at the very top of the program or module, or, more rarely, when you preface the our with a local of its own:
{
    local our @Current_Inventory = qw(bananas);
    check_warehouse();  # no, we haven't no bananas :-)
}

4.8.4. Dynamically Scoped Variables: local

Using a local operator on a global variable gives it a temporary value each time local is executed, but it does not affect that variable's global visibility. When the program reaches the end of that dynamic scope, this temporary value is discarded and the original value restored. But it's always still a global variable that just happens to hold a temporary value while that block is executing. If you call some other function while your global contains the temporary value and that function accesses that global variable, it sees the temporary value, not the original one. In other words, that other function is in your dynamic scope, even though it's presumably not in your lexical scope.[8]

[8] That's why lexical scopes are sometimes called static scopes: to contrast them with dynamic scopes and emphasize their compile-time determinability. Don't confuse this use of the term with how static is used in C or C++. The term is heavily overloaded, which is why we avoid it.

If you have a local that looks like this:

{
    local $var = $newvalue;
    some_func();
    ...
}
you can think of it purely in terms of run-time assignments:
{
    $oldvalue = $var;
    $var = $newvalue;
    some_func();
    ...
}
continue {
    $var = $oldvalue;
}
The difference is that with local the value is restored no matter how you exit the block, even if you prematurely return from that scope. The variable is still the same global variable, but the value found there depends on which scope the function was called from. That's why it's called dynamic scoping--because it changes during run time.

As with my, you can initialize a local with a copy of the same global variable. Any changes to that variable during the execution of a subroutine (and any others called from within it, which of course can still see the dynamically scoped global) will be thrown away when the subroutine returns. You'd certainly better comment what you are doing, though:

# WARNING: Changes are temporary to this dynamic scope.
local $Some_Global = $Some_Global;
A global variable then is still completely visible throughout your whole program, no matter whether it was explicitly declared with our or just allowed to spring into existence, or whether it's holding a local value destined to be discarded when the scope exits. In tiny programs, this isn't so bad, but for large ones, you'll quickly lose track of where in the code all these global variables are being used. You can forbid accidental use of globals, if you want, through the use strict 'vars' pragma, described in the next section.

Although both my and local confer some degree of protection, by and large you should prefer my over local. Sometimes, though, you have to use local so you can temporarily change the value of an existing global variable, like those listed in Chapter 28, "Special Names". Only alphanumeric identifiers may be lexically scoped, and many of those special variables aren't strictly alphanumeric. You also need to use local to make temporary changes to a package's symbol table as shown in the section Section 4.1, "Symbol Tables" in Chapter 10, "Packages". Finally, you can use local on a single element or a whole slice of an array or a hash. This even works if the array or hash happens to be a lexical variable, layering local's dynamic scoping behavior on top of those lexicals. We won't talk much more about the semantics of local here. See local in Chapter 29, "Functions" for more information.

Previous | Home | Next
4.7. Global Declarations | Book Index | 4.9. Pragmas
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


4.9. Pragmas

Many programming languages allow you to give hints to the compiler. In Perl, these hints are conveyed to the compiler with the use declaration. Some pragmas are:

use warnings;
use strict;
use integer;
use bytes;
use constant pi => ( 4 * atan2(1,1) );
Perl pragmas are all described in Chapter 31, "Pragmatic Modules", but right now we'll just talk specifically about a couple that are most useful with the material covered in this chapter.

Although a few pragmas are global declarations that affect global variables or the current package, most are lexically scoped declarations whose effects are constrained to last only until the end of the enclosing block, file, or eval (whichever comes first). A lexically scoped pragma can be countermanded in an inner scope with a no declaration, which works just like use but in reverse.

4.9.1. Controlling Warnings

To show how this works, we'll manipulate the warnings pragma to tell Perl whether to issue warnings for questionable practices:

use warnings;       # Enable warnings from here till end of file.
...
{
    no warnings;    # Disable warnings through end of block.
    ...
}
# Warnings are automatically enabled again here.
Once warnings are enabled, Perl complains about variables used only once, variable declarations that mask other declarations in the same scope, improper conversions of strings into numbers, using undefined values as legitimate strings or numbers, trying to write to files you only opened read-only (or didn't open at all), and many other conditions documented in Chapter 33, "Diagnostic Messages".

The use warnings pragma is the preferred way to control warnings. Old programs could only use the -w command-line switch or modify the global $^W variable:

{
    local $^W = 0;
    ...
}
It's much better to use the use warnings and no warnings pragmas. A pragma is better because it happens at compile time, because it's a lexical declaration and therefore cannot affect code it wasn't intended to affect, and because (although we haven't shown you in these simple examples) it affords fine-grained control over discrete classes of warnings. For more about the warnings pragma, including how to convert merely noisy warnings into fatal errors, and how to override the pragma to turn on warnings globally even if a module says not to, see use warnings in Chapter 31, "Pragmatic Modules".

4.9.2. Controlling the Use of Globals

Another commonly seen declaration is the use strict pragma, which has several functions, one of which is to control the use of global variables. Normally, Perl lets you create new globals (or all too often, step on old globals) just by mentioning them. No variable declarations are necessary--by default, that is. Because unbridled use of globals can make large programs or modules painful to maintain, you may sometimes wish to discourage their accidental use. As an aid to preventing such accidents, you can say:

use strict 'vars';
This means that any variable mentioned from here to the end of the enclosing scope must refer either to a lexical variable or to an explicitly allowed global. If it's not one of those, a compilation error results. A global is explicitly allowed if one of the following is true:

  • It's one of Perl's program-wide special variables (see Chapter 28, "Special Names").

  • It's fully qualified with its package name (see Chapter 10, "Packages"),

  • It's imported into the current package (see Chapter 11, "Modules").

  • It's masquerading as a lexically scoped variable via an our declaration. (This is the main reason we added our declarations to Perl.)

Of course, there's always the fifth alternative--if the pragma proves burdensome, simply countermand it within an inner block using:

no strict 'vars'
You can also turn on strict checking of symbolic dereferences and accidental use of barewords with this pragma. Normally people just say:
use strict;
to enable all three strictures. See the use strict entry in Chapter 31, "Pragmatic Modules" for more information.

Previous | Home | Next
4.8. Scoped Declarations | Book Index | 5. Pattern Matching
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 5. Pattern Matching

Contents:

The Regular Expression Bestiary
Pattern-Matching Operators
Metacharacters and Metasymbols
Character Classes
Quantifiers
Positions
Capturing and Clustering
Alternation
Staying in Control
Fancy Patterns

Perl's built-in support for pattern matching lets you search large amounts of data conveniently and efficiently. Whether you run a huge commercial portal site scanning every newsfeed in existence for interesting tidbits, or a government organization dedicated to figuring out human demographics (or the human genome), or an educational institution just trying to get some dynamic information up on your web site, Perl is the tool of choice, in part because of its database connections, but largely because of its pattern-matching capabilities. If you take "text" in the widest possible sense, perhaps 90% of what you do is 90% text processing. That's really what Perl is all about and always has been about--in fact, it's even part of Perl's name: Practical Extraction and Report Language. Perl's patterns provide a powerful way to scan through mountains of mere data and extract useful information from it.

You specify a pattern by creating a regular expression (or regex), and Perl's regular expression engine (the "Engine", for the rest of this chapter) then takes that expression and determines whether (and how) the pattern matches your data. While most of your data will probably be text strings, there's nothing stopping you from using regexes to search and replace any byte sequence, even what you'd normally think of as "binary" data. To Perl, bytes are just characters that happen to have an ordinal value less than 256. (More on that in Chapter 15, "Unicode".)

If you're acquainted with regular expressions from some other venue, we should warn you that regular expressions are a bit different in Perl. First, they aren't entirely "regular" in the theoretical sense of the word, which means they can do much more than the traditional regular expressions taught in computer science classes. Second, they are used so often in Perl that they have their own special variables, operators, and quoting conventions which are tightly integrated into the language, not just loosely bolted on like any other library. Programmers new to Perl often look in vain for functions like these:

match( $string, $pattern );
subst( $string, $pattern, $replacement );
But matching and substituting are such fundamental tasks in Perl that they merit one-letter operators: m/PATTERN/ and s/PATTERN/REPLACEMENT/ (m// and s///, for short). Not only are they syntactically brief, but they're also parsed like double-quoted strings rather than ordinary operators; nevertheless, they operate like operators, so we'll call them that. Throughout this chapter, you'll see these operators used to match patterns against a string. If some portion of the string fits the pattern, we say that the match is successful. There are lots of cool things you can do with a successful pattern match. In particular, if you are using s///, a successful match causes the matched portion of the string to be replaced with whatever you specified as the REPLACEMENT.

This chapter is all about how to build and use patterns. Perl's regular expressions are potent, packing a lot of meaning into a small space. They can therefore be daunting if you try to intuit the meaning of a long pattern as a whole. But if you can break it up into its parts, and if you know how the Engine interprets those parts, you can understand any regular expression. It's not unusual to see a hundred line C or Java program expressed with a one-line regular expression in Perl. That regex may be a little harder to understand than any single line out of the longer program; on the other hand, the regex will likely be much easier to understand than the longer program taken as a whole. You just have to keep these things in perspective.

5.1. The Regular Expression Bestiary

Before we dive into the rules for interpreting regular expressions, let's see what some patterns look like. Most characters in a regular expression simply match themselves. If you string several characters in a row, they must match in order, just as you'd expect. So if you write the pattern match:

/Frodo/
you can be sure that the pattern won't match unless the string contains the substring "Frodo" somewhere. (A substring is just a part of a string.) The match could be anywhere in the string, just as long as those five characters occur somewhere, next to each other and in that order.

Other characters don't match themselves, but "misbehave" in some way. We call these metacharacters. (All metacharacters are naughty in their own right, but some are so bad that they also cause other nearby characters to misbehave as well.)

Here are the miscreants:

\ | ( ) [ { ^ $ * + ? .
Metacharacters are actually very useful and have special meanings inside patterns; we'll tell you all those meanings as we go along. But we do want to reassure you that you can always match any of these twelve characters literally by putting a backslash in front of it. For example, backslash is itself a metacharacter, so to match a literal backslash, you'd backslash the backslash: \\.

You see, backslash is one of those characters that makes other characters misbehave. It just works out that when you make a misbehaving metacharacter misbehave, it ends up behaving--a double negative, as it were. So backslashing a character to get it to be taken literally works, but only on punctuational characters; backslashing an (ordinarily well-behaved) alphanumeric character does the opposite: it turns the literal character into something special. Whenever you see such a two-character sequence:

\b \D \t \3 \s

you'll know that the sequence is a metasymbol that matches something strange. For instance, \b matches a word boundary, while \t matches an ordinary tab character. Notice that a tab is one character wide, while a word boundary is zero characters wide because it's the spot between two characters. So we call \b a zero-width assertion. Still, \t and \b are alike in that they both assert something about a particular spot in the string. Whenever you assert something in a regular expression, you're just claiming that that particular something has to be true in order for the pattern to match.

Most pieces of a regular expression are some sort of assertion, including the ordinary characters that simply assert that they match themselves. To be precise, they also assert that the next thing will match one character later in the string, which is why we talk about the tab character being "one character wide". Some assertions (like \t) eat up some of the string as they match, and others (like \b) don't. But we usually reserve the term "assertion" for the zero-width assertions. To avoid confusion, we'll call the thing with width an atom. (If you're a physicist, you can think of nonzero-width atoms as massive, in contrast to the zero-width assertions, which are massless like photons.)

You'll also see some metacharacters that aren't assertions; rather, they're structural (just as braces and semicolons define the structure of ordinary Perl code, but don't really do anything). These structural metacharacters are in some ways the most important ones because the crucial first step in learning to read regular expressions is to teach your eyes to pick out the structural metacharacters. Once you've learned that, reading regular expressions is a breeze.[1]

[1]Admittedly, a stiff breeze at times, but not something that will blow you away.

One such structural metacharacter is the vertical bar, which indicates alternation:

/Frodo|Pippin|Merry|Sam/

That means that any of those strings can trigger a match; this is covered in Section 5.8, "Alternation" later in the chapter. And in Section 5.7, "Capturing and Clustering" after that, we'll show you how to use parentheses around portions of your pattern to do grouping:

/(Frodo|Drogo|Bilbo) Baggins/
or even:
/(Frod|Drog|Bilb)o Baggins/

Another thing you'll see are what we call quantifiers, which say how many of the previous thing should match in a row. Quantifiers look like this:

*  +  ?  *?  {3}  {2,5}
You'll never see them in isolation like that, though. Quantifiers only make sense when attached to atoms--that is, to assertions that have width.[2] Quantifiers attach to the previous atom only, which in human terms means they normally quantify only one character. If you want to match three copies of "bar" in a row, you need to group the individual characters of "bar" into a single "molecule" with parentheses, like this:
/(bar){3}/

[2] Quantifiers are a bit like the statement modifiers in Chapter 4, "Statements and Declarations", which can only attach to a single statement. Attaching a quantifier to a zero-width assertion would be like trying to attach a while modifier to a declaration--either of which makes about as much sense as asking your local apothecary for a pound of photons. Apothecaries only deal in atoms and such.

That will match "barbarbar". If you'd said /bar{3}/, that would match "barrr"--which might qualify you as Scottish but disqualify you as barbarbaric. (Then again, maybe not. Some of our favorite metacharacters are Scottish.) For more on quantifiers, see "Quantifiers" later.

Now that you've seen a few of the beasties that inhabit regular expressions, you're probably anxious to start taming them. However, before we discuss regular expressions in earnest, we need to backtrack a little and talk about the pattern-matching operators that make use of regular expressions. (And if you happen to spot a few more regex beasties along the way, just leave a decent tip for the tour guide.)

Previous | Home | Next
4.9. Pragmas | Book Index | 5.2. Pattern-Matching Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.2. Pattern-Matching Operators

Zoologically speaking, Perl's pattern-matching operators function as a kind of cage for regular expressions, to keep them from getting out. This is by design; if we were to let the regex beasties wander throughout the language, Perl would be a total jungle. The world needs its jungles, of course--they're the engines of biological diversity, after all--but jungles should stay where they belong. Similarly, despite being the engines of combinatorial diversity, regular expressions should stay inside pattern match operators where they belong. It's a jungle in there.

As if regular expressions weren't powerful enough, the m// and s/// operators also provide the (likewise confined) power of double-quote interpolation. Since patterns are parsed like double-quoted strings, all the normal double-quote conventions will work, including variable interpolation (unless you use single quotes as the delimiter) and special characters indicated with backslash escapes. (See "Specific Characters" later in this chapter.) These are applied before the string is interpreted as a regular expression. (This is one of the few places in the Perl language where a string undergoes more than one pass of processing.) The first pass is not quite normal double-quote interpolation, in that it knows what it should interpolate and what it should pass on to the regular expression parser. So, for instance, any $ immediately followed by a vertical bar, closing parenthesis, or the end of the string will be treated not as a variable interpolation, but as the traditional regex assertion meaning end-of-line. So if you say:

$foo = "bar";
/$foo$/;
the double-quote interpolation pass knows that those two $ signs are functioning differently. It does the interpolation of $foo, then hands this to the regular expression parser:
/bar$/;
Another consequence of this two-pass parsing is that the ordinary Perl tokener finds the end of the regular expression first, just as if it were looking for the terminating delimiter of an ordinary string. Only after it has found the end of the string (and done any variable interpolation) is the pattern treated as a regular expression. Among other things, this means you can't "hide" the terminating delimiter of a pattern inside a regex construct (such as a character class or a regex comment, which we haven't covered yet). Perl will see the delimiter wherever it is and terminate the pattern at that point.

You should also know that interpolating variables into a pattern slows down the pattern matcher, because it feels it needs to check whether the variable has changed, in case it has to recompile the pattern (which will slow it down even further). See "Variable Interpolation" later in this chapter.

The tr/// transliteration operator does not interpolate variables; it doesn't even use regular expressions! (In fact, it probably doesn't belong in this chapter at all, but we couldn't think of a better place to put it.) It does share one feature with m// and s///, however: it binds to variables using the =~ and !~ operators.

The =~ and !~ operators, described in Chapter 3, "Unary and Binary Operators", bind the scalar expression on their lefthand side to one of three quote-like operators on their right: m// for matching a pattern, s/// for substituting some string for a substring matched by a pattern, and tr/// (or its synonym, y///) for transliterating one set of characters to another set. (You may write m// as //, without the m, if slashes are used for the delimiter.) If the righthand side of =~ or !~ is none of these three, it still counts as a m// matching operation, but there'll be no place to put any trailing modifiers (see "Pattern Modifiers" later), and you'll have to handle your own quoting:

print "matches" if $somestring =~ $somepattern;
Really, there's little reason not to spell it out explicitly:
print "matches" if $somestring =~ m/$somepattern/;
When used for a matching operation, =~ and !~ are sometimes pronounced "matches" and "doesn't match" respectively (although "contains" and "doesn't contain" might cause less confusion).

Apart from the m// and s/// operators, regular expressions show up in two other places in Perl. The first argument to the split function is a special match operator specifying what not to return when breaking a string into multiple substrings. See the description and examples for split in Chapter 29, "Functions". The qr// ("quote regex") operator also specifies a pattern via a regex, but it doesn't try to match anything (unlike m//, which does). Instead, the compiled form of the regex is returned for future use. See "Variable Interpolation" for more information.

You apply one of the m//, s///, or tr/// operators to a particular string with the =~ binding operator (which isn't a real operator, just a kind of topicalizer, linguistically speaking). Here are some examples:

$haystack =~ m/needle/                # match a simple pattern
$haystack =~  /needle/                # same thing

$italiano =~ s/butter/olive oil/      # a healthy substitution

$rotate13 =~ tr/a-zA-Z/n-za-mN-ZA-M/  # easy encryption (to break)
Without a binding operator, $_ is implicitly used as the "topic":
/new life/ and              # search in $_ and (if found)
    /new civilizations/     #    boldly search $_ again

s/sugar/aspartame/          # substitute a substitute into $_

tr/ATCG/TAGC/               # complement the DNA stranded in $_
Because s/// and tr/// change the scalar to which they're applied, you may only use them on valid lvalues:
"onshore" =~ s/on/off/;      # WRONG: compile-time error
However, m// works on the result of any scalar expression:
if ((lc $magic_hat->fetch_contents->as_string) =~ /rabbit/) {
    print "Nyaa, what's up doc?\n";
}
else {
    print "That trick never works!\n";
}
But you have to be a wee bit careful, since =~ and !~ have rather high precedence--in our previous example the parentheses are necessary around the left term.[3] The !~ binding operator works like =~, but negates the logical result of the operation:
if ($song !~ /words/) {
    print qq/"$song" appears to be a song without words.\n/;
}
Since m//, s///, and tr/// are quote operators, you may pick your own delimiters. These work in the same way as the quoting operators q//, qq//, qr//, and qw// (see the section Section 5.6.3, "Pick Your Own Quotes" in Chapter 2, "Bits and Pieces").
$path =~ s#/tmp#/var/tmp/scratch#;

if ($dir =~ m[/bin]) {
    print "No binary directories please.\n";
}
When using paired delimiters with s/// or tr///, if the first part is one of the four customary bracketing pairs (angle, round, square, or curly), you may choose different delimiters for the second part than you chose for the first:
s(egg)<larva>;
s{larva}{pupa};
s[pupa]/imago/;
Whitespace is allowed in front of the opening delimiters:
s (egg)   <larva>;
s {larva} {pupa};
s [pupa]  /imago/;
Each time a pattern successfully matches (including the pattern in a substitution), it sets the $`, $&, and $' variables to the text left of the match, the whole match, and the text right of the match. This is useful for pulling apart strings into their components:
"hot cross buns" =~ /cross/;
print "Matched: <$`> $& <$'>\n";    # Matched: <hot > cross < buns>
print "Left:    <$`>\n";            # Left:    <hot >
print "Match:   <$&>\n";            # Match:   <cross>
print "Right:   <$'>\n";            # Right:   < buns>
For better granularity and efficiency, use parentheses to capture the particular portions that you want to keep around. Each pair of parentheses captures the substring corresponding to the subpattern in the parentheses. The pairs of parentheses are numbered from left to right by the positions of the left parentheses; the substrings corresponding to those subpatterns are available after the match in the numbered variables, $1, $2, $3, and so on:[4]
$_ = "Bilbo Baggins's birthday is September 22";
/(.*)'s birthday is (.*)/;
print "Person: $1\n";
print "Date: $2\n";
$`, $&, $', and the numbered variables are global variables implicitly localized to the enclosing dynamic scope. They last until the next successful pattern match or the end of the current scope, whichever comes first. More on this later, in a different scope.

[3] Without the parentheses, the lower-precedence lc would have applied to the whole pattern match instead of just the method call on the magic hat object.

[4] Not $0, though, which holds the name of your program.

Once Perl sees that you need one of $`, $&, or $' anywhere in the program, it provides them for every pattern match. This will slow down your program a bit. Perl uses a similar mechanism to produce $1, $2, and so on, so you also pay a price for each pattern that contains capturing parentheses. (See "Clustering" to avoid the cost of capturing while still retaining the grouping behavior.) But if you never use $`$&, or $', then patterns without capturing parentheses will not be penalized. So it's usually best to avoid $`, $&, and $' if you can, especially in library modules. But if you must use them once (and some algorithms really appreciate their convenience), then use them at will, because you've already paid the price. $& is not so costly as the other two in recent versions of Perl.

5.2.1. Pattern Modifiers

We'll discuss the individual pattern-matching operators in a moment, but first we'd like to mention another thing they all have in common, modifiers.

Immediately following the final delimiter of an m//, s///, qr//, or tr/// operator, you may optionally place one or more single-letter modifiers, in any order. For clarity, modifiers are usually written as "the /o modifier" and pronounced "the slash oh modifier", even though the final delimiter might be something other than a slash. (Sometimes people say "flag" or "option" to mean "modifier"; that's okay too.)

Some modifiers change the behavior of the individual operator, so we'll describe those in detail later. Others change how the regex is interpreted, so we'll talk about them here. The m//, s///, and qr// operators[5] all accept the following modifiers after their final delimiter:

[5] The tr/// operator does not take regexes, so these modifiers do not apply.

Modifier | Meaning
/i | Ignore alphabetic case distinctions (case insensitive).
/s | Let . match newline and ignore deprecated $* variable.
/m | Let ^ and $ match next to embedded \n.
/x | Ignore (most) whitespace and permit comments in pattern.
/o | Compile pattern once only.

The /i modifier says to match both upper- and lowercase (and title case, under Unicode). That way /perl/i would also match the strings "PROPERLY" or "Perlaceous" (amongst other things). A use locale pragma may also have some influence on what is considered to be equivalent. (This may be a negative influence on strings containing Unicode.)

The /s and /m modifiers don't involve anything kinky. Rather, they affect how Perl treats matches against a string that contains newlines. But they aren't about whether your string actually contains newlines; they're about whether Perl should assume that your string contains a single line (/s) or multiple lines (/m), because certain metacharacters work differently depending on whether they're expected to behave in a line-oriented fashion or not.

Ordinarily, the metacharacter "." matches any one character except a newline, because its traditional meaning is to match characters within a line. With /s, however, the "." metacharacter can also match a newline, because you've told Perl to ignore the fact that the string might contain multiple newlines. (The /s modifier also makes Perl ignore the deprecated $* variable, which we hope you too have been ignoring.) The /m modifier, on the other hand, changes the interpretation of the ^ and $ metacharacters by letting them match next to newlines within the string instead of considering only the ends of the string. See the examples in the section Section 5.6, "Positions" later in this chapter.

The /o modifier controls pattern recompilation. Unless the delimiters chosen are single quotes (m'PATTERN', s'PATTERN'REPLACEMENT', or qr'PATTERN'), any variables in the pattern will be interpolated (and may cause the pattern to be recompiled) every time the pattern operator is evaluated. If you want such a pattern to be compiled once and only once, use the /o modifier. This prevents expensive run-time recompilations; it's useful when the value you are interpolating won't change during execution. However, mentioning /o constitutes a promise that you won't change the variables in the pattern. If you do change them, Perl won't even notice. For better control over recompilation, use the qr// regex quoting operator. See "Variable Interpolation" later in this chapter for details.

The /x is the expressive modifier: it allows you to exploit whitespace and explanatory comments in order to expand your pattern's legibility, even extending the pattern across newline boundaries.

Er, that is to say, /x modifies the meaning of the whitespace characters (and the # character): instead of letting them do self-matching as ordinary characters do, it turns them into metacharacters that, oddly, now behave as whitespace (and comment characters) should. Hence, /x allows spaces, tabs, and newlines for formatting, just like regular Perl code. It also allows the # character, not normally special in a pattern, to introduce a comment that extends through the end of the current line within the pattern string.[6] If you want to match a real whitespace character (or the # character), then you'll have to put it into a character class, or escape it with a backslash, or encode it using an octal or hex escape. (But whitespace is normally matched with a \s* or \s+ sequence, so the situation doesn't arise often in practice.)

[6] Be careful not to include the pattern delimiter in the comment--because of its "find the end first" rule, Perl has no way of knowing you didn't intend to terminate the pattern at that point.

Taken together, these features go a long way toward making traditional regular expressions a readable language. In the spirit of TMTOWTDI, there's now more than one way to write a given regular expression. In fact, there's more than two ways:

m/\w+:(\s+\w+)\s*\d+/;       # A word, colon, space, word, space, digits.

m/\w+: (\s+ \w+) \s* \d+/x;  # A word, colon, space, word, space, digits.

m{
    \w+:                     # Match a word and a colon.

    (                        # (begin group)
         \s+                 # Match one or more spaces.
         \w+                 # Match another word.
    )                        # (end group)
    \s*                      # Match zero or more spaces.
    \d+                      # Match some digits
}x;
We'll explain those new metasymbols later in the chapter. (This section was supposed to be about pattern modifiers, but we've let it get out of hand in our excitement about /x. Ah well.) Here's a regular expression that finds duplicate words in paragraphs, stolen right out of the Perl Cookbook. It uses the /x and /i modifiers, as well as the /g modifier described later.
# Find duplicate words in paragraphs, possibly spanning line boundaries.
#   Use /x for space and comments, /i to match both `is'
#   in "Is is this ok?", and use /g to find all dups.
$/ = "";        # "paragrep" mode
while (<>) {
    while ( m{
                \b            # start at a word boundary
                (\w\S+)       # find a wordish chunk
                (
                    \s+       # separated by some whitespace
                    \1        # and that chunk again
                ) +           # repeat ad lib
                \b            # until another word boundary
             }xig
         )
    {
        print "dup word '$1' at paragraph $.\n";
    }
}
When run on this chapter, it produces warnings like this:
dup word 'that' at paragraph 100
As it happens, we know that that particular instance was intentional.

5.2.2. The m// Operator (Matching)

EXPR =~ m/PATTERN/cgimosx
EXPR =~ /PATTERN/cgimosx
EXPR =~ ?PATTERN?cgimosx
m/PATTERN/cgimosx
/PATTERN/cgimosx
?PATTERN?cgimosx
The m// operator searches the string in the scalar EXPR for PATTERN. If / or ? is the delimiter, the initial m is optional. Both ? and ' have special meanings as delimiters: the first is a once-only match; the second suppresses variable interpolation and the six translation escapes (\U and company, described later).

If PATTERN evaluates to a null string, either because you specified it that way using // or because an interpolated variable evaluated to the empty string, the last successfully executed regular expression not hidden within an inner block (or within a split, grep, or map) is used instead.

In scalar context, the operator returns true (1) if successful, false ("") otherwise. This form is usually seen in Boolean context:

if ($shire =~ m/Baggins/) { ... }  # search for Baggins in $shire
if ($shire =~ /Baggins/)  { ... }  # search for Baggins in $shire

if ( m#Baggins# )         { ... }  # search right here in $_
if ( /Baggins/ )          { ... }  # search right here in $_
Used in list context, m// returns a list of substrings matched by the capturing parentheses in the pattern (that is, $1, $2, $3, and so on) as described later under "Capturing and Clustering". The numbered variables are still set even when the list is returned. If the match fails in list context, a null list is returned. If the match succeeds in list context but there were no capturing parentheses (nor /g), a list value of (1) is returned. Since it returns a null list on failure, this form of m// can also be used in Boolean context, but only when participating indirectly via a list assignment:
if (($key,$value) = /(\w+): (.*)/) { ... }
Valid modifiers for m// (in whatever guise) are shown in Table 5-1.

Table 5.1. m// Modifiers

Modifier | Meaning
/i | Ignore alphabetic case.
/m | Let ^ and $ match next to embedded \n.
/s | Let . match newline and ignore deprecated $*.
/x | Ignore (most) whitespace and permit comments in pattern.
/o | Compile pattern once only.
/g | Globally find all matches.
/cg | Allow continued search after failed /g match.

The first five modifiers apply to the regex and were described earlier. The last two change the behavior of the match operation itself. The /g modifier specifies global matching--that is, matching as many times as possible within the string. How it behaves depends on context. In list context, m//g returns a list of all matches found. Here we find all the places someone mentioned "perl", "Perl", "PERL", and so on:

if (@perls = $paragraph =~ /perl/gi) {
    printf "Perl mentioned %d times.\n", scalar @perls;
}
If there are no capturing parentheses within the /g pattern, then the complete matches are returned. If there are capturing parentheses, then only the strings captured are returned. Imagine a string like:
$string = "password=xyzzy verbose=9 score=0";
Also imagine you want to use that to initialize a hash like this:
%hash = (password => "xyzzy", verbose => 9, score => 0);
Except, of course, you don't have a list, you have a string. To get the corresponding list, you can use the m//g operator in list context to capture all of the key/value pairs from the string:
%hash = $string =~ /(\w+)=(\w+)/g;
The (\w+) sequence captures an alphanumeric word. See the section Section 5.7, "Capturing and Clustering".

Used in scalar context, the /g modifier indicates a progressive match, which makes Perl start the next match on the same variable at a position just past where the last one stopped. The \G assertion represents that position in the string; see Section 5.6, "Positions" later in this chapter for a description of \G. If you use the /c (for "continue") modifier in addition to /g, then when the /g runs out, the failed match doesn't reset the position pointer.

If a ? is the delimiter, as in ?PATTERN?, this works just like a normal /PATTERN/ search, except that it matches only once between calls to the reset operator. This can be a convenient optimization when you want to match only the first occurrence of the pattern during the run of the program, not all occurrences. The operator runs the search every time you call it, up until it finally matches something, after which it turns itself off, returning false until you explicitly turn it back on with reset. Perl keeps track of the match state for you.

The ?? operator is most useful when an ordinary pattern match would find the last rather than the first occurrence:

open DICT, "/usr/dict/words" or die "Can't open words: $!\n";
while (<DICT>) {
    $first = $1 if ?(^neur.*)?;
    $last  = $1 if /(^neur.*)/;
}
print $first,"\n";          # prints "neurad"
print $last,"\n";           # prints "neurypnology"
The reset operator will reset only those instances of ?? compiled in the same package as the call to reset. Saying m?? is equivalent to saying ??.

5.2.3. The s/// Operator (Substitution)

LVALUE =~ s/PATTERN/REPLACEMENT/egimosx
s/PATTERN/REPLACEMENT/egimosx
This operator searches a string for PATTERN and, if found, replaces the matched substring with the REPLACEMENT text. (Modifiers are described later in this section.)
$lotr = $hobbit;           # Just copy The Hobbit
$lotr =~ s/Bilbo/Frodo/g;  #   and write a sequel the easy way.
The return value of an s/// operation (in scalar and list contexts alike) is the number of times it succeeded (which can be more than once if used with the /g modifier, as described earlier). On failure, since it substituted zero times, it returns false (""), which is numerically equivalent to 0.
if ($lotr =~ s/Bilbo/Frodo/) { print "Successfully wrote sequel." }
$change_count = $lotr =~ s/Bilbo/Frodo/g;
The replacement portion is treated as a double-quoted string. You may use any of the dynamically scoped pattern variables described earlier ($`, $&, $', $1, $2, and so on) in the replacement string, as well as any other double-quote gizmos you care to employ. For instance, here's an example that finds all the strings "revision", "version", or "release", and replaces each with its capitalized equivalent, using the \u escape in the replacement portion:
s/revision|version|release/\u$&/g;  # Use | to mean "or" in a pattern
All scalar variables expand in double-quote context, not just these strange ones. Suppose you had a %Names hash that mapped revision numbers to internal project names; for example, $Names{"3.0"} might be code-named "Isengard". You could use s/// to find version numbers and replace them with their corresponding project names:
s/version ([0-9.]+)/the $Names{$1} release/g;
In the replacement string, $1 returns what the first (and only) pair of parentheses captured. (You could use also \1 as you would in the pattern, but that usage is deprecated in the replacement. In an ordinary double-quoted string, \1 means a Control-A.)

If PATTERN is a null string, the last successfully executed regular expression is used instead. Both PATTERN and REPLACEMENT are subject to variable interpolation, but a PATTERN is interpolated each time the s/// operator is evaluated as a whole, while the REPLACEMENT is interpolated every time the pattern matches. (The PATTERN can match multiple times in one evaluation if you use the /g modifier.)

As before, the first five modifiers in Table 5-2 alter the behavior of the regex; they're the same as in m// and qr//. The last two alter the substitution operator itself.

Table 5.2. s/// Modifiers

Modifier | Meaning
/i | Ignore alphabetic case (when matching).
/m | Let ^ and $ match next to embedded \n.
/s | Let . match newline and ignore deprecated $*.
/x | Ignore (most) whitespace and permit comments in pattern.
/o | Compile pattern once only.
/g | Replace globally, that is, all occurrences.
/e | Evaluate the right side as an expression.

The /g modifier is used with s/// to replace every match of PATTERN with the REPLACEMENT value, not just the first one found. A s///g operator acts as a global search and replace, making all the changes at once, much like list m//g, except that m//g doesn't change anything. (And s///g is not a progressive match as scalar m//g was.)

The /e modifier treats the REPLACEMENT as a chunk of Perl code rather than as an interpolated string. The result of executing that code is used as the replacement string. For example, s/([0-9]+)/sprintf("%#x", $1)/ge would convert all numbers into hexadecimal, changing, for example, 2581 into 0xb23. Or suppose that, in our earlier example, you weren't sure that you had names for all the versions, so you wanted to leave any others unchanged. With a little creative /x formatting, you could say:

s{
    version
    \s+
    (
        [0-9.]+
    )
}{
    $Names{$1}
        ? "the $Names{$1} release"
        : $&
}xge;
The righthand side of your s///e (or in this case, the lower side) is syntax-checked and compiled at compile time along with the rest of your program. Any syntax error is detected during compilation, and run-time exceptions are left uncaught. Each additional /e after the first one (like /ee, /eee, and so on) is equivalent to calling eval STRING on the result of the code, once per extra /e. This evaluates the result of the code expression and traps exceptions in the special $@ variable. See the section Section 5.10.3, "Programmatic Patterns" later in the chapter for more details.

5.2.3.1. Modifying strings en passant

Sometimes you want a new, modified string without clobbering the old one upon which the new one was based. Instead of writing:

$lotr = $hobbit;
$lotr =~ s/Bilbo/Frodo/g;
you can combine these into one statement. Due to precedence, parentheses are required around the assignment, as they are with most combinations applying =~ to an expression.
($lotr = $hobbit) =~ s/Bilbo/Frodo/g;
Without the parentheses around the assignment, you'd only change $hobbit and get the number of replacements stored into $lotr, which would make a rather dull sequel.

You can't use a s/// operator directly on an array. For that, you need a loop. By a lucky coincidence, the aliasing behavior of for/foreach, combined with its use of $_ as the default loop variable, yields the standard Perl idiom to search and replace each element in an array:

for (@chapters) { s/Bilbo/Frodo/g }  # Do substitutions chapter by chapter.
s/Bilbo/Frodo/g for @chapters;       # Same thing.
As with a simple scalar variable, you can combine the substitution with an assignment if you'd like to keep the original values around, too:
@oldhues = ('bluebird', 'bluegrass',  'bluefish', 'the blues');
for (@newhues = @oldhues) { s/blue/red/ }
print "@newhues\n";           # prints: redbird redgrass redfish the reds
The idiomatic way to perform repeated substitutes on the same variable is to use a once-through loop. For example, here's how to canonicalize whitespace in a variable:
for ($string) {
    s/^\s+//;       # discard leading whitespace
    s/\s+$//;       # discard trailing whitespace
    s/\s+/ /g;      # collapse internal whitespace
}
which just happens to produce the same result as:
$string = join(" ", split " ", $string);
You can also use such a loop with an assignment, as we did in the array case:
for ($newshow = $oldshow) {
    s/Fred/Homer/g;
    s/Wilma/Marge/g;
    s/Pebbles/Lisa/g;
    s/Dino/Bart/g;
}

5.2.3.2. When a global substitution just isn't global enough

Occasionally, you can't just use a /g to get all the changes to occur, either because the substitutions have to happen right-to-left or because you need the length of $` to change between matches. You can usually do what you want by calling s/// repeatedly. However, you want the loop to stop when the s/// finally fails, so you have to put it into the conditional, which leaves nothing to do in the main part of the loop. So we just write a 1, which is a rather boring thing to do, but bored is the best you can hope for sometimes. Here are some examples that use a few more of those odd regex beasties that keep popping up:

# put commas in the right places in an integer
1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/;

# expand tabs to 8-column spacing
1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;

# remove (nested (even deeply nested (like this))) remarks
1 while s/\([^()]*\)//g;

# remove duplicate words (and triplicate (and quadruplicate...))
1 while s/\b(\w+) \1\b/$1/gi;
That last one needs a loop because otherwise it would turn this:
Paris in THE THE THE THE spring.
into this:
Paris in THE THE spring.
which might cause someone who knows a little French to picture Paris sitting in an artesian well emitting iced tea, since "thé" is French for "tea". A Parisian is never fooled, of course.

5.2.4. The tr/// Operator (Transliteration)

LVALUE =~ tr/SEARCHLIST/REPLACEMENTLIST/cds
tr/SEARCHLIST/REPLACEMENTLIST/cds
For sed devotees, y/// is provided as a synonym for tr///. This is why you can't call a function named y, any more than you can call a function named q or m. In all other respects, y/// is identical to tr///, and we won't mention it again.

This operator might not appear to fit into a chapter on pattern matching, since it doesn't use patterns. This operator scans a string, character by character, and replaces each occurrence of a character found in SEARCHLIST (which is not a regular expression) with the corresponding character from REPLACEMENTLIST (which is not a replacement string). It looks a bit like m// and s///, though, and you can even use the =~ or !~ binding operators on it, so we describe it here. (qr// and split are pattern-matching operators, but you don't use the binding operators on them, so they're elsewhere in the book. Go figure.)

Transliteration returns the number of characters replaced or deleted. If no string is specified via the =~ or !~ operator, the $_ string is altered. The SEARCHLIST and REPLACEMENTLIST may define ranges of sequential characters with a dash:

$message =~ tr/A-Za-z/N-ZA-Mn-za-m/;    # rot13 encryption.
Note that a range like A-Z assumes a linear character set like ASCII. But each character set has its own ideas of how characters are ordered and thus of which characters fall in a particular range. A sound principle is to use only ranges that begin from and end at either alphabets of equal case (a-e, A-E), or digits (0-4). Anything else is suspect. When in doubt, spell out the character sets in full: ABCDE.

The SEARCHLIST and REPLACEMENTLIST are not variable interpolated as double-quoted strings; you may, however, use those backslash sequences that map to a specific character, such as \n or \015.

Table 5-3 lists the modifiers applicable to the tr/// operator. They're completely different from those you apply to m//, s///, or qr//, even if some look the same.

Table 5.3. tr/// Modifiers

Modifier | Meaning
/c | Complement SEARCHLIST.
/d | Delete found but unreplaced characters.
/s | Squash duplicate replaced characters.

If the /c modifier is specified, the character set in SEARCHLIST is complemented; that is, the effective search list consists of all the characters not in SEARCHLIST. In the case of Unicode, this can represent a lot of characters, but since they're stored logically, not physically, you don't need to worry about running out of memory.

The /d modifier turns tr/// into what might be called the "transobliteration" operator: any characters specified by SEARCHLIST but not given a replacement in REPLACEMENTLIST are deleted. (This is slightly more flexible than the behavior of some tr(1) programs, which delete anything they find in SEARCHLIST, period.)

If the /s modifier is specified, sequences of characters converted to the same character are squashed down to a single instance of the character.

If the /d modifier is used, REPLACEMENTLIST is always interpreted exactly as specified. Otherwise, if REPLACEMENTLIST is shorter than SEARCHLIST, the final character is replicated until it is long enough. If REPLACEMENTLIST is null, the SEARCHLIST is replicated, which is surprisingly useful if you just want to count characters, not change them. It's also useful for squashing characters using /s.

tr/aeiou/!/;                 # change any vowel into !
tr{/\\\r\n\b\f. }{_};        # change strange chars into an underscore

tr/A-Z/a-z/ for @ARGV;       # canonicalize to lowercase ASCII

$count = ($para =~ tr/\n//); # count the newlines in $para
$count = tr/0-9//;           # count the digits in $_

$word =~ tr/a-zA-Z//s;       # bookkeeper -> bokeper

tr/@$%*//d;                  # delete any of those
tr#A-Za-z0-9+/##cd;          # remove non-base64 chars

# change en passant
($HOST = $host) =~ tr/a-z/A-Z/;

$pathname =~ tr/a-zA-Z/_/cs; # change non-(ASCII)alphas to single underbar

tr [\200-\377]
   [\000-\177];              # strip 8th bit, bytewise
If the same character occurs more than once in SEARCHLIST, only the first is used. Therefore, this:
tr/AAA/XYZ/
will change any single character A to an X (in $_).

Although variables aren't interpolated into tr///, you can still get the same effect by using eval EXPR:

$count = eval "tr/$oldlist/$newlist/";
die if $@;  # propagates exception from illegal eval contents

One more note: if you want to change your text to uppercase or lowercase, don't use tr///. Use the \U or \L sequences in a double-quoted string (or the equivalent uc and lc functions) since they will pay attention to locale or Unicode information and tr/a-z/A-Z/ won't. Additionally, in Unicode strings, the \u sequence and its corresponding ucfirst function understand the notion of titlecase, which for some languages may be distinct from simply converting to uppercase.

Previous | Home | Next
5.1. The Regular Expression Bestiary | Book Index | 5.3. Metacharacters and Metasymbols
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.3. Metacharacters and Metasymbols

Now that we've admired all the fancy cages, we can go back to looking at the critters in the cages, those funny-looking symbols you put inside the patterns. By now you'll have cottoned to the fact that these symbols aren't regular Perl code like function calls or arithmetic operators. Regular expressions are their own little language nestled inside of Perl. (There's a bit of the jungle in all of us.)

For all their power and expressivity, patterns in Perl recognize the same 12 traditional metacharacters (the Dirty Dozen, as it were) found in many other regular expression packages:

\ | ( ) [ { ^ $ * + ? .
Some of those bend the rules, making otherwise normal characters that follow them special. We don't like to call the longer sequences "characters", so when they make longer sequences, we call them metasymbols (or sometimes just "symbols"). But at the top level, those twelve metacharacters are all you (and Perl) need to think about. Everything else proceeds from there.

Some simple metacharacters stand by themselves, like . and ^ and $. They don't directly affect anything around them. Some metacharacters work like prefix operators, governing what follows them, like \. Others work like postfix operators, governing what immediately precedes them, like *, +, and ?. One metacharacter, |, acts like an infix operator, standing between the operands it governs. There are even bracketing metacharacters that work like circumfix operators, governing something contained inside them, like (...) and [...]. Parentheses are particularly important, because they specify the bounds of | on the inside, and of *, +, and ? on the outside.

If you learn only one of the twelve metacharacters, choose the backslash. (Er . . . and the parentheses.) That's because backslash disables the others. When a backslash precedes a nonalphanumeric character in a Perl pattern, it always makes that next character a literal. If you need to match one of the twelve metacharacters in a pattern literally, you write them with a backslash in front. Thus, \. matches a real dot, \$ a real dollar sign, \\ a real backslash, and so on. This is known as "escaping" the metacharacter, or "quoting it", or sometimes just "backslashing" it. (Of course, you already know that backslash is used to suppress variable interpolation in double-quoted strings.)

Although a backslash turns a metacharacter into a literal character, its effect upon a following alphanumeric character goes the other direction. It takes something that was regular and makes it special. That is, together they make a metasymbol. An alphabetical list of these metasymbols can be found below in Table 5-7.

5.3.1. Metasymbol Tables

In the following tables, the Atomic column says "yes" if the given metasymbol is quantifiable (if it can match something with width, more or less). Also, we've used "..." to represent "something else". Please see the later discussion to find out what "..." means, if it is not clear from the one-line gloss in the table.)

Table 5-4 shows the basic traditional metasymbols. The first four of these are the structural metasymbols we mentioned earlier, while the last three are simple metacharacters. The . metacharacter is an example of an atom because it matches something with width (the width of a character, in this case); ^ and $ are examples of assertions, because they match something of zero width, and because they are only evaluated to see if they're true or not.

Table 5.4. General Regex Metacharacters

Symbol | Atomic | Meaning
\... | Varies | De-meta next nonalphanumeric character, meta next alphanumeric character (maybe).
...|... | No | Alternation (match one or the other).
(...) | Yes | Grouping (treat as a unit).
[...] | Yes | Character class (match one character from a set).
^ | No | True at beginning of string (or after any newline, maybe).
. | Yes | Match one character (except newline, normally).
$ | No | True at end of string (or before any newline, maybe).

The quantifiers, which are further described in their own section, indicate how many times the preceding atom (that is, single character or grouping) should match. These are listed in Table 5-5.

Table 5.5. Regex Quantifiers

Quantifier | Atomic | Meaning
* | No | Match 0 or more times (maximal).
+ | No | Match 1 or more times (maximal).
? | No | Match 1 or 0 times (maximal).
{COUNT} | No | Match exactly COUNT times.
{MIN,} | No | Match at least MIN times (maximal).
{MIN,MAX} | No | Match at least MIN but not more than MAX times (maximal).
*? | No | Match 0 or more times (minimal).
+? | No | Match 1 or more times (minimal).
?? | No | Match 0 or 1 time (minimal).
{MIN,}? | No | Match at least MIN times (minimal).
{MIN,MAX}? | No | Match at least MIN but not more than MAX times (minimal).

A minimal quantifier tries to match as few characters as possible within its allowed range. A maximal quantifier tries to match as many characters as possible within its allowed range. For instance, .+ is guaranteed to match at least one character of the string, but will match all of them given the opportunity. The opportunities are discussed later in "The Little Engine That /Could(n't)?/".

You'll note that quantifiers may never be quantified.

We wanted to provide an extensible syntax for new kinds of metasymbols. Given that we only had a dozen metacharacters to work with, we chose a formerly illegal regex sequence to use for arbitrary syntactic extensions. These metasymbols are all of the form (?KEY...); that is, a (balanced) parenthesis followed by a question mark, followed by a KEY and the rest of the subpattern. The KEY character indicates which particular regex extension it is. See Table 5-6 for a list of these. Most of them behave structurally since they're based on parentheses, but they also have additional meanings. Again, only atoms may be quantified because they represent something that's really there (potentially).

Table 5.6. Extended Regex Sequences

Extension | Atomic | Meaning
(?#...) | No | Comment, discard.
(?:...) | Yes | Cluster-only parentheses, no capturing.
(?imsx-imsx) | No | Enable/disable pattern modifiers.
(?imsx-imsx:...) | Yes | Cluster-only parentheses plus modifiers.
(?=...) | No | True if lookahead assertion succeeds.
(?!...) | No | True if lookahead assertion fails.
(?<=...) | No | True if lookbehind assertion succeeds.
(?<!...) | No | True if lookbehind assertion fails.
(?>...) | Yes | Match nonbacktracking subpattern.
(?{...}) | No | Execute embedded Perl code.
(??{...}) | Yes | Match regex from embedded Perl code.
(?(...)...|...) | Yes | Match with if-then-else pattern.
(?(...)...) | Yes | Match with if-then pattern.

And finally, Table 5-7 shows all of your favorite alphanumeric metasymbols. (Symbols that are processed by the variable interpolation pass are marked with a dash in the Atomic column, since the Engine never even sees them.)

Table 5.7. Alphanumeric Regex Metasymbols

Symbol | Atomic | Meaning
\0 | Yes | Match the null character (ASCII NUL).
\NNN | Yes | Match the character given in octal, up to \377.
\n | Yes | Match nth previously captured string (decimal).
\a | Yes | Match the alarm character (BEL).
\A | No | True at the beginning of a string.
\b | Yes | Match the backspace character (BS).
\b | No | True at word boundary.
\B | No | True when not at word boundary.
\c X | Yes | Match the control character Control-X (\cZ, \c[, etc.).
\C | Yes | Match one byte (C char) even in utf8 (dangerous).
\d | Yes | Match any digit character.
\D | Yes | Match any nondigit character.
\e | Yes | Match the escape character (ASCII ESC, not backslash).
\E | -- | End case (\L, \U) or metaquote (\Q) translation.
\f | Yes | Match the form feed character (FF).
\G | No | True at end-of-match position of prior m//g.
\l | -- | Lowercase the next character only.
\L | -- | Lowercase till \E.
\n | Yes | Match the newline character (usually NL, but CR on Macs).
\N{NAME} | Yes | Match the named char (\N{greek:Sigma}).
\p{PROP} | Yes | Match any character with the named property.
\P{PROP} | Yes | Match any character without the named property.
\Q | -- | Quote (de-meta) metacharacters till \E.
\r | Yes | Match the return character (usually CR, but NL on Macs).
\s | Yes | Match any whitespace character.
\S | Yes | Match any nonwhitespace character.
\t | Yes | Match the tab character (HT).
\u | -- | Titlecase next character only.
\U | -- | Uppercase (not titlecase) till \E.
\w | Yes | Match any "word" character (alphanumerics plus "_").
\W | Yes | Match any nonword character.
\x{abcd} | Yes | Match the character given in hexadecimal.
\X | Yes | Match Unicode "combining character sequence" string.
\z | No | True at end of string only.
\Z | No | True at end of string or before optional newline.

The braces are optional on \p and \P if the property name is one character. The braces are optional on \x if the hexadecimal number is two digits or less. The braces are never optional on \N.

Only metasymbols with "Match the..." or "Match any..." descriptions may be used within character classes (square brackets). That is, character classes are limited to containing specific sets of characters, so within them you may only use metasymbols that describe other specific sets of characters, or that describe specific individual characters. Of course, these metasymbols may also be used outside character classes, along with all the other nonclassificatory metasymbols. Note however that \b is two entirely different beasties: it's a backspace character inside the character class, but a word boundary assertion outside.

There is some amount of overlap between the characters that a pattern can match and the characters an ordinary double-quoted string can interpolate. Since regexes undergo two passes, it is sometimes ambiguous which pass should process a given character. When there is ambiguity, the variable interpolation pass defers the interpretation of such characters to the regular expression parser.

But the variable interpolation pass can only defer to the regex parser when it knows it is parsing a regex. You can specify regular expressions as ordinary double-quoted strings, but then you must follow normal double-quote rules. Any of the previous metasymbols that happen to map to actual characters will still work, even though they're not being deferred to the regex parser. But you can't use any of the other metasymbols in ordinary double quotes (or in any similar constructs such as `...`, qq(...), qx(...), or the equivalent here documents). If you want your string to be parsed as a regular expression without doing any matching, you should be using the qr// (quote regex) operator.

Note that the case and metaquote translation escapes (\U and friends) must be processed during the variable interpolation pass because the purpose of those metasymbols is to influence how variables are interpolated. If you suppress variable interpolation with single quotes, you don't get the translation escapes either. Neither variables nor translation escapes (\U, etc.) are expanded in any single quoted string, nor in single-quoted m'...' or qr'...' operators. Even when you do interpolation, these translation escapes are ignored if they show up as the result of variable interpolation, since by then it's too late to influence variable interpolation.

Although the transliteration operator doesn't take regular expressions, any metasymbol we've discussed that matches a single specific character also works in a tr/// operation. The rest do not (except for backslash, which continues to work in the backward way it always works.)

5.3.2. Specific Characters

As mentioned before, everything that's not special in a pattern matches itself. That means an /a/ matches an "a", an /=/ matches an "=", and so on. Some characters, though, aren't very easy to type in from the keyboard or, even if you manage that, don't show up on a printout; control characters are notorious for this. In a regular expression, Perl recognizes the following double-quotish character aliases:

Escape | Meaning
\0 | Null character (ASCII NUL)
\a | Alarm (BEL)
\e | Escape (ESC)
\f | Form feed (FF)
\n | Newline (NL, CR on Mac)
\r | Return (CR, NL on Mac)
\t | Tab (HT)

Just as in double-quoted strings, Perl also honors the following four metasymbols in patterns:

\c X

A named control character, like \cC for Control-C, \cZ for Control-Z, \c[ for ESC, and \c? for DEL.

\NNN

A character specified using its two- or three-digit octal code. The leading 0 is optional, except for values less than 010 (8 decimal) since (unlike in double-quoted strings) the single-digit versions are always considered to be backreferences to captured strings within a pattern. Multiple digits are interpreted as the nth backreference if you've captured at least n substrings earlier in the pattern (where n is considered as a decimal number). Otherwise, they are interpreted as a character specified in octal.

\x{LONGHEX}
\x HEX

A character number specified as one or two hex digits ([0-9a-fA-F]), as in \x1B. The one-digit form is usable only if the character following it is not a hex digit. If braces are used, you may use as many digits as you'd like, which may result in a Unicode character. For example, \x{262f} matches a Unicode YIN YANG.

\N{NAME}

A named character, such \N{GREEK SMALL LETTER EPSILON}, \N{greek:epsilon}, or \N{epsilon}. This requires the use charnames pragma described in Chapter 31, "Pragmatic Modules", which also determines which flavors of those names you may use (":long", ":full", ":short" respectively, corresponding to the three styles just shown).

A list of all Unicode character names can be found in your closest Unicode standards document, or in PATH_TO_PERLLIB/unicode/Names.txt.

5.3.3. Wildcard Metasymbols

Three special metasymbols serve as generic wildcards, each of them matching "any" character (for certain values of "any"). These are the dot ("."), \C, and \X. None of these may be used in a character class. You can't use the dot there because it would match (nearly) any character in existence, so it's something of a universal character class in its own right. If you're going to include or exclude everything, there's not much point in having a character class. The special wildcards \C and \X have special structural meanings that don't map well to the notion of choosing a single Unicode character, which is the level at which character classes work.

The dot metacharacter matches any one character other than a newline. (And with the /s modifier, it matches that, too.) Like any of the dozen special characters in a pattern, to match a dot literally, you must escape it with a backslash. For example, this checks whether a filename ends with a dot followed by a one-character extension:

if ($pathname =~ /\.(.)\z/s) {
    print "Ends in $1\n";
}
The first dot, the escaped one, is the literal character, and the second says "match any character". The \z says to match only at the end of the string, and the /s modifier lets the dot match a newline as well. (Yes, using a newline as a file extension Isn't Very Nice, but that doesn't mean it can't happen.)

The dot metacharacter is most often used with a quantifier. A .* matches a maximal number of characters, while a .*? matches a minimal number of characters. But it's also sometimes used without a quantifier for its width: /(..):(..):(..)/ matches three colon-separated fields, each of which is two characters long.

If you use a dot in a pattern compiled under the lexically scoped use utf8 pragma, then it will match any Unicode character. (You're not supposed to need a use utf8 for that, but accidents will happen. The pragma may not be necessary by the time you read this.)

use utf8;
use charnames qw/:full/;
$BWV[887] = "G\N{MUSIC SHARP SIGN} minor";
($note, $black, $mode) = $BWV[887] =~ /^([A-G])(.)\s+(\S+)/;
print "That's lookin' sharp!\n" if $black eq chr(9839);

The \X metasymbol matches a character in a more extended sense. It really matches a string of one or more Unicode characters known as a "combining character sequence". Such a sequence consists of a base character followed by any "mark" characters (diacritical markings like cedillas or diereses) that combine with that base character to form one logical unit. \X is exactly equivalent to (?:\PM\pM*). This allows it to match one logical character, even when that really comprises several separate characters. The length of the match in /\X/ would exceed one character if it matched any combining characters. (And that's character length, which has little to do with byte length).

If you are using Unicode and really want to get at a single byte instead of a single character, you can use the \C metasymbol. This will always match one byte (specifically, one C language char type), even if this gets you out of sync with your Unicode character stream. See the appropriate warnings about doing this in Chapter 15, "Unicode".

Previous | Home | Next
5.2. Pattern-Matching Operators | Book Index | 5.4. Character Classes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.4. Character Classes

In a pattern match, you may match any character that has--or that does not have--a particular property. There are four ways to specify character classes. You may specify a character classes in the traditional way using square brackets and enumerating the possible characters, or you may use any of three mnemonic shortcuts: the classic Perl classes, the new Perl Unicode properties, or the standard POSIX classes. Each of these shortcuts matches only one character from its set. Quantify them to match larger expanses, such as \d+ to match one or more digits. (An easy mistake is to think that \w matches a word. Use \w+ to match a word.)

5.4.1. Custom Character Classes

An enumerated list of characters in square brackets is called a character class and matches any one of the characters in the list. For example, [aeiouy] matches a letter that can be a vowel in English. (For Welsh add a "w", for Scottish an "r".) To match a right square bracket, either backslash it or place it first in the list.

Character ranges may be indicated using a hyphen and the a-z notation. Multiple ranges may be combined; for example, [0-9a-fA-F] matches one hex "digit". You may use a backslash to protect a hyphen that would otherwise be interpreted as a range delimiter, or just put it at the beginning or end of the class (a practice which is arguably less readable but more traditional).

A caret (or circumflex, or hat, or up arrow) at the front of the character class inverts the class, causing it to match any single character not in the list. (To match a caret, either don't put it first, or better, escape it with a backslash.) For example, [^aeiouy] matches any character that isn't a vowel. Be careful with character class negation, though, because the universe of characters is expanding. For example, that character class matches consonants--and also matches spaces, newlines, and anything (including vowels) in Cyrillic, Greek, or nearly any other script, not to mention every idiograph in Chinese, Japanese, and Korean. And someday maybe even Cirth, Tengwar, and Klingon. (Linear B and Etruscan, for sure.) So it might be better to specify your consonants explicitly, such as [cbdfghjklmnpqrstvwxyz], or [b-df-hj-np-tv-z] for short. (This also solves the issue of "y" needing to be in two places at once, which a set complement would preclude.)

Normal character metasymbols are supported inside a character class, (see "Specific Characters"), such as \n, \t, \c X, \NNN, and \N{NAME}. Additionally, you may use \b within a character class to mean a backspace, just as it does in a double-quoted string. Normally, in a pattern match, it means a word boundary. But zero-width assertions don't make any sense in character classes, so here \b returns to its normal meaning in strings. You may also use any predefined character class described later in the chapter (classic, Unicode, or POSIX), but don't try to use them as endpoints of a range--that doesn't make sense, so the "-" will be interpreted literally.

All other metasymbols lose their special meaning inside square brackets. In particular, you can't use any of the three generic wildcards: ".", \X, or \C. The first often surprises people, but it doesn't make much sense to use the universal character class within a restricted one, and you often want to match a literal dot as part of a character class--when you're matching filenames, for instance. It's also meaningless to specify quantifiers, assertions, or alternation inside a character class, since the characters are interpreted individually. For example, [fee|fie|foe|foo] means the same thing as [feio|].

5.4.2. Classic Perl Character Class Shortcuts

Since the beginning, Perl has provided a number of character class shortcuts. These are listed in Table 5-8. All of them are backslashed alphabetic metasymbols, and in each case, the uppercase version is the negation of the lowercase version. The meanings of these are not quite as fixed as you might expect; the meanings can be influenced by locale settings. Even if you don't use locales, the meanings can change whenever a new Unicode standard comes out, adding scripts with new digits and letters. (To keep the old byte meanings, you can always use bytes. For explanations of the utf8 meanings, see "Unicode Properties" later in this chapter. In any case, the utf8 meanings are a superset of the byte meanings.)

Table 5.8. Classic Character Classes

Symbol | Meaning | As Bytes | As utf8
\d | Digit | [0-9] | \p{IsDigit}
\D | Nondigit | [^0-9] | \P{IsDigit}
\s | Whitespace | [ \t\n\r\f] | \p{IsSpace}
\S | Nonwhitespace | [^ \t\n\r\f] | \P{IsSpace}
\w | Word character | [a-zA-Z0-9_] | \p{IsWord}
\W | Non-(word character) | [^a-zA-Z0-9_] | \P{IsWord}

(Yes, we know most words don't have numbers or underscores in them; \w is for matching "words" in the sense of tokens in a typical programming language. Or Perl, for that matter.)

These metasymbols may be used either outside or inside square brackets, that is, either standalone or as part of a constructed character class:

if ($var =~ /\D/)        { warn "contains non-digit" }
if ($var =~ /[^\w\s.]/)  { warn "contains non-(word, space, dot)" }

5.4.3. Unicode Properties

Unicode properties are available using \p{PROP} and its set complement, \P{PROP}. For the rare properties with one-character names, braces are optional, as in \pN to indicate a numeric character (not necessarily decimal--Roman numerals are numeric characters too). These property classes may be used by themselves or combined in a constructed character class:

if ($var =~ /^\p{IsAlpha}+$/)      { print "all alphabetic" }
if ($var =~ s/[\p{Zl}\p{Zp}]/\n/g) { print "fixed newline wannabes" }
Some properties are directly defined in the Unicode standard, and some properties are composites defined by Perl, based on the standard properties. Zl and Zp are standard Unicode properties representing line separators and paragraph separators, while IsAlpha is defined by Perl to be a property class combining the standard properties Ll, Lu, Lt, and Lo, (that is, letters that are lowercase, uppercase, titlecase, or other). As of version 5.6.0 of Perl, you need to use utf8 for these properties to work. This restriction will be relaxed in the future.

There are a great many properties. We'll list the ones we know about, but the list is necessarily incomplete. New properties are likely to be in new versions of Unicode, and you can even define your own properties. More about that later.

The Unicode Consortium produces the online resources that turn into the various files Perl uses in its Unicode implementation. For more about these files, see Chapter 15, "Unicode". You can get a nice overview of Unicode in the document PATH_TO_PERLLIB/unicode/Unicode3.html where PATH_TO_PERLLIB is what is printed out by:

perl -MConfig -le 'print $Config{privlib}'
Most Unicode properties are of the form \p{Is PROP}. The Is is optional, since it's so common, but you may prefer to leave it in for readability.

5.4.3.1. Perl's Unicode properties

First, Table 5-9 lists Perl's composite properties. They're defined to be reasonably close to the standard POSIX definitions for character classes.

Table 5.9. Composite Unicode Properties

Property | Equivalent
IsASCII | [\x00-\x7f]
IsAlnum | [\p{IsLl}\p{IsLu}\p{IsLt}\p{IsLo}\p{IsNd}]
IsAlpha | [\p{IsLl}\p{IsLu}\p{IsLt}\p{IsLo}]
IsCntrl | \p{IsC}
IsDigit | \p{Nd}
IsGraph | [^\pC\p{IsSpace}]
IsLower | \p{IsLl}
IsPrint | \P{IsC}
IsPunct | \p{IsP}
IsSpace | [\t\n\f\r\p{IsZ}]
IsUpper | [\p{IsLu}\p{IsLt}]
IsWord | [_\p{IsLl}\p{IsLu}\p{IsLt}\p{IsLo}\p{IsNd}]
IsXDigit | [0-9a-fA-F]

Perl also provides the following composites for each of main categories of standard Unicode properties (see the next section):

Property | Meaning | Normative
IsC | Crazy control codes and such | Yes
IsL | Letters | Partly
IsM | Marks | Yes
IsN | Numbers | Yes
IsP | Punctuation | No
IsS | Symbols | No
IsZ | Separators (Zeparators?) | Yes

5.4.3.2. Standard Unicode properties

Table 5-10 lists the most basic standard Unicode properties, derived from each character's category. No character is a member of more than one category. Some properties are normative; others are merely informative. See the Unicode Standard for the standard spiel on just how normative the normative information is, and just how informative the informative information isn't.

Table 5.10. Standard Unicode Properties

Property | Meaning | Normative
IsCc | Other, Control | Yes
IsCf | Other, Format | Yes
IsCn | Other, Not assigned | Yes
IsCo | Other, Private Use | Yes
IsCs | Other, Surrogate | Yes
IsLl | Letter, Lowercase | Yes
IsLm | Letter, Modifier | No
IsLo | Letter, Other | No
IsLt | Letter, Titlecase | Yes
IsLu | Letter, Uppercase | Yes
IsMc | Mark, Combining | Yes
IsMe | Mark, Enclosing | Yes
IsMn | Mark, Nonspacing | Yes
IsNd | Number, Decimal digit | Yes
IsNl | Number, Letter | Yes
IsNo | Number, Other | Yes
IsPc | Punctuation, Connector | No
IsPd | Punctuation, Dash | No
IsPe | Punctuation, Close | No
IsPf | Punctuation, Final quote | No
IsPi | Punctuation, Initial quote | No
IsPo | Punctuation, Other | No
IsPs | Punctuation, Open | No
IsSc | Symbol, Currency | No
IsSk | Symbol, Modifier | No
IsSm | Symbol, Math | No
IsSo | Symbol, Other | No
IsZl | Separator, Line | Yes
IsZp | Separator, Paragraph | Yes
IsZs | Separator, Space | Yes

Another useful set of properties has to do with whether a given character can be decomposed (either canonically or compatibly) into other simpler characters. Canonical decomposition doesn't lose any formatting information. Compatibility decomposition may lose formatting information such as whether a character is a superscript.

Property | Information Lost
IsDecoCanon | Nothing
IsDecoCompat | Something (one of the following)
IsDCcircle | Circle around character
IsDCfinal | Final position preference (Arabic)
IsDCfont | Variant font preference
IsDCfraction | Vulgar fraction characteristic
IsDCinitial | Initial position preference (Arabic)
IsDCisolated | Isolated position preference (Arabic)
IsDCmedial | Medial position preference (Arabic)
IsDCnarrow | Narrow characteristic
IsDCnoBreak | Nonbreaking preference on space or hyphen
IsDCsmall | Small characteristic
IsDCsquare | Square around CJK character
IsDCsub | Subscription
IsDCsuper | Superscription
IsDCvertical | Rotation (horizontal to vertical)
IsDCwide | Wide characteristic
IsDCcompat | Identity (miscellaneous)

Here are some properties of interest to people doing bidirectional rendering:

Property | Meaning
IsBidiL | Left-to-right (Arabic, Hebrew)
IsBidiLRE | Left-to-right embedding
IsBidiLRO | Left-to-right override
IsBidiR | Right-to-left
IsBidiAL | Right-to-left Arabic
IsBidiRLE | Right-to-left embedding
IsBidiRLO | Right-to-left override
IsBidiPDF | Pop directional format
IsBidiEN | European number
IsBidiES | European number separator
IsBidiET | European number terminator
IsBidiAN | Arabic number
IsBidiCS | Common number separator
IsBidiNSM | Nonspacing mark
IsBidiBN | Boundary neutral
IsBidiB | Paragraph separator
IsBidiS | Segment separator
IsBidiWS | Whitespace
IsBidiON | Other Neutrals
IsMirrored | Reverse when used right-to-left

The following properties classify various syllabaries according to vowel sounds:

IsSylA         IsSylE         IsSylO         IsSylWAA       IsSylWII
IsSylAA        IsSylEE        IsSylOO        IsSylWC        IsSylWO
IsSylAAI       IsSylI         IsSylU         IsSylWE        IsSylWOO
IsSylAI        IsSylII        IsSylV         IsSylWEE       IsSylWU
IsSylC         IsSylN         IsSylWA        IsSylWI        IsSylWV
For example, \p{IsSylA} would match \N{KATAKANA LETTER KA} but not \N{KATAKANA LETTER KU}.

Now that we've basically told you all these Unicode 3.0 properties, we should point out that a few of the more esoteric ones aren't implemented in version 5.6.0 of Perl because its implementation was based in part on Unicode 2.0, and things like the bidirectional algorithm were still being worked out. However, by the time you read this, the missing properties may well be implemented, so we listed them anyway.

5.4.3.3. Unicode block properties

Some Unicode properties are of the form \p{In SCRIPT}. (Note the distinction between Is and In.) The In properties are for testing block ranges of a particular SCRIPT. If you have a character, and you wonder whether it were written in Greek script, you could test with:

print "It's Greek to me!\n" if chr(931) =~ /\p{InGreek}/;
That works by checking whether a character is "in" the valid range of that script type. This may be negated with \P{In SCRIPT} to find out whether something isn't in a particular script's block, such as \P{InDingbats} to test whether a string contains a non-dingbat. Block properties include the following:
InArabic       InCyrillic     InHangulJamo   InMalayalam    InSyriac
InArmenian     InDevanagari   InHebrew       InMongolian    InTamil
InArrows       InDingbats     InHiragana     InMyanmar      InTelugu
InBasicLatin   InEthiopic     InKanbun       InOgham        InThaana
InBengali      InGeorgian     InKannada      InOriya        InThai
InBopomofo     InGreek        InKatakana     InRunic        InTibetan
InBoxDrawing   InGujarati     InKhmer        InSinhala      InYiRadicals
InCherokee     InGurmukhi     InLao          InSpecials     InYiSyllables
Not to mention jawbreakers like these:
InAlphabeticPresentationForms         InHalfwidthandFullwidthForms
InArabicPresentationForms-A           InHangulCompatibilityJamo
InArabicPresentationForms-B           InHangulSyllables
InBlockElements                       InHighPrivateUseSurrogates
InBopomofoExtended                    InHighSurrogates
InBraillePatterns                     InIdeographicDescriptionCharacters
InCJKCompatibility                    InIPAExtensions
InCJKCompatibilityForms               InKangxiRadicals
InCJKCompatibilityIdeographs          InLatin-1Supplement
InCJKRadicalsSupplement               InLatinExtended-A
InCJKSymbolsandPunctuation            InLatinExtended-B
InCJKUnifiedIdeographs                InLatinExtendedAdditional
InCJKUnifiedIdeographsExtensionA      InLetterlikeSymbols
InCombiningDiacriticalMarks           InLowSurrogates
InCombiningHalfMarks                  InMathematicalOperators
InCombiningMarksforSymbols            InMiscellaneousSymbols
InControlPictures                     InMiscellaneousTechnical
InCurrencySymbols                     InNumberForms
InEnclosedAlphanumerics               InOpticalCharacterRecognition
InEnclosedCJKLettersandMonths         InPrivateUse
InGeneralPunctuation                  InSuperscriptsandSubscripts
InGeometricShapes                     InSmallFormVariants
InGreekExtended                       InSpacingModifierLetters
And the winner is:
InUnifiedCanadianAboriginalSyllabics
See PATH_TO_PERLLIB/unicode/In/*.pl to get an up-to-date listing of all of these character block properties. Note that these In properties are only testing to see if the character is in the block of characters allocated for that script. There is no guarantee that all characters in that range are defined; you also need to test against one of the Is properties discussed earlier to see if the character is defined. There is also no guarantee that a particular language doesn't use characters outside its assigned block. In particular, many European languages mix extended Latin characters with Latin-1 characters.

But hey, if you need a particular property that isn't provided, that's not a big problem. Read on.

5.4.3.4. Defining your own character properties

To define your own property, you need to write a subroutine with the name of the property you want (see Chapter 6, "Subroutines"). The subroutine should be defined in the package that needs the property (see Chapter 10, "Packages"), which means that if you want to use it in multiple packages, you'll either have to import it from a module (see Chapter 11, "Modules"), or inherit it as a class method from the package in which it is defined (see Chapter 12, "Objects").

Once you've got that all settled, the subroutine should return data in the same format as the files in PATH_TO_PERLLIB/unicode/Is directory. That is, just return a list of characters or character ranges in hexadecimal, one per line. If there is a range, the two numbers are separated by a tab. Suppose you wanted a property that would be true if your character is in the range of either of the Japanese syllabaries, known as hiragana and katakana. (Together they're known as kana). You can just put in the two ranges like this:

sub InKana {
    return <<'END';
3040    309F
30A0    30FF
END
}
Alternatively, you could define it in terms of existing property names:
sub InKana {
    return <<'END';
+utf8::InHiragana
+utf8::InKatakana
END
}
You can also do set subtraction using a "-" prefix. Suppose you only wanted the actual characters, not just the block ranges of characters. You could weed out all the undefined ones like this:
sub IsKana {
    return <<'END';
+utf8::InHiragana
+utf8::InKatakana
-utf8::IsCn
END
}
You can also start with a complemented character set using the "!" prefix:
sub IsNotKana {
    return <<'END';
!utf8::InHiragana
-utf8::InKatakana
+utf8::IsCn
END
}
Perl itself uses exactly the same tricks to define the meanings of its "classic" character classes (like \w) when you include them in your own custom character classes (like [-.\w\s]). You might think that the more complicated you get with your rules, the slower they will run, but in fact, once Perl has calculated the bit pattern for a particular 64-bit swatch of your property, it caches it so it never has to recalculate the pattern again. (It does it in 64-bit swatches so that it doesn't even have to decode your utf8 to do its lookups.) Thus, all character classes, built-in or custom, run at essentially the same speed (fast) once they get going.

5.4.4. POSIX-Style Character Classes

Unlike Perl's other character class shortcuts, the POSIX-style character-class syntax notation, [:CLASS:], is available for use only when constructing other character classes, that is, inside an additional pair of square brackets. For example, /[.,[:alpha:][:digit:]]/ will search for one character that is either a literal dot (because it's in a character class), a comma, an alphabetic character, or a digit.

The POSIX classes available as of revision 5.6 of Perl are shown in Table 5-11.

Table 5.11. POSIX Character Classes

Class | Meaning
alnum | Any alphanumeric, that is, an alpha or a digit.
alpha | Any letter. (That's a lot more letters than you think, unless you're thinking Unicode, in which case it's still a lot.)
ascii | Any character with an ordinal value between 0 and 127.
cntrl | Any control character. Usually characters that don't produce output as such, but instead control the terminal somehow; for example, newline, form feed, and backspace are all control characters. Characters with an ord value less than 32 are most often classified as control characters.
digit | A character representing a decimal digit, such as 0 to 9. (Includes other characters under Unicode.) Equivalent to \d.
graph | Any alphanumeric or punctuation character.
lower | A lowercase letter.
print | Any alphanumeric or punctuation character or space.
punct | Any punctuation character.
space | Any space character. Includes tab, newline, form feed, and carriage return (and a lot more under Unicode.) Equivalent to \s.
upper | Any uppercase (or titlecase) letter.
word | Any identifier character, either an alnum or underline.
xdigit | Any hexadecimal digit. Though this may seem silly ([0-9a-fA-F] works just fine), it is included for completeness.

You can negate the POSIX character classes by prefixing the class name with a ^ following the [:. (This is a Perl extension.) For example:

POSIX | Classic
[:^digit:] | \D
[:^space:] | \S
[:^word:] | \W

If the use utf8 pragma is not requested, but the use locale pragma is, the classes correlate directly with the equivalent functions in the C library's isalpha(3) interface (except for word, which is a Perl extension, mirroring \w).

If the utf8 pragma is used, POSIX character classes are exactly equivalent to the corresponding Is properties listed in Table 5-9. For example [:lower:] and \p{Lower} are equivalent, except that the POSIX classes may only be used within constructed character classes, whereas Unicode properties have no such restriction and may be used in patterns wherever Perl shortcuts like \s and \w may be used.

The brackets are part of the POSIX-style [::] construct, not part of the whole character class. This leads to writing patterns like /^[[:lower:][:digit:]]+$/, to match a string consisting entirely of lowercase letters or digits (plus an optional trailing newline). In particular, this does not work:

42 =~ /^[:digit:]$/         # WRONG
That's because it's not inside a character class. Rather, it is a character class, the one representing the characters ":", "i", "t", "g", and "d". Perl doesn't care that you specified ":" twice.

Here's what you need instead:

42 =~ /^[[:digit:]]+$/
The POSIX character classes [.cc.] and [=cc=] are recognized but produce an error indicating they are not supported. Trying to use any POSIX character class in older verions of Perl is likely to fail miserably, and perhaps even silently. If you're going to use POSIX character classes, it's best to require a new version of Perl by saying:
use 5.6.0;

Previous | Home | Next
5.3. Metacharacters and Metasymbols | Book Index | 5.5. Quantifiers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.5. Quantifiers

Unless you say otherwise, each item in a regular expression matches just once. With a pattern like /nop/, each of those characters must match, each right after the other. Words like "panoply" or "xenophobia" are fine, because where the match occurs doesn't matter.

If you wanted to match both "xenophobia" and "Snoopy", you couldn't use the /nop/ pattern, since that requires just one "o" between the "n" and the "p", and Snoopy has two. This is where quantifiers come in handy: they say how many times something may match, instead of the default of matching just once. Quantifiers in a regular expression are like loops in a program; in fact, if you think of a regex as a program, then they are loops. Some loops are exact, like "repeat this match five times only" ({5}). Others give both lower and upper bounds on the match count, like "repeat this match at least twice but no more than four times" ({2,4}). Others have no closed upper bound at all, like "match this at least twice, but as many times as you'd like" ({2,}).

Table 5-12 shows the quantifiers that Perl recognizes in a pattern.

Table 5.12. Regex Quantifiers Compared

Maximal | Minimal | Allowed Range
{MIN,MAX} | {MIN,MAX}? | Must occur at least MIN times but no more than MAX times
{MIN,} | {MIN,}? | Must occur at least MIN times
{COUNT} | {COUNT}? | Must match exactly COUNT times
* | *? | 0 or more times (same as {0,})
+ | +? | 1 or more times (same as {1,})
? | ?? | 0 or 1 time (same as {0,1})

Something with a * or a ? doesn't actually have to match. That's because they can match 0 times and still be considered a success. A + may often be a better fit, since it has to be there at least once.

Don't be confused by the use of "exactly" in the previous table. It refers only to the repeat count, not the overall string. For example, $n =~ /\d{3}/ doesn't say "is this string exactly three digits long?" It asks whether there's any point within $n at which three digits occur in a row. Strings like "101 Morris Street" test true, but so do strings like "95472" or "1-800-555-1212". All contain three digits at one or more points, which is all you asked about. See the section Section 5.6, "Positions" for how to use positional assertions (as in /^\d{3}$/) to nail this down.

Given the opportunity to match something a variable number of times, maximal quantifiers will elect to maximize the repeat count. So when we say "as many times as you'd like", the greedy quantifier interprets this to mean "as many times as you can possibly get away with", constrained only by the requirement that this not cause specifications later in the match to fail. If a pattern contains two open-ended quantifiers, then obviously both cannot consume the entire string: characters used by one part of the match are no longer available to a later part. Each quantifier is greedy at the expense of those that follow it, reading the pattern left to right.

That's the traditional behavior of quantifiers in regular expressions. However, Perl permits you to reform the behavior of its quantifiers: by placing a ? after that quantifier, you change it from maximal to minimal. That doesn't mean that a minimal quantifier will always match the smallest number of repetitions allowed by its range, any more than a maximal quantifier must always match the greatest number allowed in its range. The overall match must still succeed, and the minimal match will take as much as it needs to succeed, and no more. (Minimal quantifiers value contentment over greed.)

For example, in the match:

"exasperate" =~ /e(.*)e/    #  $1 now "xasperat"
the .* matches "xasperat", the longest possible string for it to match. (It also stores that value in $1, as described in the section Section 5.7, "Capturing and Clustering" later in the chapter.) Although a shorter match was available, a greedy match doesn't care. Given two choices at the same starting point, it always returns the longer of the two.

Contrast this with this:

"exasperate" =~ /e(.*?)e/   #  $1 now "xasp"
Here, the minimal matching version, .*?, is used. Adding the ? to * makes *? take on the opposite behavior: now given two choices at the same starting point, it always returns the shorter of the two.

Although you could read *? as saying to match zero or more of something but preferring zero, that doesn't mean it will always match zero characters. If it did so here, for example, and left $1 set to "", then the second "e" wouldn't be found, since it doesn't immediately follow the first one.

You might also wonder why, in minimally matching /e(.*?)e/, Perl didn't stick "rat" into $1. After all, "rat" also falls between two e's, and is shorter than "xasp". In Perl, the minimal/maximal choice applies only when selecting the shortest or longest from among several matches that all have the same starting point. If two possible matches exist, but these start at different offsets in the string, then their lengths don't matter--nor does it matter whether you've used a minimal quantifier or a maximal one. The earliest of several valid matches always wins out over all latecomers. It's only when multiple possible matches start at the same point that you use minimal or maximal matching to break the tie. If the starting points differ, there's no tie to break. Perl's matching is normally leftmost longest; with minimal matching, it becomes leftmost shortest. But the "leftmost" part never varies and is the dominant criterion.[7]

[7] Not all regex engines work this way. Some believe in overall greed, in which the longest match always wins, even if it shows up later. Perl isn't that way. You might say that eagerness holds priority over greed (or thrift). For a more formal discussion of this principle and many others, see the section Section 5.9.4, "The Little Engine That /Could(n't)?/".

There are two ways to defeat the leftward leanings of the pattern matcher. First, you can use an earlier greedy quantifier (typically .*) to try to slurp earlier parts of the string. In searching for a match for a greedy quantifier, it tries for the longest match first, which effectively searches the rest of the string right-to-left:

"exasperate" =~ /.*e(.*?)e/   #  $1 now "rat"
But be careful with that, since the overall match now includes the entire string up to that point.

The second way to defeat leftmostness to use positional assertions, discussed in the next section.

Previous | Home | Next
5.4. Character Classes | Book Index | 5.6. Positions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.6. Positions

Some regex constructs represent positions in the string to be matched, which is a location just to the left or right of a real character. These metasymbols are examples of zero-width assertions because they do not correspond to actual characters in the string. We often just call them "assertions". (They're also known as "anchors" because they tie some part of the pattern to a particular position.)

You can always manipulate positions in a string without using patterns. The built-in substr function lets you extract and assign to substrings, measured from the beginning of the string, the end of the string, or from a particular numeric offset. This might be all you need if you were working with fixed-length records, for instance. Patterns are only necessary when a numeric offset isn't sufficient. But most of the time, offsets aren't sufficient--at least, not sufficiently convenient, compared to patterns.

5.6.1. Beginnings: The \A and ^ Assertions

The \A assertion matches only at the beginning of the string, no matter what. However, the ^ assertion is the traditional beginning-of-line assertion as well as a beginning-of-string assertion. Therefore, if the pattern uses the /m modifier[8] and the string has embedded newlines, ^ also matches anywhere inside the string immediately following a newline character:

/\Abar/      # Matches "bar" and "barstool"
/^bar/       # Matches "bar" and "barstool"
/^bar/m      # Matches "bar" and "barstool" and "sand\nbar"
Used in conjunction with /g, the /m modifier lets ^ match many times in the same string:
s/^\s+//gm;             # Trim leading whitespace on each line
$total++ while /^./mg;  # Count nonblank lines

[8] Or you've set the deprecated $* variable to 1 and you're not overriding $* with the /s modifier.

5.6.2. Endings: The \z, \Z, and $ Assertions

The \z metasymbol matches at the end of the string, no matter what's inside. \Z matches right before the newline at the end of the string if there is a newline, or at the end if there isn't. The $ metacharacter usually means the same as \Z. However, if the /m modifier was specified and the string has embedded newlines, then $ can also match anywhere inside the string right in front of a newline:

/bot\z/      # Matches "robot"
/bot\Z/      # Matches "robot" and "abbot\n"
/bot$/       # Matches "robot" and "abbot\n"
/bot$/m      # Matches "robot" and "abbot\n" and "robot\nrules"

/^robot$/    # Matches "robot" and "robot\n"
/^robot$/m   # Matches "robot" and "robot\n" and "this\nrobot\n"
/\Arobot\Z/  # Matches "robot" and "robot\n"
/\Arobot\z/  # Matches only "robot" -- but why didn't you use eq?
As with ^, the /m modifier lets $ match many times in the same string when used with /g. (These examples assume that you've read a multiline record into $_, perhaps by setting $/ to "" before reading.)
s/\s*$//gm;   # Trim trailing whitespace on each line in paragraph

while (/^([^:]+):\s*(.*)/gm ) {  # get mail header
    $headers{$1} = $2;
}
In "Variable Interpolation" later in this chapter, we'll discuss how you can interpolate variables into patterns: if $foo is "bc", then /a$foo/ is equivalent to /abc/. Here, the $ does not match the end of the string. For a $ to match the end of the string, it must be at the end of the pattern or immediately be followed by a vertical bar or closing parenthesis.

5.6.3. Boundaries: The \b and \B Assertions

The \b assertion matches at any word boundary, defined as the position between a \w character and a \W character, in either order. If the order is \W\w, it's a beginning-of-word boundary, and if the order is \w\W, it's an end-of-word boundary. (The ends of the string count as \W characters here.) The \B assertion matches any position that is not a word boundary, that is, the middle of either \w\w or \W\W.

/\bis\b/   # matches "what it is" and "that is it"
/\Bis\B/   # matches "thistle" and "artist"
/\bis\B/   # matches "istanbul" and "so--isn't that butter?"
/\Bis\b/   # matches "confutatis" and "metropolis near you"
Because \W includes all punctuation characters (except the underscore), there are \b boundaries in the middle of strings like "isn't", "booktech@oreilly.com", "M.I.T.", and "key/value".

Inside a character class ([\b]), a \b represents a backspace rather than a word boundary.

5.6.4. Progressive Matching

When used with the /g modifier, the pos function allows you to read or set the offset where the next progressive match will start:

$burglar = "Bilbo Baggins";
while ($burglar =~ /b/gi) {
    printf "Found a B at %d\n", pos($burglar)-1;
}
(We subtract one from the position because that was the length of the string we were looking for, and pos is always the position just past the match.)

The code above prints:

Found a B at 0
Found a B at 3
Found a B at 6
After a failure, the match position normally resets back to the start. If you also apply the /c (for "continue") modifier, then when the /g runs out, the failed match doesn't reset the position pointer. This lets you continue your search past that point without starting over at the very beginning.
$burglar = "Bilbo Baggins";
while ($burglar =~ /b/gci) {        # ADD /c
    printf "Found a B at %d\n", pos($burglar)-1;
}
while ($burglar =~ /i/gi) {
    printf "Found an I at %d\n", pos($burglar)-1;
}
Besides the three B's it found earlier, Perl now reports finding an i at position 10. Without the /c, the second loop's match would have restarted from the beginning and found another i at position 6 first.

5.6.5. Where You Left Off: The \G Assertion

Whenever you start thinking in terms of the pos function, it's tempting to start carving your string up with substr, but this is rarely the right thing to do. More often, if you started with pattern matching, you should continue with pattern matching. However, if you're looking for a positional assertion, you're probably looking for \G.

The \G assertion represents within the pattern the same point that pos represents outside of it. When you're progressively matching a string with the /g modifier (or you've used the pos function to directly select the starting point), you can use \G to specify the position just after the previous match. That is, it matches the location immediately before whatever character would be identified by pos. This allows you to remember where you left off:

($recipe = <<'DISH') =~ s/^\s+//gm;
    Preheat oven to 451 deg. fahrenheit.
    Mix 1 ml. dilithium with 3 oz. NaCl and
    stir in 4 anchovies.  Glaze with 1 g.
    mercury.  Heat for 4 hours and let cool
    for 3 seconds.  Serves 10 aliens.
DISH

$recipe =~ /\d+ /g;
$recipe =~ /\G(\w+)/;           # $1 is now "deg"
$recipe =~ /\d+ /g;
$recipe =~ /\G(\w+)/;           # $1 is now "ml"
$recipe =~ /\d+ /g;
$recipe =~ /\G(\w+)/;           # $1 is now "oz"
The \G metasymbol is often used in a loop, as we demonstrate in our next example. We "pause" after every digit sequence, and at that position, we test whether there's an abbreviation. If so, we grab the next two words. Otherwise, we just grab the next word:
pos($recipe) = 0;                 # Just to be safe, reset \G to 0
while ( $recipe =~ /(\d+) /g ) {
    my $amount = $1;
    if ($recipe =~ / \G (\w{0,3}) \. \s+ (\w+) /x) {  # abbrev. + word
        print "$amount $1 of $2\n";
    } else {
        $recipe =~ / \G (\w+) /x;                     # just a word
        print "$amount $1\n";
    }
}
That produces:
451 deg of fahrenheit
1 ml of dilithium
3 oz of NaCl
4 anchovies
1 g of mercury
4 hours
3 seconds
10 aliens

Previous | Home | Next
5.5. Quantifiers | Book Index | 5.7. Capturing and Clustering
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.7. Capturing and Clustering

Patterns allow you to group portions of your pattern together into subpatterns and to remember the strings matched by those subpatterns. We call the first behavior clustering and the second one capturing.

5.7.1. Capturing

To capture a substring for later use, put parentheses around the subpattern that matches it. The first pair of parentheses stores its substring in $1, the second pair in $2, and so on. You may use as many parentheses as you like; Perl just keeps defining more numbered variables for you to represent these captured strings.

Some examples:

/(\d)(\d)/  # Match two digits, capturing them into $1 and $2
/(\d+)/     # Match one or more digits, capturing them all into $1
/(\d)+/     # Match a digit one or more times, capturing the last into $1
Note the difference between the second and third patterns. The second form is usually what you want. The third form does not create multiple variables for multiple digits. Parentheses are numbered when the pattern is compiled, not when it is matched.

Captured strings are often called backreferences because they refer back to parts of the captured text. There are actually two ways to get at these backreferences. The numbered variables you've seen are how you get at backreferences outside of a pattern, but inside the pattern, that doesn't work. You have to use \1, \2, etc.[9] So to find doubled words like "the the" or "had had", you might use this pattern:

/\b(\w+) \1\b/i
But most often, you'll be using the $1 form, because you'll usually apply a pattern and then do something with the substrings. Suppose you have some text (a mail header) that looks like this:
From: gnat@perl.com
To: camelot@oreilly.com
Date: Mon, 17 Jul 2000 09:00:00 -1000
Subject: Eye of the needle
and you want to construct a hash that maps the text before each colon to the text afterward. If you were looping through this text line by line (say, because you were reading it from a file) you could do that as follows:
while (<>) {
    /^(.*?): (.*)$/;    # Pre-colon text into $1, post-colon into $2
    $fields{$1} = $2;
}
Like $`, $&, and $', these numbered variables are dynamically scoped through the end of the enclosing block or eval string, or to the next successful pattern match, whichever comes first. You can use them in the righthand side (the replacement part) of a substitute, too:
s/^(\S+) (\S+)/$2 $1/;  # Swap first two words
Groupings can nest, and when they do, the groupings are counted by the location of the left parenthesis. So given the string "Primula Brandybuck", the pattern:

[9] You can't use $1 for a backreference within the pattern because that would already have been interpolated as an ordinary variable back when the regex was compiled. So we use the traditional \1 backreference notation inside patterns. For two- and three-digit backreference numbers, there is some ambiguity with octal character notation, but that is neatly solved by considering how many captured patterns are available. For instance, if Perl sees a \11 metasymbol, it's equivalent to $11 only if there are at least 11 substrings captured earlier in the pattern. Otherwise, it's equivalent to \011, that is, a tab character.

/^((\w+) (\w+))$/

would capture "Primula Brandybuck" into $1, "Primula" into $2, and "Brandybuck" into $3. This is depicted in Figure 5-1.

Figure 5.1. Creating backreferences with parentheses

Patterns with captures are often used in list context to populate a list of values, since the pattern is smart enough to return the captured substrings as a list:

($first, $last)        =  /^(\w+) (\w+)$/;
($full, $first, $last) =  /^((\w+) (\w+))$/;
With the /g modifier, a pattern can return multiple substrings from multiple matches, all in one list. Suppose you had the mail header we saw earlier all in one string (in $_, say). You could do the same thing as our line-by-line loop, but with one statement:
%fields = /^(.*?): (.*)$/gm;
The pattern matches four times, and each time it matches, it finds two substrings. The /gm match returns all of these as a flat list of eight strings, which the list assignment to %fields will conveniently interpret as four key/value pairs, thus restoring harmony to the universe.

Several other special variables deal with text captured in pattern matches. $& contains the entire matched string, $` everything to the left of the match, $' everything to the right. $+ contains the contents of the last backreference.

$_ = "Speak, <EM>friend</EM>, and enter.";
m[ (<.*?>) (.*?) (</.*?>) ]x;     # A tag, then chars, then an end tag
print "prematch: $`\n";           # Speak,
print "match: $&\n";              # <EM>friend</EM>
print "postmatch: $'\n";          # , and enter.
print "lastmatch: $+\n";          # </EM>
For more explanation of these magical Elvish variables (and for a way to write them in English), see Chapter 28, "Special Names".

The @- (@LAST_MATCH_START) array holds the offsets of the beginnings of any submatches, and @+ (@LAST_MATCH_END) holds the offsets of the ends:

#!/usr/bin/perl
$alphabet = "abcdefghijklmnopqrstuvwxyz";
$alphabet =~ /(hi).*(stu)/;

print "The entire match began at $-[0] and ended at $+[0]\n";
print "The first  match began at $-[1] and ended at $+[1]\n";
print "The second match began at $-[2] and ended at $+[2]\n";

If you really want to match a literal parenthesis character instead of having it interpreted as a metacharacter, backslash it:

/\(e.g., .*?\)/
This matches a parenthesized example (e.g., this statement). But since dot is a wildcard, this also matches any parenthetical statement with the first letter e and third letter g (ergo, this statement too).

5.7.2. Clustering

Bare parentheses both cluster and capture. But sometimes you don't want that. Sometimes you just want to group portions of the pattern without creating a backreference. You can use an extended form of parentheses to suppress capturing: the (?:PATTERN) notation will cluster without capturing.

There are at least three reasons you might want to cluster without capturing:

  1. To quantify something.

  2. To limit the scope of interior alternation; for example, /^cat|cow|dog$/ needs to be /^(?:cat|cow|dog)$/ so that the cat doesn't run away with the ^.

  3. To limit the scope of an embedded pattern modifier to a particular subpattern, such as in /foo(?-i:Case_Matters)bar/i. (See the next section, Section 5.7.3, "Cloistered Pattern Modifiers")

In addition, it's more efficient to suppress the capture of something you're not going to use. On the minus side, the notation is a little noisier, visually speaking.

In a pattern, a left parenthesis immediately followed by a question mark denotes a regex extension. The current regular expression bestiary is relatively fixed--we don't dare create a new metacharacter, for fear of breaking old Perl programs. Instead, the extension syntax is used to add new features to the bestiary.

In the remainder of the chapter, we'll see many more regex extensions, all of which cluster without capturing, as well as doing something else. The (?:PATTERN) extension is just special in that it does nothing else. So if you say:

@fields = split(/\b(?:a|b|c)\b/)
it's like:
@fields = split(/\b(a|b|c)\b/)
but doesn't spit out extra fields. (The split operator is a bit like m//g in that it will emit extra fields for all the captured substrings within the pattern. Ordinarily, split only returns what it didn't match. For more on split see Chapter 29, "Functions".)

5.7.3. Cloistered Pattern Modifiers

You may cloister the /i, /m, /s, and /x modifiers within a portion of your pattern by inserting them (without the slash) between the ? and : of the clustering notation. If you say:

/Harry (?i:s) Truman/
it matches both "Harry S Truman" and "Harry s Truman", whereas:
/Harry (?x: [A-Z] \.? \s )?Truman/
matches both "Harry S Truman" and "Harry S. Truman", as well as "Harry Truman", and:
/Harry (?ix: [A-Z] \.? \s )?Truman/
matches all five, by combining the /i and /x modifiers within the cloister.

You can also subtract modifiers from a cloister with a minus sign:

/Harry (?x-i: [A-Z] \.? \s )?Truman/i
This matches any capitalization of the name--but if the middle initial is provided, it must be capitalized, since the /i applied to the overall pattern is suspended inside the cloister.

By omitting the colon and PATTERN, you can export modifier settings to an outer cluster, turning it into a cloister. That is, you can selectively turn modifiers on and off for the cluster one level outside the modifiers' parentheses, like so:

/(?i)foo/            # Equivalent to /foo/i
/foo((?-i)bar)/i     # "bar" must be lower case
/foo((?x-i) bar)/    # Enables /x and disables /i for "bar"
Note that the second and third examples create backreferences. If that wasn't what you wanted, then you should have been using (?-i:bar) and (?x-i: bar), respectively.

Setting modifiers on a portion of your pattern is particularly useful when you want "." to match newlines in part of your pattern but not in the rest of it. Setting /s on the whole pattern doesn't help you there.

Previous | Home | Next
5.6. Positions | Book Index | 5.8. Alternation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.8. Alternation

Inside a pattern or subpattern, use the | metacharacter to specify a set of possibilities, any one of which could match. For instance:

/Gandalf|Saruman|Radagast/
matches Gandalf or Saruman or Radagast. The alternation extends only as far as the innermost enclosing parentheses (whether capturing or not):
/prob|n|r|l|ate/    # Match prob, n, r, l, or ate
/pro(b|n|r|l)ate/   # Match probate, pronate, prorate, or prolate
/pro(?:b|n|r|l)ate/ # Match probate, pronate, prorate, or prolate
The second and third forms match the same strings, but the second form captures the variant character in $1 and the third form does not.

At any given position, the Engine tries to match the first alternative, and then the second, and so on. The relative length of the alternatives does not matter, which means that in this pattern:

/(Sam|Samwise)/
$1 will never be set to Samwise no matter what string it's matched against, because Sam will always match first. When you have overlapping matches like this, put the longer ones at the beginning.

But the ordering of the alternatives only matters at a given position. The outer loop of the Engine does left-to-right matching, so the following always matches the first Sam:

"'Sam I am,' said Samwise" =~ /(Samwise|Sam)/;   # $1 eq "Sam"
But you can force right-to-left scanning by making use of greedy quantifiers, as discussed earlier in "Quantifiers":
"'Sam I am,' said Samwise" =~ /.*(Samwise|Sam)/; # $1 eq "Samwise"
You can defeat any left-to-right (or right-to-left) matching by including any of the various positional assertions we saw earlier, such as \G, ^, and $. Here we anchor the pattern to the end of the string:
"'Sam I am,' said Samwise" =~ /(Samwise|Sam)$/;  # $1 eq "Samwise"
That example factors the $ out of the alternation (since we already had a handy pair of parentheses to put it after), but in the absence of parentheses you can also distribute the assertions to any or all of the individual alternatives, depending on how you want them to match. This little program displays lines that begin with either a __DATA__ or __END__ token:
#!/usr/bin/perl
while (<>) {
    print if /^__DATA__|^__END__/;
}
But be careful with that. Remember that the first and last alternatives (before the first | and after the last one) tend to gobble up the other elements of the regular expression on either side, out to the ends of the expression, unless there are enclosing parentheses. A common mistake is to ask for:
/^cat|dog|cow$/
when you really mean:
/^(cat|dog|cow)$/
The first matches "cat" at the beginning of the string, or "dog" anywhere, or "cow" at the end of the string. The second matches any string consisting solely of "cat" or "dog" or "cow". It also captures $1, which you may not want. You can also say:
/^cat$|^dog$|^cow$/
We'll show you another solution later.

An alternative can be empty, in which case it always matches.

/com(pound|)/;      # Matches "compound" or "com"
/com(pound(s|)|)/;  # Matches "compounds", "compound", or "com"
This is much like using the ? quantifier, which matches 0 times or 1 time:
/com(pound)?/;      # Matches "compound" or "com"
/com(pound(s?))?/;  # Matches "compounds", "compound", or "com"
/com(pounds?)?/;    # Same, but doesn't use $2
There is one difference, though. When you apply the ? to a subpattern that captures into a numbered variable, that variable will be undefined if there's no string to go there. If you used an empty alternative, it would still be false, but would be a defined null string instead.

Previous | Home | Next
5.7. Capturing and Clustering | Book Index | 5.9. Staying in Control
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.9. Staying in Control

As any good manager knows, you shouldn't micromanage your employees. Just tell them what you want, and let them figure out the best way of doing it. Similarly, it's often best to think of a regular expression as a kind of specification: "Here's what I want; go find a string that fits the bill."

On the other hand, the best managers also understand the job their employees are trying to do. The same is true of pattern matching in Perl. The more thoroughly you understand of how Perl goes about the task of matching any particular pattern, the more wisely you'll be able to make use of Perl's pattern matching capabilities.

One of the most important things to understand about Perl's pattern-matching is when not to use it.

5.9.1. Letting Perl Do the Work

When people of a certain temperament first learn regular expressions, they're often tempted to see everything as a problem in pattern matching. And while that may even be true in the larger sense, pattern matching is about more than just evaluating regular expressions. It's partly about looking for your car keys where you dropped them, not just under the streetlamp where you can see better. In real life, we all know that it's a lot more efficient to look in the right places than the wrong ones.

Similarly, you should use Perl's control flow to decide which patterns to execute, and which ones to skip. A regular expression is pretty smart, but it's smart like a horse. It can get distracted if it sees too much at once. So sometimes you have to put blinders onto it. For example, you'll recall our earlier example of alternation:

/Gandalf|Saruman|Radagast/
That works as advertised, but not as well as it might, because it searches every position in the string for every name before it moves on to the next position. Astute readers of The Lord of the Rings will recall that, of the three wizards named above, Gandalf is mentioned much more frequently than Saruman, and Saruman is mentioned much more frequently than Radagast. So it's generally more efficient to use Perl's logical operators to do the alternation:
/Gandalf/ || /Saruman/ || /Radagast/
This is yet another way of defeating the "leftmost" policy of the Engine. It only searches for Saruman if Gandalf was nowhere to be seen. And it only searches for Radagast if Saruman is also absent.

Not only does this change the order in which things are searched, but it sometimes allows the regular expression optimizer to work better. It's generally easier to optimize searching for a single string than for several strings simultaneously. Similarly, anchored searches can often be optimized if they're not too complicated.

You don't have to limit your control of the control flow to the || operator. Often you can control things at the statement level. You should always think about weeding out the common cases first. Suppose you're writing a loop to process a configuration file. Many configuration files are mostly comments. It's often best to discard comments and blank lines early before doing any heavy-duty processing, even if the heavy duty processing would throw out the comments and blank lines in the course of things:

while (<CONF>) {
    next if /^#/;
    next if /^\s*(#|$)/;
    chomp;
    munchabunch($_);
}
Even if you're not trying to be efficient, you often need to alternate ordinary Perl expressions with regular expressions simply because you want to take some action that is not possible (or very difficult) from within the regular expression, such as printing things out. Here's a useful number classifier:
warn "has nondigits"        if     /\D/;
warn "not a natural number" unless /^\d+$/;             # rejects -3
warn "not an integer"       unless /^-?\d+$/;           # rejects +3
warn "not an integer"       unless /^[+-]?\d+$/;
warn "not a decimal number" unless /^-?\d+\.?\d*$/;     # rejects .2
warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
warn "not a C float"
       unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
We could stretch this section out a lot longer, but really, that sort of thing is what this whole book is about. You'll see many more examples of the interplay of Perl code and pattern matching as we go along. In particular, see the later section Section 5.10.3, "Programmatic Patterns". (It's okay to read the intervening material first, of course.)

5.9.2. Variable Interpolation

Using Perl's control flow mechanisms to control regular expression matching has its limits. The main difficulty is that it's an "all or nothing" approach; either you run the pattern, or you don't. Sometimes you know the general outlines of the pattern you want, but you'd like to have the capability of parameterizing it. Variable interpolation provides that capability, much like parameterizing a subroutine lets you have more influence over its behavior than just deciding whether to call it or not. (More about subroutines in the next chapter).

One nice use of interpolation is to provide a little abstraction, along with a little readability. With regular expressions you may certainly write things concisely:

if ($num =~ /^[-+]?\d+\.?\d*$/) { ... }
But what you mean is more apparent when you write:
$sign = '[-+]?';
$digits = '\d+';
$decimal = '\.?';
$more_digits = '\d*';
$number = "$sign$digits$decimal$more_digits";
...
if ($num =~ /^$number$/o) { ... }
We'll cover this use of interpolation more under "Generated patterns" later in this chapter. We'll just point out that we used the /o modifier to suppress recompilation because we don't expect $number to change its value over the course of the program.

Another cute trick is to turn your tests inside out and use the variable string to pattern-match against a set of known strings:

chomp($answer = <STDIN>);
if    ("SEND"  =~ /^\Q$answer/i) { print "Action is send\n"  }
elsif ("STOP"  =~ /^\Q$answer/i) { print "Action is stop\n"  }
elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" }
elsif ("LIST"  =~ /^\Q$answer/i) { print "Action is list\n"  }
elsif ("EDIT"  =~ /^\Q$answer/i) { print "Action is edit\n"  }
This lets your user perform the "send" action by typing any of S, SE, SEN, or SEND (in any mixture of upper- and lowercase). To "stop", they'd have to type at least ST (or St, or sT, or st).

5.9.2.1. When backslashes happen

When you think of double-quote interpolation, you usually think of both variable and backslash interpolation. But as we mentioned earlier, for regular expressions there are two passes, and the interpolation pass defers most of the backslash interpretation to the regular expression parser (which we discuss later). Ordinarily, you don't notice the difference, because Perl takes pains to hide the difference. (One sequence that's obviously different is the \b metasymbol, which turns into a word boundary assertion--outside of character classes, anyway. Inside a character class where assertions make no sense, it reverts to being a backspace, as it is normally.)

It's actually fairly important that the regex parser handle the backslashes. Suppose you're searching for tab characters in a pattern with a /x modifier:

($col1, $col2) = /(.*?) \t+ (.*?)/x;
If Perl didn't defer the interpretation of \t to the regex parser, the \t would have turned into whitespace, which the regex parser would have ignorantly ignored because of the /x. But Perl is not so ignoble, or tricky.

You can trick yourself though. Suppose you abstracted out the column separator, like this:

$colsep = "\t+";                         # (double quotes)
($col1, $col2) = /(.*?) $colsep (.*?)/x;
Now you've just blown it, because the \t turns into a real tab before it gets to the regex parser, which will think you said /(.*?)+(.*?)/ after it discards the whitespace. Oops. To fix, avoid /x, or use single quotes. Or better, use qr//. (See the next section.)

The only double-quote escapes that are processed as such are the six translation escapes: \U, \u, \L, \l, \Q, and \E. If you ever look into the inner workings of the Perl regular expression compiler, you'll find code for handling escapes like \t for tab, \n for newline, and so on. But you won't find code for those six translation escapes. (We only listed them in Table 5-7 because people expect to find them there.) If you somehow manage to sneak any of them into the pattern without going through double-quotish evaluation, they won't be recognized.

How could they find their way in? Well, you can defeat interpolation by using single quotes as your pattern delimiter. In m'...', qr'...', and s'...'...', the single quotes suppress variable interpolation and the processing of translation escapes, just as they would in a single-quoted string. Saying m'\ufrodo' won't find a capitalized version of poor frodo. However, since the "normal" backslash characters aren't really processed on that level anyway, m'\t\d' still matches a real tab followed by any digit.

Another way to defeat interpolation is through interpolation itself. If you say:

$var = '\U';
/${var}frodo/;
poor frodo remains uncapitalized. Perl won't redo the interpolation pass for you just because you interpolated something that looks like it might want to be reinterpolated. You can't expect that to work any more than you'd expect this double interpolation to work:
$hobbit = 'Frodo';
$var = '$hobbit';           # (single quotes)
/$var/;                     # means m'$hobbit', not m'Frodo'.

Here's another example that shows how most backslashes are interpreted by the regex parser, not by variable interpolation. Imagine you have a simple little grep-style program written in Perl:[10]

#!/usr/bin/perl
$pattern = shift;
while (<>) {
    print if /$pattern/o;
}
If you name that program pgrep and call it this way:
% pgrep '\t\d' *.c
then you'll find that it prints out all lines of all your C source files in which a digit follows a tab. You didn't have to do anything special to get Perl to realize that \t was a tab. If Perl's patterns were just double-quote interpolated, you would have; fortunately, they aren't. They're recognized directly by the regex parser.

[10] If you didn't know what a grep program was before, you will now. No system should be without grep--we believe grep is the most useful small program ever invented. (It logically follows that we don't believe Perl is a small program.)

The real grep program has a -i switch that turns off case-sensitive matching. You don't have to add such a switch to your pgrep program; it can already handle that without modification. You just pass it a slightly fancier pattern, with an embedded /i modifier:

% pgrep '(?i)ring' LotR*.pod
That now searches for any of "Ring", "ring", "RING", and so on. You don't see this feature too much in literal patterns, since you can always just write /ring/i. But for patterns passed in on the command line, in web search forms, or embedded in configuration files, it can be a lifesaver. (Speaking of rings.)

5.9.2.2. The qr// quote regex operator

Variables that interpolate into patterns necessarily do so at run time, not compile time. This slows down execution because Perl has to check whether you've changed the contents of the variable; if so, it would have to recompile the regular expression. As mentioned in "Pattern-Matching Operators", if you promise never to change the pattern, you can use the /o option to interpolate and compile only once:

print if /$pattern/o;
Although that works fine in our pgrep program, in the general case, it doesn't. Imagine you have a slew of patterns, and you want to match each of them in a loop, perhaps like this:
foreach $item (@data) {
    foreach $pat (@patterns) {
        if ($item =~ /$pat/) { ... }
    }
}
You couldn't write /$pat/o because the meaning of $pat varies each time through the inner loop.

The solution to this is the qr/PATTERN/imosx operator. This operator quotes--and compiles--its PATTERN as a regular expression. PATTERN is interpolated the same way as in m/PATTERN/. If ' is used as the delimiter, no interpolation of variables (or the six translation escapes) is done. The operator returns a Perl value that may be used instead of the equivalent literal in a corresponding pattern match or substitute. For example:

$regex = qr/my.STRING/is;
s/$regex/something else/;
is equivalent to:
s/my.STRING/something else/is;
So for our nested loop problem above, preprocess your pattern first using a separate loop:
@regexes = ();
foreach $pat (@patterns) {
    push @regexes, qr/$pat/;
}
Or all at once using Perl's map operator:
@regexes = map { qr/$_/ } @patterns;
And then change the loop to use those precompiled regexes:
foreach $item (@data) {
    foreach $re (@regexes) {
        if ($item =~ /$re/) { ... }
    }
}
Now when you run the match, Perl doesn't have to create a compiled regular expression on each if test, because it sees that it already has one.

The result of a qr// may even be interpolated into a larger match, as though it were a simple string:

$regex = qr/$pattern/;
$string =~ /foo${regex}bar/;   # interpolate into larger patterns
This time, Perl does recompile the pattern, but you could always chain several qr// operators together into one.

The reason this works is because the qr// operator returns a special kind of object that has a stringification overload as described in Chapter 13, "Overloading". If you print out the return value, you'll see the equivalent string:

$re = qr/my.STRING/is;
print $re;                  # prints (?si-xm:my.STRING)
The /s and /i modifiers were enabled in the pattern because they were supplied to qr//. The /x and /m, however, are disabled because they were not.

Any time you interpolate strings of unknown provenance into a pattern, you should be prepared to handle any exceptions thrown by the regex compiler, in case someone fed you a string containing untamable beasties:

$re = qr/$pat/is;                      # might escape and eat you
$re = eval { qr/$pat/is } || warn ...  # caught it in an outer cage
For more on the eval operator, see Chapter 29, "Functions".

5.9.3. The Regex Compiler

After the variable interpolation pass has had its way with the string, the regex parser finally gets a shot at trying to understand your regular expression. There's not actually a great deal that can go wrong at this point, apart from messing up the parentheses, or using a sequence of metacharacters that doesn't mean anything. The parser does a recursive-descent analysis of your regular expression and, if it parses, turns it into a form suitable for interpretation by the Engine (see the next section). Most of the interesting stuff that goes on in the parser involves optimizing your regular expression to run as fast as possible. We're not going to explain that part. It's a trade secret. (Rumors that looking at the regular expression code will drive you insane are greatly exaggerated. We hope.)

But you might like to know what the parser actually thought of your regular expression, and if you ask it politely, it will tell you. By saying use re "debug", you can examine how the regex parser processes your pattern. (You can also see the same information by using the -Dr command-line switch, which is available to you if your Perl was compiled with the -DDEBUGGING flag during installation.)

#!/usr/bin/perl
use re "debug";
"Smeagol" =~ /^Sm(.*)g[aeiou]l$/;
The output is below. You can see that prior to execution Perl compiles the regex and assigns meaning to the components of the pattern: BOL for the beginning of line (^), REG_ANY for the dot, and so on:
Compiling REx `^Sm(.*)g[aeiou]l$'
size 24 first at 2
rarest char l at 0
rarest char S at 0
   1: BOL(2)
   2: EXACT <Sm>(4)
   4: OPEN1(6)
   6:   STAR(8)
   7:     REG_ANY(0)
   8: CLOSE1(10)
  10: EXACT <g>(12)
  12: ANYOF[aeiou](21)
  21: EXACT <l>(23)
  23: EOL(24)
  24: END(0)
anchored `Sm' at 0 floating `l'$ at 4..2147483647
     (checking anchored) anchored(BOL) minlen 5
Omitting $` $& $' support.
Some of the lines summarize the conclusions of the regex optimizer. It knows that the string must start with "Sm", and that therefore there's no reason to do the ordinary left-to-right scan. It knows that the string must end with an "l", so it can reject out of hand any string that doesn't. It knows that the string must be at least five characters long, so it can ignore any string shorter than that right off the bat. It also knows what the rarest character in each constant string is, which can help in searching "studied" strings. (See study in Chapter 29, "Functions".)

It then goes on to trace how it executes the pattern:

EXECUTING...

Guessing start of match, REx `^Sm(.*)g[aeiou]l$' against `Smeagol'...
Guessed: match at offset 0
Matching REx `^Sm(.*)g[aeiou]l$' against `Smeagol'
  Setting an EVAL scope, savestack=3
   0 <> <Smeagol>         |  1:  BOL
   0 <> <Smeagol>         |  2:  EXACT <Sm>
   2 <Sm> <eagol>         |  4:  OPEN1
   2 <Sm> <eagol>         |  6:  STAR
                           REG_ANY can match 5 times out of 32767...
  Setting an EVAL scope, savestack=3
   7 <Smeagol> <>         |  8:    CLOSE1
   7 <Smeagol> <>         | 10:    EXACT <g>
                              failed...
   6 <Smeago> <l>         |  8:    CLOSE1
   6 <Smeago> <l>         | 10:    EXACT <g>
                              failed...
   5 <Smeag> <ol>         |  8:    CLOSE1
   5 <Smeag> <ol>         | 10:    EXACT <g>
                              failed...
   4 <Smea> <gol>         |  8:    CLOSE1
   4 <Smea> <gol>         | 10:    EXACT <g>
   5 <Smeag> <ol>         | 12:    ANYOF[aeiou]
   6 <Smeago> <l>         | 21:    EXACT <l>
   7 <Smeagol> <>         | 23:    EOL
   7 <Smeagol> <>         | 24:    END
Match successful!
Freeing REx: `^Sm(.*)g[aeiou]l$'
If you follow the stream of whitespace down the middle of Smeagol, you can actually see how the Engine overshoots to let the .* be as greedy as possible, then backtracks on that until it finds a way for the rest of the pattern to match. But that's what the next section is about.

5.9.4. The Little Engine That /Could(n't)?/

And now we'd like to tell you the story of the Little Regex Engine that says, "I think I can. I think I can. I think I can."

In this section, we lay out the rules used by Perl's regular expression engine to match your pattern against a string. The Engine is extremely persistent and hardworking. It's quite capable of working even after you think it should quit. The Engine doesn't give up until it's certain there's no way to match the pattern against the string. The Rules below explain how the Engine "thinks it can" for as long as possible, until it knows it can or can't. The problem for our Engine is that its task is not merely to pull a train over a hill. It has to search a (potentially) very complicated space of possibilities, keeping track of where it has been and where it hasn't.

The Engine uses a nondeterministic finite-state automaton (NFA, not to be confused with NFL, a nondeterministic football league) to find a match. That just means that it keeps track of what it has tried and what it hasn't, and when something doesn't pan out, it backs up and tries something else. This is known as backtracking. (Er, sorry, we didn't invent these terms. Really.) The Engine is capable of trying a million subpatterns at one spot, then giving up on all those, backing up to within one choice of the beginning, and trying the million subpatterns again at a different spot. The Engine is not terribly intelligent; just persistent, and thorough. If you're cagey, you can give the Engine an efficient pattern that doesn't let it do a lot of silly backtracking.

When someone trots out a phrase like "Regexes choose the leftmost, longest match", that means that Perl generally prefers the leftmost match over longest match. But the Engine doesn't realize it's "preferring" anything, and it's not really thinking at all, just gutting it out. The overall preferences are an emergent behavior resulting from many individual and unrelated choices. Here are those choices:[11]

[11] Some of these choices may be skipped if the regex optimizer has any say, which is equivalent to the Little Engine simply jumping through the hill via quantum tunneling. But for this discussion we're pretending the optimizer doesn't exist.

Rule 1

The Engine tries to match as far left in the string as it can, such that the entire regular expression matches under Rule 2.

The Engine starts just before the first character and tries to match the entire pattern starting there. The entire pattern matches if and only if the Engine reaches the end of the pattern before it runs off the end of the string. If it matches, it quits immediately--it doesn't keep looking for a "better" match, even though the pattern might match in many different ways.

If it is unable to match the pattern at the first position in the string, it admits temporary defeat and moves to the next position in the string, between the first and second characters, and tries all the possibilities again. If it succeeds, it stops. If it fails, it continues on down the string. The pattern match as a whole doesn't fail until it has tried to match the entire regular expression at every position in the string, including after the last character.

A string of n characters actually provides n+ 1 positions to match at. That's because the beginnings and the ends of matches are between the characters of the string. This rule sometimes surprises people when they write a pattern like /x*/ that can match zero or more "x" characters. If you try that pattern on a string like "fox", it won't find the "x". Instead, it will immediately match the null string before the "f" and never look further. If you want it to match one or more x characters, you need to use /x+/ instead. See the quantifiers under Rule 5.

A corollary to this rule is that any pattern matching the null string is guaranteed to match at the leftmost position in the string (in the absence of any zero-width assertions to the contrary).

Rule 2

When the Engine encounters a set of alternatives (separated by | symbols), either at the top level or at the current "cluster" level, it tries them left-to-right, stopping on the first successful match that allows successful completion of the entire pattern.

A set of alternatives matches a string if any of the alternatives match under Rule 3. If none of the alternatives matches, it backtracks to the Rule that invoked this Rule, which is usually Rule 1, but could be Rule 4 or 6, if we're within a cluster. That rule will then look for a new position at which to apply Rule 2.

If there's only one alternative, then either it matches or it doesn't, and Rule 2 still applies. (There's no such thing as zero alternatives, because a null string always matches.)

Rule 3

Any particular alternative matches if every item listed in the alternative matches sequentially according to Rules 4 and 5 (such that the entire regular expression can be satisfied).

An item consists of either an assertion, which is covered in Rule 4, or a quantified atom, covered by Rule 5. Items that have choices on how to match are given a "pecking order" from left to right. If the items cannot be matched in order, the Engine backtracks to the next alternative under Rule 2.

Items that must be matched sequentially aren't separated in the regular expression by anything syntactic--they're merely juxtaposed in the order they must match. When you ask to match /^foo/, you're actually asking for four items to be matched one after the other. The first is a zero-width assertion, matched under Rule 4, and the other three are ordinary characters that must match themselves, one after the other, under Rule 5.

The left-to-right pecking order means that in a pattern like:

/x*y*/
x* gets to pick one way to match, and then y* tries all its ways. If that fails, then x* gets to pick its second choice, and make y* try all of its ways again. And so on. The items to the right "vary faster", to borrow a phrase from multi-dimensional arrays.

Rule 4

If an assertion does not match at the current position, the Engine backtracks to Rule 3 and retries higher-pecking-order items with different choices.

Some assertions are fancier than others. Perl supports many regex extensions, some of which are zero-width assertions. For example, the positive lookahead (?=...) and the negative lookahead (?!...) don't actually match any characters, but merely assert that the regular expression represented by ... would (or would not) match at this point, were we to attempt it, hypothetically speaking.[12]

[12]In actual fact, the Engine does attempt it. The Engine goes back to Rule 2 to test the subpattern, and then wipes out any record of how much string was eaten, returning only the success or failure of the subpattern as the value of the assertion. (It does, however, remember any captured substrings.)

Rule 5

A quantified atom matches only if the atom itself matches some number of times that is allowed by the quantifier. (The atom itself is matched according to Rule 6.)

Different quantifiers require different numbers of matches, and most of them allow a range of numbers of matches. Multiple matches must all match in a row; that is, they must be adjacent within the string. An unquantified atom is assumed to have a quantifier requiring exactly one match (that is, /x/ is the same as /x{1}/). If no match can be found at the current position for any allowed quantity of the atom in question, the Engine backtracks to Rule 3 and retries higher-pecking-order items with different choices.

The quantifiers are *, +, ?, *?, +?, ??, and the various brace forms. If you use the {COUNT} form, then there is no choice, and the atom must match exactly that number of times or not at all. Otherwise, the atom can match over a range of quantities, and the Engine keeps track of all the choices so that it can backtrack if necessary. But then the question arises as to which of these choices to try first. One could start with the maximal number of matches and work down, or the minimal number of matches and work up.

The traditional quantifiers (without a trailing question mark) specify greedy matching; that is, they attempt to match as many characters as possible. To find the greediest match, the Engine has to be a little bit careful. Bad guesses are potentially rather expensive, so the Engine doesn't actually count down from the maximum value, which after all could be Very Large and cause millions of bad guesses. What the Engine actually does is a little bit smarter: it first counts up to find out how many matching atoms (in a row) are really there in the string, and then it uses that actual maximum as its first choice. (It also remembers all the shorter choices in case the longest one doesn't pan out.) It then (at long last) tries to match the rest of the pattern, assuming the longest choice to be the best. If the longest choice fails to produce a match for the rest of the pattern, it backtracks and tries the next longest.

If you say /.*foo/, for example, it will try to match the maximal number of "any" characters (represented by the dot) clear out to the end of the line before it ever tries looking for "foo"; and then when the "foo" doesn't match there (and it can't, because there's not enough room for it at the end of the string), the Engine will back off one character at a time until it finds a "foo". If there is more than one "foo" in the line, it'll stop on the last one, since that will really be the first one it encounters as it backtracks. When the entire pattern succeeds using some particular length of .*, the Engine knows it can throw away all the other shorter choices for .* (the ones it would have used had the current "foo" not panned out).

By placing a question mark after any greedy quantifier, you turn it into a frugal quantifier that chooses the smallest quantity for the first try. So if you say /.*?foo/, the .*? first tries to match 0 characters, then 1 character, then 2, and so on until it can match the "foo". Instead of backtracking backward, it backtracks forward, so to speak, and ends up finding the first "foo" on the line instead of the last.

Rule 6

Each atom matches according to the designated semantics of its type. If the atom doesn't match (or does match, but doesn't allow a match of the rest of the pattern), the Engine backtracks to Rule 5 and tries the next choice for the atom's quantity.

Atoms match according to the following types:

  • A regular expression in parentheses, (...), matches whatever the regular expression (represented by ...) matches according to Rule 2. Parentheses therefore serve as a clustering operator for quantification. Bare parentheses also have the side effect of capturing the matched substring for later use in a backreference. This side effect can be suppressed by using (?:...) instead, which has only the clustering semantics--it doesn't store anything in $1, $2, and so on. Other forms of parenthetical atoms (and assertions) are possible--see the rest of this chapter.

  • A dot matches any character, except maybe newline.

  • A list of characters in square brackets (a character class)matches any one of the characters specified by the list.

  • A backslashed letter matches either a particular character or a character from a set of characters, as listed in Table 5-7.

  • Any other backslashed character matches that character.

  • Any character not mentioned above matches itself.

That all sounds rather complicated, but the upshot of it is that, for each set of choices given by a quantifier or alternation, the Engine has a knob it can twiddle. It will twiddle those knobs until the entire pattern matches. The Rules just say in which order the Engine is allowed to twiddle those knobs. Saying the Engine prefers the leftmost match merely means it twiddles the start position knob the slowest. And backtracking is just the process of untwiddling the knob you just twiddled in order to try twiddling a knob higher in the pecking order, that is, one that varies slower.

Here's a more concrete example, a program that detects when two consecutive words share a common ending and beginning:

$a = 'nobody';
$b = 'bodysnatcher';
if ("$a $b" =~ /^(\w+)(\w+) \2(\w+)$/) {
    print "$2 overlaps in $1-$2-$3\n";
}
This prints:
body overlaps in no-body-snatcher
You might think that $1 would first grab up all of "nobody" due to greediness. And in fact, it does--at first. But once it's done so, there aren't any further characters to put in $2, which needs characters put into it because of the + quantifier. So the Engine backs up and $1 begrudgingly gives up one character to $2. This time the space character matches successfully, but then it sees \2, which represents a measly "y". The next character in the string is not a "y", but a "b". This makes the Engine back up all the way and try several more times, eventually forcing $1 to surrender the body to $2. Habeas corpus, as it were.

Actually, that won't quite work out if the overlap is itself the product of a doubling, as in the two words "rococo" and "cocoon". The algorithm above would have decided that the overlapping string, $2, must be just "co" rather than "coco". But we don't want a "rocococoon"; we want a "rococoon". Here's one of those places you can outsmart the Engine. Adding a minimal matching quantifier to the $1 part gives the much better pattern /^(\w+?)(\w+) \2(\w+)$/, which does exactly what we want.

For a much more detailed discussion of the pros and cons of various kinds of regular expression engines, see Jeffrey Friedl's book, Mastering Regular Expressions. Perl's regular expression Engine works very well for many of the everyday problems you want to solve with Perl, and it even works okay for those not-so-everyday problems, if you give it a little respect and understanding.

Previous | Home | Next
5.8. Alternation | Book Index | 5.10. Fancy Patterns
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


5.10. Fancy Patterns

5.10.1. Lookaround Assertions

Sometimes you just need to sneak a peek. There are four regex extensions that help you do just that, and we call them lookaround assertions because they let you scout around in a hypothetical sort of way, without committing to matching any characters. What these assertions assert is that some pattern would (or would not) match if we were to try it. The Engine works it all out for us by actually trying to match the hypothetical pattern, and then pretending that it didn't match (if it did).

When the Engine peeks ahead from its current position in the string, we call it a lookahead assertion. If it peeks backward, we call it a lookbehind assertion. The lookahead patterns can be any regular expression, but the lookbehind patterns may only be fixed width, since they have to know where to start the hypothetical match from.

While these four extensions are all zero-width assertions, and hence do not consume characters (at least, not officially), you can in fact capture substrings within them if you supply extra levels of capturing parentheses.

(?=PATTERN) (positive lookahead)

When the Engine encounters (?=PATTERN), it looks ahead in the string to ensure that PATTERN occurs. If you'll recall, in our earlier duplicate word remover, we had to write a loop because the pattern ate too much each time through:

$_ = "Paris in THE THE THE THE spring.";

# remove duplicate words (and triplicate (and quadruplicate...))
1 while s/\b(\w+) \1\b/$1/gi;
Whenever you hear the phrase "ate too much", you should always think "lookahead assertion". (Well, almost always.) By peeking ahead instead of gobbling up the second word, you can write a one-pass duplicate word remover like this:
s/ \b(\w+) \s (?= \1\b ) //gxi;
Of course, this isn't quite right, since it will mess up valid phrases like "The clothes you DON DON't fit."

(?!PATTERN) (negative lookahead)

When the Engine encounters (?!PATTERN), it looks ahead in the string to ensure that PATTERN does not occur. To fix our previous example, we can add a negative lookahead assertion after the positive assertion to weed out the case of contractions:

s/ \b(\w+) \s (?= \1\b (?! '\w))//xgi;
That final \w is necessary to avoid confusing contractions with words at the ends of single-quoted strings. We can take this one step further, since earlier in this chapter we intentionally used "that that particular", and we'd like our program to not "fix" that for us. So we can add an alternative to the negative lookahead in order to pre-unfix that "that", (thereby demonstrating that any pair of parentheses can be used to cluster alternatives):
s/ \b(\w+) \s (?= \1\b (?! '\w | \s particular))//gix;
Now we know that that particular phrase is safe. Unfortunately, the Gettysburg Address is still broken. So we add another exception:
s/ \b(\w+) \s (?= \1\b (?! '\w | \s particular | \s nation))//igx;
This is just starting to get out of hand. So let's do an Official List of Exceptions, using a cute interpolation trick with the $" variable to separate the alternatives with the | character:
@thatthat = qw(particular nation);
local $" = '|';
s/ \b(\w+) \s (?= \1\b (?! '\w | \s (?: @thatthat )))//xig;

(?<=PATTERN) (positive lookbehind)

When the Engine encounters (?<=PATTERN), it looks backward in the string to ensure that PATTERN already occurred.

Our example still has a problem. Although it now lets Honest Abe say things like "that that nation", it also allows "Paris, in the the nation of France". We can add a positive lookbehind assertion in front of our exception list to make sure that we apply our @thatthat exceptions only to a real "that that".

s/ \b(\w+) \s (?= \1\b (?! '\w | (?<= that) \s (?: @thatthat )))//ixg;
Yes, it's getting terribly complicated, but that's why this section is called "Fancy Patterns", after all. If you need to complicate the pattern any more than we've done so far, judicious use of comments and qr// will help keep you sane. Or at least saner.

(?<!PATTERN) (negative lookbehind)

When the Engine encounters (?<!PATTERN), it looks backward in the string to ensure that PATTERN did not occur.

Let's go for a really simple example this time. How about the easy version of that old spelling rule, "I before E except after C"? In Perl, you spell it:

s/(?<!c)ei/ie/g
You'll have to weigh for yourself whether you want to handle any of the exceptions. (For example, "weird" is spelled weird, especially when you spell it "wierd".)

5.10.2. Nonbacktracking Subpatterns

As described in "The Little Engine That /Could(n't)?/", the Engine often backtracks as it proceeds through the pattern. You can block the Engine from backtracking back through a particular set of choices by creating a nonbacktracking subpattern. A nonbacktracking subpattern looks like (?>PATTERN), and it works exactly like a simple (?:PATTERN), except that once PATTERN has found a match, it suppresses backtracking on any of the quantifiers or alternatives inside the subpattern. (Hence, it is meaningless to use this on a PATTERN that doesn't contain quantifiers or alternatives.) The only way to get it to change its mind is to backtrack to something before the subpattern and reenter the subpattern from the left.

It's like going into a car dealership. After a certain amount of haggling over the price, you deliver an ultimatum: "Here's my best offer; take it or leave it." If they don't take it, you don't go back to haggling again. Instead, you backtrack clear out the door. Maybe you go to another dealership, and start haggling again. You're allowed to haggle again, but only because you reentered the nonbacktracking pattern again in a different context.

For devotees of Prolog or SNOBOL, you can think of this as a scoped cut or fence operator.

Consider how in "aaab" =~ /(?:a*)ab/, the a* first matches three a's, but then gives up one of them because the last a is needed later. The subgroup sacrifices some of what it wants in order for the whole match to succeed. (Which is like letting the car salesman talk you into giving him more of your money because you're afraid to walk away from the deal.) In contrast, the subpattern in "aaab" =~ /(?>a*)ab/ will never give up what it grabs, even though this behavior causes the whole match to fail. (As the song says, you have to know when to hold 'em, when to fold 'em, and when to walk away.)

Although (?>PATTERN) is useful for changing the behavior of a pattern, it's mostly used for speeding up the failure of certain matches that you know will fail anyway (unless they succeed outright). The Engine can take a spectacularly long time to fail, particular with nested quantifiers. The following pattern will succeed almost instantly:

$_ = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
/a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*[b]/;
But success is not the problem. Failure is. If you remove that final "b" from the string, the pattern will probably run for many, many years before failing. Many, many millennia. Actually, billions and billions of years.[13] You can see by inspection that the pattern can't succeed if there's no "b" on the end of the string, but the regex optimizer is not smart enough (as of this writing) to figure out that /[b]/ is equivalent to /b/. But if you give it a hint, you can get it to fail quickly while still letting it succeed where it can:
/(?>a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*)[b]/;
For a (hopefully) more realistic example, imagine a program that's supposed to read in a paragraph at a time and show just the lines that are continued, where contination lines are specified with trailing backslashes. Here's a sample from Perl's Makefile that uses this line-continuation convention:
# Files to be built with variable substitution before miniperl
# is available.
sh = Makefile.SH cflags.SH config_h.SH makeaperl.SH makedepend.SH \
        makedir.SH myconfig.SH writemain.SH
You could write your simple program this way:
#!/usr/bin/perl -00p
while ( /( (.+) ( (?<=\\) \n .* )+ ) /gx) {
    print "GOT $.: $1\n\n";
}
That works, but it's really quite slow. That's because the Engine backtracks a character at a time from the end of the line, shrinking what's in $1. This is pointless. And writing it without the extraneous captures doesn't help much. Using:
(.+(?:(?<=\\)\n.*)+)
for a pattern is somewhat faster, but not much. This is where a nonbacktracking subpattern helps a lot. The pattern:
((?>.+)(?:(?<=\\)\n.*)+)
does the same thing, but more than an order of magnitude faster because it doesn't waste time backtracking in search of something that isn't there.

[13] Actually, it's more on the order of septillions and septillions. We don't know exactly how long it would take. We didn't care to wait around watching it not fail. In any event, your computer is likely to crash before the heat death of the universe, and this regular expression takes longer than either of those.

You'll never get a success with (?>...) that you wouldn't get with (?:...) or even a simple (...). But if you're going to fail, it's best to fail quickly and get on with your life.

5.10.3. Programmatic Patterns

Most Perl programs tend to follow an imperative (also called procedural) programming style, like a series of discrete commands laid out in a readily observable order: "Preheat oven, mix, glaze, heat, cool, serve to aliens." Sometimes into this mix you toss a few dollops of functional programming ("Use a little more glaze than you think you need, even after taking this into account, recursively"), or sprinkle it with bits of object-oriented techniques ("but please hold the anchovy objects"). Often it's a combination of all of these.

But the regular expression Engine takes a completely different approach to problem solving, more of a declarative approach. You describe goals in the language of regular expressions, and the Engine implements whatever logic is needed to solve your goals. Logic programming languages (such as Prolog) don't always get as much exposure as the other three styles, but they're more common than you'd think. Perl couldn't even be built without make(1) or yacc(1), both of which could be considered, if not purely declarative languages, at least hybrids that blend imperative and logic programming together.

You can do this sort of thing in Perl, too, by blending goal declarations and imperative code together more miscibly than we've done so far, drawing upon the strengths of both. You can programmatically build up the string you'll eventually present to the regex Engine, in a sense creating a program that writes a new program on the fly.

You can also supply ordinary Perl expressions as the replacement part of s/// via the /e modifier. This allows you to dynamically generate the replacement string by executing a bit of code every time the pattern matches.

Even more elaborately, you can interject bits of code wherever you'd like in a middle of a pattern using the (?{CODE}) extension, and that code will be executed every time the Engine encounters that code as it advances and recedes in its intricate backtracking dance.

Finally, you can use s///ee or (??{CODE}) to add another level of indirection: the results of executing those code snippets will themselves be re-evaluated for further use, creating bits of program and pattern on the fly, just in time.

5.10.3.1. Generated patterns

It has been said[14] that programs that write programs are the happiest programs in the world. In Jeffrey Friedl's book, Mastering Regular Expressions, the final tour de force demonstrates how to write a program that produces a regular expression to determine whether a string conforms to the RFC 822 standard; that is, whether it contains a standards-compliant, valid mail header. The pattern produced is several thousand characters long, and about as easy to read as a crash dump in pure binary. But Perl's pattern matcher doesn't care about that; it just compiles up the pattern without a hitch and, even more interestingly, executes the match very quickly--much more quickly, in fact, than many short patterns with complex backtracking requirements.

[14] By Andrew Hume, the famous Unix philosopher.

That's a very complicated example. Earlier we showed you a very simple example of the same technique when we built up a $number pattern out of its components (see the section Section 5.9.2, "Variable Interpolation"). But to show you the power of this programmatic approach to producing a pattern, let's work out a problem of medium complexity.

Suppose you wanted to pull out all the words with a certain vowel-consonant sequence; for example, "audio" and "eerie" both follow a VVCVV pattern. Although describing what counts as a consonant or a vowel is easy, you wouldn't ever want to type that in more than once. Even for our simple VVCVV case, you'd need to type in a pattern that looked something like this:

^[aeiouy][aeiouy][cbdfghjklmnpqrstvwxzy][aeiouy][aeiouy]$
A more general-purpose program would accept a string like "VVCVV" and programmatically generate that pattern for you. For even more flexibility, it could accept a word like "audio" as input and use that as a template to infer "VVCVV", and from that, the long pattern above. It sounds complicated, but really isn't, because we'll let the program generate the pattern for us. Here's a simple cvmap program that does all of that:
#!/usr/bin/perl
$vowels = 'aeiouy';
$cons   = 'cbdfghjklmnpqrstvwxzy';
%map = (C => $cons, V => $vowels);  # init map for C and V

for $class ($vowels, $cons) {       # now for each type
    for (split //, $class) {        # get each letter of that type
        $map{$_} .= $class;         # and map the letter back to the type
    }
}

for $char (split //, shift) {       # for each letter in template word
    $pat .= "[$map{$char}]";        # add appropriate character class
}

$re = qr/^${pat}$/i;                # compile the pattern
print "REGEX is $re\n";             # debugging output
@ARGV = ('/usr/dict/words')         # pick a default dictionary
    if -t && !@ARGV;

while (<>) {                        # and now blaze through the input
    print if /$re/;                 # printing any line that matches
}
The %map variable holds all the interesting bits. Its keys are each letter of the alphabet, and the corresponding value is all the letters of its type. We throw in C and V, too, so you can specify either "VVCVV" or "audio", and still get out "eerie". Each character in the argument supplied to the program is used to pull out the right character class to add to the pattern. Once the pattern is created and compiled up with qr//, the match (even a very long one) will run quickly. Here's why you might get if you run this program on "fortuitously":
% cvmap fortuitously /usr/dict/wordses
REGEX is (?i-xsm:^[cbdfghjklmnpqrstvwxzy][aeiouy][cbdfghjklmnpqrstvwxzy][cbd
fghjklmnpqrstvwxzy][aeiouy][aeiouy][cbdfghjklmnpqrstvwxzy][aeiouy][aeiouy][c
bdfghjklmnpqrstvwxzy][cbdfghjklmnpqrstvwxzy][aeiouycbdfghjklmnpqrstvwxzy]$)
carriageable
circuitously
fortuitously
languorously
marriageable
milquetoasts
sesquiquarta
sesquiquinta
villainously
Looking at that REGEX, you can see just how much villainous typing you saved by programming languorously, albeit circuitously.

5.10.3.2. Substitution evaluations

When the /e modifier ("e" is for expression evaluation) is used on an s/PATTERN/CODE/e expression, the replacement portion is interpreted as a Perl expression, not just as a double-quoted string. It's like an embedded do {CODE}. Even though it looks like a string, it's really just a code block that gets compiled up at the same time as rest of your program, long before the substitution actually happens.

You can use the /e modifier to build replacement strings with fancier logic than double-quote interpolation allows. This shows the difference:

s/(\d+)/$1 * 2/;     # Replaces "42" with "42 * 2"
s/(\d+)/$1 * 2/e;    # Replaces "42" with "84"
And this converts Celsius temperatures into Fahrenheit:
$_ = "Preheat oven to 233C.\n";
s/\b(\d+\.?\d*)C\b/int($1 * 1.8 + 32) . "F"/e;   # convert to 451F
Applications of this technique are limitless. Here's a filter that modifies its files in place (like an editor) by adding 100 to every number that starts a line (and that is followed by a colon, which we only peek at, but don't actually match, or replace):
% perl -pi -e 's/^(\d+)(?=:)/100 + $1/e' filename
Now and then, you want to do more than just use the string you matched in another computation. Sometimes you want that string to be a computation, whose own evaluation you'll use for the replacement value. Each additional /e modifier after the first wraps an eval around the code to execute. The following two lines do the same thing, but the first one is easier to read:
s/PATTERN/CODE/ee
s/PATTERN/eval(CODE)/e
You could use this technique to replace mentions of simple scalar variables with their values:
s/(\$\w+)/$1/eeg;       # Interpolate most scalars' values
Because it's really an eval, the /ee even finds lexical variables. A slightly more elaborate example calculates a replacement for simple arithmetical expressions on (nonnegative) integers:
$_ = "I have 4 + 19 dollars and 8/2 cents.\n";
s{ (
        \d+ \s*         # find an integer
        [+*/-]          # and an arithmetical operator
        \s* \d+         # and another integer
   )
}{ $1 }eegx;            # then expand $1 and run that code
print;                  # "I have 23 dollars and 4 cents."
Like any other eval STRING, compile-time errors (like syntax problems) and run-time exceptions (like dividing by zero) are trapped. If so, the $@ ($EVAL_ERROR) variable says what went wrong.

5.10.3.3. Match-time code evaluation

In most programs that use regular expressions, the surrounding program's run-time control structure drives the logical execution flow. You write if or while loops, or make function or method calls, that wind up calling a pattern-matching operation now and then. Even with s///e, it's the substitution operator that is in control, executing the replacement code only after a successful match.

With code subpatterns, the normal relationship between regular expression and program code is inverted. As the Engine is applying its Rules to your pattern at match time, it may come across a regex extension of the form (?{CODE}). When triggered, this subpattern doesn't do any matching or any looking about. It's a zero-width assertion that always "succeeds", evaluated only for its side effects. Whenever the Engine needs to progress over the code subpattern as it executes the pattern, it runs that code.

"glyph" =~ /.+ (?{ print "hi" }) ./x;  # Prints "hi" twice.
As the Engine tries to match glyph against this pattern, it first lets the .+ eat up all five letters. Then it prints "hi". When it finds that final dot, all five letters have been eaten, so it needs to backtrack back to the .+ and make it give up one of the letters. Then it moves forward through the pattern again, stopping to print "hi" again before assigning h to the final dot and completing the match successfully.

The braces around the CODE fragment are intended to remind you that it is a block of Perl code, and it certainly behaves like a block in the lexical sense. That is, if you use my to declare a lexically scoped variable in it, it is private to the block. But if you use local to localize a dynamically scoped variable, it may not do what you expect. A (?{ CODE}) subpattern creates an implicit dynamic scope that is valid throughout the rest of the pattern, until it either succeeds or backtracks through the code subpattern. One way to think of it is that the block doesn't actually return when it gets to the end. Instead, it makes an invisible recursive call to the Engine to try to match the rest of the pattern. Only when that recursive call is finished does it return from the block, delocalizing the localized variables.[15]

[15] People who are familiar with recursive descent parsers may find this behavior confusing because such compilers return from a recursive function call whenever they figure something out. The Engine doesn't do that--when it figures something out, it goes deeper into recursion (even when exiting a parenthetical group!). A recursive descent parser is at a minimum of recursion when it succeeds at the end, but the Engine is at a local maximum of recursion when it succeeds at the end of the pattern. You might find it helpful to dangle the pattern from its left end and think of it as a skinny representation of a call graph tree. If you can get that picture into your head, the dynamic scoping of local variables will make more sense. (And if you can't, you're no worse off than before.)

In the next example, we initialize $i to 0 by including a code subpattern at the beginning of the pattern. Then we match any number of characters with .*--but we place another code subpattern in between the . and the * so we can count how many times . matches.

$_ = 'lothlorien';
m/  (?{ $i = 0 })                    # Set $i to 0
    (.    (?{ $i++ })    )*          # Update $i, even after backtracking
    lori                             # Forces a backtrack
 /x;
The Engine merrily goes along, setting $i to 0 and letting the .* gobble up all 10 characters in the string. When it encounters the literal lori in the pattern, it backtracks and gives up those four characters from the .*. After the match, $i will still be 10.

If you wanted $i to reflect how many characters the .* actually ended up with, you could make use of the dynamic scope within the pattern:

$_ = 'lothlorien';
m/  (?{ $i = 0 })
    (. (?{ local $i = $i + 1; }) )*  # Update $i, backtracking-safe.
    lori
    (?{ $result = $i })              # Copy to non-localized location.
 /x;
Here, we use local to ensure that $i contains the number of characters matched by .*, regardless of backtracking. $i will be forgotten after the regular expression ends, so the code subpattern, (?{ $result = $i }), ensures that the count will live on in $result.

The special variable $^R (described in Chapter 28, "Special Names") holds the result of the last (?{CODE}) that was executed as part of a successful match.

You can use a (?{CODE}) extension as the COND of a (?(COND)IFTRUE|IFFALSE). If you do this, $^R will not be set, and you may omit the parentheses around the conditional:

"glyph" =~ /.+(?(?{ $foo{bar} gt "symbol" }).|signet)./;
Here, we test whether $foo{bar} is greater than symbol. If so, we include . in the pattern, and if not, we include signet in the pattern. Stretched out a bit, it might be construed as more readable:
"glyph" =~ m{
    .+                              # some anythings
    (?(?{                           # if
            $foo{bar} gt "symbol"   # this is true
        })
            .                       # match another anything
        |                           # else
            signet                  # match signet
    )
    .                               # and one more anything
}x;
When use re 'eval' is in effect, a regex is allowed to contain (?{CODE}) subpatterns even if the regular expression interpolates variables:
/(.*?) (?{length($1) < 3 && warn}) $suffix/;  # Error without use re 'eval'
This is normally disallowed since it is a potential security risk. Even though the pattern above may be innocuous because $suffix is innocuous, the regex parser can't tell which parts of the string were interpolated and which ones weren't, so it just disallows code subpatterns entirely if there were any interpolations.

If the pattern is obtained from tainted data, even use re 'eval' won't allow the pattern match to proceed.

When use re 'taint' is in effect and a tainted string is the target of a regex, the captured subpatterns (either in the numbered variables or in the list of values returned by m// in list context) are tainted. This is useful when regex operations on tainted data are meant not to extract safe substrings, but merely to perform other transformations. See Chapter 23, "Security", for more on tainting. For the purpose of this pragma, precompiled regular expressions (usually obtained from qr//) are not considered to be interpolated:

/foo${pat}bar/
This is allowed if $pat is a precompiled regular expression, even if $pat contains (?{CODE}) subpatterns.

Earlier we showed you a bit of what usere'debug' prints out. A more primitive debugging solution is to use (?{CODE}) subpatterns to print out what's been matched so far during the match:

"abcdef" =~ / .+ (?{print "Matched so far: $&\n"}) bcdef $/x;
This prints:
Matched so far: abcdef
Matched so far: abcde
Matched so far: abcd
Matched so far: abc
Matched so far: ab
Matched so far: a
showing the .+ grabbing all the letters and giving them up one by one as the Engine backtracks.

5.10.3.4. Match-time pattern interpolation

You can build parts of your pattern from within the pattern itself. The (??{ CODE }) extension allows you to insert code that evaluates to a valid pattern. It's like saying /$pattern/, except that you can generate $pattern at run time--more specifically, at match time. For instance:

/\w (??{ if ($threshold > 1) { "red" } else { "blue" } }) \d/x;
This is equivalent to /\wred\d/ if $threshold is greater than 1, and /\wblue\d/ otherwise.

You can include backreferences inside the evaluated code to derive patterns from just-matched substrings (even if they will later become unmatched through backtracking). For instance, this matches all strings that read the same backward as forward (known as palindromedaries, phrases with a hump in the middle):

/^ (.+) .? (??{quotemeta reverse $1}) $/xi;
You can balance parentheses like so:
$text =~ /( \(+ ) (.*?) (??{ '\)' x length $1 })/x;
This matches strings of the form (shazam!) and (((shazam!))), sticking shazam! into $2. Unfortunately, it doesn't notice whether the parentheses in the middle are balanced. For that we need recursion.

Fortunately, you can do recursive patterns too. You can have a compiled pattern that uses (??{CODE}) to refer to itself. Recursive matching is pretty irregular, as regular expressions go. Any text on regular expressions will tell you that a standard regex can't match nested parentheses correctly. And that's correct. It's also correct that Perl's regexes aren't standard. The following pattern[16] matches a set of nested parentheses, however deep they go:

$np = qr{
           \(
           (?:
              (?> [^()]+ )    # Non-parens without backtracking
            |
              (??{ $np })     # Group with matching parens
           )*
           \)
        }x;
You could use it like this to match a function call:
$funpat = qr/\w+$np/;
'myfunfun(1,(2*(3+4)),5)' =~ /^$funpat$/;   # Matches!

[16]Note that you can't declare the variable in the same statement in which you're going to use it. You can always declare it earlier, of course.

5.10.3.5. Conditional interpolation

The (?(COND)IFTRUE|IFFALSE) regex extension is similar to Perl's ?: operator. If COND is true, the IFTRUE pattern is used; otherwise, the IFFALSE pattern is used. The COND can be a backreference (expressed as a bare integer, without the \ or $), a lookaround assertion, or a code subpattern. (See Section 5.10.1, "Lookaround Assertions" and Section 5.10.3.3, "Match-time code evaluation" earlier in this chapter.)

If the COND is an integer, it is treated as a backreference. For instance, consider:

#!/usr/bin/perl
$x = 'Perl is free.';
$y = 'ManagerWare costs $99.95.';

foreach ($x, $y) {
    /^(\w+) (?:is|(costs)) (?(2)(\$\d+)|\w+)/;  # Either (\$\d+) or \w+
    if ($3) {
        print "$1 costs money.\n";         # ManagerWare costs money.
    } else {
        print "$1 doesn't cost money.\n";  # Perl doesn't cost money.
    }
}
Here, the COND is (2), which is true if a second backreference exists. If that's the case, (\$\d+) is included in the pattern at that point (creating the $3 backreference); otherwise, \w+ is used.

If the COND is a lookaround or code subpattern, the truth of the assertion is used to determine whether to include IFTRUE or IFFALSE:

/[ATGC]+(?(?<=AA)G|C)$/;
This uses a lookbehind assertion as the COND to match a DNA sequence that ends in either AAG, or some other base combination and C.

You can omit the |IFFALSE alternative. If you do, the IFTRUE pattern will be included in the pattern as usual if the COND is true, but if the condition isn't true, the Engine will move on to the next portion of the pattern.

5.10.4. Defining Your Own Assertions

You can't change how Perl's Engine works, but if you're sufficiently warped, you can change how it sees your pattern. Since Perl interprets your pattern similarly to double-quoted strings, you can use the wonder of overloaded string constants to see to it that text sequences of your choosing are automatically translated into other text sequences.

In the example below, we specify two transformations to occur when Perl encounters a pattern. First, we define \tag so that when it appears in a pattern, it's automatically translated to (?:<.*?>), which matches most HTML and XML tags. Second, we "redefine" the \w metasymbol so that it handles only English letters.

We'll define a package called Tagger that hides the overloading from our main program. Once we do that, we'll be able to say:

use Tagger;
$_ = '<I>camel</I>';
print "Tagged camel found" if /\tag\w+\tag/;
Here's Tagger.pm, couched in the form of a Perl module (see Chapter 11, "Modules"):
package Tagger;
use overload;

sub import { overload::constant 'qr' => \&convert }

sub convert {
    my $re = shift;
    $re =~ s/ \\tag  /<.*?>/xg;
    $re =~ s/ \\w    /[A-Za-z]/xg;
    return $re;
}

1;
The Tagger module is handed the pattern immediately before interpolation, so you can bypass the overloading by bypassing interpolation, as follows:
$re = '\tag\w+\tag';   # This string begins with \t, a tab
print if /$re/;        # Matches a tab, followed by an "a"...
If you wanted the interpolated variable to be customized, call the convert function directly:
$re = '\tag\w+\tag';         # This string begins with \t, a tab
$re = Tagger::convert $re;   # expand \tag and \w
print if /$re/;              # $re becomes <.*?>[A-Za-z]+<.*?>
Now if you're still wondering what those sub thingies are there in the Tagger module, you'll find out soon enough because that's what our next chapter is all about.

Previous | Home | Next
5.9. Staying in Control | Book Index | 6. Subroutines
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 6. Subroutines

Contents:

Syntax
Semantics
Passing References
Prototypes
Subroutine Attributes

Like many languages, Perl provides for user-defined subroutines.[1] These subroutines may be defined anywhere in the main program, loaded in from other files via the do, require, or use keywords, or generated at run time using eval. You can even load them at run time with the mechanism described in the section Section 6.2, "Autoloading" in Chapter 10, "Packages". You can call a subroutine indirectly, using a variable containing either its name or a reference to the routine, or through an object, letting the object determine which subroutine should really be called. You can generate anonymous subroutines, accessible only through references, and if you want, use these to clone new, nearly identical functions via closures, which are covered in the section by that name in Chapter 8, "References".

[1] We'll also call them functions, but functions are the same thing as subroutines in Perl. Sometimes we'll even call them methods, which are defined the same way, but called differently.

6.1. Syntax

To declare a named subroutine without defining it, use one of these forms:

sub NAME
sub NAME PROTO
sub NAME       ATTRS
sub NAME PROTO ATTRS
To declare and define a named subroutine, add a BLOCK:
sub NAME             BLOCK
sub NAME PROTO       BLOCK
sub NAME       ATTRS BLOCK
sub NAME PROTO ATTRS BLOCK
To create an anonymous subroutine or closure, leave out the NAME:
sub                  BLOCK
sub      PROTO       BLOCK
sub            ATTRS BLOCK
sub      PROTO ATTRS BLOCK
PROTO and ATTRS stand for the prototype and attributes, each of which is discussed in its own section later in the chapter. They're not so important--the NAME and the BLOCK are the essential parts, even when they're missing.

For the forms without a NAME, you still have to provide some way of calling the subroutine. So be sure to save the return value since this form of sub declaration is not only compiled at compile time as you would expect, but also produces a run-time return value:

$subref = sub BLOCK;
To import subroutines defined in another module, say:
use MODULE qw(NAME1 NAME2 NAME3...);
To call subroutines directly, say:
NAME(LIST)            # & is optional with parentheses.
NAME LIST             # Parens optional if sub predeclared/imported.
&NAME                 # Exposes current @_ to that subroutine,
                      # (and circumvents prototypes).
To call subroutines indirectly (by name or by reference), use any of these:
&$subref(LIST)        # The & is not optional on indirect call
$subref->(LIST)       # (unless using infix notation).
&$subref              # Exposes current @_ to that subroutine.

The official name of a subroutine includes the & prefix. A subroutine may be called using the prefix, but the & is usually optional, and so are the parentheses if the subroutine has been predeclared. However, the & is not optional when you're just naming the subroutine, such as when it's used as an argument to defined or undef or when you want to generate a reference to a named subroutine by saying $subref = \&name. Nor is the & optional when you want to make an indirect subroutine call using the &$subref() or &{$subref}() constructs. However, the more convenient $subref->() notation does not require it. See Chapter 8, "References" for more about references to subroutines.

Perl doesn't force a particular capitalization style on your subroutine names. However, one loosely held convention is that functions called indirectly by Perl's run-time system (BEGIN, CHECK, INIT, END, AUTOLOAD, DESTROY, and all the functions mentioned in Chapter 14, "Tied Variables") are in all capitals, so you might want to avoid using that style. (But subroutines used for constant values are customarily named with all caps too. That's okay. We hope...)

Previous | Home | Next
5.10. Fancy Patterns | Book Index | 6.2. Semantics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.2. Semantics

Before you get too worked up over all that syntax, just remember that the normal way to define a simple subroutine ends up looking like this:

sub razzle {
    print "Ok, you've been razzled.\n";
}
and the normal way to call it is simply:
razzle();
In this case, we ignored inputs (arguments) and outputs (return values). But the Perl model for passing data into and out of a subroutine is really quite simple: all function parameters are passed as one single, flat list of scalars, and multiple return values are likewise returned to the caller as one single, flat list of scalars. As with any LIST, any arrays or hashes passed in these lists will interpolate their values into the flattened list, losing their identities--but there are several ways to get around this, and the automatic list interpolation is frequently quite useful. Both parameter lists and return lists may contain as many or as few scalar elements as you'd like (though you may put constraints on the parameter list by using prototypes). Indeed, Perl is designed around this notion of variadic functions (those taking any number of arguments), unlike C, where they're sort of grudgingly kludged in so that you can call printf(3).

Now, if you're going to design a language around the notion of passing varying numbers of arbitrary arguments, you'd better make it easy to process those arbitrary lists of arguments. Any arguments passed to a Perl routine come in as the array @_. If you call a function with two arguments, they are accessible inside the function as the first two elements of that array: $_[0] and $_[1]. Since @_ is a just a regular array with an irregular name, you can do anything to it you'd normally do to an array.[2] The array @_ is a local array, but its values are aliases to the actual scalar parameters. (This is known as pass-by-reference semantics.) Thus you can modify the actual parameters if you modify the corresponding element of @_. (This is rarely done, however, since it's so easy to return interesting values in Perl.)

[2] This is an area where Perl is more orthogonal than the typical programming language.

The return value of the subroutine (or of any other block, for that matter) is the value of the last expression evaluated. Or you may use an explicit return statement to specify the return value and exit the subroutine from any point in the subroutine. Either way, as the subroutine is called in a scalar or list context, so also is the final expression of the routine evaluated in that same scalar or list context.

6.2.1. Tricks with Parameter Lists

Perl does not yet have named formal parameters, but in practice all you do is copy the values of @_ to a my list, which serves nicely for a list of formal parameters. (Not coincidentally, copying the values changes the pass-by-reference semantics into pass-by-value, which is how people usually expect parameters to work anyway, even if they don't know the fancy computer science terms for it.) Here's a typical example:

sub maysetenv {
    my ($key, $value) = @_;
    $ENV{$key} = $value unless $ENV{$key};
}
But you aren't required to name your parameters, which is the whole point of the @_ array. For example, to calculate a maximum, you can just iterate over @_ directly:
sub max {
    my $max = shift(@_);
    for my $item (@_) {
        $max = $item if $max < $item;
    }
    return $max;
}

$bestday = max($mon,$tue,$wed,$thu,$fri);
Or you can fill an entire hash at once:
sub configuration {
    my %options = @_;
    print "Maximum verbosity.\n" if $options{VERBOSE} == 9;
}

configuration(PASSWORD => "xyzzy", VERBOSE => 9, SCORE => 0);
Here's an example of not naming your formal arguments so that you can modify your actual arguments:
upcase_in($v1, $v2);  # this changes $v1 and $v2
sub upcase_in {
    for (@_) { tr/a-z/A-Z/ }
}
You aren't allowed to modify constants in this way, of course. If an argument were actually a scalar literal like "hobbit" or read-only scalar variable like $1, and you tried to change it, Perl would raise an exception (presumably fatal, possibly career-threatening). For example, this won't work:
upcase_in("frederick");
It would be much safer if the upcase_in function were written to return a copy of its parameters instead of changing them in place:
($v3, $v4) = upcase($v1, $v2);
sub upcase {
    my @parms = @_;
    for (@parms) { tr/a-z/A-Z/ }
    # Check whether we were called in list context.
    return wantarray ? @parms : $parms[0];
}
Notice how this (unprototyped) function doesn't care whether it was passed real scalars or arrays. Perl will smash everything into one big, long, flat @_ parameter list. This is one of the places where Perl's simple argument-passing style shines. The upcase function will work perfectly well without changing the upcase definition even if we feed it things like this:
@newlist = upcase(@list1, @list2);
@newlist = upcase( split /:/, $var );
Do not, however, be tempted to do this:
(@a, @b) = upcase(@list1, @list2);   # WRONG
Why not? Because, like the flat incoming parameter list in @_, the return list is also flat. So this stores everything in @a and empties out @b by storing the null list there. See the later section Section 6.3, "Passing References" for alternatives.

6.2.2. Error Indications

If you want your function to return in such a way that the caller will realize there's been an error, the most natural way to do this in Perl is to use a bare return statement without an argument. That way when the function is used in scalar context, the caller gets undef, and when used in list context, the caller gets a null list.

Under extraordinary circumstances, you might choose to raise an exception to indicate an error. Use this measure sparingly, though; otherwise, your whole program will be littered with exception handlers. For example, failing to open a file in a generic file-opening function is hardly an exceptional event. However, ignoring that failure might well be. The wantarray built-in returns undef if your function was called in void context, so you can tell if you're being ignored:

if ($something_went_awry) {
    return if defined wantarray;  # good, not void context.
    die "Pay attention to my error, you danglesocket!!!\n";
}

6.2.3. Scoping Issues

Subroutines may be called recursively because each call gets its own argument array, even when the routine calls itself. If a subroutine is called using the & form, the argument list is optional. If the & is used but the argument list is omitted, something special happens: the @_ array of the calling routine is supplied implicitly. This is an efficiency mechanism that new users may wish to avoid.

&foo(1,2,3);    # pass three arguments
foo(1,2,3);     # the same

foo();          # pass a null list
&foo();         # the same

&foo;           # foo() gets current args, like foo(@_), but faster!
foo;            # like foo() if sub foo predeclared, else bareword "foo"
Not only does the & form make the argument list optional, but it also disables any prototype checking on the arguments you do provide. This is partly for historical reasons and partly to provide a convenient way to cheat if you know what you're doing. See the section Section 6.4, "Prototypes" later in this chapter.

Variables you access from inside a function that haven't been declared private to that function are not necessarily global variables; they still follow the normal block-scoping rules of Perl. As explained in Section 6.5, "Names" in Chapter 2, "Bits and Pieces", this means they look first in the surrounding lexical scope (or scopes) for resolution, then on to the single package scope. From the viewpoint of a subroutine, then, any my variables from an enclosing lexical scope are still perfectly visible.

For example, the bumpx function below has access to the file-scoped $x lexical variable because the scope where the my was declared--the file itself--hasn't been closed off before the subroutine is defined:

# top of file
my $x = 10;         # declare and initialize variable
sub bumpx { $x++ }  # function can see outer lexical variable

C and C++ programmers would probably think of $x as a "file static" variable. It's private as far as functions in other files are concerned, but global from the perspective of functions declared after the my. C programmers who come to Perl looking for what they would call "static variables" for files or functions find no such keyword in Perl. Perl programmers generally avoid the word "static", because static systems are dead and boring, and because the word is so muddled in historical usage.

Although Perl doesn't include the word "static" in its lexicon, Perl programmers have no problem creating variables that are private to a function and persist across function calls. There's just no special word for these. Perl's richer scoping primitives combine with automatic memory management in ways that someone looking for a "static" keyword might never think of trying.

Lexical variables don't get automatically garbage collected just because their scope has exited; they wait to get recycled until they're no longer used, which is much more important. To create private variables that aren't automatically reset across function calls, enclose the whole function in an extra block and put both the my declaration and the function definition within that block. You can even put more than one function there for shared access to an otherwise private variable:

{
    my $counter = 0;
    sub next_counter { return ++$counter }
    sub prev_counter { return --$counter }
}
As always, access to the lexical variable is limited to code within the same lexical scope. The names of the two functions, on the other hand, are globally accessible (within the package), and, since they were defined inside $counter's scope, they can still access that variable even though no one else can.

If this function is loaded via require or use, then this is probably just fine. If it's all in the main program, you'll need to make sure any run-time assignment to my is executed early enough, either by putting the whole block before your main program, or alternatively, by placing a BEGIN or INIT block around it to make sure it gets executed before your program starts:

BEGIN {
    my @scale = ('A' .. 'G');
    my $note  = -1;
    sub next_pitch { return $scale[ ($note += 1) %= @scale ] };
}
The BEGIN doesn't affect the subroutine definition, nor does it affect the persistence of any lexicals used by the subroutine. It's just there to ensure the variables get initialized before the subroutine is ever called. For more on declaring private and global variables, see my and our respectively in Chapter 29, "Functions". The BEGIN and INIT constructs are explained in Chapter 18, "Compiling".

Previous | Home | Next
6.1. Syntax | Book Index | 6.3. Passing References
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.3. Passing References

If you want to pass more than one array or hash into or out of a function, and you want them to maintain their integrity, then you'll need to use an explicit pass-by-reference mechanism. Before you do that, you need to understand references as detailed in Chapter 8, "References". This section may not make much sense to you otherwise. But hey, you can always look at the pictures...

Here are a few simple examples. First, let's define a function that expects a reference to an array. When the array is large, it's much faster to pass it in as a single reference than a long list of values:

$total = sum ( \@a );

sub sum {
    my ($aref)  = @_;
    my ($total) = 0;
    foreach (@$aref) { $total += $_ }
    return $total;
}
Let's pass in several arrays to a function and have it pop each of them, returning a new list of all their former last elements:
@tailings = popmany ( \@a, \@b, \@c, \@d );

sub popmany {
    my @retlist = ();
    for my $aref (@_) {
        push @retlist, pop @$aref;
    }
    return @retlist;
}

Here's how you might write a function that does a kind of set intersection by returning a list of keys occurring in all the hashes passed to it:

@common = inter( \%foo, \%bar, \%joe );
sub inter {
    my %seen;
    for my $href (@_) {
        while (my $k = each %$href ) {
            $seen{$k}++;
        }
    }
    return grep { $seen{$_} == @_ } keys %seen;
}
So far, we're just using the normal list return mechanism. What happens if you want to pass or return a hash? Well, if you're only using one of them, or you don't mind them concatenating, then the normal calling convention is okay, although a little expensive.

As we explained earlier, where people get into trouble is here:

(@a, @b) = func(@c, @d);
or here:
(%a, %b) = func(%c, %d);
That syntax simply won't work. It just sets @a or %a and clears @b or %b. Plus the function doesn't get two separate arrays or hashes as arguments: it gets one long list in @_, as always.

You may want to arrange for your functions to use references for both input and output. Here's a function that takes two array references as arguments and returns the two array references ordered by the number of elements they have in them:

($aref, $bref) = func(\@c, \@d);
print "@$aref has more than @$bref\n";
sub func {
    my ($cref, $dref) = @_;
    if (@$cref > @$dref) {
        return ($cref, $dref);
    } else {
        return ($dref, $cref);
    }
}
For passing filehandles or directory handles into or out of functions, see the sections "Filehandle References" and Section 6.2.5, "Symbol Table References" in Chapter 8, "References".

Previous | Home | Next
6.2. Semantics | Book Index | 6.4. Prototypes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.4. Prototypes

Perl lets you define your own functions to be called like Perl's built-in functions. Consider push(@array, $item), which must tacitly receive a reference to @array, not just the list values held in @array, so that the array can be modified. Prototypes let you declare subroutines to take arguments just like many of the built-ins, that is, with certain constraints on the number and types of arguments. We call them "prototypes", but they work more like automatic templates for the calling context than like what C or Java programmers would think of as prototypes. With these templates, Perl will automatically add implicit backslashes, or calls to scalar, or whatever else it takes to get things to show up in a way that matches the template. For instance, if you declare:

sub mypush (\@@);
then mypush takes arguments exactly like push does. For this to work, the declaration of the function to be called must be visible at compile time. The prototype only affects the interpretation of function calls when the & character is omitted. In other words, if you call it like a built-in function, it behaves like a built-in function. If you call it like an old-fashioned subroutine, then it behaves like an old-fashioned subroutine. The & suppresses prototype checks and associated contextual effects.

Since prototypes are taken into consideration only at compile time, it naturally falls out that they have no influence on subroutine references like \&foo or on indirect subroutine calls like &{$subref} or $subref->(). Method calls are not influenced by prototypes, either. That's because the actual function to be called is indeterminate at compile time, depending as it does on inheritance, which is dynamically determined in Perl.

Since the intent is primarily to let you define subroutines that work like built-in functions, here are some prototypes you might use to emulate the corresponding built-ins:

Declared as | Called as
sub mylink ($$) | mylink $old, $new
sub myreverse (@) | myreverse $a,$b,$c
sub myjoin ($@) | myjoin ":",$a,$b,$c
sub mypop (\@) | mypop @array
sub mysplice (\@$$@) | mysplice @array,@array,0,@pushme
sub mykeys (\%) | mykeys %{$hashref}
sub mypipe (**) | mypipe READHANDLE, WRITEHANDLE
sub myindex ($$;$) | myindex &getstring, "substr"
 | myindex &getstring, "substr", $start
sub mysyswrite (*$;$$) | mysyswrite OUTF, $buf
 | mysyswrite OUTF, $buf, length($buf)-$off, $off
sub myopen (*;$@) | myopen HANDLE
 | myopen HANDLE, $name
 | myopen HANDLE, "-|", @cmd
sub mygrep (&@) | mygrep { /foo/ } $a,$b,$c
sub myrand ($) | myrand 42
sub mytime () | mytime

Any backslashed prototype character (shown between parentheses in the left column above) represents an actual argument (exemplified in the right column), which absolutely must start with that character. Just as the first argument to keys must start with %, so too must the first argument to mykeys.

A semicolon separates mandatory arguments from optional arguments. (It would be redundant before @ or %, since lists can be null.) Unbackslashed prototype characters have special meanings. Any unbackslashed @ or % eats all the rest of the actual arguments and forces list context. (It's equivalent to LIST in a syntax description.) An argument represented by $ has scalar context forced on it. An & requires a reference to a named or anonymous subroutine.

A * allows the subroutine to accept anything in that slot that would be accepted by a built-in as a filehandle: a bare name, a constant, a scalar expression, a typeglob, or a reference to a typeglob. The value will be available to the subroutine either as a simple scalar or (in the latter two cases) as a reference to the typeglob. If you wish to always convert such arguments to a typeglob reference, use Symbol::qualify_to_ref as follows:

use Symbol 'qualify_to_ref';

sub foo (*) {
    my $fh = qualify_to_ref(shift, caller);
    ...
}
Note how the last three examples in the table are treated specially by the parser. mygrep is parsed as a true list operator, myrand is parsed as a true unary operator with unary precedence the same as rand, and mytime is truly argumentless, just like time.

That is, if you say:

mytime +2;
you'll get mytime() + 2, not mytime(2), which is how it would be parsed without the prototype, or with a unary prototype.

The mygrep example also illustrates how & is treated specially when it is the first argument. Ordinarily, an & prototype would demand an argument like \&foo or sub{}. When it is the first argument, however, you can leave off the sub of your anonymous subroutine, and just pass a bare block in the "indirect object" slot (with no comma after it). So one nifty thing about the & prototype is that you can generate new syntax with it, provided the & is in the initial position:

sub try (&$) {
    my ($try, $catch) = @_;
    eval { &$try };
    if ($@) {
        local $_ = $@;
        &$catch;
    }
}
sub catch (&) { $_[0] }

try {
    die "phooey";
}                   # not the end of the function call!
catch {
    /phooey/ and print "unphooey\n";
};
This prints "unphooey". What happens is that try is called with two arguments, the anonymous function {die "phooey";} and the return value of the catch function, which in this case is nothing but its own argument, the entire block of yet another anonymous function. Within try, the first function argument is called while protected within an eval block to trap anything that blows up. If something does blow up, the second function is called with a local version of the global $_ variable set to the raised exception.[3] If this all sounds like pure gobbledygook, you'll have to read about die and eval in Chapter 29, "Functions", and then go check out anonymous functions and closures in Chapter 8, "References". On the other hand, if it intrigues you, you might check out the Error module on CPAN, which uses this to implement elaborately structured exception handling with try, catch, except, otherwise, and finally clauses.

[3] Yes, there are still unresolved issues having to do with the visibility of @_. We're ignoring that question for the moment. But if we make @_ lexically scoped someday, as already occurs in the experimental threaded versions of Perl, those anonymous subroutines can act like closures.

Here's a reimplementation of the grep operator (the built-in one is more efficient, of course):

sub mygrep (&@) {
    my $coderef = shift;
    my @result;
    foreach $_ (@_) {
        push(@result, $_) if &$coderef;
    }
    return @result;
}
Some folks would prefer to see full alphanumeric prototypes. Alphanumerics have been intentionally left out of prototypes for the express purpose of someday adding named, formal parameters. (Maybe.) The current mechanism's main goal is to let module writers enforce a certain amount of compile-time checking on module users.

6.4.1. Inlining Constant Functions

Functions prototyped with (), meaning that they take no arguments at all, are parsed like the time built-in. More interestingly, the compiler treats such functions as potential candidates for inlining. If the result of that function, after Perl's optimization and constant-folding pass, is either a constant or a lexically scoped scalar with no other references, then that value will be used in place of calls to that function. Calls made using &NAME are never inlined, however, just as they are not subject to any other prototype effects. (See the use constant pragma in Chapter 31, "Pragmatic Modules", for an easy way to declare such constants.)

Both version of these functions to compute [image] will be inlined by the compiler:

sub pi ()           { 3.14159 }             # Not exact, but close
sub PI ()           { 4 * atan2(1, 1) }     # As good as it gets
In fact, all of the following functions are inlined because Perl can determine everything at compile time:
sub FLAG_FOO ()     { 1 << 8 }
sub FLAG_BAR ()     { 1 << 9 }
sub FLAG_MASK ()    { FLAG_FOO | FLAG_BAR }

sub OPT_GLARCH ()   { (0x1B58 & FLAG_MASK) == 0 }
sub GLARCH_VAL ()   {
    if (OPT_GLARCH) { return 23 }
    else            { return 42 }
}

sub N () { int(GLARCH_VAL) / 3 }
BEGIN {                 # compiler runs this block at compile time
    my $prod = 1;       # persistent, private variable
    for (1 .. N) { $prod *= $_ }
    sub NFACT () { $prod }
}
In the last example, the NFACT function is inlined because it has a void prototype and the variable it returns is not changed by that function--and furthermore can't be changed by anyone else, since it's in a lexical scope. So the compiler replaces uses of NFACT with that value, which was precomputed at compile time because of the surrounding BEGIN.

If you redefine a subroutine that was eligible for inlining, you'll get a mandatory warning. (You can use this warning to tell whether the compiler inlined a particular subroutine.) The warning is considered severe enough not to be optional, because previously compiled invocations of the function will still use the old value of the function. If you need to redefine the subroutine, ensure that it isn't inlined either by dropping the () prototype (which changes calling semantics, so beware) or by thwarting the inlining mechanism in some other way, such as:

sub not_inlined () {
    return 23 if $$;
}
See Chapter 18, "Compiling" for more about what happens during the compilation and execution phases of your program's life.

6.4.2. Care with Prototypes

It's probably best to put prototypes on new functions, not retrofit prototypes onto older ones. These are context templates, not ANSI C prototypes, so you must be especially careful about silently imposing a different context. Suppose, for example, you decide that a function should take just one parameter, like this:

sub func ($) {
    my $n = shift;
    print "you gave me $n\n";
}
That makes it a unary operator (like the rand built-in) and changes how the compiler determines the function's arguments. With the new prototype, the function consumes just one, scalar-context argument instead of many arguments in list context. If someone has been calling it with an array or list expression, even if that array or list contained just a single element, where before it worked, now you've got something completely different:
func @foo;                  # counts @foo elements
func split /:/;             # counts number of fields returned
func "a", "b", "c";         # passes "a" only, discards "b" and "c"
func("a", "b", "c");        # suddenly, a compiler error!
You've just supplied an implicit scalar in front of the argument list, which can be more than a bit surprising. The old @foo that used to hold one thing doesn't get passed in. Instead, 1 (the number of elements in @foo) is now passed to func. And the split, being called in scalar context, scribbles all over your @_ parameter list. In the third example, because func has been prototyped as a unary operator, only "a" is passed in; then the return value from func is discarded as the comma operator goes on to evaluate the next two items and return "c." In the final example, the user now gets a syntax error at compile time on code that used to compile and run just fine.

If you're writing new code and would like a unary operator that takes only a scalar variable, not any old scalar expression, you could prototype it to take a scalar reference:

sub func (\$) {
    my $nref = shift;
    print "you gave me $$nref\n";
}
Now the compiler won't let anything by that doesn't start with a dollar sign:
func @foo;              # compiler error, saw @, want $
func split/:/;          # compiler error, saw function, want $
func $s;                # this one is ok -- got real $ symbol
func $a[3];             # and this one
func $h{stuff}[-1];     # or even this
func 2+5;               # scalar expr still a compiler error
func ${ \(2+5) };       # ok, but is the cure worse than the disease?
If you aren't careful, you can get yourself into trouble with prototypes. But if you are careful, you can do a lot of neat things with them. This is all very powerful, of course, and should only be used in moderation to make the world a better place.

Previous | Home | Next
6.3. Passing References | Book Index | 6.5. Subroutine Attributes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


6.5. Subroutine Attributes

A subroutine declaration or definition may have a list of attributes associated with it. If such an attribute list is present, it is broken up at whitespace or colon boundaries and treated as though a use attributes had been seen. See the use attributes pragma in Chapter 31, "Pragmatic Modules" for internal details. There are three standard attributes for subroutines: locked, method, and lvalue.

6.5.1. The locked and method Attributes

# Only one thread is allowed into this function.
sub afunc : locked { ... }

# Only one thread is allowed into this function on a given object.
sub afunc : locked method { ... }
Setting the locked attribute is meaningful only when the subroutine or method is intended to be called by multiple threads simultaneously. When set on a nonmethod subroutine, Perl ensures that a lock is acquired on the subroutine itself before that subroutine is entered. When set on a method subroutine (that is, one also marked with the method attribute), Perl ensures that any invocation of it implicitly locks its first argument (the object) before execution.

Semantics of this lock are the same as using the lock operator on the subroutine as the first statement in that routine. See Chapter 17, "Threads", for more on locking.

The method attribute can be used by itself:

sub afunc : method { ... }
Currently this has only the effect of marking the subroutine so as not to trigger the "Ambiguous call resolved as CORE::%s" warning. (We may make it mean more someday.)

The attribute system is user-extensible, letting you create your own attribute names. These new attributes must be valid as simple identifier names (without any punctuation other than the "_" character). They may have a parameter list appended, which is currently only checked for whether its parentheses nest properly.

Here are examples of valid syntax (even though the attributes are unknown):

sub fnord (&\%) : switch(10,foo(7,3))  :  expensive;
sub plugh () : Ugly('\(") :Bad;
sub xyzzy : _5x5 { ... }
Here are examples of invalid syntax:
sub fnord : switch(10,foo();  # ()-string not balanced
sub snoid : Ugly('(');        # ()-string not balanced
sub xyzzy : 5x5;              # "5x5" not a valid identifier
sub plugh : Y2::north;        # "Y2::north" not a simple identifier
sub snurt : foo + bar;        # "+" not a colon or space
The attribute list is passed as a list of constant strings to the code that associates them with the subroutine. Exactly how this works (or doesn't) is highly experimental. Check attributes(3) for current details on attribute lists and their manipulation.

6.5.2. The lvalue Attribute

It is possible to return a modifiable scalar value from a subroutine, but only if you declare the subroutine to return an lvalue:

my $val;
sub canmod : lvalue {
    $val;
}
sub nomod {
    $val;
}

canmod() = 5;   # Assigns to $val.
nomod()  = 5;   # ERROR
If you're passing parameters to an lvalued subroutine, you'll usually want parentheses to disambiguate what's being assigned:
canmod $x  = 5;     # assigns 5 to $x first!
canmod 42  = 5;     # can't change a constant; compile-time error
canmod($x) = 5;     # this is ok
canmod(42) = 5;     # and so is this
If you want to be sneaky, you can get around this in the particular case of a subroutine that takes one argument. Declaring the function with a prototype of ($) causes the function to be parsed with the precedence of a named unary operator. Since named unaries have higher precedence than assignment, you no longer need the parentheses. (Whether this is desirable or not is left up to the style police.)

You don't have to be sneaky in the particular case of a subroutine that allows zero arguments (that is, with a () prototype). You can without ambiguity say this:

canmod = 5;
That works because no valid term begins with =. Similarly, lvalued method calls can omit the parentheses when you don't pass any arguments:
$obj->canmod = 5;
We promise not to break those two constructs in future versions of Perl. They're handy when you want to wrap object attributes in method calls (so that they can be inherited like method calls but accessed like variables).

The scalar or list context of both the lvalue subroutine and the righthand side of an assignment to that subroutine is determined as if the subroutine call were replaced by a scalar. For example, consider:

data(2,3) = get_data(3,4);
Both subroutines here are called in scalar context, while in:
(data(2,3)) = get_data(3,4);
and in:
(data(2),data(3)) = get_data(3,4);
all the subroutines are called in list context.

The current implementation does not allow arrays and hashes to be returned from lvalue subroutines directly. You can always return a reference instead.

Previous | Home | Next
6.4. Prototypes | Book Index | 7. Formats
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 7. Formats

Contents:

Format Variables
Footers

Perl has a mechanism to help you generate simple reports and charts. To facilitate this, Perl helps you code up your output page close to how it will look when it's printed. It can keep track of things like how many lines are on a page, the current page number, when to print page headers, and so on. Keywords are borrowed from FORTRAN: format to declare and write to execute; see the relevant entries in Chapter 29, "Functions". Fortunately, the layout is much more legible, more like the PRINT USING statement of BASIC. Think of it as a poor man's nroff(1). (If you know nroff, that may not sound like a recommendation.)

Formats, like packages and subroutines, are declared rather than executed, so they may occur at any point in your program. (Usually it's best to rukeep them all together.) They have their own namespace apart from all the other types in Perl. This means that if you have a function named "Foo", it is not the same thing as a format named "Foo". However, the default name for the format associated with a given filehandle is the same as the name of that filehandle. Thus, the default format for STDOUT is named "STDOUT", and the default format for filehandle TEMP is named "TEMP". They just look the same. They aren't.

Output record formats are declared as follows:

format NAME =
FORMLIST
.
If NAME is omitted, format STDOUT is defined. FORMLIST consists of a sequence of lines, each of which may be of one of three types:

  • A comment, indicated by putting a # in the first column.

  • A "picture" line giving the format for one output line.

  • An argument line supplying values to plug into the previous picture line.

Picture lines are printed exactly as they look, except for certain fields that substitute values into the line.[1] Each substitution field in a picture line starts with either @ (at) or ^ (caret). These lines do not undergo any kind of variable interpolation. The @ field (not to be confused with the array marker @) is the normal kind of field; the other kind, the ^ field, is used to do rudimentary multiline text-block filling. The length of the field is supplied by padding out the field with multiple <, >, or | characters to specify, respectively, left justification, right justification, or centering. If the variable exceeds the width specified, it is truncated.

[1] Even those fields maintain the integrity of the columns you put them in, however. There is nothing in a picture line that can cause fields to grow or shrink or shift back and forth. The columns you see are sacred in a WYSIWYG sense--assuming you're using a fixed-width font. Even control characters are assumed to have a width of one.

As an alternate form of right justification, you may also use # characters (after an initial @ or ^) to specify a numeric field. You can insert a . in place of one of the # characters to line up the decimal points. If any value supplied for these fields contains a newline, only the text up to the newline is printed. Finally, the special field @* can be used for printing multiline, nontruncated values; it should generally appear on a picture line by itself.

The values are specified on the following line in the same order as the picture fields. The expressions providing the values should be separated by commas. The expressions are all evaluated in a list context before the line is processed, so a single list expression could produce multiple list elements. The expressions may be spread out to more than one line if enclosed in braces. (If so, the opening brace must be the first token on the first line). This lets you line up the values under their respective format fields for easier reading.

If an expression evaluates to a number with a decimal part, and if the corresponding picture specifies that the decimal part should appear in the output (that is, any picture except multiple # characters without an embedded .), the character used for the decimal point is always determined by the current LC_NUMERIC locale. This means that if, for example, the run-time environment happens to specify a German locale, a comma will be used instead of a period. See the perllocale manpage for more information.

Inside an expression, the whitespace characters \n, \t, and \f are all considered equivalent to a single space. Thus, you could think of this filter as being applied to each value in the format:

$value =~ tr/\n\t\f/ /;
The remaining whitespace character, \r, forces the printing of a new line if the picture line allows it.

Picture fields that begin with ^ rather than @ are treated specially. With a # field, the field is blanked out if the value is undefined. For other field types, the caret enables a kind of fill mode. Instead of an arbitrary expression, the value supplied must be a scalar variable name that contains a text string. Perl puts as much text as it can into the field, and then chops off the front of the string so that the next time the variable is referenced, more of the text can be printed. (Yes, this means that the variable itself is altered during execution of the write call and is not preserved. Use a scratch variable if you want to preserve the original value.) Normally you would use a sequence of fields lined up vertically to print out a block of text. You might wish to end the final field with the text "...", which will appear in the output if the text was too long to appear in its entirety. You can change which characters are legal to "break" on (or after) by changing the variable $: (that's $FORMAT_LINE_BREAK_CHARACTERS if you're using the English module) to a list of the desired characters.

Using ^ fields can produce variable-length records. If the text to be formatted is short, just repeat the format line with the ^ field in it a few times. If you just do this for short data you'd end up getting a few blank lines. To suppress lines that would end up blank, put a ~ (tilde) character anywhere in the line. (The tilde itself will be translated to a space upon output.) If you put a second tilde next to the first, the line will be repeated until all the text in the fields on that line are exhausted. (This works because the ^ fields chew up the strings they print. But if you use a field of the @ variety in conjunction with two tildes, the expression you supply had better not give the same value every time forever! Use a shift, or some other operator with a side effect that exhausts the set of values.)

Top-of-form processing is by default handled by a format with the same name as the current filehandle with _TOP concatenated to it. It's triggered at the top of each page. See write in Chapter 29, "Functions".

Here are some examples:

# a report on the /etc/passwd file
format STDOUT_TOP =
                         Passwd File
Name                Login    Office   Uid   Gid Home
------------------------------------------------------------------
.
format STDOUT =
@<<<<<<<<<<<<<<<<<< @||||||| @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<<
$name,              $login,  $office,$uid,$gid, $home
.

# a report from a bug report form
format STDOUT_TOP =
                         Bug Reports
@<<<<<<<<<<<<<<<<<<<<<<<     @|||         @>>>>>>>>>>>>>>>>>>>>>>>
$system,                      $%,         $date
------------------------------------------------------------------
.
format STDOUT =
Subject: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
         $subject
Index: @<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
       $index,                       $description
Priority: @<<<<<<<<<< Date: @<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
          $priority,        $date,   $description
From: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      $from,                         $description
Assigned to: @<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
             $programmer,            $description
~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                     $description
~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                     $description
~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                     $description
~                                    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                     $description
~                                    ^<<<<<<<<<<<<<<<<<<<<<<<...
                                     $description
.

Lexical variables are not visible within a format unless the format is declared within the scope of the lexical variable.

It is possible to intermix prints with writes on the same output channel, but you'll have to handle the $- special variable ($FORMAT_LINES_LEFT if you're using the English module) yourself.

7.1. Format Variables

The current format name is stored in the variable $~ ($FORMAT_NAME), and the current top-of-form format name is in $^ ($FORMAT_TOP_NAME). The current output page number is stored in $% ($FORMAT_PAGE_NUMBER), and the number of lines on the page is in $= ($FORMAT_LINES_PER_PAGE). Whether to flush the output buffer on this handle automatically is stored in $| ($OUTPUT_AUTOFLUSH). The string to be output before each top of page (except the first) is stored in $^L ($FORMAT_FORMFEED). These variables are set on a per-filehandle basis, so you'll need to select the filehandle associated with a format in order to affect its format variables:

select((select(OUTF),
        $~ = "My_Other_Format",
        $^ = "My_Top_Format"
       )[0]);
Pretty ugly, eh? It's a common idiom though, so don't be too surprised when you see it. You can at least use a temporary variable to hold the previous filehandle:
$ofh = select(OUTF);
$~ = "My_Other_Format";
$^ = "My_Top_Format";
select($ofh);

This is a much better approach in general because not only does legibility improve, but you now have an intermediary statement in the code to stop on when you're single-stepping in the debugger. If you use the English module, you can even read the variable names:

use English;
$ofh = select(OUTF);
$FORMAT_NAME     = "My_Other_Format";
$FORMAT_TOP_NAME = "My_Top_Format";
select($ofh);

But you still have those funny calls to select. If you want to avoid them, use the FileHandle module bundled with Perl. Now you can access these special variables using lowercase method names instead:

use FileHandle;
OUTF->format_name("My_Other_Format");
OUTF->format_top_name("My_Top_Format");
Much better!

Since the values line following your picture line may contain arbitrary expressions (for @ fields, not ^ fields), you can farm out more sophisticated processing to other functions, like sprintf or one of your own. For example, to insert commas into a number:

format Ident =
    @<<<<<<<<<<<<<<<
    commify($n)
.
To get a real @, ~, or ^ into the field, do this:
format Ident =
I have an @ here.
         "@"
.

To center a whole line of text, do something like this:

format Ident =
@||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                          "Some text line"
.

The > field-length indicator ensures that the text will be right-justified within the field, but the field as a whole occurs exactly where you show it occurring. There is no built-in way to say "float this field to the right-hand side of the page, however wide it is." You have to specify where it goes relative to the left margin. The truly desperate can generate their own format on the fly, based on the current number of columns (not supplied), and then eval it:

$format  = "format STDOUT = \n"
         . '^' . '<' x $cols . "\n"
         . '$entry' . "\n"
         . "\t^" . "<" x ($cols-8) . "~~\n"
         . '$entry' . "\n"
         . ".\n";
print $format if $Debugging;
eval $format;
die $@ if $@;
The most important line there is probably the print. What the print would print out looks something like this:
format STDOUT =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$entry
    ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
$entry
.

Here's a little program that behaves like the fmt(1) Unix utility:

format =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
$_

.

$/ = "";
while (<>) {
    s/\s*\n\s*/ /g;
    write;
}
Previous | Home | Next
6.5. Subroutine Attributes | Book Index | 7.2. Footers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


7.2. Footers

While $^ ($FORMAT_TOP_NAME) contains the name of the current header format, there is no corresponding mechanism to do the same thing automatically for a footer. Not knowing how big a format is going to be until you evaluate it is one of the major problems. It's on the TODO list.[2]

[2]That doesn't guarantee we'll ever do it, of course. Formats are somewhat passé in this age of WWW, Unicode, XML, XSLT, and whatever the next few things after that are.

Here's one strategy: if you have a fixed-size footer, you can get footers by checking $- ($FORMAT_LINES_LEFT) before each write and then print the footer yourself if necessary.

Here's another strategy; open a pipe to yourself, using open(MESELF, "|-") (see the open entry in Chapter 29, "Functions") and always write to MESELF instead of STDOUT. Have your child process postprocess its STDIN to rearrange headers and footers however you like. Not very convenient, but doable.

7.2.1. Accessing Formatting Internals

For low-level access to the internal formatting mechanism, you may use the built-in formline operator and access $^A (the $ACCUMULATOR variable) directly. (Formats essentially compile into a sequence of calls to formline.) For example:

$str = formline <<'END', 1,2,3;
@<<<  @|||  @>>>
END

print "Wow, I just stored `$^A' in the accumulator!\n";
Or to create an swrite subroutine that is to write as sprintf is to printf, do this:
use Carp;
sub swrite {
    croak "usage: swrite PICTURE ARGS" unless @_;
    my $format = shift;
    $^A = "";
    formline($format, @_);
    return $^A;
}

$string = swrite(<<'END', 1, 2, 3);
Check me out
@<<<  @|||  @>>>
END
print $string;

If you were using the FileHandle module, you could use formline as follows to wrap a block of text at column 72:

use FileHandle;
STDOUT->formline("^" . ("<" x 72) . "~~\n", $long_text);

Previous | Home | Next
7.1. Format Variables | Book Index | 8. References
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 8. References

Contents:

What Is a Reference?
Creating References
Using Hard References
Symbolic References
Braces, Brackets, and Quoting

For both practical and philosophical reasons, Perl has always been biased in favor of flat, linear data structures. And for many problems, this is just what you want.

Suppose you wanted to build a simple table (two-dimensional array) showing vital statistics--age, eye color, and weight--for a group of people. You could do this by first creating an array for each individual:

@john = (47, "brown", 186);
@mary = (23, "hazel", 128);
@bill = (35, "blue",  157);
You could then construct a single, additional array consisting of the names of the other arrays:
@vitals = ('john', 'mary', 'bill');
To change John's eyes to "red" after a night on the town, we want a way to change the contents of the @john array given only the simple string "john". This is the basic problem of indirection, which various languages solve in various ways. In C, the most common form of indirection is the pointer, which lets one variable hold the memory address of another variable. In Perl, the most common form of indirection is the reference.

8.1. What Is a Reference?

In our example, $vitals[0] has the value "john". That is, it contains a string that happens to be the name of another (global) variable. We say that the first variable refers to the second, and this sort of reference is called a symbolic reference, since Perl has to look up @john in a symbol table to find it. (You might think of symbolic references as analogous to symbolic links in the filesystem.) We'll talk about symbolic references later in this chapter.

The other kind of reference is a hard reference, and this is what most Perl programmers use to accomplish their indirections (if not their indiscretions). We call them hard references not because they're difficult, but because they're real and solid. If you like, think of hard references as real references and symbolic references as fake references. It's like the difference between true friendship and mere name-dropping. When we don't specify which type of reference we mean, it's a hard reference. Figure 8-1 depicts a variable named $bar referring to the contents of a scalar named $foo which has the value "bot".

Figure 8.1. A hard reference and a symbolic reference

Unlike a symbolic reference, a real reference refers not to the name of another variable (which is just a container for a value) but to an actual value itself, some internal glob of data. There's no good word for that thing, but when we have to, we'll call it a referent. Suppose, for example, that you create a hard reference to a lexically scoped array named @array. This hard reference, and the referent it refers to, will continue to exist even after @array goes out of scope. A referent is only destroyed when all the references to it are eliminated.

A referent doesn't really have a name of its own, apart from the references to it. To put it another way, every Perl variable name lives in some kind of symbol table, holding one hard reference to its underlying (otherwise nameless) referent. That referent might be simple, like a number or string, or complex, like an array or hash. Either way, there's still exactly one reference from the variable to its value. You might create additional hard references to the same referent, but if so, the variable doesn't know (or care) about them.[1]

[1] If you're curious, you can determine the underlying refcount with the Devel::Peek module, bundled with Perl.

A symbolic reference is just a string that happens to name something in a package symbol table. It's not so much a distinct type as it is something you do with a string. But a hard reference is a different beast entirely. It is the third of the three kinds of fundamental scalar data types, the other two being strings and numbers. A hard reference doesn't know something's name just to refer to it, and it's actually completely normal for there to be no name to use in the first place. Such totally nameless referents are called anonymous; we discuss them in "Anonymous Data" below.

To reference a value, in the terminology of this chapter, is to create a hard reference to it. (There's a special operator for this creative act.) The reference so created is simply a scalar, which behaves in all familiar contexts just like any other scalar. To dereference this scalar means to use the reference to get at the referent. Both referencing and dereferencing occur only when you invoke certain explicit mechanisms; implicit referencing or dereferencing never occurs in Perl. Well, almost never.

A function call can use implicit pass-by-reference semantics--if it has a prototype declaring it that way. If so, the caller of the function doesn't explicitly pass a reference, although you still have to dereference it explicitly within the function. See the section Section 8.4, "Prototypes" in Chapter 6, "Subroutines". And to be perfectly honest, there's also some behind-the-scenes dereferencing happening when you use certain kinds of filehandles, but that's for backward compatibility and is transparent to the casual user. Finally, two built-in functions, bless and lock, each take a reference for their argument but implicitly dereference it to work their magic on what lies behind. But those confessions aside, the basic principle still holds that Perl isn't interested in muddling your levels of indirection.

A reference can point to any data structure. Since references are scalars, you can store them in arrays and hashes, and thus build arrays of arrays, arrays of hashes, hashes of arrays, arrays of hashes and functions, and so on. There are examples of these in Chapter 9, "Data Structures".

Keep in mind, though, that Perl arrays and hashes are internally one-dimensional. That is, their elements can hold only scalar values (strings, numbers, and references). When we use a phrase like "array of arrays", we really mean "array of references to arrays", just as when we say "hash of functions" we really mean "hash of references to subroutines". But since references are the only way to implement such structures in Perl, it follows that the shorter, less accurate phrase is not so inaccurate as to be false, and therefore should not be totally despised, unless you're into that sort of thing.

Previous | Home | Next
7.2. Footers | Book Index | 8.2. Creating References
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.2. Creating References

There are several ways to create references, most of which we will describe before explaining how to use (dereference) the resulting references.

8.2.1. The Backslash Operator

You can create a reference to any named variable or subroutine with a backslash. (You may also use it on an anonymous scalar value like 7 or "camel", although you won't often need to.) This operator works like the & (address-of) operator in C--at least at first glance.

Here are some examples:

$scalarref = \$foo;
$constref  = \186_282.42;
$arrayref  = \@ARGV;
$hashref   = \%ENV;
$coderef   = \&handler;
$globref   = \*STDOUT;
The backslash operator can do more than produce a single reference. It will generate a whole list of references if applied to a list. See the section Section 8.3.6, "Other Tricks You Can Do with Hard References" for details.

8.2.2. Anonymous Data

In the examples just shown, the backslash operator merely makes a duplicate of a reference that is already held in a variable name--with one exception. The 186_282.42 isn't referenced by a named variable--it's just a value. It's one of those anonymous referents we mentioned earlier. Anonymous referents are accessed only through references. This one happens to be a number, but you can create anonymous arrays, hashes, and subroutines as well.

8.2.2.1. The anonymous array composer

You can create a reference to an anonymous array with square brackets:

$arrayref = [1, 2, ['a', 'b', 'c', 'd']];
Here we've composed an anonymous array of three elements, whose final element is a reference to an anonymous array of four elements (depicted in Figure 8-2). (The multidimensional syntax described later can be used to access this. For example, $arrayref->[2][1] would have the value "b".)

Figure 8.2. A reference to an array, whose third element is itself an array reference

We now have one way to represent the table at the beginning of the chapter:

$table = [ [ "john", 47, "brown", 186],
           [ "mary", 23, "hazel", 128],
           [ "bill", 35, "blue",  157] ];
Square brackets work like this only where the Perl parser is expecting a term in an expression. They should not be confused with the brackets in an expression like $array[6]--although the mnemonic association with arrays is intentional. Inside a quoted string, square brackets don't compose anonymous arrays; instead, they become literal characters in the string. (Square brackets do still work for subscripting in strings, or you wouldn't be able to print string values like "VAL=$array[6]\n". And to be totally honest, you can in fact sneak anonymous array composers into strings, but only when embedded in a larger expression that is being interpolated. We'll talk about this cool feature later in the chapter because it involves dereferencing as well as referencing.)

8.2.2.2. The anonymous hash composer

You can create a reference to an anonymous hash with braces:

$hashref = {
    'Adam'   => 'Eve',
    'Clyde'  => $bonnie,
    'Antony' => 'Cleo' . 'patra',
};
For the values (but not the keys) of the hash, you can freely mix other anonymous array, hash, and subroutine composers to produce as complicated a structure as you like.

We now have another way to represent the table at the beginning of the chapter:

$table = {
            "john" => [ 47, "brown", 186 ],
            "mary" => [ 23, "hazel", 128 ],
            "bill" => [ 35, "blue",  157 ],
};
That's a hash of arrays. Choosing the best data structure is a tricky business, and the next chapter is devoted to it. But as a teaser, we could even use a hash of hashes for our table:
$table = {
           "john" => { age    => 47,
                       eyes   => "brown",
                       weight => 186,
                     },
           "mary" => { age    => 23,
                       eyes   => "hazel",
                       weight => 128,
                     },
           "bill" => { age    => 35,
                       eyes   => "blue",
                       weight => 157,
                     },
 };
As with square brackets, braces work like this only where the Perl parser is expecting a term in an expression. They should not be confused with the braces in an expression like $hash{key}--although the mnemonic association with hashes is (again) intentional. The same caveats apply to the use of braces within strings.

There is one additional caveat which didn't apply to square brackets. Since braces are also used for several other things (including blocks), you may occasionally have to disambiguate braces at the beginning of a statement by putting a + or a return in front, so that Perl realizes the opening brace isn't starting a block. For example, if you want a function to make a new hash and return a reference to it, you have these options:

sub hashem {        { @_ } }   # Silently WRONG -- returns @_.
sub hashem {       +{ @_ } }   # Ok.
sub hashem { return { @_ } }   # Ok.

8.2.2.3. The anonymous subroutine composer

You can create a reference to an anonymous subroutine by using sub without a subroutine name:

$coderef = sub { print "Boink!\n" };  # Now &$coderef prints "Boink!"
Note the presence of the semicolon, required here to terminate the expression. (It isn't required after the more common usage of sub NAME{} that declares and defines a named subroutine.) A nameless sub {} is not so much a declaration as it is an operator--like do {} or eval {}--except that the code inside isn't executed immediately. Instead, it just generates a reference to the code, which in our example is stored in $coderef. However, no matter how many times you execute the line shown above, $coderef will still refer to the same anonymous subroutine.[2]

[2]But even though there's only one anonymous subroutine, there may be several copies of the lexical variables in use by the subroutine, depending on when the subroutine reference was generated. These are discussed later in the section Section 8.3.7, "Closures".

8.2.3. Object Constructors

Subroutines can also return references. That may sound trite, but sometimes you are supposed to use a subroutine to create a reference rather than creating the reference yourself. In particular, special subroutines called constructors create and return references to objects. An object is simply a special kind of reference that happens to know which class it's associated with, and constructors know how to create that association. They do so by taking an ordinary referent and turning it into an object with the bless operator, so we can speak of an object as a blessed reference. There's nothing religious going on here; since a class acts as a user-defined type, blessing a referent simply makes it a user-defined type in addition to a built-in one. Constructors are often named new--especially by C++ programmers--but they can be named anything in Perl.

Constructors can be called in any of these ways:

$objref = Doggie::->new(Tail => 'short', Ears => 'long');  #1
$objref = new Doggie:: Tail => 'short', Ears => 'long';    #2
$objref = Doggie->new(Tail => 'short', Ears => 'long');    #3
$objref = new Doggie Tail => 'short', Ears => 'long';      #4
The first and second invocations are the same. They both call a function named new that is supplied by the Doggie module. The third and fourth invocations are the same as the first two, but are slightly more ambiguous: the parser will get confused if you define your own subroutine named Doggie. (Which is why people typically stick with lowercase names for subroutines and uppercase for modules.) The fourth invocation can also get confused if you've defined your own new subroutine and don't happen to have done either a require or a use of the Doggie module, either of which has the effect of declaring the module. Always declare your modules if you want to use #4. (And watch out for stray Doggie subroutines.)

See Chapter 12, "Objects" for a discussion of Perl objects.

8.2.4. Handle References

References to filehandles or directory handles can be created by referencing the typeglob of the same name:

splutter(\*STDOUT);

sub splutter {
    my $fh = shift;
    print $fh "her um well a hmmm\n";
}

$rec = get_rec(\*STDIN);
sub get_rec {
    my $fh = shift;
    return scalar <$fh>;
}
If you're passing around filehandles, you can also use the bare typeglob to do so: in the example above, you could have used *STDOUT or *STDIN instead of \*STDOUT and \*STDIN.

Although you can usually use typeglob and references to typeglobs interchangeably, there are a few places where you can't. Simple typeglobs can't be blessed into objectdom, and typeglob references can't be passed back out of the scope of a localized typeglob.

When generating new filehandles, older code would often do something like this to open a list of files:

for $file (@names) {
    local *FH;
    open(*FH, $file) || next;
    $handle{$file} = *FH;
}

That still works, but now it's just as easy to let an undefined variable autovivify an anonymous typeglob:

for $file (@names) {
    my $fh;
    open($fh, $file) || next;
    $handle{$file} = $fh;
}
With indirect filehandles, it doesn't matter whether you use use typeglobs, references to typeglobs, or one of the more exotic I/O objects. You just use a scalar that--one way or another--gets interpreted as a filehandle. For most purposes, you can use either a typeglob or a typeglob reference almost indiscriminately. As we admitted earlier, there is some implicit dereferencing magic going on here.

8.2.5. Symbol Table References

In unusual circumstances, you might not know what type of reference you need when your program is written. A reference can be created by using a special syntax, affectionately known as the *foo{THING} syntax. *foo{THING} returns a reference to the THING slot in *foo, which is the symbol table entry holding the values of $foo, @foo, %foo, and friends.

$scalarref = *foo{SCALAR};   # Same as \$foo
$arrayref  = *ARGV{ARRAY};   # Same as \@ARGV
$hashref   = *ENV{HASH};     # Same as \%ENV
$coderef   = *handler{CODE}; # Same as \&handler
$globref   = *foo{GLOB};     # Same as \*foo
$ioref     = *STDIN{IO};     # Er...
All of these are self-explanatory except for *STDIN{IO}. It yields the actual internal IO::Handle object that the typeglob contains, that is, the part of the typeglob that the various I/O functions are actually interested in. For compatibility with previous versions of Perl, *foo{FILEHANDLE} is a synonym for the hipper *foo{IO} notation.

In theory, you can use a *HANDLE{IO} anywhere you'd use a *HANDLE or a \*HANDLE, such as for passing handles into or out of subroutines, or storing them in larger data structures. (In practice, there are still some wrinkles to be ironed out.) The advantage of them is that they access only the real I/O object you want, not the whole typeglob, so you run no risk of clobbering more than you want to through a typeglob assignment (although if you always assign to a scalar variable instead of to a typeglob, you'll be okay). One disadvantage is that there's no way to autovivify one as of yet.[3]

splutter(*STDOUT);
splutter(*STDOUT{IO});

sub splutter {
    my $fh = shift;
    print $fh "her um well a hmmm\n";
}
Both invocations of splutter() print "her um well a hmmm".

[3] Currently, open my $fh autovivifies a typeglob instead of an IO::Handle object, but someday we may fix that, so you shouldn't rely on the typeglobbedess of what open currently autovivifies.

The *foo{THING} thing returns undef if that particular THING hasn't been seen by the compiler yet, except when THING is SCALAR. It so happens that *foo{SCALAR} returns a reference to an anonymous scalar even if $foo hasn't been seen yet. (Perl always adds a scalar to any typeglob as an optimization to save a bit of code elsewhere. But don't depend on it to stay that way in future releases.)

8.2.6. Implicit Creation of References

A final method for creating references is not really a method at all. References of an appropriate type simply spring into existence if you dereference them in an lvalue context that assumes they exist. This is extremely useful, and is also What You Expect. This topic is covered later in this chapter, where we'll discuss how to dereference all of the references we've created so far.

Previous | Home | Next
8.1. What Is a Reference? | Book Index | 8.3. Using Hard References
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.3. Using Hard References

Just as there are numerous ways to create references, there are also several ways to use, or dereference, a reference. There is just one overriding principle: Perl does no implicit referencing or dereferencing.[4] When a scalar is holding a reference, it always behaves like a simple scalar. It doesn't magically start being an array or hash or subroutine; you have to tell it explicitly to do so, by dereferencing it.

[4] We already confessed that this was a small fib. We're not about to do so again.

8.3.1. Using a Variable as a Variable Name

When you encounter a scalar like $foo, you should be thinking "the scalar value of foo." That is, there's a foo entry in the symbol table, and the $ funny character is a way of looking at whatever scalar value might be inside. If what's inside is a reference, you can look inside that (dereferencing $foo) by prepending another funny character. Or looking at it the other way around, you can replace the literal foo in $foo with a scalar variable that points to the actual referent. This is true of any variable type, so not only is $$foo the scalar value of whatever $foo refers to, but @$bar is the array value of whatever $bar refers to, %$glarch is the hash value of whatever $glarch refers to, and so on. The upshot is that you can put an extra funny character on the front of any simple scalar variable to dereference it:

$foo         = "three humps";
$scalarref   = \$foo;         # $scalarref is now a reference to $foo
$camel_model = $$scalarref;   # $camel_model is now "three humps"
Here are some other dereferences:
$bar = $$scalarref;

push(@$arrayref, $filename);
$$arrayref[0] = "January";            # Set the first element of @$arrayref
@$arrayref[4..6] = qw/May June July/; # Set several elements of @$arrayref

%$hashref = (KEY => "RING", BIRD => "SING");  # Initialize whole hash
$$hashref{KEY} = "VALUE";                     # Set one key/value pair
@$hashref{"KEY1","KEY2"} = ("VAL1","VAL2");   # Set two more pairs

&$coderef(1,2,3);

print $handleref "output\n";

This form of dereferencing can only make use of a simple scalar variable (one without a subscript). That is, dereferencing happens before (or binds tighter than) any array or hash lookups. Let's use some braces to clarify what we mean: an expression like $$arrayref[0] is equivalent to ${$arrayref}[0] and means the first element of the array referred to by $arrayref. That is not at all the same as ${$arrayref[0]}, which is dereferencing the first element of the (probably nonexistent) array named @arrayref. Likewise, $$hashref{KEY} is the same as ${$hashref}{KEY}, and has nothing to do with ${$hashref{KEY}}, which would be dereferencing an entry in the (probably nonexistent) hash named %hashref. You will be miserable until you understand this.

You can achieve multiple levels of referencing and dereferencing by concatenating the appropriate funny characters. The following prints "howdy":

$refrefref = \\\"howdy";
print $$$$refrefref;
You can think of the dollar signs as operating right to left. But the beginning of the chain must still be a simple, unsubscripted scalar variable. There is, however, a way to get fancier, which we already sneakily used earlier, and which we'll explain in the next section.

8.3.2. Using a BLOCK as a Variable Name

Not only can you dereference a simple variable name, you can also dereference the contents of a BLOCK. Anywhere you'd put an alphanumeric identifier as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type. In other words, the earlier examples could all be disambiguated like this:

$bar = ${$scalarref};
push(@{$arrayref}, $filename);
${$arrayref}[0] = "January";
@{$arrayref}[4..6] = qw/May June July/;
${$hashref}{"KEY"} = "VALUE";
@{$hashref}{"KEY1","KEY2"} = ("VAL1","VAL2");
&{$coderef}(1,2,3);
not to mention:
$refrefref = \\\"howdy";
print ${${${$refrefref}}};
Admittedly, it's silly to use the braces in these simple cases, but the BLOCK can contain any arbitrary expression. In particular, it can contain subscripted expressions. In the following example, $dispatch{$index} is assumed to contain a reference to a subroutine (sometimes called a "coderef"). The example invokes the subroutine with three arguments.
&{ $dispatch{$index} }(1, 2, 3);
Here, the BLOCK is necessary. Without that outer pair of braces, Perl would have treated $dispatch as the coderef instead of $dispatch{$index}.

8.3.3. Using the Arrow Operator

For references to arrays, hashes, or subroutines, a third method of dereferencing involves the use of the -> infix operator. This form of syntactic sugar that makes it easier to get at individual array or hash elements, or to call a subroutine indirectly.

The type of the dereference is determined by the right operand, that is, by what follows directly after the arrow. If the next thing after the arrow is a bracket or brace, the left operand is treated as a reference to an array or a hash, respectively, to be subscripted by the expression on the right. If the next thing is a left parenthesis, the left operand is treated as a reference to a subroutine, to be called with whatever parameters you supply in the parentheses on the right.

Each of these next trios is equivalent, corresponding to the three notations we've introduced. (We've inserted some spaces to line up equivalent elements.)

$  $arrayref  [2] = "Dorian";         #1
${ $arrayref }[2] = "Dorian";         #2
   $arrayref->[2] = "Dorian";         #3

$  $hashref  {KEY} = "F#major";       #1
${ $hashref }{KEY} = "F#major";       #2
   $hashref->{KEY} = "F#major";       #3

&  $coderef  (Presto => 192);         #1
&{ $coderef }(Presto => 192);         #2
   $coderef->(Presto => 192);         #3
You can see that the initial funny character is missing from the third notation in each trio. The funny character is guessed at by Perl, which is why it can't be used to dereference complete arrays, complete hashes, or slices of either. As long as you stick with scalar values, though, you can use any expression to the left of the ->, including another dereference, because multiple arrow operators associate left to right:
print $array[3]->{"English"}->[0];
You can deduce from this expression that the fourth element of @array is intended to be a hash reference, and the value of the "English" entry in that hash is intended to be an array reference.

Note that $array[3] and $array->[3] are not the same. The first is talking about the fourth element of @array, while the second one is talking about the fourth element of the (possibly anonymous) array whose reference is contained in $array.

Suppose now that $array[3] is undefined. The following statement is still legal:

$array[3]->{"English"}->[0] = "January";
This is one of those cases mentioned earlier in which references spring into existence (or "autovivify") when used as an lvalue (that is, when a value is being assigned to it). If $array[3] was undefined, it's automatically defined as a hash reference so that we can set a value for $array[3]->{"English"} in it. Once that's done, $array[3]->{"English"} is automatically defined as an array reference so that we can assign something to the first element in that array. Note that rvalues are a little different: print $array[3]->{"English"}->[0] only defines $array[3] and $array[3]->{"English"}, not $array[3]->{"English"}->[0], since the final element is not an lvalue. (The fact that it defines the first two at all in an rvalue context could be considered a bug. We may fix that someday.)

The arrow is optional between brackets or braces, or between a closing bracket or brace and a parenthesis for an indirect function call. So you can shrink the previous code down to:

$dispatch{$index}(1, 2, 3);
$array[3]{"English"}[0] = "January";
In the case of ordinary arrays, this gives you multidimensional arrays that are just like C's array:
$answer[$x][$y][$z] += 42;
Well, okay, not entirely like C's arrays. For one thing, C doesn't know how to grow its arrays on demand, while Perl does. Also, some constructs that are similar in the two languages parse differently. In Perl, the following two statements do the same thing:
$listref->[2][2] = "hello";    # Pretty clear
$$listref[2][2]  = "hello";    # A bit confusing
This second of these statements may disconcert the C programmer, who is accustomed to using *a[i] to mean "what's pointed to by the ith element of a". But in Perl, the five characters ($ @ * % &) effectively bind more tightly than braces or brackets.[5] Therefore, it is $$listref and not $listref[2] that is taken to be a reference to an array. If you want the C behavior, either you have to write ${$listref[2]} to force the $listref[2] to get evaluated before the leading $ dereferencer, or you have to use the -> notation:
$listref[2]->[$greeting] = "hello";

[5] But not because of operator precedence. The funny characters in Perl are not operators in that sense. Perl's grammar simply prohibits anything more complicated than a simple variable or block from following the initial funny character, for various funny reasons.

8.3.4. Using Object Methods

If a reference happens to be a reference to an object, then the class that defines that object probably provides methods to access the innards of the object, and you should generally stick to those methods if you're merely using the class (as opposed to implementing it). In other words, be nice, and don't treat an object like a regular reference, even though Perl lets you when you really need to. Perl does not enforce encapsulation. We are not totalitarians here. We do expect some basic civility, however.

In return for this civility, you get complete orthogonality between objects and data structures. Any data structure can behave as an object when you want it to. Or not, when you don't.

8.3.5. Pseudohashes

A pseudohash is any reference to an array whose first element is a reference to a hash. You can treat the pseudohash reference as either an array reference (as you would expect) or a hash reference (as you might not expect). Here's an example of a pseudohash:

$john = [ {age => 1, eyes => 2, weight => 3}, 47, "brown", 186 ];
The underlying hash in $john->[0] defines the names ("age", "eyes", "weight") of the array elements that follow (47, "brown", 186). Now you can access an element with both hash and array notations:
$john->{weight}             # Treats $john as a hashref
$john->[3]                  # Treats $john as an arrayref
Pseudohash magic is not deep; it only knows one "trick": how to turn a hash dereference into an array dereference. When adding another element to a pseudohash, you have to explicitly tell the underlying mapping hash where the element will reside before you can use the hash notation:
$john->[0]{height} = 4;     # height is to be element 4
$john->{height} = "tall";   # Or $john->[4] = "tall"
Perl raises an exception if you try to delete a key from a pseudohash, although you can always delete keys from the mapping hash. Perl also raises an exception if you try to access a nonexistent key, where "existence" means presence in the mapping hash:
delete $john->[0]{height};  # Deletes from the underlying hash only
$john->{height};            # This now raises an exception
$john->[4];                 # Still prints "tall"
Don't try to splice the array unless you know what you're doing. If the array elements move around, the mapping hash values will still refer to the old element positions, unless you change those explicitly, too. Pseudohash magic is not deep.

To avoid inconsistencies, you can use the fields::phash function provided by the use fields pragma to create a pseudohash:

use fields;
$ph = fields::phash(age => 47, eyes => "brown", weight => 186);
print $ph->{age};
There are two ways to check for the existence of a key in a pseudohash. The first is to use exists, which checks whether the given field has ever been set. It acts this way to match the behavior of a real hash. For instance:
use fields;
$ph= fields::phash([qw(age eyes brown)], [47]);
$ph->{eyes} = undef;

print exists $ph->{age};     # True, 'age' was set in declaration.
print exists $ph->{weight};  # False, 'weight' has not been used.
print exists $ph->{eyes};    # True, your 'eyes' have been touched.
The second way is to use exists on the mapping hash sitting in the first array element. This checks whether the given key is a valid field for that pseudohash:
print exists $ph->[0]{age};   # True, 'age' is a valid field
print exists $ph->[0]{name};  # False, 'name' can't be used
Unlike what happens in a real hash, calling delete on a pseudohash element deletes only the array value corresponding to the key, not the real key in the mapping hash. To delete the key, you have to explicitly delete it from the mapping hash. Once you do that, you may no longer use that key name as a pseudohash subscript:
print delete $ph->{age};     # Removes and returns $ph->[1], 47
print exists $ph->{age};     # Now false
print exists $ph->[0]{age};  # True, 'age' key still usable
print delete $ph->[0]{age};  # Now 'age' key is gone
print $ph->{age};            # Run-time exception
You've probably begun to wonder what could possibly have motivated this masquerade of arrays prancing about in hashes' clothing. Arrays provide faster lookups and more efficient storage, while hashes offer the convenience of naming (instead of numbering) your data; pseudohashes provide the best of both worlds. But it's not until you consider Perl's compilation phase that the greatest benefit becomes apparent. With the help of a pragma or two, the compiler can verify proper access to valid fields, so you can find out about nonexistent subscripts (or spelling errors) before your program starts to run.

Pseudohashes' properties of speed, efficiency, and compile-time access checking (you might even think of it as type safety) are especially handy for creating efficient and robust class modules. See the discussion of the use fields pragma in Chapter 12, "Objects" and Chapter 31, "Pragmatic Modules".

Pseudohashes are a new and relatively experimental feature; as such, the underlying implementation may well change in the future. To protect yourself from such changes, always go through the fields module's documented interface via its phash and new functions.

8.3.6. Other Tricks You Can Do with Hard References

As mentioned earlier, the backslash operator is usually used on a single referent to generate a single reference, but it doesn't have to be. When used on a list of referents, it produces a list of corresponding references. The second line of the following example does the same thing as the first line, since the backslash is automatically distributed throughout the whole list.

@reflist = (\$s, \@a, \%h, \&f);     # List of four references
@reflist = \($s,  @a   %h,  &f);     # Same thing
If a parenthesized list contains exactly one array or hash, then all of its values are interpolated and references to each returned:
@reflist = \(@x);                    # Interpolate array, then get refs
@reflist = map { \$_ } @x;           # Same thing
This also occurs when there are internal parentheses:
@reflist = \(@x, (@y));              # But only single aggregates expand
@reflist = (\@x, map { \$_ } @y);    # Same thing
If you try this with a hash, the result will contain references to the values (as you'd expect), but references to copies of the keys (as you might not expect).

Since array and hash slices are really just lists, you can backslash a slice of either of these to get a list of references. Each of the next three lines does exactly the same thing:

@envrefs = \@ENV{'HOME', 'TERM'};         # Backslashing a slice
@envrefs = \( $ENV{HOME},  $ENV{TERM} );  # Backslashing a list
@envrefs = ( \$ENV{HOME}, \$ENV{TERM} );  # A list of two references
Since functions can return lists, you can apply a backslash to them. If you have more than one function to call, first interpolate each function's return values into a larger list and then backslash the whole thing:
@reflist = \fx();
@reflist = map { \$_ } fx();                # Same thing

@reflist = \( fx(), fy(), fz() );
@reflist = ( \fx(), \fy(), \fz() );         # Same thing
@reflist = map { \$_ } fx(), fy(), fz();    # Same thing
The backslash operator always supplies a list context to its operand, so those functions are all called in list context. If the backslash is itself in scalar context, you'll end up with a reference to the last value of the list returned by the function:
@reflist = \localtime();      # Ref to each of nine time elements
$lastref = \localtime();      # Ref to whether it's daylight savings time
In this regard, the backslash behaves like the named Perl list operators, such as print, reverse, and sort, which always supply a list context on their right no matter what might be happening on their left. As with named list operators, use an explicit scalar to force what follows into scalar context:
$dateref = \scalar localtime();    # \"Sat Jul 16 11:42:18 2000"

You can use the ref operator to determine what a reference is pointing to. Think of ref as a "typeof" operator that returns true if its argument is a reference and false otherwise. The value returned depends on the type of thing referenced. Built-in types include SCALAR, ARRAY, HASH, CODE, GLOB, REF, LVALUE, IO, IO::Handle, and Regexp. Here, we use it to check subroutine arguments:

sub sum {
    my $arrayref = shift;
    warn "Not an array reference" if ref($arrayref) ne "ARRAY";
    return eval join("+", @$arrayref);
}

If you use a hard reference in a string context, it'll be converted to a string containing both the type and the address: SCALAR(0x1fc0e). (The reverse conversion cannot be done, since reference count information is lost during stringification--and also because it would be dangerous to let programs access a memory address named by an arbitrary string.)

You can use the bless operator to associate a referent with a package functioning as an object class. When you do this, ref returns the class name instead of the internal type. An object reference used in a string context returns a string with the external and internal types, and the address in memory: MyType=HASH(0x20d10) or IO::Handle=IO(0x186904). See Chapter 12, "Objects" for more details about objects.

Since the way in which you dereference something always indicates what sort of referent you're looking for, a typeglob can be used the same way a reference can, despite the fact that a typeglob contains multiple referents of various types. So ${*main::foo} and ${\$main::foo} both access the same scalar variable, although the latter is more efficient.

Here's a trick for interpolating the return value of a subroutine call into a string:

print "My sub returned @{[ mysub(1,2,3) ]} that time.\n";
It works like this. At compile time, when the @{...} is seen within the double-quoted string, it's parsed as a block that returns a reference. Within the block, there are square brackets that create a reference to an anonymous array from whatever is in the brackets. So at run time, mysub(1,2,3) is called in list context, and the results are loaded into an anonymous array, a reference to which is then returned within the block. That array reference is then immediately dereferenced by the surrounding @{...}, and the array value is interpolated into the double-quoted string just as an ordinary array would be. This chicanery is also useful for arbitrary expressions, such as:
print "We need @{ [$n + 5] } widgets!\n";
Be careful though: square brackets supply a list context to their expression. In this case it doesn't matter, although the earlier call to mysub might care. When it does matter, use an explicit scalar to force the context:
print "mysub returns @{ [scalar mysub(1,2,3)] } now.\n";

8.3.7. Closures

Earlier we talked about creating anonymous subroutines with a nameless sub {}. You can think of those subroutines as defined at run time, which means that they have a time of generation as well as a location of definition. Some variables might be in scope when the subroutine is created, and different variables might be in scope when the subroutine is called.

Forgetting about subroutines for a moment, consider a reference that refers to a lexical variable:

{
    my $critter = "camel";
    $critterref = \$critter;
}
The value of $$critterref will remain "camel" even though $critter disappears after the closing curly brace. But $critterref could just as well have referred to a subroutine that refers to $critter:
{
    my $critter = "camel";
    $critterref = sub { return $critter };
}
This is a closure, which is a notion out of the functional programming world of LISP and Scheme.[6] It means that when you define an anonymous function in a particular lexical scope at a particular moment, it pretends to run in that scope even when later called from outside that scope. (A purist would say it doesn't have to pretend--it actually does run in that scope.)

[6] In this context, the word "functional" should not be construed as an antonym of "dysfunctional".

In other words, you are guaranteed to get the same copy of a lexical variable each time, even if other instances of that lexical variable have been created before or since for other instances of that closure. This gives you a way to set values used in a subroutine when you define it, not just when you call it.

You can also think of closures as a way to write a subroutine template without using eval. The lexical variables act as parameters for filling in the template, which is useful for setting up little bits of code to run later. These are commonly called callbacks in event-based programming, where you associate a bit of code with a keypress, mouse click, window exposure, and so on. When used as callbacks, closures do exactly what you expect, even if you don't know the first thing about functional programming. (Note that this closure business only applies to my variables. Global variables work as they've always worked, since they're neither created nor destroyed the way lexical variables are.)

Another use for closures is within function generators; that is, functions that create and return brand new functions. Here's an example of a function generator implemented with closures:

sub make_saying  {
    my $salute = shift;
    my $newfunc = sub {
        my $target = shift;
        print "$salute, $target!\n";
    };
    return $newfunc;            # Return a closure
}

$f = make_saying("Howdy");      # Create a closure
$g = make_saying("Greetings");  # Create another closure

# Time passes...

$f->("world");
$g->("earthlings");
This prints:
Howdy, world!
Greetings, earthlings!
Note in particular how $salute continues to refer to the actual value passed into make_saying, despite the fact that the my $salute has gone out of scope by the time the anonymous subroutine runs. That's what closures are all about. Since $f and $g hold references to functions that, when called, still need access to the distinct versions of $salute, those versions automatically stick around. If you now overwrite $f, its version of $salute would automatically disappear. (Perl only cleans up when you're not looking.)

Perl doesn't provide references to object methods (described in Chapter 12, "Objects") but you can get a similar effect using a closure. Suppose you want a reference not just to the subroutine the method represents, but one which, when invoked, would call that method on a particular object. You can conveniently remember both the object and the method as lexical variables bound up inside a closure:

sub get_method_ref {
    my ($self, $methodname) = @_;
    my $methref = sub {
        # the @_ below is not the same as the one above!
        return $self->$methodname(@_);
    };
    return $methref;
}

my $dog = new Doggie::
            Name => "Lucky",
            Legs => 3,
            Tail => "clipped";

our $wagger = get_method_ref($dog, 'wag');
$wagger->("tail");        # Calls $dog->wag('tail').
Not only can you get Lucky to wag what's left of his tail now, even once the lexical $dog variable has gone out of scope and Lucky is nowhere to be seen, the global $wagger variable can still get him to wag his tail, wherever he is.

8.3.7.1. Closures as function templates

Using a closure as a function template allows you to generate many functions that act similarly. Suppose you want a suite of functions that generate HTML font changes for various colors:

print "Be ", red("careful"), "with that ", green("light"), "!!!";
The red and green functions would be very similar. We'd like to name our functions, but closures don't have names since they're just anonymous subroutines with an attitude. To get around that, we'll perform the cute trick of naming our anonymous subroutines. You can bind a coderef to an existing name by assigning it to a typeglob of the name of the function you want. (See the section Section 8.1, "Symbol Tables" in Chapter 10, "Packages". In this case, we'll bind it to two different names, one uppercase and one lowercase:
@colors = qw(red blue green yellow orange purple violet);
for my $name (@colors) {
    no strict 'refs';       # Allow symbolic references
    *$name = *{uc $name} = sub { "<FONT COLOR='$name'7gt;@_</FONT>" };
}
Now you can call functions named red, RED, blue, BLUE, and so on, and the appropriate closure will be invoked. This technique reduces compile time and conserves memory, and is less error-prone as well, since syntax checks happen during compilation. It's critical that any variables in the anonymous subroutine be lexicals in order to create a closure. That's the reason for the my above.

This is one of the few places where giving a prototype to a closure makes sense. If you wanted to impose scalar context on the arguments of these functions (probably not a wise idea for this example), you could have written it this way instead:

*$name = sub ($) { "<FONT COLOR='$name'>$_[0]</FONT>" };
That's almost good enough. However, since prototype checking happens during compile time, the run-time assignment above happens too late to be of much use. You could fix this by putting the whole loop of assignments within a BEGIN block, forcing it to occur during compilation. (More likely, you'd put it out in a module that you use at compile time.) Then the prototypes will be visible during the rest of the compilation.

8.3.7.2. Nested subroutines

If you are accustomed (from other programming languages) to using subroutines nested within other subroutines, each with their own private variables, you'll have to work at it a bit in Perl. Named subroutines do not nest properly, although anonymous ones do.[7] Anyway, we can emulate nested, lexically scoped subroutines using closures. Here's an example:

sub outer {
    my $x = $_[0] + 35;
    local *inner = sub { return $x * 19 };
    return $x + inner();
}
Now inner can only be called from within outer, because of the temporary assignments of the closure. But when it is, it has normal access to the lexical variable $x from the scope of outer.

[7]To be more precise, globally named subroutines don't nest. Unfortunately, that's the only kind of named subroutine declaration we have. We haven't yet implemented lexically scoped, named subroutines (known as my subs), but when we do, they should nest correctly.

This has the interesting effect of creating a function local to another function, something not normally supported in Perl. Because local is dynamically scoped, and because function names are global to their package, any other function that outer called could also call the temporary version of inner. To prevent that, you'd need an extra level of indirection:

sub outer {
    my $x = $_[0] + 35;
    my $inner = sub { return $x * 19 };
    return $x + $inner->();
}

Previous | Home | Next
8.2. Creating References | Book Index | 8.4. Symbolic References
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.4. Symbolic References

What happens if you try to dereference a value that is not a hard reference? The value is then treated as a symbolic reference. That is, the reference is interpreted as a string representing the name of a global variable.

Here is how this works:

$name = "bam";
$$name = 1;                # Sets $bam
$name->[0] = 4;            # Sets the first element of @bam
$name->{X} = "Y";          # Sets the X element of %bam to Y
@$name = ();               # Clears @bam
keys %$name;               # Yields the keys of %bam
&$name;                    # Calls &bam

This is very powerful, and slightly dangerous, in that it's possible to intend (with the utmost sincerity) to use a hard reference, but to accidentally use a symbolic reference instead. To protect against that, you can say:

use strict 'refs';
and then only hard references will be allowed for the rest of the enclosing block. An inner block may countermand the decree with:
no strict 'refs';
It is also important to understand the difference between the following two lines of code:
${identifier};    # Same as $identifier.
${"identifier"};  # Also $identifier, but a symbolic reference.
Because the second form is quoted, it is treated as a symbolic reference and will generate an error if use strict 'refs' is in effect. Even if strict 'refs' is not in effect, it can only refer to a package variable. But the first form is identical to the unbracketed form, and will refer to even a lexically scoped variable if one is declared. The next example shows this (and the next section discusses it).

Only package variables are accessible through symbolic references, because symbolic references always go through the package symbol table. Since lexical variables aren't in a package symbol table, they are therefore invisible to this mechanism. For example:

our $value  = "global";
{
    my $value = "private";
    print "Inside, mine is ${value}, ";
    print "but ours is ${'value'}.\n";
}
print "Outside, ${value} is again ${'value'}.\n";
which prints:
Inside, mine is private, but ours is global.
Outside, global is again global.

Previous | Home | Next
8.3. Using Hard References | Book Index | 8.5. Braces, Brackets, and Quoting
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


8.5. Braces, Brackets, and Quoting

In the previous section, we pointed out that ${identifier} is not treated as a symbolic reference. You might wonder how this interacts with reserved words, and the short answer is that it doesn't. Despite the fact that push is a reserved word, these two statements print "pop on over":

$push = "pop on ";
print "${push}over";
The reason is that, historically, this use of braces is how Unix shells have isolated a variable name from subsequent alphanumeric text that would otherwise be interpreted as part of the name. It's how many people expect variable interpolation to work, so we made it work the same way in Perl. But with Perl, the notion extends further and applies to any braces used in generating references, whether or not they're inside quotes. This means that:
print ${push} . 'over';
or even (since spaces never matter):
print ${ push } . 'over';
both print "pop on over", even though the braces are outside of double quotes. The same rule applies to any identifier used for subscripting a hash. So, instead of writing:
$hash{ "aaa" }{ "bbb" }{ "ccc" }
you can just write:
$hash{ aaa }{ bbb }{ ccc }
or:
$hash{aaa}{bbb}{ccc}
and not worry about whether the subscripts are reserved words. So this:
$hash{ shift }
is interpreted as $hash{"shift"}. You can force interpretation as a reserved word by adding anything that makes it more than a mere identifier:
$hash{  shift()  }
$hash{ +shift   }
$hash{  shift @_ }

8.5.1. References Don't Work as Hash Keys

Hash keys are stored internally as strings.[8] If you try to store a reference as a key in a hash, the key value will be converted into a string:

$x{ \$a } = $a;
($key, $value) = each %x;
print $$key;                # WRONG

[8] They're also stored externally as strings, such as when you put them into a DBM file. In fact, DBM files require that their keys (and values) be strings.

We mentioned earlier that you can't convert a string back to a hard reference. So if you try to dereference $key, which contains a mere string, it won't return a hard dereference, but rather a symbolic dereference--and since you probably don't have a variable named SCALAR(0x1fc0e), you won't accomplish what you're attempting. You might want to do something more like:

$r = \@a;
$x{ $r } = $r;
Then at least you can use the hash value, which will be a hard reference, instead of the key, which won't.

Although you can't store a reference as a key, if (as in the earlier example) you use a hard reference in a string context, it is guaranteed to produce a unique string, since the address of the reference is included as part of the resulting string. So you can in fact use a reference as a unique hash key. You just can't dereference it later.

There is one special kind of hash in which you are able to use references as keys. Through the magic[9] of the Tie::RefHash module bundled with Perl, the thing we just said you couldn't do, you can do:

use Tie::RefHash;
tie my %h, 'Tie::RefHash';
%h = (
    ["this", "here"]   => "at home",
    ["that", "there"]  => "elsewhere",
);
while ( my($keyref, $value) = each %h ) {
    print "@$keyref is $value\n";
}
In fact, by tying different implementations to the built-in types, you can make scalars, hashes, and arrays behave in many of the ways we've said you can't. That'll show us! Stupid authors...

[9]Yes, that is a technical term, as you'll notice if you muddle through the mg.c file in the Perl source distribution.

For more about tying, see Chapter 14, "Tied Variables".

8.5.2. Garbage Collection, Circular References, and Weak References

High-level languages typically allow programmers not to worry about deallocating memory when they're done using it. This automatic reclamation process is known as garbage collection. For most purposes, Perl uses a fast and simple reference-based garbage collector.

When a block is exited, its locally scoped variables are normally freed up, but it is possible to hide your garbage so that Perl's garbage collector can't find it. One serious concern is that unreachable memory with a nonzero reference count will normally not get freed. Therefore, circular references are a bad idea:

{               # make $a and $b point to each other
    my ($a, $b);
    $a = \$b;
    $b = \$a;
}
or more simply:
{               # make $a point to itself
    my $a;
    $a = \$a;
}
Even though $a should be deallocated at the end of the block, it isn't. When building recursive data structures, you'll have to break (or weaken; see below) the self-reference yourself if you want to reclaim the memory before your program (or thread) exits. (Upon exit, the memory will be reclaimed for you automatically via a costly but complete mark-and-sweep garbage collection.) If the data structure is an object, you can use a DESTROY method to break the reference automatically; see "Garbage Collection with DESTROY Methods" in Chapter 12, "Objects".

A similar situation can occur with caches--repositories of data designed for faster-than-normal retrieval. Outside the cache, there are references to data inside the cache. The problem occurs when all of those references are deleted, but the cache data with its internal reference remains. The existence of any reference prevents the referent from being reclaimed by Perl, even though we want cache data to disappear as soon as it's no longer needed. As with circular references, we want a reference that doesn't affect the reference count, and therefore doesn't delay garbage collection.

Weak references solve the problems caused by circular references and cache data by allowing you to "weaken" any reference; that is, make it not affect the reference count. When the last nonweak reference to an object is deleted, the object is destroyed and all the weak references to the object are automatically freed.

To use this feature, you need the WeakRef package from CPAN, which contains additional documentation. Weak references are an experimental feature. But hey, somebody's gotta be the guinea pig.

Previous | Home | Next
8.4. Symbolic References | Book Index | 9. Data Structures
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 9. Data Structures

Contents:

Arrays of Arrays
Hashes of Arrays
Arrays of Hashes
Hashes of Hashes
Hashes of Functions
More Elaborate Records
Saving Data Structures

Perl provides for free many of the data structures that you have to build yourself in other programming languages. The stacks and queues that budding computer scientists learn about are both just arrays in Perl. When you push and pop (or shift and unshift) an array, it's a stack; when you push and shift (or unshift and pop) an array, it's a queue. And many of the tree structures in the world are built only to provide fast, dynamic access to a conceptually flat lookup table. Hashes, of course, are built into Perl, and provide fast, dynamic access to a conceptually flat lookup table, only without the mind-numbingly recursive data structures that are claimed to be beautiful by people whose minds have been suitably numbed already.

But sometimes you want nested data structures because they most naturally model the problem you're trying to solve. So Perl lets you combine and nest arrays and hashes to create arbitrarily complex data structures. Properly applied, they can be used to create linked lists, binary trees, heaps, B-trees, sets, graphs, and anything else you can devise. See Mastering Algorithms with Perl (O'Reilly, 1999), the Perl Cookbook (O'Reilly, 1998), or CPAN, the central repository for all such modules. But simple combinations of arrays and hashes may be all you ever need, so they're what we'll talk about in this chapter.

9.1. Arrays of Arrays

There are many kinds of nested data structures. The simplest kind to build is an array of arrays, also called a two-dimensional array or a matrix. (The obvious generalization applies: an array of arrays of arrays is a three-dimensional array, and so on for higher dimensions.) It's reasonably easy to understand, and nearly everything that applies here will also be applicable to the fancier data structures that we'll explore in subsequent sections.

9.1.1. Creating and Accessing a Two-Dimensional Array

Here's how to put together a two-dimensional array:

# Assign a list of array references to an array.
@AoA = (
         [ "fred", "barney" ],
         [ "george", "jane", "elroy" ],
         [ "homer", "marge", "bart" ],
);

print $AoA[2][1];   # prints "marge"
The overall list is enclosed by parentheses, not brackets, because you're assigning a list and not a reference. If you wanted a reference to an array instead, you'd use brackets:
# Create an reference to an array of array references.
$ref_to_AoA = [
    [ "fred", "barney", "pebbles", "bamm bamm", "dino", ],
    [ "homer", "bart", "marge", "maggie", ],
    [ "george", "jane", "elroy", "judy", ],
];

print $ref_to_AoA->[2][3];   # prints "judy"
Remember that there is an implied -> between every pair of adjacent braces or brackets. Therefore these two lines:
$AoA[2][3]
$ref_to_AoA->[2][3]
are equivalent to these two lines:
$AoA[2]->[3]
$ref_to_AoA->[2]->[3]
There is, however, no implied -> before the first pair of brackets, which is why the dereference of $ref_to_AoA requires the initial ->. Also remember that you can count backward from the end of an array with a negative index, so:
$AoA[0][-2]
is the next-to-last element of the first row.

9.1.2. Growing Your Own

Those big list assignments are well and good for creating a fixed data structure, but what if you want to calculate each element on the fly, or otherwise build the structure piecemeal?

Let's read in a data structure from a file. We'll assume that it's a plain text file, where each line is a row of the structure, and each line consists of elements delimited by whitespace. Here's how to proceed:[1]

while (<>) {
    @tmp = split;           # Split elements into an array.
    push @AoA, [ @tmp ];    # Add an anonymous array reference to @AoA.
}
Of course, you don't need to name the temporary array, so you could also say:
while (<>) {
    push @AoA, [ split ];
}
If you want a reference to an array of arrays, you can do this:
while (<>) {
    push @$ref_to_AoA, [ split ];
}
Both of those examples add new rows to the array of arrays. What about adding new columns? If you're just dealing with two-dimensional arrays, it's often easiest to use simple assignment:[2]
for $x (0 .. 9) {                       # For each row...
    for $y (0 .. 9) {                   # For each column...
        $AoA[$x][$y] = func($x, $y);    # ...set that cell
    }
}

for $x ( 0..9 ) {                       # For each row...
    $ref_to_AoA->[$x][3] = func2($x);   # ...set the fourth column
}
It doesn't matter in what order you assign the elements, nor does it matter whether the subscripted elements of @AoA are already there or not; Perl will gladly create them for you, setting intervening elements to the undefined value as need be. (Perl will even create the original reference in $ref_to_AoA for you if it needs to.) If you just want to append to a row, you have to do something a bit funnier:
# Append new columns to an existing row.
push @{ $AoA[0] }, "wilma", "betty";
Notice that this wouldn't work:
push $AoA[0], "wilma", "betty";  # WRONG!
That won't even compile, because the argument to push must be a real array, not just a reference to an array. Therefore, the first argument absolutely must begin with an @ character. What comes after the @ is somewhat negotiable.

[1] Here as in other chapters, we omit (for clarity) the my declarations that you would ordinarily put in. In this example, you'd normally write my @tmp = split.

[2] As with the temp assignment earlier, we've simplified; the loops in this chapter would likely be written for my $x in real code.

9.1.3. Access and Printing

Now let's print the data structure. If you only want one element, this is sufficient:

print $AoA[3][2];
But if you want to print the whole thing, you can't just say:
print @AoA;         # WRONG

It's wrong because you'll see stringified references instead of your data. Perl never automatically dereferences for you. Instead, you have to roll yourself a loop or two. The following code prints the whole structure, looping through the elements of @AoA and dereferencing each inside the print statement:

for $row ( @AoA ) {
    print "@$row\n";
}
If you want to keep track of subscripts, you might do this:
for $i ( 0 .. $#AoA ) {
    print "row $i is: @{$AoA[$i]}\n";
}
or maybe even this (notice the inner loop):
for $i ( 0 .. $#AoA ) {
    for $j ( 0 .. $#{$AoA[$i]} ) {
        print "element $i $j is $AoA[$i][$j]\n";
    }
}
As you can see, things are getting a bit complicated. That's why sometimes it's easier to use a temporary variable on your way through:
for $i ( 0 .. $#AoA ) {
    $row = $AoA[$i];
    for $j ( 0 .. $#{$row} ) {
        print "element $i $j is $row->[$j]\n";
    }
}

9.1.4. Slices

If you want to access a slice (part of a row) of a multidimensional array, you're going to have to do some fancy subscripting. The pointer arrows give us a nice way to access a single element, but no such convenience exists for slices. You can always extract the elements of your slice one-by-one with a loop:

@part = ();
for ($y = 7; $y < 13; $y++) {
    push @part, $AoA[4][$y];
}
This particular loop could be replaced with an array slice:
@part = @{ $AoA[4] } [ 7..12 ];
If you want a two-dimensional slice, say, with $x running from 4..8 and $y from 7..12, here's one way to do it:
@newAoA = ();
for ($startx = $x = 4; $x <= 8; $x++) {
    for ($starty = $y = 7; $y <= 12; $y++) {
        $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
    }
}
In this example, the individual values within our destination two-dimensional array, @newAoA, are assigned one by one, taken from a two-dimensional subarray of @AoA. An alternative is to create anonymous arrays, each consisting of a desired slice of an @AoA subarray, and then put references to these anonymous arrays into @newAoA. We would then be writing references into @newAoA (subscripted once, so to speak) instead of subarray values into a twice-subscripted @newAoA. This method eliminates the innermost loop:
for ($x = 4; $x <= 8; $x++) {
    push @newAoA, [ @{ $AoA[$x] } [ 7..12 ] ];
}
Of course, if you do this often, you should probably write a subroutine called something like extract_rectangle. And if you do it very often with large collections of multidimensional data, you should probably use the PDL (Perl Data Language) module, available from CPAN.

9.1.5. Common Mistakes

As mentioned earlier, Perl arrays and hashes are one-dimensional. In Perl, even "multidimensional" arrays are actually one-dimensional, but the values along that dimension are references to other arrays, which collapse many elements into one. If you print these values out without dereferencing them, you will get the stringified references rather than the data you want. For example, these two lines:

@AoA = ( [2, 3], [4, 5, 7], [0] );
print "@AoA";
result in something like:
ARRAY(0x83c38) ARRAY(0x8b194) ARRAY(0x8b1d0)
On the other hand, this line displays 7:
print $AoA[1][2];

When constructing an array of arrays, remember to compose new references for the subarrays. Otherwise, you will just create an array containing the element counts of the subarrays, like this:

for $i (1..10) {
    @array = somefunc($i);
    $AoA[$i] = @array;       # WRONG!
}
Here @array is being accessed in a scalar context, and therefore yields the count of its elements, which is dutifully assigned to $AoA[$i]. The proper way to assign the reference will be shown in a moment.

After making the previous mistake, people realize they need to assign a reference, so the next mistake people naturally make involves taking a reference to the same memory location over and over again:

for $i (1..10) {
    @array = somefunc($i);
    $AoA[$i] = \@array;      # WRONG AGAIN!
}
Every reference generated by the second line of the for loop is the same, namely, a reference to the single array @array. Yes, this array changes on each pass through the loop, but when everything is said and done, $AoA contains 10 references to the same array, which now holds the last set of values assigned to it. print @{$AoA[1]} will reveal the same values as print @{$AoA[2]}.

Here's a more successful approach:

for $i (1..10) {
    @array = somefunc($i);
    $AoA[$i] = [ @array ];   # RIGHT!
}
The brackets around @array create a new anonymous array, into which the elements of @array are copied. We then store a reference to that new array.

A similar result--though more difficult to read--would be produced by:

for $i (1..10) {
    @array = somefunc($i);
    @{$AoA[$i]} = @array;
}
Since $AoA[$i] needs to be a new reference, the reference springs into existence. Then, the preceding @ dereferences this new reference, with the result that the values of @array are assigned (in list context) to the array referenced by $AoA[$i]. You might wish to avoid this construct for clarity's sake.

But there is a situation in which you might use it. Suppose @AoA is already an array of references to arrays. That is, you've made assignments like:

$AoA[3] = \@original_array;
And now suppose that you want to change @original_array (that is, you want to change the fourth row of $AoA) so that it refers to the elements of @array. This code will work:
@{$AoA[3]} = @array;
In this case, the reference itself does not change, but the elements of the referenced array do. This overwrites the values of @original_array.

Finally, the following dangerous-looking code actually works fine:

for $i (1..10) {
    my @array = somefunc($i);
    $AoA[$i] = \@array;
}
That's because the lexically scoped my @array variable is created afresh on each pass through the loop. So even though it looks as though you've stored the same variable reference each time, you haven't. This is a subtle distinction, but the technique can produce more efficient code, at the risk of misleading less-enlightened programmers. (It's more efficient because there's no copy in the final assignment.) On the other hand, if you have to copy the values anyway (which the first assignment in the loop is doing), then you might as well use the copy implied by the brackets and avoid the temporary variable:
for $i (1..10) {
    $AoA[$i] = [ somefunc($i) ];
}
In summary:
$AoA[$i] = [ @array ];   # Safest, sometimes fastest
$AoA[$i] = \@array;      # Fast but risky, depends on my-ness of array
@{ $AoA[$i] } = @array;  # A bit tricky
Once you've mastered arrays of arrays, you'll want to tackle more complex data structures. If you're looking for C structures or Pascal records, you won't find any special reserved words in Perl to set these up for you. What you get instead is a more flexible system. If your idea of a record structure is less flexible than this, or if you'd like to provide your users with something more opaque and rigid, then you can use the object-oriented features detailed in Chapter 12, "Objects".

Perl has just two ways of organizing data: as ordered lists stored in arrays and accessed by position, or as unordered key/value pairs stored in hashes and accessed by name. The best way to represent a record in Perl is with a hash reference, but how you choose to organize such records will vary. You might want to keep an ordered list of these records that you can look up by number, in which case you'd use an array of hash references to store the records. Or, you might wish to look the records up by name, in which case you'd maintain a hash of hash references. You could even do both at once, with pseudohashes.

In the following sections, you will find code examples detailing how to compose (from scratch), generate (from other sources), access, and display several different data structures. We first demonstrate three straightforward combinations of arrays and hashes, followed by a hash of functions and more irregular data structures. We end with a demonstration of how these data structures can be saved. These examples assume that you have already familiarized yourself with the explanations set forth earlier in this chapter.

Previous | Home | Next
8.5. Braces, Brackets, and Quoting | Book Index | 9.2. Hashes of Arrays
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.2. Hashes of Arrays

Use a hash of arrays when you want to look up each array by a particular string rather than merely by an index number. In our example of television characters, instead of looking up the list of names by the zeroth show, the first show, and so on, we'll set it up so we can look up the cast list given the name of the show.

Because our outer data structure is a hash, we can't order the contents, but we can use the sort function to specify a particular output order.

9.2.1. Composition of a Hash of Arrays

You can create a hash of anonymous arrays as follows:

# We customarily omit quotes when the keys are identifiers.
%HoA = (
    flintstones    => [ "fred", "barney" ],
    jetsons        => [ "george", "jane", "elroy" ],
    simpsons       => [ "homer", "marge", "bart" ],
);
To add another array to the hash, you can simply say:
$HoA{teletubbies} = [ "tinky winky", "dipsy", "laa-laa", "po" ];

9.2.2. Generation of a Hash of Arrays

Here are some techniques for populating a hash of arrays. To read from a file with the following format:

flintstones: fred barney wilma dino
jetsons:     george jane elroy
simpsons:    homer marge bart
you could use either of the following two loops:
while ( <> ) {
    next unless s/^(.*?):\s*//;
    $HoA{$1} = [ split ];
}

while ( $line = <> ) {
    ($who, $rest) = split /:\s*/, $line, 2;
    @fields = split ' ', $rest;
    $HoA{$who} = [ @fields ];
}
If you have a subroutine get_family that returns an array, you can use it to stuff %HoA with either of these two loops:
for $group ( "simpsons", "jetsons", "flintstones" ) {
    $HoA{$group} = [ get_family($group) ];
}

for $group ( "simpsons", "jetsons", "flintstones" ) {
    @members = get_family($group);
    $HoA{$group} = [ @members ];
}
You can append new members to an existing array like so:
push @{ $HoA{flintstones} }, "wilma", "pebbles";

9.2.3. Access and Printing of a Hash of Arrays

You can set the first element of a particular array as follows:

$HoA{flintstones}[0] = "Fred";
To capitalize the second Simpson, apply a substitution to the appropriate array element:
$HoA{simpsons}[1] =~ s/(\w)/\u$1/;
You can print all of the families by looping through the keys of the hash:
for $family ( keys %HoA ) {
    print "$family: @{ $HoA{$family} }\n";
}
With a little extra effort, you can add array indices as well:
for $family ( keys %HoA ) {
    print "$family: ";
    for $i ( 0 .. $#{ $HoA{$family} } ) {
        print " $i = $HoA{$family}[$i]";
    }
    print "\n";
}
Or sort the arrays by how many elements they have:
for $family ( sort { @{$HoA{$b}} <=> @{$HoA{$a}} } keys %HoA ) {
    print "$family: @{ $HoA{$family} }\n"
}
Or even sort the arrays by the number of elements and then order the elements ASCIIbetically (or to be precise, utf8ically):
# Print the whole thing sorted by number of members and name.
for $family ( sort { @{$HoA{$b}} <=> @{$HoA{$a}} } keys %HoA ) {
    print "$family: ", join(", ", sort @{ $HoA{$family} }), "\n";
}

Previous | Home | Next
9.1. Arrays of Arrays | Book Index | 9.3. Arrays of Hashes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.3. Arrays of Hashes

An array of hashes is useful when you have a bunch of records that you'd like to access sequentially, and each record itself contains key/value pairs. Arrays of hashes are used less frequently than the other structures in this chapter.

9.3.1. Composition of an Array of Hashes

You can create an array of anonymous hashes as follows:

@AoH = (
    {
       husband  => "barney",
       wife     => "betty",
       son      => "bamm bamm",
    },
    {
       husband => "george",
       wife    => "jane",
       son     => "elroy",
    },

    {
       husband => "homer",
       wife    => "marge",
       son     => "bart",
    },
  );
To add another hash to the array, you can simply say:
push @AoH, { husband => "fred", wife => "wilma", daughter => "pebbles" };

9.3.2. Generation of an Array of Hashes

Here are some techniques for populating an array of hashes. To read from a file with the following format:

husband=fred friend=barney
you could use either of the following two loops:
while ( <> ) {
    $rec = {};
    for $field ( split ) {
        ($key, $value) = split /=/, $field;
        $rec->{$key} = $value;
    }
    push @AoH, $rec;
}

while ( <> ) {
    push @AoH, { split /[\s=]+/ };
}
If you have a subroutine get_next_pair that returns key/value pairs, you can use it to stuff @AoH with either of these two loops:
while ( @fields = get_next_pair() ) {
    push @AoH, { @fields };
}

while (<>) {
    push @AoH, { get_next_pair($_) };
}
You can append new members to an existing hash like so:
$AoH[0]{pet} = "dino";
$AoH[2]{pet} = "santa's little helper";

9.3.3. Access and Printing of an Array of Hashes

You can set a key/value pair of a particular hash as follows:

$AoH[0]{husband} = "fred";
To capitalize the husband of the second array, apply a substitution:
$AoH[1]{husband} =~ s/(\w)/\u$1/;
You can print all of the data as follows:
for $href ( @AoH ) {
    print "{ ";
    for $role ( keys %$href ) {
         print "$role=$href->{$role} ";
    }
    print "}\n";
}
and with indices:
for $i ( 0 .. $#AoH ) {
    print "$i is { ";
    for $role ( keys %{ $AoH[$i] } ) {
         print "$role=$AoH[$i]{$role} ";
    }
    print "}\n";
}

Previous | Home | Next
9.2. Hashes of Arrays | Book Index | 9.4. Hashes of Hashes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.4. Hashes of Hashes

A multidimensional hash is the most flexible of Perl's nested structures. It's like building up a record that itself contains other records. At each level, you index into the hash with a string (quoted when necessary). Remember, however, that the key/value pairs in the hash won't come out in any particular order; you can use the sort function to retrieve the pairs in whatever order you like.

9.4.1. Composition of a Hash of Hashes

You can create a hash of anonymous hashes as follows:

%HoH = (
    flintstones => {
        husband   => "fred",
        pal       => "barney",
    },
    jetsons => {
        husband   => "george",
        wife      => "jane",
        "his boy" => "elroy",  # Key quotes needed.
    },
    simpsons => {
        husband   => "homer",
        wife      => "marge",
        kid       => "bart",
    },
);
To add another anonymous hash to %HoH, you can simply say:
$HoH{ mash } = {
    captain  => "pierce",
    major    => "burns",
    corporal => "radar",
};

9.4.2. Generation of a Hash of Hashes

Here are some techniques for populating a hash of hashes. To read from a file with the following format:

flintstones: husband=fred pal=barney wife=wilma pet=dino
you could use either of the following two loops:
while ( <> ) {
    next unless s/^(.*?):\s*//;
    $who = $1;
    for $field ( split ) {
        ($key, $value) = split /=/, $field;
        $HoH{$who}{$key} = $value;
    }
}

while ( <> ) {
    next unless s/^(.*?):\s*//;
    $who = $1;
    $rec = {};
    $HoH{$who} = $rec;
    for $field ( split ) {
        ($key, $value) = split /=/, $field;
        $rec->{$key} = $value;
    }
}
If you have a subroutine get_family that returns a list of key/value pairs, you can use it to stuff %HoH with either of these three snippets:
for $group ( "simpsons", "jetsons", "flintstones" ) {
    $HoH{$group} = { get_family($group) };
}

for $group ( "simpsons", "jetsons", "flintstones" ) {
    @members = get_family($group);
    $HoH{$group} = { @members };
}

sub hash_families {
    my @ret;
    for $group ( @_ ) {
        push @ret, $group, { get_family($group) };
    }
    return @ret;
}
%HoH = hash_families( "simpsons", "jetsons", "flintstones" );
You can append new members to an existing hash like so:
%new_folks = (
    wife => "wilma",
    pet  => "dino";
);
for $what (keys %new_folks) {
    $HoH{flintstones}{$what} = $new_folks{$what};
}

9.4.3. Access and Printing of a Hash of Hashes

You can set a key/value pair of a particular hash as follows:

$HoH{flintstones}{wife} = "wilma";
To capitalize a particular key/value pair, apply a substitution to an element:
$HoH{jetsons}{'his boy'} =~ s/(\w)/\u$1/;
You can print all the families by looping through the keys of the outer hash and then looping through the keys of the inner hash:
for $family ( keys %HoH ) {
    print "$family: ";
    for $role ( keys %{ $HoH{$family} } ) {
         print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}
In very large hashes, it may be slightly faster to retrieve both keys and values at the same time using each (which precludes sorting):
while ( ($family, $roles) = each %HoH ) {
    print "$family: ";
    while ( ($role, $person) = each %$roles ) {
        print "$role=$person ";
    }
    print "\n";
}
(Unfortunately, it's the large hashes that really need to be sorted, or you'll never find what you're looking for in the printout.) You can sort the families and then the roles as follows:
for $family ( sort keys %HoH ) {
    print "$family: ";
    for $role ( sort keys %{ $HoH{$family} } ) {
         print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}
To sort the families by the number of members (instead of ASCIIbetically (or utf8ically)), you can use keys in a scalar context:
for $family ( sort { keys %{$HoH{$a}} <=> keys %{$HoH{$b}} } keys %HoH ) {
    print "$family: ";
    for $role ( sort keys %{ $HoH{$family} } ) {
         print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}
To sort the members of a family in some fixed order, you can assign ranks to each:
$i = 0;
for ( qw(husband wife son daughter pal pet) ) { $rank{$_} = ++$i }

for $family ( sort { keys %{$HoH{$a}} <=> keys %{$HoH{$b}} } keys %HoH ) {
    print "$family: ";
    for $role ( sort { $rank{$a} <=> $rank{$b} } keys %{ $HoH{$family} } ) {
        print "$role=$HoH{$family}{$role} ";
    }
    print "\n";
}

Previous | Home | Next
9.3. Arrays of Hashes | Book Index | 9.5. Hashes of Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.5. Hashes of Functions

When writing a complex application or network service in Perl, you might want to make a large number of commands available to your users. Such a program might have code like this to examine the user's selection and take appropriate action:

if    ($cmd =~ /^exit$/i)     { exit }
elsif ($cmd =~ /^help$/i)     { show_help() }
elsif ($cmd =~ /^watch$/i)    { $watch = 1 }
elsif ($cmd =~ /^mail$/i)     { mail_msg($msg) }
elsif ($cmd =~ /^edit$/i)     { $edited++; editmsg($msg); }
elsif ($cmd =~ /^delete$/i)   { confirm_kill() }
else {
    warn "Unknown command: `$cmd'; Try `help' next time\n";
}
You can also store references to functions in your data structures, just as you can store references to arrays or hashes:
%HoF = (                           # Compose a hash of functions
    exit    =>  sub { exit },
    help    =>  \&show_help,
    watch   =>  sub { $watch = 1 },
    mail    =>  sub { mail_msg($msg) },
    edit    =>  sub { $edited++; editmsg($msg); },
    delete  =>  \&confirm_kill,
);

if   ($HoF{lc $cmd}) { $HoF{lc $cmd}->() }   # Call function
else { warn "Unknown command: `$cmd'; Try `help' next time\n" }
In the second to last line, we check whether the specified command name (in lowercase) exists in our "dispatch table", %HoF. If so, we invoke the appropriate command by dereferencing the hash value as a function and pass that function an empty argument list. We could also have dereferenced it as &{ $HoF{lc $cmd} }(), or, as of the 5.6 release of Perl, simply $HoF{lc $cmd}().

Previous | Home | Next
9.4. Hashes of Hashes | Book Index | 9.6. More Elaborate Records
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.6. More Elaborate Records

So far, what we've seen in this chapter are simple, two-level, homogeneous data structures: each element contains the same kind of referent as all the other elements at that level. It certainly doesn't have to be that way. Any element can hold any kind of scalar, which means that it could be a string, a number, or a reference to anything at all. The reference could be an array or hash reference, or a pseudohash, or a reference to a named or anonymous function, or an object. The only thing you can't do is to stuff multiple referents into one scalar. If you find yourself trying to do that, it's a sign that you need an array or hash reference to collapse multiple values into one.

In the sections that follow, you will find code examples designed to illustrate many of the possible types of data you might want to store in a record, which we'll implement using a hash reference. The keys are uppercase strings, a convention sometimes employed (and occasionally unemployed, but only briefly) when the hash is being used as a specific record type.

9.6.1. Composition, Access, and Printing of More Elaborate Records

Here is a record with six disparate fields:

$rec = {
    TEXT      => $string,
    SEQUENCE  => [ @old_values ],
    LOOKUP    => { %some_table },
    THATCODE  => \&some_function,
    THISCODE  => sub { $_[0] ** $_[1] },
    HANDLE    => \*STDOUT,
};
The TEXT field is a simple string, so you can just print it:
print $rec->{TEXT};
SEQUENCE and LOOKUP are regular array and hash references:
print $rec->{SEQUENCE}[0];
$last = pop @{ $rec->{SEQUENCE} };

print $rec->{LOOKUP}{"key"};
($first_k, $first_v) = each %{ $rec->{LOOKUP} };
THATCODE is a named subroutine and THISCODE is an anonymous subroutine, but they're invoked identically:
$that_answer = $rec->{THATCODE}->($arg1, $arg2);
$this_answer = $rec->{THISCODE}->($arg1, $arg2);
With an extra pair of braces, you can treat $rec->{HANDLE} as an indirect object:
print { $rec->{HANDLE} } "a string\n";
If you're using the FileHandle module, you can even treat the handle as a regular object:
use FileHandle;
$rec->{HANDLE}->autoflush(1);
$rec->{HANDLE}->print("a string\n");

9.6.2. Composition, Access, and Printing of Even More Elaborate Records

Naturally, the fields of your data structures can themselves be arbitrarily complex data structures in their own right:

%TV = (
    flintstones => {
        series   => "flintstones",
        nights   => [ "monday", "thursday", "friday" ],
        members  => [
            { name => "fred",    role => "husband", age  => 36, },
            { name => "wilma",   role => "wife",    age  => 31, },
            { name => "pebbles", role => "kid",     age  =>  4, },
        ],
    },

    jetsons     => {
        series   => "jetsons",
        nights   => [ "wednesday", "saturday" ],
        members  => [
            { name => "george",  role => "husband", age  => 41, },
            { name => "jane",    role => "wife",    age  => 39, },
            { name => "elroy",   role => "kid",     age  =>  9, },
        ],
    },

    simpsons    => {
        series   => "simpsons",
        nights   => [ "monday" ],
        members  => [
            { name => "homer", role => "husband", age => 34, },
            { name => "marge", role => "wife",    age => 37, },
            { name => "bart",  role => "kid",     age => 11, },
        ],
    },
);

9.6.3. Generation of a Hash of Complex Records

Because Perl is quite good at parsing complex data structures, you might just put your data declarations in a separate file as regular Perl code, and then load them in with the do or require built-in functions. Another popular approach is to use a CPAN module (such as XML::Parser) to load in arbitrary data structures expressed in some other language (such as XML).

You can build data structures piecemeal:

$rec = {};
$rec->{series} = "flintstones";
$rec->{nights} = [ find_days() ];
Or read them in from a file (here, assumed to be in field=value syntax):
@members = ();
while (<>) {
     %fields = split /[\s=]+/;
     push @members, { %fields };
}
$rec->{members} = [ @members ];
And fold them into larger data structures keyed by one of the subfields:
$TV{ $rec->{series} } = $rec;
You can use extra pointer fields to avoid duplicate data. For example, you might want a "kids" field included in a person's record, which might be a reference to an array containing references to the kids' own records. By having parts of your data structure refer to other parts, you avoid the data skew that would result from updating the data in one place but not in another:
for $family (keys %TV) {
    my $rec = $TV{$family};   # temporary pointer
    @kids = ();
    for $person ( @{$rec->{members}} ) {
        if ($person->{role} =~ /kid|son|daughter/) {
            push @kids, $person;
        }
    }
    # $rec and $TV{$family} point to same data!
    $rec->{kids} = [ @kids ];
}
The $rec->{kids} = [ @kids ] assignment copies the array contents--but they are merely references to uncopied data. This means that if you age Bart as follows:
$TV{simpsons}{kids}[0]{age}++;            # increments to 12
then you'll see the following result, because $TV{simpsons}{kids}[0] and $TV{simpsons}{members}[2] both point to the same underlying anonymous hash table:
print $TV{simpsons}{members}[2]{age};     # also prints 12
Now, to print the entire %TV structure:
for $family ( keys %TV ) {
    print "the $family";
    print " is on ", join (" and ", @{ $TV{$family}{nights} }), "\n";
    print "its members are:\n";
    for $who ( @{ $TV{$family}{members} } ) {
        print " $who->{name} ($who->{role}), age $who->{age}\n";
    }
    print "children: ";
    print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
    print "\n\n";
}

Previous | Home | Next
9.5. Hashes of Functions | Book Index | 9.7. Saving Data Structures
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


9.7. Saving Data Structures

If you want to save your data structures for use by another program later, there are many ways to do it. The easiest way is to use Perl's Data::Dumper module, which turns a (possibly self-referential) data structure into a string that can be saved externally and later reconstituted with eval or do.

use Data::Dumper;
$Data::Dumper::Purity = 1;       # since %TV is self-referential
open (FILE, "> tvinfo.perldata") or die "can't open tvinfo: $!";
print FILE Data::Dumper->Dump([\%TV], ['*TV']);
close FILE                       or die "can't close tvinfo: $!";
A separate program (or the same program) can then read in the file later:
open (FILE, "< tvinfo.perldata") or die "can't open tvinfo: $!";
undef $/;                        # read in file all at once
eval <FILE>;                     # recreate %TV
die "can't recreate tv data from tvinfo.perldata: $@" if $@;
close FILE                       or die "can't close tvinfo: $!";
print $TV{simpsons}{members}[2]{age};
or simply:
do "tvinfo.perldata"            or die "can't recreate tvinfo: $! $@";
print $TV{simpsons}{members}[2]{age};
Many other solutions are available, with storage formats ranging from packed binary (very fast) to XML (very interoperable). Check out a CPAN mirror near you today!

Previous | Home | Next
9.6. More Elaborate Records | Book Index | 10. Packages
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 10. Packages

Contents:

Symbol Tables
Autoloading

In this chapter, we get to start having fun, because we get to start talking about software design. If we're going to talk about good software design, we have to talk about Laziness, Impatience, and Hubris, the basis of good software design.

We've all fallen into the trap of using cut-and-paste when we should have defined a higher-level abstraction, if only just a loop or subroutine.[1] To be sure, some folks have gone to the opposite extreme of defining ever-growing mounds of higher-level abstractions when they should have used cut-and-paste.[2] Generally, though, most of us need to think about using more abstraction rather than less.

[1] This is a form of False Laziness.

[2]This is a form of False Hubris.

Caught somewhere in the middle are the people who have a balanced view of how much abstraction is good, but who jump the gun on writing their own abstractions when they should be reusing existing code.[3]

[3] You guessed it--this is False Impatience. But if you're determined to reinvent the wheel, at least try to invent a better one.

Whenever you're tempted to do any of these things, you need to sit back and think about what will do the most good for you and your neighbor over the long haul. If you're going to pour your creative energies into a lump of code, why not make the world a better place while you're at it? (Even if you're only aiming for the program to succeed, you need to make sure it fits the right ecological niche.)

The first step toward ecologically sustainable programming is simply this: don't litter in the park. When you write a chunk of code, think about giving the code its own namespace, so that your variables and functions don't clobber anyone else's, or vice versa. A namespace is a bit like your home, where you're allowed to be as messy as you like, as long as you keep your external interface to other citizens moderately civil. In Perl, a namespace is called a package. Packages provide the fundamental building block upon which the higher-level concepts of modules and classes are constructed.

Like the notion of "home", the notion of "package" is a bit nebulous. Packages are independent of files. You can have many packages in a single file, or a single package that spans several files, just as your home could be one small garret in a larger building (if you're a starving artist), or it could comprise several buildings (if your name happens to be Queen Elizabeth). But the usual size of a home is one building, and the usual size of a package is one file. Perl provides some special help for people who want to put one package in one file, as long as you're willing to give the file the same name as the package and use an extension of .pm, which is short for "perl module". The module is the fundamental unit of reusability in Perl. Indeed, the way you use a module is with the use command, which is a compiler directive that controls the importation of subroutines and variables from a module. Every example of use you've seen until now has been an example of module reuse.

The Comprehensive Perl Archive Network, or CPAN, is where you should put your modules if other people might find them useful. Perl has thrived because of the willingness of programmers to share the fruits of their labor with the community. Naturally, CPAN is also where you can find modules that others have thoughtfully uploaded for everyone to use. See Chapter 22, "CPAN", and www.cpan.org for details.

The trend over the last 25 years or so has been to design computer languages that enforce a state of paranoia. You're expected to program every module as if it were in a state of siege. Certainly there are some feudal cultures where this is appropriate, but not all cultures are like this. In Perl culture, for instance, you're expected to stay out of someone's home because you weren't invited in, not because there are bars on the windows.[4]

[4] But Perl provides some bars if you want them, too. See "Handling Insecure Code" in Chapter 23, "Security".

This is not a book about object-oriented methodology, and we're not here to convert you into a raving object-oriented zealot, even if you want to be converted. There are already plenty of books out there for that. Perl's philosophy of object-oriented design fits right in with Perl's philosophy of everything else: use object-oriented design where it makes sense, and avoid it where it doesn't. Your call.

In OO-speak, every object belongs to a grouping called a class. In Perl, classes and packages and modules are all so closely related that novices can often think of them as being interchangeable. The typical class is implemented by a module that defines a package with the same name as the class. We'll explain all of this in the next few chapters.

When you use a module, you benefit from direct software reuse. With classes, you benefit from indirect software reuse when one class uses another through inheritance. And with classes, you get something more: a clean interface to another namespace. Everything in a class is accessed indirectly, insulating the class from the outside world.

As we mentioned in Chapter 8, "References", object-oriented programming in Perl is accomplished through references whose referents know which class they belong to. In fact, now that you know about references, you know almost everything difficult about objects. The rest of it just "lays under the fingers", as a pianist would say. You will need to practice a little, though.

One of your basic finger exercises consists of learning how to protect different chunks of code from inadvertently tampering with each other's variables. Every chunk of code belongs to a particular package, which determines what variables and subroutines are available to it. As Perl encounters a chunk of code, it is compiled into what we call the current package. The initial current package is called "main", but you can switch the current package to another one at any time with the package declaration. The current package determines which symbol table is used to find your variables, subroutines, I/O handles, and formats.

Any variable not declared with my is associated with a package--even seemingly omnipresent variables like $_ and %SIG. In fact, there's really no such thing as a global variable in Perl, just package variables. (Special identifiers like _ and SIG merely seem global because they default to the main package instead of the current one.)

The scope of a package declaration is from the declaration itself through the end of the enclosing scope (block, file, or eval--whichever comes first) or until another package declaration at the same level, which supersedes the earlier one. (This is a common practice).

All subsequent identifiers (including those declared with our, but not including those declared with my or those qualified with a different package name) will be placed in the symbol table belonging to the current package. (Variables declared with my are independent of packages; they are always visible within, and only within, their enclosing scope, regardless of any package declarations.)

Typically, a package declaration will be the first statement of a file meant to be included by require or use. But again, that's by convention. You can put a package declaration anywhere you can put a statement. You could even put it at the end of a block, in which case it would have no effect whatsoever. You can switch into a package in more than one place; a package declaration merely selects the symbol table to be used by the compiler for the rest of that block. (This is how a given package can span more than one file.)

You can refer to identifiers[5] in other packages by prefixing ("qualifying") the identifier with the package name and a double colon: $Package::Variable. If the package name is null, the main package is assumed. That is, $::sail is equivalent to $main::sail.[6]

[5] By identifiers, we mean the names used as symbol table keys for accessing scalar variables, array variables, hash variables, subroutines, file or directory handles, and formats. Syntactically speaking, labels are also identifiers, but they aren't put into a particular symbol table; rather, they are attached directly to the statements in your program. Labels cannot be package qualified.

[6] To clear up another bit of potential confusion, in a variable name like $main::sail, we use the term "identifier" to talk about main and sail, but not main::sail. We call that a variable name instead, because identifiers cannot contain colons.

The old package delimiter was a single quote, so in old Perl programs you'll see variables like $main'sail and $somepack'horse. But the double colon is now the preferred delimiter, in part because it's more readable to humans, and in part because it's more readable to emacs macros. It also makes C++ programmers feel like they know what's going on--as opposed to using the single quote as the separator, which was there to make Ada programmers feel like they knew what's going on. Because the old-fashioned syntax is still supported for backward compatibility, if you try to use a string like "This is $owner's house", you'll be accessing $owner::s; that is, the $s variable in package owner, which is probably not what you meant. Use braces to disambiguate, as in "This is ${owner}'s house".

The double colon can be used to chain together identifiers in a package name: $Red::Blue::var. This means the $var belonging to the Red::Blue package. The Red::Blue package has nothing to do with any Red or Blue packages that might happen to exist. That is, a relationship between Red::Blue and Red or Blue may have meaning to the person writing or using the program, but it means nothing to Perl. (Well, other than the fact that, in the current implementation, the symbol table Red::Blue happens to be stored in the symbol table Red. But the Perl language makes no use of that directly.)

For this reason, every package declaration must declare a complete package name. No package name ever assumes any kind of implied "prefix", even if (seemingly) declared within the scope of some other package declaration.

Only identifiers (names starting with letters or an underscore) are stored in a package's symbol table. All other symbols are kept in the main package, including all the nonalphabetic variables, like $!, $?, and $_. In addition, when unqualified, the identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC, and SIG are forced to be in package main, even when used for other purposes than their built-in ones. Don't name your package m, s, y, tr, q, qq, qr, qw, or qx unless you're looking for a lot of trouble. For instance, you won't be able to use the qualified form of an identifier as a filehandle because it will be interpreted instead as a pattern match, a substitution, or a transliteration.

Long ago, variables beginning with an underscore were forced into the main package, but we decided it was more useful for package writers to be able to use a leading underscore to indicate semi-private identifiers meant for internal use by that package only. (Truly private variables can be declared as file-scoped lexicals, but that works best when the package and module have a one-to-one relationship, which is common but not required.)

The %SIG hash (which is for trapping signals; see Chapter 16, "Interprocess Communication") is also special. If you define a signal handler as a string, it's assumed to refer to a subroutine in the main package unless another package name is explicitly used. Use a fully qualified signal handler name if you want to specify a particular package, or avoid strings entirely by assigning a typeglob or a function reference instead:

$SIG{QUIT} = "Pkg::quit_catcher"; # fully qualified handler name
$SIG{QUIT} = "quit_catcher";      # implies "main::quit_catcher"
$SIG{QUIT} = *quit_catcher;       # forces current package's sub
$SIG{QUIT} = \&quit_catcher;      # forces current package's sub
$SIG{QUIT} = sub { print "Caught SIGQUIT\n" };   # anonymous sub
The notion of "current package" is both a compile-time and run-time concept. Most variable name lookups happen at compile time, but run-time lookups happen when symbolic references are dereferenced, and also when new bits of code are parsed under eval. In particular, when you eval a string, Perl knows which package the eval was invoked in and propagates that package inward when evaluating the string. (You can always switch to a different package inside the eval string, of course, since an eval string counts as a block, just like a file loaded in with do, require, or use.)

Alternatively, if an eval wants to find out what package it's in, the special symbol __PACKAGE__ contains the current package name. Since you can treat it as a string, you could use it in a symbolic reference to access a package variable. But if you were doing that, chances are you should have declared the variable with our instead so it could be accessed as if it were a lexical.

10.1. Symbol Tables

The contents of a package are collectively called a symbol table. Symbol tables are stored in a hash whose name is the same as the package, but with two colons appended. The main symbol table's name is thus %main::. Since main also happens to be the default package, Perl provides %:: as an abbreviation for %main::.

Likewise, the symbol table for the Red::Blue package is named %Red::Blue::. As it happens, the main symbol table contains all other top-level symbol tables, including itself, so %Red::Blue:: is also %main::Red::Blue::.

When we say that a symbol table "contains" another symbol table, we mean that it contains a reference to the other symbol table. Since main is the top-level package, it contains a reference to itself, with the result that %main:: is the same as %main::main::, and %main::main::main::, and so on, ad infinitum. It's important to check for this special case if you write code that traverses all symbol tables.

Inside a symbol table's hash, each key/value pair matches a variable name to its value. The keys are the symbol identifiers, and the values are the corresponding typeglobs. So when you use the *NAME typeglob notation, you're really just accessing a value in the hash that holds the current package's symbol table. In fact, the following have (nearly) the same effect:

*sym = *main::variable;
*sym = $main::{"variable"};
The first is more efficient because the main symbol table is accessed at compile time. It will also create a new typeglob by that name if none previously exists, whereas the second form will not.

Since a package is a hash, you can look up the keys of the package and get to all the variables of the package. Since the values of the hash are typeglobs, you can dereference them in several ways. Try this:

foreach $symname (sort keys %main::) {
    local *sym = $main::{$symname};
    print "\$$symname is defined\n" if defined $sym;
    print "\@$symname is nonnull\n" if         @sym;
    print "\%$symname is nonnull\n" if         %sym;
}
Since all packages are accessible (directly or indirectly) through the main package, you can write Perl code to visit every package variable in your program. The Perl debugger does precisely that when you ask it to dump all your variables with the V command. Note that if you do this, you won't see variables declared with my since those are independent of packages, although you will see variables declared with our. See Chapter 20, "The Perl Debugger".

Earlier we said that only identifiers are stored in packages other than main. That was a bit of a fib: you can use any string you want as the key in a symbol table hash--it's just that it wouldn't be valid Perl if you tried to use a non-identifier directly:

$!@#$%           = 0;         # WRONG, syntax error.
${'!@#$%'}       = 1;         # Ok, though unqualified.

${'main::!@#$%'} = 2;         # Can qualify within the string.
print ${ $main::{'!@#$%'} }   # Ok, prints 2!
Assignment to a typeglob performs an aliasing operation; that is,
*dick = *richard;
causes variables, subroutines, formats, and file and directory handles accessible via the identifier richard to also be accessible via the symbol dick. If you want to alias only a particular variable or subroutine, assign a reference instead:
*dick = \$richard;
That makes $richard and $dick the same variable, but leaves @richard and @dick as separate arrays. Tricky, eh?

This is how the Exporter works when importing symbols from one package to another. For example:

*SomePack::dick = \&OtherPack::richard;
imports the &richard function from package OtherPack into SomePack, making it available as the &dick function. (The Exporter module is described in the next chapter.) If you precede the assignment with a local, the aliasing will only last as long as the current dynamic scope.

This mechanism may be used to retrieve a reference from a subroutine, making the referent available as the appropriate data type:

*units = populate() ;         # Assign \%newhash to the typeglob
print $units{kg};             # Prints 70; no dereferencing needed!

sub populate {
    my %newhash = (km => 10, kg => 70);
    return \%newhash;
}
Likewise, you can pass a reference into a subroutine and use it without dereferencing:
%units = (miles => 6, stones => 11);
fillerup( \%units );          # Pass in a reference
print $units{quarts};         # Prints 4

sub fillerup {
    local *hashsym = shift;   # Assign \%units to the typeglob
    $hashsym{quarts} = 4;     # Affects %units; no dereferencing needed!
}
These are tricky ways to pass around references cheaply when you don't want to have to explicitly dereference them. Note that both techniques only work with package variables; they would not have worked had we declared %units with my.

Another use of symbol tables is for making "constant" scalars:

*PI = \3.14159265358979;
Now you cannot alter $PI, which is probably a good thing, all in all. This isn't the same as a constant subroutine, which is optimized at compile time. A constant subroutine is one prototyped to take no arguments and to return a constant expression; see Section 10.4.1, "Inlining Constant Functions" in Chapter 6, "Subroutines", for details. The use constant pragma (see Chapter 31, "Pragmatic Modules") is a convenient shorthand:
use constant PI => 3.14159;
Under the hood, this uses the subroutine slot of *PI, instead of the scalar slot used earlier. It's equivalent to the more compact (but less readable):
*PI = sub () { 3.14159 };
That's a handy idiom to know anyway--assigning a sub {} to a typeglob is the way to give a name to an anonymous subroutine at run time.

Assigning a typeglob reference to another typeglob (*sym = \*oldvar) is the same as assigning the entire typeglob, because Perl automatically dereferences the typeglob reference for you. And when you set a typeglob to a simple string, you get the entire typeglob named by that string, because Perl looks up the string in the current symbol table. The following are all equivalent to one another, though the first two compute the symbol table entry at compile time, while the last two do so at run time:

*sym =   *oldvar;
*sym =  \*oldvar;       # autodereference
*sym = *{"oldvar"};     # explicit symbol table lookup
*sym =   "oldvar";      # implicit symbol table lookup
When you perform any of the following assignments, you're replacing just one of the references within the typeglob:
*sym = \$frodo;
*sym = \@sam;
*sym = \%merry;
*sym = \&pippin;
If you think about it sideways, the typeglob itself can be viewed as a kind of hash, with entries for the different variable types in it. In this case, the keys are fixed, since a typeglob can contain exactly one scalar, one array, one hash, and so on. But you can pull out the individual references, like this:
*pkg::sym{SCALAR}      # same as \$pkg::sym
*pkg::sym{ARRAY}       # same as \@pkg::sym
*pkg::sym{HASH}        # same as \%pkg::sym
*pkg::sym{CODE}        # same as \&pkg::sym
*pkg::sym{GLOB}        # same as \*pkg::sym
*pkg::sym{IO}          # internal file/dir handle, no direct equivalent
*pkg::sym{NAME}        # "sym" (not a reference)
*pkg::sym{PACKAGE}     # "pkg" (not a reference)
You can say *foo{PACKAGE} and *foo{NAME} to find out what name and package the *foo symbol table entry comes from. This may be useful in a subroutine that is passed typeglobs as arguments:
sub identify_typeglob {
    my $glob = shift;
    print 'You gave me ', *{$glob}{PACKAGE}, '::', *{$glob}{NAME}, "\n";
}

identify_typeglob(*foo);
identify_typeglob(*bar::glarch);
This prints:
You gave me main::foo
You gave me bar::glarch
The *foo{THING} notation can be used to obtain references to individual elements of *foo. See the section Section 10.2.5, "Symbol Table References" in Chapter 8, "References" for details.

This syntax is primarily used to get at the internal filehandle or directory handle reference, because the other internal references are already accessible in other ways. (The old *foo{FILEHANDLE} is still supported to mean *foo{IO}, but don't let its name fool you into thinking it can distinguish filehandles from directory handles.) But we thought we'd generalize it because it looks kind of pretty. Sort of. You probably don't need to remember all this unless you're planning to write another Perl debugger.

Previous | Home | Next
9.7. Saving Data Structures | Book Index | 10.2. Autoloading
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


10.2. Autoloading

Normally, you can't call a subroutine that isn't defined. However, if there is a subroutine named AUTOLOAD in the undefined subroutine's package (or in the case of an object method, in the package of any of the object's base classes), then the AUTOLOAD subroutine is called with the same arguments that would have been passed to the original subroutine. You can define the AUTOLOAD subroutine to return values just like a regular subroutine, or you can make it define the routine that didn't exist and then call that as if it'd been there all along.

The fully qualified name of the original subroutine magically appears in the package-global $AUTOLOAD variable, in the same package as the AUTOLOAD routine. Here's a simple example that gently warns you about undefined subroutine invocations instead of exiting:

sub AUTOLOAD {
    our $AUTOLOAD;
    warn "Attempt to call $AUTOLOAD failed.\n";
}

blarg(10);              # our $AUTOLOAD will be set to main::blarg
print "Still alive!\n";
Or you can return a value on behalf of the undefined subroutine:
sub AUTOLOAD {
    our $AUTOLOAD;
    return "I see $AUTOLOAD(@_)\n";
}

print blarg(20);        # prints: I see main::blarg(20)
Your AUTOLOAD subroutine might load a definition for the undefined subroutine using eval or require, or use the glob assignment trick discussed earlier, and then execute that subroutine using the special form of goto that can erase the stack frame of the AUTOLOAD routine without a trace. Here we define the subroutine by assigning a closure to the glob:
sub AUTOLOAD {
    my $name = our $AUTOLOAD;
    *$AUTOLOAD = sub { print "I see $name(@_)\n" };
    goto &$AUTOLOAD;    # Restart the new routine.
}

blarg(30);              # prints: I see main::blarg(30)
glarb(40);              # prints: I see main::glarb(40)
blarg(50);              # prints: I see main::blarg(50)
The standard AutoSplit module is used by module writers to split their modules into separate files (with filenames ending in .al), each holding one routine. The files are placed in the auto/ directory of your system's Perl library, after which the files can be autoloaded on demand by the standard AutoLoader module.

A similar approach is taken by the SelfLoader module, except that it autoloads functions from the file's own DATA area, which is less efficient in some ways and more efficient in others. Autoloading of Perl functions by AutoLoader and SelfLoader is analogous to dynamic loading of compiled C functions by DynaLoader, except that autoloading is done at the granularity of the function call, whereas dynamic loading is done at the granularity of the complete module, and will usually link in many C or C++ functions all at once. (Note that many Perl programmers get along just fine without the AutoSplit, AutoLoader, SelfLoader, or DynaLoader modules. You just need to know that they're there, in case you can't get along just fine without them.)

One can have great fun with AUTOLOAD routines that serve as wrappers to other interfaces. For example, let's pretend that any function that isn't defined should just call system with its arguments. All you'd do is this:

sub AUTOLOAD {
    my $program = our $AUTOLOAD;
    $program =~ s/.*:://;  # trim package name
    system($program, @_);
}
(Congratulations, you've now implemented a rudimentary form of the Shell module that comes standard with Perl.) You can call your autoloader (on Unix) like this:
date();
who('am', 'i');
ls('-l');
echo("Abadugabudabuda...");
In fact, if you predeclare the functions you want to call that way, you can pretend they're built-ins and omit the parentheses on the call:
sub date (;$$);       # Allow zero to two arguments.
sub who (;$$$$);      # Allow zero to four args.
sub ls;               # Allow any number of args.
sub echo ($@);        # Allow at least one arg.

date;
who "am", "i";
ls "-l";
echo "That's all, folks!";

Previous | Home | Next
10.1. Symbol Tables | Book Index | 11. Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 11. Modules

Contents:

Using Modules
Creating Modules
Overriding Built-in Functions

The module is the fundamental unit of code reuse in Perl. Under the hood, it's just a package defined in a file of the same name (with .pm on the end). In this chapter, we'll explore how you can use other people's modules and create your own.

Perl comes bundled with a large number of modules, which you can find in the lib directory of your Perl distribution. Many of those modules are described in Chapter 32, "Standard Modules", and Chapter 31, "Pragmatic Modules". All the standard modules also have extensive online documentation, which (horrors) may be more up-to-date than this book. Try the perldoc command if your man command doesn't work.

The Comprehensive Perl Archive Network (CPAN) contains a worldwide repository of modules contributed by the Perl community, and is discussed in Chapter 22, "CPAN". See also http://www.cpan.org.

11.1. Using Modules

Modules come in two flavors: traditional and object-oriented. Traditional modules define subroutines and variables for the caller to import and use. Object-oriented modules function as class definitions and are accessed through method calls, described in Chapter 12, "Objects". Some modules do both.

Perl modules are typically included in your program by saying:

use MODULE LIST;
or just:
use MODULE;

MODULE must be an identifier naming the module's package and file. (The syntax descriptions here are meant to be suggestive; the full syntax of the use statement is given in Chapter 29, "Functions".)

The use statement does a preload of MODULE at compile time and then an import of the symbols you've requested so that they'll be available for the rest of the compilation. If you do not supply a LIST of symbols that you want, the symbols named in the module's internal @EXPORT array are used--assuming you're using the Exporter module, described in "Module Privacy and the Exporter" later in this chapter. (If you do supply a LIST, all your symbols must be mentioned in the module's @EXPORT or @EXPORT_OK arrays, or an error will result.)

Since modules use the Exporter to import symbols into the current package, you can use symbols from the module without providing a package qualifier:

use Fred;       # If Fred.pm has @EXPORT = qw(flintstone)
flintstone();   # ...this calls Fred::flintstone().

All Perl module files have the extension .pm. Both use and require assume this (as well as the quotes) so that you don't have to spell out "MODULE.pm". Using the bare identifier helps to differentiate new modules from .pl and .ph libraries used in old versions of Perl. It also introduces MODULE as an official module name, which helps the parser in certain ambiguous situations. Any double colons in the module name are translated into your system's directory separator, so if your module is named Red::Blue::Green, Perl might look for it as Red/Blue/Green.pm.

Perl will search for modules in each of the directories listed in the @INC array. Since use loads modules at compile time, any modifications to @INC need to occur at compile time as well. You can do this with the lib pragma described in Chapter 31, "Pragmatic Modules" or with a BEGIN block. Once a module is included, a key/value pair will be added to the %INC hash. The key will be the module filename (Red/Blue/Green.pm in our example) and the value will be the full pathname, which might be something like C:/perl/site/lib/Red/Blue/Green.pm for a properly installed module on a Windows system.

Module names should be capitalized unless they're functioning as pragmas. Pragmas are in effect compiler directives (hints for the compiler), so we reserve the lowercase pragma names for future use.

When you use a module, any code inside the module is executed, just as it would be for an ordinary require. If you really don't care whether the module is pulled in at compile time or run time, you can just say:

require MODULE;
In general, however, use is preferred over require because it looks for modules during compilation, so you learn about any mistakes sooner.

These two statements do almost the same thing:

require MODULE;
require "MODULE.pm";
They differ in two ways, however. In the first statement, require translates any double colons in the module name into your system's directory separator, just as use does. The second case does no translation, forcing you to specify the pathname of your module literally, which is less portable. The other difference is that the first require tells the compiler that the expressions with indirect object notation involving "MODULE" (such as $ob = purge MODULE) are method calls, not function calls. (Yes, this really can make a difference, if there's a conflicting definition of purge in your own module.)

Because the use declaration and the related no declaration imply a BEGIN block, the compiler loads the module (and runs any executable initialization code in it) as soon as it encounters that declaration, before it compiles the rest of the file. This is how pragmas can change the compiler's behavior, and also how modules are able to declare subroutines that are then visible as list operators for the remainder of compilation. This will not work if you use require instead of use. Just about the only reason to use require is if you have two modules that each need a function from the other. (And we're not sure that's a good reason.)

Perl modules always load a .pm file, but that file may in turn load associated files, such as dynamically linked C or C++ libraries or autoloaded Perl subroutine definitions. If so, the additional shenanigans will be entirely transparent to the module user. It is the responsibility of the .pm file to load (or arrange to autoload) any additional functionality. The POSIX module happens to perform both dynamic loading and autoloading, but the user can say just:

use POSIX;
to get all the exported functions and variables.

Previous | Home | Next
10.2. Autoloading | Book Index | 11.2. Creating Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.2. Creating Modules

Earlier, we said that there are two ways for a module to make its interface available to your program: by exporting symbols or by allowing method calls. We'll show you an example of the first style here; the second style is for object-oriented modules and is described in the next chapter. (Object-oriented modules should export nothing, since the whole idea of methods is that Perl finds them for you automatically, based on the type of the object.)

To construct a module called Bestiary, create a file called Bestiary.pm that looks like this:

package      Bestiary;
require      Exporter;

our @ISA       = qw(Exporter);
our @EXPORT    = qw(camel);    # Symbols to be exported by default
our @EXPORT_OK = qw($weight);  # Symbols to be exported on request
our $VERSION   = 1.00;         # Version number

### Include your variables and functions here

sub camel { print "One-hump dromedary" }

$weight = 1024;

1;
A program can now say use Bestiary to be able to access the camel function (but not the $weight variable), and use Bestiary qw(camel $weight) to access both the function and the variable.

You can also create modules that dynamically load code written in C. See Chapter 21, "Internals and Externals", for details.

11.2.1. Module Privacy and the Exporter

Perl does not automatically patrol private/public borders within its modules--unlike languages such as C++, Java, and Ada, Perl isn't obsessed with enforced privacy. A Perl module would prefer that you stay out of its living room because you weren't invited, not because it has a shotgun.

The module and its user have a contract, part of which is common law and part of which is written. Part of the common law contract is that a module refrain from changing any namespace it wasn't asked to change. The written contract for the module (that is, the documentation) may make other provisions. But then, having read the contract, you presumably know that when you say use RedefineTheWorld you're redefining the world, and you're willing to risk the consequences. The most common way to redefine worlds is to use the Exporter module. As we'll see later in the chapter, you can even redefine built-ins with this module.

When you use a module, the module typically makes some variables or functions available to your program, or more specifically, to your program's current package. This act of exporting symbols from the module (and thus importing them into your program) is sometimes called polluting your namespace. Most modules use Exporter to do this; that's why most modules say something like this near the top:

require Exporter;
our @ISA = ("Exporter");
These two lines make the module inherit from the Exporter class. Inheritance is described in the next chapter, but all you need to know is our Bestiary module can now export symbols into other packages with lines like these:
our @EXPORT    = qw($camel %wolf ram);              # Export by default
our @EXPORT_OK = qw(leopard @llama $emu);           # Export by request
our %EXPORT_TAGS = (                                # Export as group
                     camelids => [qw($camel @llama)],
                     critters => [qw(ram $camel %wolf)],
                   );

From the viewpoint of the exporting module, the @EXPORT array contains the names of variables and functions to be exported by default: what your program gets when it says use Bestiary. Variables and functions in @EXPORT_OK are exported only when the program specifically requests them in the use statement. Finally, the key/value pairs in %EXPORT_TAGS allow the program to include particular groups of the symbols listed in @EXPORT and @EXPORT_OK.

From the viewpoint of the importing package, the use statement specifies a list of symbols to import, a group named in %EXPORT_TAGS, a pattern of symbols, or nothing at all, in which case the symbols in @EXPORT would be imported from the module into your program.

You can include any of these statements to import symbols from the Bestiary module:

use Bestiary;                    # Import @EXPORT symbols
use Bestiary ();                 # Import nothing
use Bestiary qw(ram @llama);     # Import the ram function and @llama array
use Bestiary qw(:camelids);      # Import $camel and @llama
use Bestiary qw(:DEFAULT);       # Import @EXPORT symbols
use Bestiary qw(/am/);           # Import $camel, @llama, and ram
use Bestiary qw(/^\$/);          # Import all scalars
use Bestiary qw(:critters !ram); # Import the critters, but exclude ram
use Bestiary qw(:critters !:camelids);
                                 # Import critters, but no camelids
Leaving a symbol off the export lists (or removing it explicitly from the import list with the exclamation point) does not render it inaccessible to the program using the module. The program will always be able to access the contents of the module's package by fully qualifying the package name, like %Bestiary::gecko. (Since lexical variables do not belong to packages, privacy is still possible: see "Private Methods" in the next chapter.)

You can say BEGIN { $Exporter::Verbose=1 } to see how the specifications are being processed and what is actually being imported into your package.

The Exporter is itself a Perl module, and if you're curious you can see the typeglob trickery it uses to export symbols from one package into another. Inside the Export module, the key function is named import, which performs the necessary aliasing to make a symbol in one package appear to be in another. In fact, a use Bestiary LIST statement is exactly equivalent to:

BEGIN {
    require Bestiary;
    import Bestiary LIST;
}
This means that your modules don't have to use the Exporter. A module can do anything it jolly well pleases when it's used, since use just calls the ordinary import method for the module, and you can define that method to do anything you like.

11.2.1.1. Exporting without using Exporter's import method

The Exporter defines a method called export_to_level, used for situations where (for some reason) you can't directly call Exporter's import method. The export_to_level method is invoked like this:

MODULE->export_to_level($where_to_export, @what_to_export);
where $where_to_export is an integer indicating how far up the calling stack to export your symbols, and @what_to_export is an array listing the symbols to export (usually @_).

For example, suppose our Bestiary had an import function of its own:

package Bestiary;
@ISA = qw(Exporter);
@EXPORT_OK = qw ($zoo);

sub import {
    $Bestiary::zoo = "menagerie";
}
The presence of this import function prevents Exporter's import function from being inherited. If you want Bestiary's import function to behave just like Exporter's import function once it sets $Bestiary::zoo, you'd define it as follows:
sub import {
    $Bestiary::zoo = "menagerie";
    Bestiary->export_to_level(1, @_);
}
This exports symbols to the package one level "above" the current package. That is, to whatever program or module is using the Bestiary.

11.2.1.2. Version checking

If your module defines a $VERSION variable, a program using your module can ensure that the module is sufficiently recent. For example:

use Bestiary 3.14;   # The Bestiary must be version 3.14 or later
use Bestiary v1.0.4; # The Bestiary must be version 1.0.4 or later
These are converted into calls to Bestiary->require_version, which your module then inherits.

11.2.1.3. Managing unknown symbols

In some situations, you may want to prevent certain symbols from being exported. Typically, this applies to modules that have functions or constants that might not make sense on some systems. You can prevent the Exporter from exporting those symbols by placing them in the @EXPORT_FAIL array.

If a program attempts to import any of these symbols, the Exporter gives the module an opportunity to handle the situation before generating an error. It does this by calling an export_fail method with a list of the failed symbols, which you might define as follows (assuming your module uses the Carp module):

sub export_fail {
    my $class = shift;
    carp "Sorry, these symbols are unavailable: @_";
    return @_;
}
The Exporter provides a default export_fail method, which simply returns the list unchanged and makes the use fail with an exception raised for each symbol. If export_fail returns an empty list, no error is recorded and all the requested symbols are exported.

11.2.1.4. Tag-handling utility functions

Since the symbols listed within %EXPORT_TAGS must also appear in either @EXPORT or @EXPORT_OK, the Exporter provides two functions to let you add those tagged sets of symbols:

%EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);

Exporter::export_tags('foo');     # add aa, bb and cc to @EXPORT
Exporter::export_ok_tags('bar');  # add aa, cc and dd to @EXPORT_OK
Specifying names that are not tags is erroneous.

Previous | Home | Next
11.1. Using Modules | Book Index | 11.3. Overriding Built-in Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


11.3. Overriding Built-in Functions

Many built-in functions may be overridden, although (like knocking holes in your walls) you should do this only occasionally and for good reason. Typically, this might be done by a package attempting to emulate missing built-in functionality on a non-Unix system. (Do not confuse overriding with overloading, which adds additional object-oriented meanings to built-in operators, but doesn't override much of anything. See the discussion of the overload module in Chapter 13, "Overloading" for more on that.)

Overriding may be done only by importing the name from a module--ordinary predeclaration isn't good enough. To be perfectly forthcoming, it's the assignment of a code reference to a typeglob that triggers the override, as in *open = \&myopen. Furthermore, the assignment must occur in some other package; this makes accidental overriding through typeglob aliasing intentionally difficult. However, if you really want to do your own overriding, don't despair, because the subs pragma lets you predeclare subroutines via the import syntax, so those names then override the built-in ones:

use subs qw(chdir chroot chmod chown);
chdir $somewhere;
sub chdir { ... }
In general, modules should not export built-in names like open or chdir as part of their default @EXPORT list, since these names may sneak into someone else's namespace and change the semantics unexpectedly. If the module includes the name in the @EXPORT_OK list instead, importers will be forced to explicitly request that the built-in name be overridden, thus keeping everyone honest.

The original versions of the built-in functions are always accessible via the CORE pseudopackage. Therefore, CORE::chdir will always be the version originally compiled into Perl, even if the chdir keyword has been overridden.

Well, almost always. The foregoing mechanism for overriding built-in functions is restricted, quite deliberately, to the package that requests the import. But there is a more sweeping mechanism you can use when you wish to override a built-in function everywhere, without regard to namespace boundaries. This is achieved by defining the function in the CORE::GLOBAL pseudopackage. Below is an example that replaces the glob operator with something that understands regular expressions. (Note that this example does not implement everything needed to cleanly override Perl's built-in glob, which behaves differently depending on whether it appears in a scalar or list context. Indeed, many Perl built-ins have such context-sensitive behaviors, and any properly written override should adequately support these. For a fully functional example of glob overriding, study the File::Glob module bundled with Perl.) Anyway, here's the antisocial version:

*CORE::GLOBAL::glob = sub {
    my $pat = shift;
    my @got;
    local *D;
    if (opendir D, '.') {
        @got = grep /$pat/, readdir D;
        closedir D;
    }
    return @got;
}

package Whatever;

print <^[a-z_]+\.pm\$>;       # show all pragmas in the current directory
By overriding glob globally, this preemptively forces a new (and subversive) behavior for the glob operator in every namespace, without the cognizance or cooperation of modules that own those namespaces. Naturally, this must be done with extreme caution--if it must be done at all. And it probably mustn't.

Our overriding philosophy is: it's nice to be important, but it's more important to be nice.

Previous | Home | Next
11.2. Creating Modules | Book Index | 12. Objects
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 12. Objects

Contents:

Brief Refresher on Object-Oriented Lingo
Perl's Object System
Method Invocation
Object Construction
Class Inheritance
Instance Destructors
Managing Instance Data
Managing Class Data
Summary

First of all, you need to understand packages and modules; see Chapter 10, "Packages", and Chapter 11, "Modules". You also need to know about references and data structures; see Chapter 8, "References" and Chapter 9, "Data Structures". It's also helpful to understand a little about object-oriented programming (OOP), so in the next section we'll give you a little course on OOL (object-oriented lingo).

12.1. Brief Refresher on Object-Oriented Lingo

An object is a data structure with a collection of behaviors. We generally speak of the behaviors as acted out by the object directly, sometimes to the point of anthropomorphizing the object. For example, we might say that a rectangle "knows" how to display itself on the screen, or that it "knows" how to compute its own area.

Every object gets its behaviors by virtue of being an instance of a class. The class defines methods: behaviors that apply to the class and its instances. When the distinction matters, we refer to methods that apply only to a particular object as instance methods and those that apply to the entire class as class methods. But this is only a convention--to Perl, a method is just a method, distinguished only by the type of its first argument.

You can think of an instance method as some action performed by a particular object, such as printing itself out, copying itself, or altering one or more of its properties ("set this sword's name to Anduril"). Class methods might perform operations on many objects collectively ("display all swords") or provide other operations that aren't dependent on any particular object ("from now on, whenever a new sword is forged, register its owner in this database"). Methods that generate instances (objects) of a class are called constructor methods ("create a sword with a gem-studded hilt and a secret inscription"). These are usually class methods ("make me a new sword") but can also be instance methods ("make a copy just like this sword here").

A class may inherit methods from parent classes, also known as base classes or superclasses. If it does, it's known as a derived class or a subclass. (Confusing the issue further, some literature uses "base class" to mean a "most super" superclass. That's not what we mean by it.) Inheritance makes a new class that behaves just like an existing one but also allows for altered or added behaviors not found in its parents. When you invoke a method whose definition is not found in the class, Perl automatically consults the parent classes for a definition. For example, a sword class might inherit its attack method from a generic blade class. Parents can themselves have parents, and Perl will search those classes as well when it needs to. The blade class might in turn inherit its attack method from an even more generic weapon class.

When the attack method is invoked on an object, the resulting behavior may depend on whether that object is a sword or an arrow. Perhaps there wouldn't be any difference at all, which would be the case if both swords and arrows inherited their attacking behavior from the generic weapon class. But if there were a difference in behaviors, the method dispatch mechanism would always select the attack method suitable for the object in question. The useful property of always selecting the most appropriate behavior for a particular type of object is known as polymorphism. It's an important form of not caring.

You have to care about the innards of your objects when you're implementing a class, but when you use a class, you should be thinking of its objects as black boxes. You can't see what's inside, you shouldn't need to know how it works, and you interact with the box only on its terms: via the methods provided by the class. Even if you know what those methods do to the object, you should resist the urge to fiddle around yourself. It's like the remote control for your television set: even if you know what's going on inside it, you shouldn't monkey with its innards without good reason.

Perl lets you peer inside the object from outside the class when you need to. But doing so breaks its encapsulation, the principle that all access to an object should be through methods alone. Encapsulation decouples the published interface (how an object should be used) from the implementation (how it actually works). Perl does not have an explicit interface facility apart from this unwritten contract between designer and user. Both parties are expected to exercise common sense and common decency: the user by relying only upon the documented interface, the designer by not breaking that interface.

Perl doesn't force a particular style of programming on you, and it doesn't have the obsession with privacy that some other object-oriented languages do. Perl does have an obsession with freedom, however, and one of the freedoms you have as a Perl programmer is the right to select as much or as little privacy as you like. In fact, Perl can have stronger privacy in its classes and objects than C++. That is, Perl does not restrict you from anything, and in particular it doesn't restrict you from restricting yourself, if you're into that kind of thing. The sections Section 12.5.5, "Private Methods" and Section 12.7.5, "Using Closures for Private Objects" later in this chapter demonstrate how you can increase your dosage of discipline.

Admittedly, there's a lot more to objects than this, and a lot of ways to find out more about object-oriented design. But that's not our purpose here. So, on we go.

Previous | Home | Next
11.3. Overriding Built-in Functions | Book Index | 12.2. Perl's Object System
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.2. Perl's Object System

Perl doesn't provide any special syntax for defining objects, classes, or methods. Instead, it reuses existing constructs to implement these three concepts.[1]

[1]Now there's an example of software reuse for you!

Here are some simple definitions that you may find reassuring:

An object is simply a reference...er, a referent.

Since references let individual scalars represent larger collections of data, it shouldn't be a surprise that references are used for all objects. Technically, an object isn't the reference proper--it's really the referent that the reference points at. This distinction is frequently blurred by Perl programmers, however, and since we feel it's a lovely metonymy, we will perpetuate the usage here when it suits us.[2]

[2] We prefer linguistic vigor over mathematical rigor. Either you will agree or you won't.

A class is simply a package.

A package serves as a class by using the package's subroutines to execute the class's methods, and by using the package's variables to hold the class's global data. Often, a module is used to hold one or more classes.

A method is simply a subroutine.

You just declare subroutines in the package you're using as the class; these will then be used as the class's methods. Method invocation, a new way to call subroutines, passes an extra argument: the object or package used for invoking the method.

Previous | Home | Next
12.1. Brief Refresher on Object-Oriented Lingo | Book Index | 12.3. Method Invocation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.3. Method Invocation

If you were to boil down all of object-oriented programming into one quintessential notion, it would be abstraction. It's the single underlying theme you'll find running through all those 10-dollar words that OO enthusiasts like to bandy about, like polymorphism and inheritance and encapsulation. We believe in those fancy words, but we'll address them from the practical viewpoint of what it means to invoke methods. Methods lie at the heart of the object system because they provide the abstraction layer needed to implement all these fancy terms. Instead of directly accessing a piece of data sitting in an object, you invoke an instance method. Instead of directly calling a subroutine in some package, you invoke a class method. By interposing this level of indirection between class use and class implementation, the program designer remains free to tinker with the internal workings of the class, with little risk of breaking programs that use it.

Perl supports two different syntactic forms for invoking methods. One uses a familiar style you've already seen elsewhere in Perl, and the second is a form you may recognize from other programming languages. No matter which form of method invocation is used, the subroutine constituting the method is always passed an extra initial argument. If a class is used to invoke the method, that argument will be the name of the class. If an object is used to invoke the method, that argument will be the reference to the object. Whichever it is, we'll call it the method's invocant. For a class method, the invocant is the name of a package. For an instance method, the invocant is a reference that specifies an object.

In other words, the invocant is whatever the method was invoked with. Some OO literature calls this the method's agent or its actor. Grammatically, the invocant is neither the subject of the action nor the receiver of that action. It's more like an indirect object, the beneficiary on whose behalf the action is performed--just like the word "me" in the command, "Forge me a sword!" Semantically, you can think of the invocant as either an invoker or an invokee, whichever fits better into your mental apparatus. We're not going to tell you how to think. (Well, not about that.)

Most methods are invoked explicitly, but methods may also be invoked implicitly when triggered by object destructors, overloaded operators, or tied variables. Properly speaking, these are not regular subroutine calls, but rather method invocations automatically triggered by Perl on behalf of an object. Destructors are described later in this chapter, overloading is described in Chapter 13, "Overloading", and ties are described in Chapter 14, "Tied Variables".

One difference between methods and regular subroutines is when their packages are resolved--that is, how early (or late) Perl decides which code should be executed for the method or subroutine. A subroutine's package is resolved during compilation, before your program begins to run.[3] In contrast, a method's package isn't resolved until it is actually invoked. (Prototypes are checked at compile time, which is why regular subroutines can use them but methods can't.)

[3] More precisely, the subroutine call is resolved down to a particular typeglob, a reference to which is stuffed into the compiled opcode tree. The meaning of that typeglob is negotiable even at run time--this is how AUTOLOAD can autoload a subroutine for you. Normally, however, the meaning of the typeglob is also resolved at compile time by the definition of an appropriately named subroutine.

The reason a method's package can't be resolved earlier is relatively straightforward: the package is determined by the class of the invocant, and the invocant isn't known until the method is actually invoked. At the heart of OO is this simple chain of logic: once the invocant is known, the invocant's class is known, and once the class is known, the class's inheritance is known, and once the class's inheritance is known, the actual subroutine to call is known.

The logic of abstraction comes at a price. Because of the late resolution of methods, an object-oriented solution in Perl is likely to run slower than the corresponding non-OO solution. For some of the fancier techniques described later, it could be a lot slower. However, many common problems are solved not by working faster, but by working smarter. That's where OO shines.

12.3.1. Method Invocation Using the Arrow Operator

We mentioned that there are two styles of method invocation. The first style for invoking a method looks like this:

INVOCANT->METHOD(LIST)
INVOCANT->METHOD

For obvious reasons, this style is usually called the arrow form of invocation. (Do not confuse -> with =>, the "double-barreled" arrow used as a fancy comma.) Parentheses are required if there are any arguments. When executed, the invocation first locates the subroutine determined jointly by the class of the INVOCANT and the METHOD name, and then calls that subroutine, passing INVOCANT as its first argument.

When INVOCANT is a reference, we say that METHOD is invoked as an instance method, and when INVOCANT is a package name, we say that METHOD is invoked as a class method. There really is no difference between the two, other than that the package name is more obviously associated with the class itself than with the objects of the class. You'll have to take our word for it that the objects also know their class. We'll tell you in a bit how to associate an object with a class name, but you can use objects without knowing that.

For example, to construct an object using the class method summon and then invoke the instance method speak on the resulting object, you might say this:

$mage = Wizard->summon("Gandalf");  # class method
$mage->speak("friend");             # instance method
The summon and speak methods are defined by the Wizard class--or one of the classes from which it inherits. But you shouldn't worry about that. Do not meddle in the affairs of Wizards.

Since the arrow operator is left associative (see Chapter 3, "Unary and Binary Operators"), you can even combine the two statements into one:

Wizard->summon("Gandalf")->speak("friend");
Sometimes you want to invoke a method without knowing its name ahead of time. You can use the arrow form of method invocation and replace the method name with a simple scalar variable:
$method = "summon";
$mage = Wizard->$method("Gandalf");  # Invoke Wizard->summon

$travel = $companion eq "Shadowfax" ? "ride" : "walk";
$mage->$travel("seven leagues");     # Invoke $mage->ride or $mage->walk
Although you're using the name of the method to invoke it indirectly, this usage is not forbidden by use strict 'refs', since all method calls are in fact looked up symbolically at the time they're resolved.

In our example, we stored the name of a subroutine in $travel, but you could also store a subroutine reference. This bypasses the method lookup algorithm, but sometimes that's exactly what you want to do. See both the section Section 12.5.5, "Private Methods" and the discussion of the can method in the section Section 12.5.3, "UNIVERSAL: The Ultimate Ancestor Class". To create a reference to a particular method being called on a particular instance, see the section Section 12.3.7, "Closures" in Chapter 8, "References".

12.3.2. Method Invocation Using Indirect Objects

The second style of method invocation looks like this:

METHOD INVOCANT (LIST)
METHOD INVOCANT LIST
METHOD INVOCANT

The parentheses around LIST are optional; if omitted, the method acts as a list operator. So you can have statements like the following, all of which use this style of method call:

$mage = summon Wizard "Gandalf";
$nemesis = summon Balrog home => "Moria", weapon => "whip";
move $nemesis "bridge";
speak $mage "You cannot pass";
break $staff;               # safer to use: break $staff ();
The list operator syntax should be familiar to you; it's the same style used for passing filehandles to print or printf:
print STDERR "help!!!\n";
It's also similar to English sentences like "Give Gollum the Preciousss", so we call it the indirect object form. The invocant is expected in the indirect object slot. When you read about passing a built-in function like system or exec something in its "indirect object slot", this means that you're supplying this extra, comma-less argument in the same place you would when you invoke a method using the indirect object syntax.

The indirect object form even permits you to specify the INVOCANT as a BLOCK that evaluates to an object (reference) or class (package). This lets you combine those two invocations into one statement this way:

speak { summon Wizard "Gandalf" } "friend";

12.3.3. Syntactic Snafus with Indirect Objects

One syntax will often be more readable than the other. The indirect object syntax is less cluttered, but suffers from several forms of syntactic ambiguity. The first is that the LIST part of an indirect object invocation is parsed the same as any other list operator. Thus, the parentheses of:

enchant $sword ($pips + 2) * $cost;
are assumed to surround all the arguments, regardless of what comes afterward. It would therefore be be equivalent to this:
($sword->enchant($pips + 2)) * $cost;
That's unlikely to do what you want: enchant is only being called with $pips + 2, and the method's return value is then multiplied by $cost. As with other list operators, you must also be careful of the precedence of && and || versus and and or.

For example, this:

name $sword $oldname || "Glamdring";   # can't use "or" here!
becomes the intended:
$sword->name($oldname || "Glamdring");
but this:
speak $mage "friend" && enter();        # should've been "and" here!
becomes the dubious:
$mage->speak("friend" && enter());
which could be fixed by rewriting into one of these equivalent forms:
enter() if $mage->speak("friend");
$mage->speak("friend") && enter();
speak $mage "friend" and enter();
The second syntactic infelicity of the indirect object form is that its INVOCANT is limited to a name, an unsubscripted scalar variable, or a block.[4] As soon as the parser sees one of these, it has its INVOCANT, so it starts looking for its LIST. So these invocations:
move $party->{LEADER};               # probably wrong!
move $riders[$i];                    # probably wrong!
actually parse as these:
$party->move->{LEADER};
$riders->move([$i]);
rather than what you probably wanted:
$party->{LEADER}->move;
$riders[$i]->move;
The parser only looks a little ways ahead to find the invocant for an indirect object, not even as far as it would look for a unary operator. This oddity does not arise with the first notation, so you might wish to stick with the arrow as your weapon of choice.

[4] Attentive readers will recall that this is precisely the same list of syntactic items that are allowed after a funny character to indicate a variable dereference--for example, @ary, @$aryref, or @{$aryref}.

Even English has a similar issue here. Think about the command, "Throw your cat out the window a toy mouse to play with." If you parse that sentence too quickly, you'll end up throwing the cat, not the mouse (unless you notice that the cat is already out the window). Like Perl, English has two different syntaxes for expressing the agent: "Throw your cat the mouse" and "Throw the mouse to your cat." Sometimes the longer form is clearer and more natural, and sometimes the shorter one is. At least in Perl, you're required to use braces around any complicated indirect object.

12.3.4. Package-Quoted Classes

The final syntactic ambiguity with the indirect object style of method invocation is that it may not be parsed as a method call at all, because the current package may have a subroutine of the same name as the method. When using a class method with a literal package name as the invocant, there is a way to resolve this ambiguity while still keeping the indirect object syntax: package-quote the classname by appending a double colon to it.

$obj = method CLASS::;   # forced to be "CLASS"->method
This is important because the commonly seen notation:
$obj = new CLASS;        # might not parse as method
will not always behave properly if the current package has a subroutine named new or CLASS. Even if you studiously use the arrow form instead of the indirect object form to invoke methods, this can, on rare occasion, still be a problem. At the cost of extra punctuation noise, the CLASS:: notation guarantees how Perl will parse your method invocation. The first two examples below do not always parse the same way, but the second two do:
$obj = new ElvenRing;               # could be new("ElvenRing")
                                    # or even new(ElvenRing())
$obj = ElvenRing->new;              # could be ElvenRing()->new()

$obj = new ElvenRing::;             # always "ElvenRing"->new()
$obj = ElvenRing::->new;            # always "ElvenRing"->new()
This package-quoting notation can be made prettier with some creative alignment:
$obj = new ElvenRing::
            name    => "Narya",
            owner   => "Gandalf",
            domain  => "fire",
            stone   => "ruby";
Still, you may say, "Oh, ugh!" at that double colon, so we'll tell you that you can almost always get away with a bare class name, provided two things are true. First, there is no subroutine of the same name as the class. (If you follow the convention that subroutine names like new start lowercase and class names like ElvenRing start uppercase, this is never a problem.) Second, the class has been loaded with one of:
use ElvenRing;
require ElvenRing;
Either of these declarations ensures that Perl knows ElvenRing is a module name, which forces any bare name like new before the class name ElvenRing to be interpreted as a method call, even if you happen to have declared a new subroutine of your own in the current package. People don't generally get into trouble with indirect objects unless they start cramming multiple classes into the same file, in which case Perl might not know that a particular package name was supposed to be a class name. People who name subroutines with names that look like ModuleNames also come to grief eventually.

Previous | Home | Next
12.2. Perl's Object System | Book Index | 12.4. Object Construction
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.4. Object Construction

All objects are references, but not all references are objects. A reference won't work as an object unless its referent is specially marked to tell Perl what package it belongs to. The act of marking a referent with a package name--and therefore, its class, since a class is just a package--is known as blessing. You can think of the blessing as turning a reference into an object, although it's more accurate to say that it turns the reference into an object reference.

The bless function takes either one or two arguments. The first argument is a reference and the second is the package to bless the referent into. If the second argument is omitted, the current package is used.

$obj = { };                 # Get reference to anonymous hash.
bless($obj);                # Bless hash into current package.
bless($obj, "Critter");     # Bless hash into class Critter.
Here we've used a reference to an anonymous hash, which is what people usually use as the data structure for their objects. Hashes are extremely flexible, after all. But allow us to emphasize that you can bless a reference to anything you can make a reference to in Perl, including scalars, arrays, subroutines, and typeglobs. You can even bless a reference to a package's symbol table hash if you can think of a good reason to. (Or even if you can't.) Object orientation in Perl is completely orthogonal to data structure.

Once the referent has been blessed, calling the built-in ref function on its reference returns the name of the blessed class instead of the built-in type, such as HASH. If you want the built-in type, use the reftype function from the attributes module. See use attributes in Chapter 31, "Pragmatic Modules".

And that's how to make an object. Just take a reference to something, give it a class by blessing it into a package, and you're done. That's all there is to it if you're designing a minimal class. If you're using a class, there's even less to it, because the author of a class will have hidden the bless inside a method called a constructor, which creates and returns instances of the class. Because bless returns its first argument, a typical constructor can be as simple as this:

package Critter;
sub spawn { bless {}; }
Or, spelled out slightly more explicitly:
package Critter;
sub spawn {
    my     $self = {};       # Reference to an empty anonymous hash
    bless  $self, "Critter"; # Make that hash a Critter object
    return $self;            # Return the freshly generated Critter
}
With that definition in hand, here's how one might create a Critter object:
$pet = Critter->spawn;

12.4.1. Inheritable Constructors

Like all methods, a constructor is just a subroutine, but we don't call it as a subroutine. We always invoke it as a method--a class method, in this particular case, because the invocant is a package name. Method invocations differ from regular subroutine calls in two ways. First, they get the extra argument we discussed earlier. Second, they obey inheritance, allowing one class to use another's methods.

We'll describe the underlying mechanics of inheritance more rigorously in the next section, but for now, some simple examples of its effects should help you design your constructors. For instance, suppose we have a Spider class that inherits methods from the Critter class. In particular, suppose the Spider class doesn't have its own spawn method. The following correspondences apply:

Method Call | Resulting Subroutine Call
Critter->spawn() | Critter::spawn("Critter")
Spider->spawn() | Critter::spawn("Spider")

The subroutine called is the same in both cases, but the argument differs. Note that our spawn constructor above completely ignored its argument, which means our Spider object was incorrectly blessed into class Critter. A better constructor would provide the package name (passed in as the first argument) to bless:

sub spawn {
    my $class =  shift;       # Store the package name
    my $self  =  { };
    bless($self, $class);     # Bless the reference into that package
    return $self;
}
Now you could use the same subroutine for both these cases:
$vermin = Critter->spawn;
$shelob = Spider->spawn;
And each object would be of the proper class. This even works indirectly, as in:
$type  = "Spider";
$shelob = $type->spawn;         # same as "Spider"->spawn
That's still a class method, not an instance method, because its invocant holds a string and not a reference.

If $type were an object instead of a class name, the previous constructor definition wouldn't have worked, because bless needs a class name. But for many classes, it makes sense to use an existing object as the template from which to create another. In these cases, you can design your constructors so that they work with either objects or class names:

sub spawn {
    my $invocant = shift;
    my $class    = ref($invocant) || $invocant;  # Object or class name
    my $self     = { };
    bless($self, $class);
    return $self;
}

12.4.2. Initializers

Most objects maintain internal information that is indirectly manipulated by the object's methods. All our constructors so far have created empty hashes, but there's no reason to leave them empty. For instance, we could have the constructor accept extra arguments to store into the hash as key/value pairs. The OO literature often refers to such data as properties, attributes, accessors, member data, instance data, or instance variables. The section "Instance Variables" later in this chapter discusses attributes in more detail.

Imagine a Horse class with instance attributes like "name" and "color":

$steed = Horse->new(name => "Shadowfax", color => "white");
If the object is implemented as a hash reference, the key/value pairs can be interpolated directly into the hash once the invocant is removed from the argument list:
sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = { @_ };          # Remaining args become attributes
    bless($self, $class);       # Bestow objecthood
    return $self;
}
This time we used a method named new for the class's constructor, which just might lull C++ programmers into thinking they know what's going on. But Perl doesn't consider "new" to be anything special; you may name your constructors whatever you like. Any method that happens to create and return an object is a de facto constructor. In general, we recommend that you name your constructors whatever makes sense in the context of the problem you're solving. For example, constructors in the Tk module are named after the widgets they create. In the DBI module, a constructor named connect returns a database handle object, and another constructor named prepare is invoked as an instance method and returns a statement handle object. But if there is no suitable context-specific constructor name, new is perhaps not a terrible choice. Then again, maybe it's not such a bad thing to pick a random name to force people to read the interface contract (meaning the class documentation) before they use its constructors.

Elaborating further, you can set up your constructor with default key/value pairs, which the user could later override by supplying them as arguments:

sub new {
    my $invocant = shift;
    my $class   = ref($invocant) || $invocant;
    my $self = {
        color  => "bay",
        legs   => 4,
        owner  => undef,
        @_,                 # Override previous attributes
    };
    return bless $self, $class;
}

$ed       = Horse->new;                    # A 4-legged bay horse
$stallion = Horse->new(color => "black");  # A 4-legged black horse
This Horse constructor ignores its invocant's existing attributes when used as an instance method. You could create a second constructor designed to be called as an instance method, and if designed properly, you could use the values from the invoking object as defaults for the new one:
$steed  = Horse->new(color => "dun");
$foal   = $steed->clone(owner => "EquuGen Guild, Ltd.");

sub clone {
    my $model = shift;
    my $self  = $model->new(%$model, @_);
    return $self;     # Previously blessed by ->new
}
(You could also have rolled this functionality directly into new, but then the name wouldn't quite fit the function.)

Notice how even in the clone constructor, we don't hardcode the name of the Horse class. We have the original object invoke its own new method, whatever that may be. If we had written that as Horse->new instead of $model->new, then the class wouldn't have facilitated inheritance by a Zebra or Unicorn class. You wouldn't want to clone Pegasus and suddenly find yourself with a horse of a different color.

Sometimes, however, you have the opposite problem: rather than trying to share one constructor among several classes, you're trying to have several constructors share one class's object. This happens whenever a constructor wants to call a base class's constructor to do part of the construction work. Perl doesn't do hierarchical construction for you. That is, Perl does not automatically call the constructors (or the destructors) for any base classes of the class requested, so your constructor will have to do that itself and then add any additional attributes the derived class needs. So the situation is not unlike the clone routine, except that instead of copying an existing object into the new object, you want to call your base class's constructor and then transmogrify the new base object into your new derived object.

Previous | Home | Next
12.3. Method Invocation | Book Index | 12.5. Class Inheritance
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.5. Class Inheritance

As with the rest of Perl's object system, inheritance of one class by another requires no special syntax to be added to the language. When you invoke a method for which Perl finds no subroutine in the invocant's package, that package's @ISA array[5] is examined. This is how Perl implements inheritance: each element of a given package's @ISA array holds the name of another package, which is searched when methods are missing. For example, the following makes the Horse class a subclass of the Critter class. (We declare @ISA with our because it has to be a package variable, not a lexical declared with my.)

package Horse;
our @ISA = "Critter";
You should now be able to use a Horse class or object everywhere that a Critter was previously used. If your new class passes this empty subclass test, you know that Critter is a proper base class, fit for inheritance.

[5] Pronounced "is a", as in "A horse is a critter."

Suppose you have a Horse object in $steed and invoke a move method on it:

$steed->move(10);
Because $steed is a Horse, Perl's first choice for that method is the Horse::move subroutine. If there isn't one, instead of raising a run-time exception, Perl consults the first element of @Horse::ISA, which directs it to look in the Critter package for Critter::move. If this subroutine isn't found either, and Critter has its own @Critter::ISA array, then that too will be consulted for the name of an ancestral package that might supply a move method, and so on back up the inheritance hierarchy until we come to a package without an @ISA.

The situation we just described is single inheritance, where each class has only one parent. Such inheritance is like a linked list of related packages. Perl also supports multiple inheritance; just add more packages to the class's @ISA. This kind of inheritance works more like a tree data structure, because every package can have more than one immediate parent. Some people find this to be sexier.

When you invoke a method methname on an invocant of type classname, Perl tries six different ways to find a subroutine to use:

  1. First, Perl looks in the invocant's own package for a subroutine named classname::methname. If that fails, inheritance kicks in, and we go to step 2.

  2. Next, Perl checks for methods inherited from base classes by looking in all parent packages listed in @classname::ISA for a parent::methname subroutine. The search is left-to-right, recursive, and depth-first. The recursion assures that grandparent classes, great-grandparent classes, great-great-grandparent classes, and so on, are all searched.

  3. If that fails, Perl looks for a subroutine named UNIVERSAL::methname.

  4. At this point, Perl gives up on methname and starts looking for an AUTOLOAD. First, it looks for a subroutine named classname::AUTOLOAD.

  5. Failing that, Perl searches all parent packages listed in @classname::ISA, for any parent::AUTOLOAD subroutine. The search is again left-to-right, recursive, and depth-first.

  6. Finally, Perl looks for a subroutine named UNIVERSAL::AUTOLOAD.

Perl stops after the first successful attempt and invokes that subroutine. If no subroutine is found, an exception is raised, one that you'll see frequently:

Can't locate object method "methname" via package "classname"
If you've built a debugging version of Perl using the -DDEBUGGING option to your C compiler, by using Perl's -Do switch, you can watch it go through each of these steps when it resolves method invocation.

We will discuss the inheritance mechanism in more detail as we go along.

12.5.1. Inheritance Through @ISA

If @ISA contains more than one package name, the packages are all searched in left-to-right order. The search is depth-first, so if you have a Mule class set up for inheritance this way:

package Mule;
our @ISA = ("Horse", "Donkey");
Perl looks for any methods missing from Mule first in Horse (and any of its ancestors, like Critter) before going on to search through Donkey and its ancestors.

If a missing method is found in a base class, Perl internally caches that location in the current class for efficiency, so the next time it has to find the method, it doesn't have to look as far. Changing @ISA or defining new methods invalidates the cache and causes Perl to perform the lookup again.

When Perl searches for a method, it makes sure that you haven't created a circular inheritance hierarchy. This could happen if two classes inherit from one another, even indirectly through other classes. Trying to be your own great-grandfather is too paradoxical even for Perl, so the attempt raises an exception. However, Perl does not consider it an error to inherit from more than one class sharing a common ancestry, which is rather like cousins marrying. Your inheritance hierarchy just stops looking like a tree and starts to look like a directed acyclic graph. This doesn't bother Perl--so long as the graph really is acyclic.

When you set @ISA, the assignment normally happens at run time, so unless you take precautions, code in BEGIN, CHECK, or INIT blocks won't be able to use the inheritance hierarchy. One precaution (or convenience) is the use base pragma, which lets you require classes and add them to @ISA at compile time. Here's how you might use it:

package Mule;
use base ("Horse", "Donkey");   # declare superclasses
This is a shorthand for:
package Mule;
BEGIN {
    our @ISA = ("Horse", "Donkey");
    require Horse;
    require Donkey;
}
except that use base also takes into account any use fields declarations.

Sometimes folks are surprised that including a class in @ISA doesn't require the appropriate module for you. That's because Perl's class system is largely orthogonal to its module system. One file can hold many classes (since they're just packages), and one package may be mentioned in many files. But in the most common situation, where one package and one class and one module and one file all end up being pretty interchangeable if you squint enough, the use base pragma offers a declarative syntax that establishes inheritance, loads in module files, and accommodates any declared base class fields. It's one of those convenient diagonals we keep mentioning.

See the descriptions of use base and use fields in Chapter 31, "Pragmatic Modules" for further details.

12.5.2. Accessing Overridden Methods

When a class defines a method, that subroutine overrides methods of the same name in any base classes. Imagine that you've a Mule object (which is derived from class Horse and class Donkey), and you decide to invoke your object's breed method. Although the parent classes have their own breed methods, the designer of the Mule class overrode those by supplying the Mule class with its own breed method. That means the following cross is unlikely to be productive:

$stallion = Horse->new(gender => "male");
$molly = Mule->new(gender => "female");
$colt = $molly->breed($stallion);
Now suppose that through the miracle of genetic engineering, you find some way around a mule's notorious sterility problem, so you want to skip over the nonviable Mule::breed method. You could call your method as an ordinary subroutine, being sure to pass the invocant explicitly:
$colt = Horse::breed($molly, $stallion);
However, this sidesteps inheritance, which is nearly always the wrong thing to do. It's perfectly imaginable that no Horse::breed subroutine exists because both Horses and Donkeys derive that behavior from a common parent class called Equine. If, on the other hand, you want to specify that Perl should start searching for a method in a particular class, just use ordinary method invocation but qualify the method name with the class:
$colt = $molly->Horse::breed($stallion);
Occasionally, you'll want a method in a derived class to act as a wrapper around some method in a base class. The method in the derived class can itself invoke the method in the base class, adding its own actions before or after that invocation. You could use the notation just demonstrated to specify at which class to start the search. But in most cases of overridden methods, you don't want to have to know or specify which parent class's overridden method to execute.

That's where the SUPER pseudoclass comes in handy. It lets you invoke an overridden base class method without having to specify which class defined that method.[6] The following subroutine looks in the current package's @ISA without making you specify particular classes:

package Mule;
our @ISA = qw(Horse Donkey);
sub kick {
    my $self = shift;
    print "The mule kicks!\n";
    $self->SUPER::kick(@_);
}
The SUPER pseudopackage is meaningful only when used inside a method. Although the implementer of a class can employ SUPER in their own code, someone who merely uses a class's objects cannot.

[6] This is not to be confused with the mechanism mentioned in Chapter 11, "Modules" for overriding Perl's built-in functions, which aren't object methods and so aren't overridden by inheritance. You call overridden built-ins via the CORE pseudopackage, not the SUPER pseudopackage.

SUPER does not always work as you might like when multiple inheritance is involved. As you'd expect, it follows @ISA just as the regular inheritance mechanism does: in left-to-right, recursive, depth-first order. If both Horse and Donkey had a speak method, and you preferred the Donkey method, you'd have to name that parent class explicitly:

sub speak {
    my $self = shift;
    print "The mule speaks!\n";
    $self->Donkey::speak(@_);
}
More elaborate approaches to multiple inheritance situations can be crafted using the UNIVERSAL::can method described in the next section. Or you can grab the Class::Multimethods module from CPAN, which provides many elaborate solutions, including finding the closest match instead of leftmost one.

Every bit of code in Perl knows what its current package is, as determined by the last package statement. A SUPER method consults the @ISA only of the package into which the call to SUPER was compiled. It does not care about the class of the invocant, nor about the package of the subroutine that was called. This can cause problems if you try to define methods in another class by merely playing tricks with the method name:

package Bird;
use Dragonfly;
sub Dragonfly::divebomb { shift->SUPER::divebomb(@_) }

Unfortunately, this invokes Bird's superclass, not Dragonfly's. To do what you're trying to do, you need to explicitly switch into the appropriate package for the compilation of SUPER as well:

package Bird;
use Dragonfly;
{
    package Dragonfly;
    sub divebomb { shift->SUPER::divebomb(@_) }
}
As this example illustrates, you never need to edit a module file just to add methods to an existing class. Since a class is just a package, and a method just a subroutine, all you have to do is define a function in that package as we've done here, and the class suddenly has a new method. No inheritance required. Only the package matters, and since packages are global, any package can be accessed from anywhere in the program. (Did we mention we're going to install a jacuzzi in your living room next week?)

12.5.3. UNIVERSAL: The Ultimate Ancestor Class

If no method definition with the right name is found after searching the invocant's class and all its ancestor classes recursively, one more check for a method of that name is made in the special predefined class called UNIVERSAL. This package never appears in an @ISA, but is always consulted when an @ISA check fails. You can think of UNIVERSAL as the ultimate ancestor from which all classes implicitly derive.

The following predefined methods are available in class UNIVERSAL, and thus in all classes. These all work regardless of whether they are invoked as class methods or object methods.

INVOCANT->isa(CLASS)

The isa method returns true if INVOCANT's class is CLASS or any class inheriting from CLASS. Instead of a package name, CLASS may also be one of the built-in types, such as "HASH" or "ARRAY". (Checking for an exact type does not bode well for encapsulation or polymorphism, though. You should be relying on method dispatch to give you the right method.)

use FileHandle;
if (FileHandle->isa("Exporter")) {
    print "FileHandle is an Exporter.\n";
}

$fh = FileHandle->new();
if ($fh->isa("IO::Handle")) {
    print "\$fh is some sort of IOish object.\n";
}
if ($fh->isa("GLOB")) {
    print "\$fh is really a GLOB reference.\n";
}

INVOCANT->can(METHOD)

The can method returns a reference to the subroutine that would be called if METHOD were applied to INVOCANT. If no such subroutine is found, can returns undef.

if ($invocant->can("copy")) {
    print "Our invocant can copy.\n";
}
This could be used to conditionally invoke a method only if one exists:
$obj->snarl if $obj->can("snarl");
Under multiple inheritance, this allows a method to invoke all overridden base class methods, not just the leftmost one:
sub snarl {
    my $self = shift;
    print "Snarling: @_\n";
    my %seen;
    for my $parent (@ISA) {
        if (my $code = $parent->can("snarl")) {
            $self->$code(@_) unless $seen{$code}++;
        }
    }
}
We use the %seen hash to keep track of which subroutines we've already called, so we can avoid calling the same subroutine more than once. This could happen if several parent classes shared a common ancestor.

Methods that would trigger an AUTOLOAD (described in the next section) will not be accurately reported unless the package has declared (but not defined) the subroutines it wishes to have autoloaded.

INVOCANT->VERSION(NEED)

The VERSION method returns the version number of INVOCANT's class, as stored in the package's $VERSION variable. If the NEED argument is provided, it verifies that the current version isn't less than NEED and raises an exception if it is. This is the method that use invokes to determine whether a module is sufficiently recent.

use Thread 1.0;   # calls Thread->VERSION(1.0)
print "Running version ", Thread->VERSION, " of Thread.\n";
You may supply your own VERSION method to override the method in UNIVERSAL. However, this will cause any classes derived from your class to use the overridden method, too. If you don't want that to happen, you should design your method to delegate other classes' version requests back up to UNIVERSAL.

The methods in UNIVERSAL are built-in Perl subroutines, which you may call if you fully qualify them and pass two arguments, as in UNIVERSAL::isa($formobj, "HASH"). (This is not recommended, though, because can usually has the answer you're really looking for.)

You're free to add your own methods to class UNIVERSAL. (You should be careful, of course; you could really mess someone up who is expecting not to find the method name you're defining, perhaps so that they can autoload it from somewhere else.) Here we create a copy method that objects of all classes can use if they've not defined their own. (We fail spectacularly if invoked on a class instead of an object.)

use Data::Dumper;
use Carp;
sub UNIVERSAL::copy {
    my $self = shift;
    if (ref $self) {
        return eval Dumper($self);  # no CODE refs
    } else {
        confess "UNIVERSAL::copy can't copy class $self";
    }
}
This Data::Dumper strategy doesn't work if the object contains any references to subroutines, because they cannot be properly reproduced. Even if the source were available, the lexical bindings would be lost.

12.5.4. Method Autoloading

Normally, when you call an undefined subroutine in a package that defines an AUTOLOAD subroutine, the AUTOLOAD subroutine is called in lieu of raising an exception (see the section Section 12.2, "Autoloading" in Chapter 10, "Packages"). With methods, this works a little differently. If the regular method search (through the class, its ancestors, and finally UNIVERSAL) fails to find a match, the same sequence is run again, this time looking for an AUTOLOAD subroutine. If found, this subroutine is called as a method, with the package's $AUTOLOAD variable set to the fully qualified name of the subroutine on whose behalf AUTOLOAD was called.

You need to be a bit cautious when autoloading methods. First, the AUTOLOAD subroutine should return immediately if it's being called on behalf of a method named DESTROY, unless your goal was to simulate DESTROY, which has a special meaning to Perl described in the section Section 12.6, "Instance Destructors" later in this chapter.

sub AUTOLOAD {
    return if our $AUTOLOAD =~ /::DESTROY$/;
    ...
}
Second, if the class is providing an AUTOLOAD safety net, you won't be able to use UNIVERAL::can on a method name to check whether it's safe to invoke. You have to check for AUTOLOAD separately:
if ($obj->can("methname") || $obj->can("AUTOLOAD")) {
    $obj->methname();
}
Finally, under multiple inheritance, if a class inherits from two or more classes each of which has an AUTOLOAD, only the leftmost will ever be triggered, since Perl stops as soon as it finds the first AUTOLOAD.

The last two quirks are easily circumvented by declaring the subroutines in the package whose AUTOLOAD is supposed to manage those methods. You can do this either with individual declarations:

package Goblin;
sub kick;
sub bite;
sub scratch;
or with the use subs pragma, which is more convenient if you have many methods to declare:
package Goblin;
use subs qw(kick bite scratch);
Even though you've only declared these subroutines and not defined them, this is enough for the system to think they're real. They show up in a UNIVERAL::can check, and, more importantly, they show up in step 2 of the search for a method, which will never progress to step 3, let alone step 4.

"But, but," you exclaim, "they invoke AUTOLOAD, don't they?" Well, yes, they do eventually, but the mechanism is different. Having found the method stub via step 2, Perl tries to call it. When it is discovered that the method isn't all it was cracked up to be, the AUTOLOAD method search kicks in again, but this time, it starts its search in the class containing the stub, which restricts the method search to that class and its ancestors (and UNIVERSAL). That's how Perl finds the correct AUTOLOAD to run and knows to ignore AUTOLOADs from the wrong part of the original inheritance tree.

12.5.5. Private Methods

There is one way to invoke a method so that Perl ignores inheritance altogether. If instead of a literal method name, you specify a simple scalar variable containing a reference to a subroutine, then the subroutine is called immediately. In the description of UNIVERSAL->can in the previous section, the last example invokes all overridden methods using the subroutine's reference, not its name.

An intriguing aspect of this behavior is that it can be used to implement private method calls. If you put your class in a module, you can make use of the file's lexical scope for privacy. First, store an anonymous subroutine in a file-scoped lexical:

# declare private method
my $secret_door = sub {
    my $self = shift;
    ...
};
Later on in the file, you can use that variable as though it held a method name. The closure will be called directly, without regard to inheritance. As with any other method, the invocant is passed as an extra argument.
sub knock {
    my $self = shift;
    if ($self->{knocked}++ > 5) {
        $self->$secret_door();
    }
}
This enables the file's own subroutines (the class methods) to invoke a method that code outside that lexical scope cannot access.

Previous | Home | Next
12.4. Object Construction | Book Index | 12.6. Instance Destructors
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.6. Instance Destructors

As with any other referent in Perl, when the last reference to an object goes away, its memory is implicitly recycled. With an object, you have the opportunity to capture control just as this is about to happen by defining a DESTROY subroutine in the class's package. This method is triggered automatically at the appropriate moment, with the about-to-be-recycled object as its only argument.

Destructors are rarely needed in Perl, because memory management is handled automatically for you. Some objects, though, may have state outside the memory system that you'd like to attend to, such as filehandles or database connections.

package MailNotify;
sub DESTROY {
    my $self = shift;
    my $fh   = $self->{mailhandle};
    my $id   = $self->{name};
    print $fh "\n$id is signing off at " . localtime() . "\n";
    close $fh;  # close pipe to mailer
}

Just as Perl uses only a single method to construct an object even when the constructor's class inherits from one or more other classes, Perl also uses only one DESTROY method per object destroyed regardless of inheritance. In other words, Perl does not do hierarchical destruction for you. If your class overrides a superclass's destructor, then your DESTROY method may need to invoke the DESTROY method for any applicable base classes:

sub DESTROY {
    my $self = shift;
    # check for an overridden destructor...
    $self->SUPER::DESTROY if $self->can("SUPER::DESTROY");
    # now do your own thing before or after
}
This applies only to inherited classes; an object that is simply contained within the current object--as, for example, one value in a larger hash--will be freed and destroyed automatically. This is one reason why containership via mere aggregation (sometimes called a "has-a" relationship) is often cleaner and clearer than inheritance (an "is-a" relationship). In other words, often you really only need to store one object inside another directly instead of through inheritance, which can add unnecessary complexity. Sometimes when users reach for multiple inheritance, single inheritance will suffice.

Explicitly calling DESTROY is possible but seldom needed. It might even be harmful since running the destructor more than once on the same object could prove unpleasant.

12.6.1. Garbage Collection with DESTROY Methods

As described in the section Section 12.5.2, "Garbage Collection, Circular References, and Weak References" in Chapter 8, "References", a variable that refers to itself (or multiple variables that refer to one another indirectly) will not be freed until the program (or embedded interpreter) is about to exit. If you want to reclaim the memory any earlier, you usually have to explicitly break the reference or weaken it using the WeakRef module on CPAN.

With objects, an alternative solution is to create a container class that holds a pointer to the self-referential data structure. Define a DESTROY method for the containing object's class that manually breaks the circularities in the self-referential structure. You can find an example of this in Chapter 13 of the Perl Cookbook in the recipe 13.13, "Coping with Circular Data Structures".

When an interpreter shuts down, all its objects are destroyed, which is important for multithreaded or embedded Perl applications. Objects are always destroyed in a separate pass before ordinary references. This is to prevent DESTROY methods from using references that have themselves been destroyed. (And also because plain references are only garbage-collected in embedded interpreters, since exiting a process is a very fast way of reclaiming references. But exiting won't run the object destructors, so Perl does that first.)

Previous | Home | Next
12.5. Class Inheritance | Book Index | 12.7. Managing Instance Data
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.7. Managing Instance Data

Most classes create objects that are essentially just data structures with several internal data fields (instance variables) plus methods to manipulate them.

Perl classes inherit methods, not data, but as long as all access to the object is through method calls anyway, this works out fine. If you want data inheritance, you have to effect it through method inheritance. By and large, this is not a necessity in Perl, because most classes store the attributes of their object in an anonymous hash. The object's instance data is contained within this hash, which serves as its own little namespace to be carved up by whatever classes do something with the object. For example, if you want an object called $city to have a data field named elevation, you can simply access $city->{elevation}. No declarations are necessary. But method wrappers have their uses.

Suppose you want to implement a Person object. You decide to have a data field called "name", which by a strange coincidence you'll store under the key name in the anonymous hash that will serve as the object. But you don't want users touching the data directly. To reap the rewards of encapsulation, users need methods to access that instance variable without lifting the veil of abstraction.

For example, you might make a pair of accessor methods:

sub get_name {
    my $self = shift;
    return $self->{name};
}

sub set_name {
    my $self      = shift;
    $self->{name} = shift;
}
which leads to code like this:
$him = Person->new();
$him->set_name("Frodo");
$him->set_name( ucfirst($him->get_name) );
You could even combine both methods into one:
sub name {
    my $self = shift;
    if (@_) { $self->{name} = shift }
    return $self->{name};
}
This would then lead to code like this:
$him = Person->new();
$him->name("Frodo");
$him->name( ucfirst($him->name) );
The advantage of writing a separate function for each instance variable (which for our Person class might be name, age, height, and so on) is that it is direct, obvious, and flexible. The drawback is that every time you want a new class, you end up defining one or two nearly identical methods per instance variable. This isn't too bad for the first few, and you're certainly welcome to do it that way if you'd like. But when convenience is preferred over flexibility, you might prefer one of the techniques described in the following sections.

Note that we will be varying the implementation, not the interface. If users of your class respect the encapsulation, you'll be able to transparently swap one implementation for another without the users noticing. (Family members in your inheritance tree using your class for a subclass or superclass might not be so forgiving, since they know you far better than strangers do.) If your users have been peeking and poking into the private affairs of your class, the inevitable disaster is their own fault and none of your concern. All you can do is live up to your end of the contract by maintaining the interface. Trying to stop everyone else in the world from ever doing something slightly wicked will take up all your time and energy--and in the end, fail anyway.

Dealing with family members is more challenging. If a subclass overrides a superclass's attribute accessor, should it access the same field in the hash, or not? An argument can be made either way, depending on the nature of the attribute. For the sake of safety in the general case, each accessor can prefix the name of the hash field with its own classname, so that subclass and superclass can both have their own version. Several of the examples below, including the standard Struct::Class module, use this subclass-safe strategy. You'll see accessors resembling this:

sub name {
    my $self = shift;
    my $field = __PACKAGE__ . "::name";
    if (@_) { $self->{$field} = shift }
    return $self->{$field};
}
In each of the following examples, we create a simple Person class with fields name, race, and aliases, each with an identical interface but a completely different implementation. We're not going to tell you which one we like the best, because we like them all the best, depending on the occasion. And tastes differ. Some folks prefer stewed conies; others prefer fissssh.

12.7.1. Field Declarations with use fields

Objects don't have to be implemented as anonymous hashes. Any reference will do. For example, if you used an anonymous array, you could set up a constructor like this:

sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    return bless [], $class;
}
and have accessors like these:
sub name {
    my $self = shift;
    if (@_) { $self->[0] = shift }
    return $self->[0];
}

sub race {
    my $self = shift;
    if (@_) { $self->[1] = shift }
    return $self->[1];
}

sub aliases {
    my $self = shift;
    if (@_) { $self->[2] = shift }
    return $self->[2];
}
Arrays are somewhat faster to access than hashes and don't take up quite as much memory, but they're not at all convenient to use. You have to keep track of the index numbers (not just in your class, but in your superclass, too), which must somehow indicate which pieces of the array your class is using. Otherwise, you might reuse a slot.

The use fields pragma addresses all of these points:

package Person;
use fields qw(name race aliases);
This pragma does not create accessor methods for you, but it does rely on some built-in magic (called pseudohashes) to do something similar. (You may wish to wrap accessors around the fields anyway, as we do in the following example.) Pseudohashes are array references that you can use like hashes because they have an associated key map table. The use fields pragma sets this key map up for you, effectively declaring which fields are valid for the Person object; this makes the Perl compiler aware of them. If you declare the type of your object variable (as in my Person $self, in the next example), the compiler is smart enough to optimize access to the fields into straight array accesses. Perhaps more importantly, it validates field names for type safety (well, typo safety, really) at compile time. (See the section Section 12.3.5, "Pseudohashes" in Chapter 8, "References".)

A constructor and sample accessors would look like this:

package Person;
use fields qw(name race aliases);
sub new {
    my $type = shift;
    my Person $self = fields::new(ref $type || $type);
    $self->{name} = "unnamed";
    $self->{race}  = "unknown";
    $self->{aliases} = [];
    return $self;
}
sub name {
    my Person $self = shift;
    $self->{name} = shift if @_;
    return $self->{name};
}
sub race {
    my Person $self = shift;
    $self->{race} = shift if @_;
    return $self->{race};
}
sub aliases {
    my Person $self = shift;
    $self->{aliases} = shift if @_;
    return $self->{aliases};
}
1;
If you misspell one of the literal keys used to access the pseudohash, you won't have to wait until run time to learn about this. The compiler knows what type of object $self is supposed to refer to (because you told it), so it can check that the code accesses only those fields that Person objects actually have. If you have horses on the brain and try to access a nonexistent field (such as $self->{mane}), the compiler can flag this error right away and will never turn the erroneous program over to the interpreter to run.

There's still a bit of repetition in declaring methods to get at instance variables, so you still might like to automate the creation of simple accessor methods using one of the techniques below. However, because all these techniques use some sort of indirection, if you use them, you will lose the compile-time benefits of typo-checking lexically typed hash accesses. You'll still keep the (small) time and space advantages, though.

If you do elect to use a pseudohash to implement your class, any class that inherits from this one must be aware of that underlying pseudohash implementation. If an object is implemented as a pseudohash, all participants in the inheritance hierarchy should employ the use base and use fields declarations. For example,

package Wizard;
use base "Person";
use fields qw(staff color sphere);
This makes the Wizard module a subclass of class Person, and loads the Person.pm file. It also registers three new fields in this class to go along with those from Person. That way when you write:
my Wizard $mage = fields::new("Wizard");
you'll get a pseudohash object with access to both classes' fields:
$mage->name("Gandalf");
$mage->color("Grey");

Since all subclasses must know that they are using a pseudohash implementation, they should use the direct pseudohash notation for both efficiency and type safety:

$mage->{name} = "Gandalf";
$mage->{color} = "Grey";
If you want to keep your implementations interchangeable, however, outside users of your class must use the accessor methods.

Although use base supports only single inheritance, this is seldom a severe restriction. See the descriptions of use base and use fields in Chapter 31, "Pragmatic Modules".

12.7.2. Generating Classes with Class::Struct

The standard Class::Struct module exports a function named struct. This creates all the trapping you'll need to get started on an entire class. It generates a constructor named new, plus accessor methods for each of the data fields (instance variables) named in that structure.

For example, if you put the class in a Person.pm file:

package Person;
use Class::Struct;
struct Person => {    # create a definition for a "Person"
    name    => '$',   #    name field is a scalar
    race    => '$',   #    race field is also a scalar
    aliases => '@',   #    but aliases field is an array ref
};
1;
Then you could use that module this way:
use Person;
my $mage = Person->new();
$mage->name("Gandalf");
$mage->race("Istar");
$mage->aliases( ["Mithrandir", "Olorin", "Incanus"] );
The Class::Struct module created all four of those methods. Because it follows the subclass-safe policy of always prefixing the field name with the class name, it also permits an inherited class to have its own separate field of the same name as a base class field without conflict. That means in this case that "Person::name" rather than just "name" is used for the hash key for that particular instance variable.

Fields in a struct declaration don't have to be basic Perl types. They can also specify other classes, but classes created with struct work best because the function makes assumptions about how the classes behave that aren't generally true of all classes. For example, the new method for the appropriate class is invoked to initialize the field, but many classes have constructors with other names.

See the description of Class::Struct in Chapter 32, "Standard Modules", and its online documentation for more information. Many standard modules use Class::Struct to implement their classes, including User::pwent and Net::hostent. Reading their code can prove instructive.

12.7.3. Generating Accessors with Autoloading

As we mentioned earlier, when you invoke a nonexistent method, Perl has two different ways to look for an AUTOLOAD method, depending on whether you declared a stub method. You can use this property to provide access to the object's instance data without writing a separate function for each instance. Inside the AUTOLOAD routine, the name of the method actually invoked can be retrieved from the $AUTOLOAD variable. Consider the following code:

use Person;
$him = Person->new;
$him->name("Aragorn");
$him->race("Man");
$him->aliases( ["Strider", "Estel", "Elessar"] );
printf "%s is of the race of %s.\n", $him->name, $him->race;
print "His aliases are: ", join(", ", @{$him->aliases}), ".\n";
As before, this version of the Person class implements a data structure with three fields: name, race, and aliases:
package Person;
use Carp;

my %Fields = (
    "Person::name"  => "unnamed",
    "Person::race"   => "unknown",
    "Person::aliases"  => [],
);

# The next declaration guarantees we get our own autoloader.
use subs qw(name race aliases);

sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self  = { %Fields, @_ };    # clone like Class::Struct
    bless $self, $class;
    return $self;
}

sub AUTOLOAD {
    my $self = shift;
    # only handle instance methods, not class methods
    croak "$self not an object" unless ref($invocant);
    my $name = our $AUTOLOAD;
    return if $name =~ /::DESTROY$/;
    unless (exists $self->{$name}) {
        croak "Can't access `$name' field in $self";
    }
    if (@_) { return $self->{$name} = shift }
    else    { return $self->{$name} }
}
As you see, there are no methods named name, race, or aliases anywhere to be found. The AUTOLOAD routine takes care of all that. When someone uses $him->name("Aragorn"), the AUTOLOAD subroutine is called with $AUTOLOAD set to "Person::name". Conveniently, by leaving it fully qualified, it's in exactly the right form for accessing fields of the object hash. That way if you use this class as part of a larger class hierarchy, you don't conflict with uses of the same name in other classes.

12.7.4. Generating Accessors with Closures

Most accessor methods do essentially the same thing: they simply fetch or store a value from that instance variable. In Perl, the most natural way to create a family of near-duplicate functions is looping around a closure. But closures are anonymous functions lacking names, and methods need to be named subroutines in the class's package symbol table so that they can be called by name. This is no problem--just assign the closure reference to a typeglob of the appropriate name.

package Person;

sub new {
    my $invocant = shift;
    my $self = bless({}, ref $invocant || $invocant);
    $self->init();
    return $self;
}

sub init {
    my $self = shift;
    $self->name("unnamed");
    $self->race("unknown");
    $self->aliases([]);
}

for my $field (qw(name race aliases)) {
    my $slot = __PACKAGE__ . "::$field";
    no strict "refs";          # So symbolic ref to typeglob works.

    *$field = sub {
        my $self = shift;
        $self->{$slot} = shift if @_;
        return $self->{$slot};
    };
}
Closures are the cleanest hand-rolled way to create a multitude of accessor methods for your instance data. It's efficient for both the computer and you. Not only do all the accessors share the same bit of code (they only need their own lexical pads), but later if you decide to add another attribute, the changes required are minimal: just add one more word to the for loop's list, and perhaps something to the init method.

12.7.5. Using Closures for Private Objects

So far, these techniques for managing instance data have offered no mechanism for "protection" from external access. Anyone outside the class can open up the object's black box and poke about inside--if they don't mind voiding the warranty. Enforced privacy tends to get in the way of people trying to get their jobs done. Perl's philosophy is that it's better to encapsulate one's data with a sign that says:

IN CASE OF FIRE
  BREAK GLASS
You should respect such encapsulation when possible, but still have easy access to the contents in an emergency situation, like for debugging.

But if you do want to enforce privacy, Perl isn't about to get in your way. Perl offers low-level building blocks that you can use to surround your class and its objects with an impenetrable privacy shield--one stronger, in fact, than that found in many popular object-oriented languages. Lexical scopes and the lexical variables inside them are the key components here, and closures play a pivotal role.

In the section Section 12.5.5, "Private Methods" we saw how a class can use closures to implement methods that are invisible outside the module file. Later we'll look at accessor methods that regulate class data so private that not even the rest of the class has unrestricted access. Those are still fairly traditional uses of closures. The truly interesting approach is to use a closure as the very object itself. The object's instance variables are locked up inside a scope to which the object alone--that is, the closure--has free access. This is a very strong form of encapsulation; not only is it proof against external tampering, even other methods in the same class must use the proper access methods to get at the object's instance data.

Here's an example of how this might work. We'll use closures both for the objects themselves and for the generated accessors:

package Person;
sub new {
    my $invocant  = shift;
    my $class = ref($invocant) || $invocant;
    my $data = {
       NAME     => "unnamed",
       RACE     => "unknown",
       ALIASES  => [],
    };
    my $self = sub {
       my $field = shift;
       #############################
       ### ACCESS CHECKS GO HERE ###
       #############################
       if (@_) { $data->{$field} = shift }
       return    $data->{$field};
    };
    bless($self, $class);
    return $self;
}
# generate method names
for my $field (qw(name race aliases)) {
    no strict "refs";  # for access to the symbol table
    *$field = sub {
        my $self = shift;
        return $self->(uc $field, @_);
    };
}
The object created and returned by the new method is no longer a hash, as it was in other constructors we've looked at. It's a closure with unique access to the attribute data stored in the hash referred to by $data. Once the constructor call is finished, the only access to $data (and hence to the attributes) is via the closure.

In a call like $him->name("Bombadil"), the invoking object stored in $self is the closure that was blessed and returned by the constructor. There's not a lot one can do with a closure beyond calling it, so we do just that with $self->(uc $field, @_). Don't be fooled by the arrow; this is just a regular indirect function call, not a method invocation. The initial argument is the string "name", and any remaining arguments are whatever else was passed in.[7] Once we're executing inside the closure, the hash reference inside $data is again accessible. The closure is then free to permit or deny access to whatever it pleases.

[7] Sure, the double-function call is slow, but if you wanted fast, would you really be using objects in the first place?

No one outside the closure object has unmediated access to this very private instance data, not even other methods in the class. They could try to call the closure the way the methods generated by the for loop do, perhaps setting an instance variable the class never heard of. But this approach is easily blocked by inserting various bits of code in the constructor where you see the comment about access checks. First, we need a common preamble:

use Carp;
local $Carp::CarpLevel = 1;  # Keeps croak messages short
my ($cpack, $cfile) = caller();
Now for each of the checks. The first one makes sure the specified attribute name exists:
croak "No valid field '$field' in object"
    unless exists $data->{$field};
This one allows access only by callers from the same file:
carp "Unmediated access denied to foreign file"
    unless $cfile eq __FILE__;
This one allows access only by callers from the same package:
carp "Unmediated access denied to foreign package ${cpack}::"
    unless $cpack eq __PACKAGE__;
And this one allows access only by callers whose classes inherit ours:
carp "Unmediated access denied to unfriendly class ${cpack}::"
    unless $cpack->isa(__PACKAGE__);
All these checks block unmediated access only. Users of the class who politely use the class's designated methods are under no such restriction. Perl gives you the tools to be just as persnickety as you want to be. Fortunately, not many people want to be.

But some people ought to be. Persnickety is good when you're writing flight control software. If you either want or ought to be one of those people, and you prefer using working code over reinventing everything on your own, check out Damian Conway's Tie::SecureHash module on CPAN. It implements restricted hashes with support for public, protected, and private persnicketations. It also copes with the inheritance issues that we've ignored in the previous example. Damian has also written an even more ambitious module, Class::Contract, that imposes a formal software engineering regimen over Perl's flexible object system. This module's feature list reads like a checklist from a computer science professor's software engineering textbook,[8]including enforced encapsulation, static inheritance, and design-by-contract condition checking for object-oriented Perl, along with a declarative syntax for attribute, method, constructor, and destructor definitions at both the object and class level, and preconditions, postconditions, and class invariants. Whew!

[8] Can you guess what Damian's job is? By the way, we highly recommend his book, Object Oriented Perl (Manning Publications, 1999).

12.7.6. New Tricks

As of release 5.6 of Perl, you can also declare a method to indicate that it returns an lvalue. This is done with the lvalue subroutine attribute (not to be confused with object attributes). This experimental feature allows you to treat the method as something that would appear on the lefthand side of an equal sign:

package Critter;

sub new {
    my $class = shift;
    my $self = { pups => 0, @_ };    # Override default.
    bless $self, $class;
}

sub pups : lvalue {                  # We'll assign to pups() later.
    my $self = shift;
    $self->{pups};
}

package main;
$varmint = Critter->new(pups => 4);
$varmint->pups *= 2;                 # Assign to $varmint->pups!
$varmint->pups =~ s/(.)/$1$1/;       # Modify $varmint->pups in place!
print $varmint->pups;                # Now we have 88 pups.
This lets you pretend $varmint->pups is a variable while still obeying encapsulation. See the section Section 12.5.2, "The lvalue Attribute" in Chapter 6, "Subroutines".

If you're running a threaded version of Perl and want to ensure that only one thread can call a particular method on an object, you can use the locked and method attributes to do that:

sub pups : locked method {
    ...
}
When any thread invokes the pups method on an object, Perl locks the object before execution, preventing other threads from doing the same. See the section Section 12.5.1, "The locked and method Attributes" in Chapter 6, "Subroutines".

Previous | Home | Next
12.6. Instance Destructors | Book Index | 12.8. Managing Class Data
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.8. Managing Class Data

We've looked at several approaches to accessing per-object data values. Sometimes, though, you want some common state shared by all objects of a class. Instead of being an attribute of just one instance of the class, these variables are global to the entire class, no matter which class instance (object) you use to access them through. (C++ programmers would think of these as static member data.) Here are some situations where class variables might come in handy:

  • To keep a count of all objects ever created, or how many are still kicking around.

  • To keep a list of all objects over which you can iterate.

  • To store the name or file descriptor of a log file used by a class-wide debugging method.

  • To keep collective data, like the total amount of cash dispensed by all ATMs in a network in a given day.

  • To track the last object created by a class, or the most accessed object.

  • To keep a cache of in-memory objects that have already been reconstituted from persistent memory.

  • To provide an inverted lookup table so you can find an object based on the value one of its attributes.

The question comes down to deciding where to store the state for those shared attributes. Perl has no particular syntactic mechanism to declare class attributes, any more than it has for instance attributes. Perl provides the developer with a broad set of powerful but flexible features that can be uniquely crafted to the particular demands of the situation. You can then select the mechanism that makes the most sense for the given situation instead of having to live with someone else's design decisions. Alternatively, you can live with the design decisions someone else has packaged up and put onto CPAN. Again, TMTOWTDI.

Like anything else pertaining to a class, class data shouldn't be accessed directly, especially from outside the implementation of the class itself. It doesn't say much for encapsulation to set up carefully controlled accessor methods for instance variables but then invite the public in to diddle your class variables directly, such as by setting $SomeClass::Debug = 1. To establish a clear firewall between interface and implementation, you can create accessor methods to manipulate class data similar to those you use for instance data.

Imagine we want to keep track of the total world population of Critter objects. We'll store that number in a package variable, but provide a method called population so that users of the class don't have to know about the implementation.

Critter->population()       # Access via class name
$gollum->population()       # Access via instance

Since a class in Perl is just a package, the most natural place to store class data is in a package variable. Here's a simple implementation of such a class. The population method ignores its invocant and just returns the current value of the package variable, $Population. (Some programmers like to capitalize their globals.)

package Critter;
our $Population = 0;
sub population { return $Population; }
sub DESTROY { $Population-- }
sub spawn {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    $Population++;
    return bless { name => shift || "anon" }, $class;
}
sub name {
    my $self = shift;
    $self->{name} = shift if @_;
    return $self->{name};
}
If you want to make class data methods that work like accessors for instance data, do this:
our $Debugging = 0;     # class datum
sub debug {
    shift;              # intentionally ignore invocant
    $Debugging = shift if @_;
    return $Debugging;
}
Now you can set the overall debug level through the class or through any of its instances.

Because it's a package variable, $Debugging is globally accessible. But if you change the our variable to my, then only code later in that same file can see it. You can go still further--you can restrict unfettered access to class attributes even from the rest of class itself. Wrap the variable declaration in a block scope:

{
    my $Debugging = 0;          # lexically scoped class datum
    sub debug {
        shift;                  # intentionally ignore invocant
        $Debugging = shift if @_;

        return $Debugging;
    }
}
Now no one is allowed to read or write the class attributes without using the accessor method, since only that subroutine is in the same scope as the variable and has access to it.

If a derived class inherits these class accessors, then these still access the original data, no matter whether the variables were declared with our or my. The data isn't package-relative. You might look at it as methods executing in the class in which they were originally defined, not in the class that invoked them.

For some kinds of class data, this approach works fine, but for others, it doesn't. Suppose we create a Warg subclass of Critter. If we want to keep our populations separate, Warg can't inherit Critter's population method, because that method as written always returns the value of $Critter::Population.

You'll have to decide on a case-by-case basis whether it makes any sense for class attributes to be package relative. If you want package-relative attributes, use the invocant's class to locate the package holding the class data:

sub debug {
    my $invocant = shift;
    my $class   = ref($invocant) || $invocant;
    my $varname = $class . "::Debugging";
    no strict "refs";       # to access package data symbolically
    $$varname = shift if @_;
    return $$varname;
}
We temporarily rescind strict references because otherwise we couldn't use the fully qualified symbolic name for the package global. This is perfectly reasonable: since all package variables by definition live in a package, there's nothing wrong with accessing them via that package's symbol table.

Another approach is to make everything an object needs--even its global class data--available via that object (or passed in as parameters). To do this, you'll often have to make a dedicated constructor for each class, or at least have a dedicated initialization routine to be called by the constructor. In the constructor or initializer, you store references to any class data directly in the object itself, so nothing ever has to go looking for it. The accessor methods use the object to find a reference to the data.

Rather than put the complexity of locating the class data in each method, just let the object tell the method where the data is located. This approach works well only when the class data accessor methods are invoked as instance methods, because the class data could be in unreachable lexicals you couldn't get at using a package name.

No matter how you roll it, package-relative class data is always a bit awkward. It's really a lot cleaner if, when you inherit a class data accessor method, you effectively inherit the state data that it's accessing as well. See the perltootc manpage for numerous, more elaborate approaches to management of class data.

Previous | Home | Next
12.7. Managing Instance Data | Book Index | 12.9. Summary
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


12.9. Summary

That's about all there is to it, except for everything else. Now you just need to go off and buy a book about object-oriented design methodology and bang your forehead with it for the next six months or so.

Previous | Home | Next
12.8. Managing Class Data | Book Index | 13. Overloading
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 13. Overloading

Contents:

The overload Pragma
Overload Handlers
Overloadable Operators
The Copy Constructor (=)
When an Overload Handler Is Missing (nomethod and fallback)
Overloading Constants
Public Overload Functions
Inheritance and Overloading
Run-Time Overloading
Overloading Diagnostics

Objects are cool, but sometimes they're just a little too cool. Sometimes you would rather they behaved a little less like objects and a little more like regular data types. But there's a problem: objects are referents represented by references, and references aren't terribly useful except as references. You can't add references, or print them, or (usefully) apply many of Perl's built-in operators. The only thing you can do is dereference them. So you find yourself writing many explicit method invocations, like this:

print $object->as_string;
$new_object = $subject->add($object);
Such explicit dereferencing is in general a good thing; you should never confuse your references with your referents, except when you want to confuse them. Now would be one of those times. If you design your class with overloading, you can pretend the references aren't there and simply say:
print $object;
$new_object = $subject + $object;
When you overload one of Perl's built-in operators, you define how it behaves when it's applied to objects of a particular class. A number of standard Perl modules use overloading, such as Math::BigInt, which lets you create Math::BigInt objects that behave just like regular integers but have no size limits. You can add them with +, divide them with /, compare them with <=>, and print them with print.

Note that overloading is not the same as autoloading, which is loading a missing function or method on demand. Neither is it the same as overriding, which is one function or method masking another. Overloading hides nothing; it adds meaning to an operation that would have been nonsense on a mere reference.

13.1. The overload Pragma

The use overload pragma implements operator overloading. You provide it with a key/value list of operators and their associated behaviors:

package MyClass;

use overload   '+' => \&myadd,            # coderef
               '<' => "less_than";        # named method
             'abs' => sub { return @_ },  # anonymous subroutine
Now when you try to add two MyClass objects, the myadd subroutine will be called to create the result.

When you try to compare two MyClass objects with the < operator, Perl notices that the behavior is specified as a string and interprets the string as a method name and not simply as a subroutine name. In the example above, the less_than method might be supplied by the MyClass package itself or inherited from a base class of MyClass, but the myadd subroutine must be supplied by the current package. The anonymous subroutine for abs supplies itself even more directly. However these routines are supplied, we'll call them handlers.

For unary operators (those taking only one operand, like abs), the handler specified for the class is invoked whenever the operator is applied to an object of that class.

For binary operators like + or <, the handler is invoked whenever the first operand is an object of the class or when the second operand is an object of the class and the first operand has no overloading behavior. That's so you can say either:

$object + 6
or:
6 + $object
without having to worry about the order of operands. (In the second case, the operands will be swapped when passed to the handler). If our expression was:
$animal + $vegetable
and $animal and $vegetable were objects of different classes, both of which used overloading, then the overloading behavior of $animal would be triggered. (We'll hope the animal likes vegetables.)

There is only one trinary (ternary) operator in Perl, ?:, and you can't overload it. Fortunately.

Previous | Home | Next
12.9. Summary | Book Index | 13.2. Overload Handlers
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.2. Overload Handlers

When an overloaded operator is, er, operated, the corresponding handler is invoked with three arguments. The first two arguments are the two operands. If the operator only uses one operand, the second argument is undef.

The third argument indicates whether the first two arguments were swapped. Even under the rules of normal arithmetic, some operations, like addition or multiplication, don't usually care about the order of their arguments, but others, like subtraction and division, do.[1] Consider the difference between:

$object - 6
and:
6 - $object
If the first two arguments to a handler have been swapped, the third argument will be true. Otherwise, the third argument will be false, in which case there is a finer distinction as well: if the handler has been triggered by another handler involving assignment (as in += using + to figure out how to add), then the third argument is not merely false, but undef. This distinction enables some optimizations.

[1] Your overloaded objects are not required to respect the rules of normal arithmetic, of course, but it's usually best not to surprise people. Oddly, many languages make the mistake of overloading + with string concatenation, which is not commutative and only vaguely additive. For a different approach, see Perl.

As an example, here is a class that lets you manipulate a bounded range of numbers. It overloads both + and - so that the result of adding or subtracting objects constrains the values within the range 0 and 255:

package ClipByte;

use overload '+' => \&clip_add,
             '-' => \&clip_sub;

sub new {
    my $class = shift;
    my $value = shift;
    return bless \$value => $class;
}

sub clip_add {
    my ($x, $y) = @_;
    my ($value) = ref($x) ? $$x : $x;
    $value     += ref($y) ? $$y : $y;
    $value = 255 if $value > 255;
    $value =   0 if $value < 0;
    return bless \$value => ref($x);
}

sub clip_sub {
    my ($x, $y, $swap) = @_;
    my ($value) = (ref $x) ? $$x : $x;
    $value     -= (ref $y) ? $$y : $y;
    if ($swap) { $value = -$value }
    $value = 255 if $value > 255;
    $value =   0 if $value < 0;
    return bless \$value => ref($x);
}

package main;

$byte1 = ClipByte->new(200);
$byte2 = ClipByte->new(100);

$byte3 = $byte1 + $byte2;    # 255
$byte4 = $byte1 - $byte2;    # 100
$byte5 = 150 - $byte2;       # 50
You'll note that every function here is by necessity a constructor, so each one takes care to bless its new object back into the current class, whatever that is; we assume our class might be inherited. We also assume that if $y is a reference, it's a reference to an object of our own type. Instead of testing ref($y), we could have called $y->isa("ClipByte") if we wanted to be more thorough (and run slower).

Previous | Home | Next
13.1. The overload Pragma | Book Index | 13.3. Overloadable Operators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.3. Overloadable Operators

You can only overload certain operators, which are shown in Table 13-1. The operators are also listed in the %overload::ops hash made available when you use overload, though the categorization is a little different there.

Table 13.1. Overloadable Operators

Category | Operators
Conversion | "" 0+ bool
Arithmetic | + - * / % ** x . neg
Logical | !
Bitwise | & | ~ ^ ! << >>
Assignment | += -= *= /= %= **= x= .= <<= >>= ++ --
Comparison | == < <= > >= != <=> lt le gt ge eq ne cmp
Mathematical | atan2 cos sin exp abs log sqrt
Iterative | <>
Dereference | ${} @{} %{} &{} *{}
Pseudo | nomethod fallback =>

Note that neg, bool, nomethod, and fallback are not actual Perl operators. The five dereferencers, "", and 0+ probably don't seem like operators either. Nevertheless, they are all valid keys for the parameter list you provide to use overload. This is not really a problem. We'll let you in on a little secret: it's a bit of a fib to say that the overload pragma overloads operators. It overloads the underlying operations, whether invoked explicitly via their "official" operators, or implicitly via some related operator. (The pseudo-operators we mentioned can only be invoked implicitly.) In other words, overloading happens not at the syntactic level, but at the semantic level. The point is not to look good. The point is to do the right thing. Feel free to generalize.

Note also that = does not overload Perl's assignment operator, as you might expect. That would not do the right thing. More on that later.

We'll start by discussing the conversion operators, not because they're the most obvious (they aren't), but because they're the most useful. Many classes overload nothing but stringification, specified by the "" key. (Yes, that really is two double-quotes in a row.)

Conversion operators: "", 0+, bool

These three keys let you provide behaviors for Perl's automatic conversions to strings, numbers, and Boolean values, respectively.

We say that stringification occurs when any nonstring variable is used as a string. It's what happens when you convert a variable into a string via printing, interpolation, concatenation, or even by using it as a hash key. Stringification is also why you see something like SCALAR(0xba5fe0) when you try to print an object.

We say that numification occurs when a nonnumeric variable is converted into a number in any numeric context, such as any mathematical expression, array index, or even as an operand of the .. range operator.

Finally, while nobody here quite has the nerve to call it boolification, you can define how an object should be interpreted in a Boolean context (such as if, unless, while, for, and, or, &&, ||, ?:, or the block of a grep expression) by creating a bool handler.

Any of the three conversion operators can be autogenerated if you have any one of them (we'll explain autogeneration later). Your handlers can return any value you like. Note that if the operation that triggered the conversion is also overloaded, that overloading will occur immediately afterward.

Here's a demonstration of "" that invokes an object's as_string handler upon stringification. Don't forget to quote the quotes:

package Person;

use overload q("") => \&as_string;

sub new {
    my $class = shift;
    return bless { @_ } => $class;
}

sub as_string {
    my $self = shift;
    my ($key, $value, $result);
    while (($key, $value) = each %$self) {
        $result .= "$key => $value\n";
    }
    return $result;
}

$obj = Person->new(height => 72, weight => 165, eyes => "brown");

print $obj;
Instead of something like Person=HASH(0xba1350), this prints (in hash order):
weight => 165
height => 72
eyes => brown
(We sincerely hope this person was not measured in kg and cm.)

Arithmetic operators: +, -, *, /, %, **, x, ., neg

These should all be familiar except for neg, which is a special overloading key for the unary minus: the - in -123. The distinction between the neg and - keys allows you to specify different behaviors for unary minus and binary minus, more commonly known as subtraction.

If you overload - but not neg, and then try to use a unary minus, Perl will emulate a neg handler for you. This is known as autogeneration, where certain operators can be reasonably deduced from other operators (on the assumption that the overloaded operators will have the same relationships as the regular operators). Since unary minus can be expressed as a function of binary minus (that is, -123 is equivalent to 0 - 123), Perl doesn't force you to overload neg when - will do. (Of course, if you've arbitrarily defined binary minus to divide the second argument by the first, unary minus will be a fine way to throw a divide-by-0 exception.)

Concatenation via the . operator can be autogenerated via the stringification handler (see "" above).

Logical operator: !

If a handler for ! is not specified, it can be autogenerated using the bool, "", or 0+ handler. If you overload the ! operator, the not operator will also trigger whatever behavior you requested. (Remember our little secret?)

You may be surprised at the absence of the other logical operators, but most logical operators can't be overloaded because they short-circuit. They're really control-flow operators that need to be able to delay evaluation of some of their arguments. That's also the reason the ?: operator isn't overloaded.

Bitwise operators: &, |, ~, ^, <<, >>

The ~ operator is a unary operator; all the others are binary. Here's how we could overload >> to do something like chop:

package ShiftString;

use overload
    '>>' => \&right_shift,
    '""' => sub { ${ $_[0] } };

sub new {
    my $class = shift;
    my $value = shift;
    return bless \$value => $class;
}

sub right_shift {
    my ($x, $y) = @_;
    my $value = $$x;
    substr($value, -$y) = "";
    return bless \$value => ref($x);
}

$camel = ShiftString->new("Camel");
$ram = $camel >> 2;
print $ram;            # Cam

Assignment operators: +=, -=, *=, /=, %=, **=, x=, .=, <<=, >>=, ++, --

These assignment operators might change the value of their arguments or leave them as is. The result is assigned to the lefthand operand only if the new value differs from the old one. This allows the same handler to be used to overload both += and +. Although this is permitted, it is seldom recommended, since by the semantics described later under "When an Overload Handler Is Missing (nomethod and fallback)", Perl will invoke the handler for + anyway, assuming += hasn't been overloaded directly.

Concatenation (.=) can be autogenerated using stringification followed by ordinary string concatenation. The ++ and -- operators can be autogenerated from + and - (or += and -=).

Handlers implementing ++ and -- are expected to mutate (alter) their arguments. If you wanted autodecrement to work on letters as well as numbers, you could do that with a handler as follows:

package MagicDec;

use overload
    q(--) => \&decrement,
    q("") => sub { ${ $_[0] } };

sub new {
    my $class = shift;
    my $value = shift;
    bless \$value => $class;
}

sub decrement {
    my @string = reverse split(//, ${ $_[0] } );
    my $i;
    for ($i = 0; $i < @string; $i++ ) {
        last unless $string[$i] =~ /a/i;
        $string[$i] = chr( ord($string[$i]) + 25 );
    }
    $string[$i] = chr( ord($string[$i]) - 1 );
    my $result = join('', reverse @string);
    $_[0] = bless \$result => ref($_[0]);
}

package main;

for $normal (qw/perl NZ Pa/) {
    $magic = MagicDec->new($normal);
    $magic--;
    print "$normal goes to $magic\n";
}
That prints out:
perl goes to perk
NZ goes to NY
Pa goes to Oz
exactly reversing Perl's magical string autoincrement operator.

The ++$a operation can be autogenerated using $a += 1 or $a = $a + 1, and $a-- using $a -= 1 or $a = $a - 1. However, this does not trigger the copying behavior that a real ++ operator would. See "The Copy Constructor" later in this chapter.

Comparison operators: ==, <, <=, >, >=, !=, <=>, lt, le, gt, ge, eq, ne, cmp

If <=> is overloaded, it can be used to autogenerate behaviors for <, <=, >, >=, ==, and !=. Similarly, if cmp is overloaded, it can be used to autogenerate behaviors for lt, le, gt, ge, eq, and ne.

Note that overloading cmp won't let you sort objects as easily as you'd like, because what will be compared are the stringified versions of the objects instead of the objects themselves. If that was your goal, you'd want to overload "" as well.

Mathematical functions: atan2, cos, sin, exp, abs, log, sqrt

If abs is unavailable, it can be autogenerated from < or <=> combined with either unary minus or subtraction.

An overloaded - can be used to autogenerate missing handlers for unary minus or for the abs function, which may also be separately overloaded. (Yes, we know that abs looks like a function, whereas unary minus looks like an operator, but they aren't all that different as far as Perl's concerned.)

Iterative operator: <>

The <> handler can be triggered by using either readline (when it reads from a filehandle, as in while (<FH>)) or glob (when it is used for fileglobbing, as in @files = <*.*>).

package LuckyDraw;

use overload
    '<>' => sub {
        my $self = shift;
        return splice @$self, rand @$self, 1;
    };

sub new {
    my $class = shift;
    return bless [@_] => $class;
}

package main;

$lotto = new LuckyDraw 1 .. 51;

for (qw(1st 2nd 3rd 4th 5th 6th)) {
    $lucky_number = <$lotto>;
    print "The $_ lucky number is: $lucky_number.\n";
}

$lucky_number = <$lotto>;
print "\nAnd the bonus number is: $lucky_number.\n";
In California, this prints:
The 1st lucky number is: 18
The 2nd lucky number is: 11
The 3rd lucky number is: 40

The 4th lucky number is: 7
The 5th lucky number is: 51
The 6th lucky number is: 33

And the bonus number is: 5

Dereference operators: ${}, @{}, %{}, &{}, *{}

Attempts to dereference scalar, array, hash, subroutine, and glob references can be intercepted by overloading these five symbols.

The online Perl documentation for overload demonstrates how you can use this operator to simulate your own pseudohashes. Here's a simpler example that implements an object as an anonymous array but permits hash referencing. Don't try to treat it as a real hash; you won't be able to delete key/value pairs from the object. If you want to combine array and hash notations, use a real pseudohash (as it were).

package PsychoHash;

use overload '%{}' => \&as_hash;

sub as_hash {
    my ($x) = shift;
    return { @$x };
}

sub new {
    my $class = shift;
    return bless [ @_ ] => $class;
}

$critter = new PsychoHash( height => 72, weight => 365, type => "camel" );

print $critter->{weight};   # prints 365
Also see Chapter 14, "Tied Variables", for a mechanism to let you redefine basic operations on hashes, arrays, and scalars.

When overloading an operator, try not to create objects with references to themselves. For instance,

use overload '+' => sub { bless [ \$_[0], \$_[1] ] };
This is asking for trouble, since if you say $animal += $vegetable, the result will make $animal a reference to a blessed array reference whose first element is $animal. This is a circular reference, which means that even if you destroy $animal, its memory won't be freed until your process (or interpreter) terminates. See "Garbage Collection, Circular References, and Weak References" in Chapter 8, "References".

Previous | Home | Next
13.2. Overload Handlers | Book Index | 13.4. The Copy Constructor (=)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.4. The Copy Constructor (=)

Although it looks like a regular operator, = has a special and slightly subintuitive meaning as an overload key. It does not overload the Perl assignment operator. It can't, because that operator has to be reserved for assigning references, or everything breaks.

The handler for = is used in situations where a mutator (such as ++, --, or any of the assignment operators) is applied to a reference that shares its object with another reference. The = handler lets you intercept the mutator and copy the object yourself so that the copy alone is mutated. Otherwise, you'd clobber the original.

$copy = $original;   # copies only the reference
++$copy;             # changes underlying shared object
Now, bear with us. Suppose that $original is a reference to an object. To make ++$copy modify only $copy and not $original, a copy of $copy is first made, and $copy is assigned a reference to this new object. This operation is not performed until ++$copy is executed, so $copy coincides with $original before the increment--but not afterward. In other words, it's the ++ that recognizes the need for the copy and calls out to your copy constructor.

The need for copying is recognized only by mutators such as ++ or +=, or by nomethod, which is described later. If the operation is autogenerated via +, as in:

$copy = $original;
$copy = $copy + 1;
then no copying occurs, because + doesn't know it's being used as a mutator.

If the copy constructor is required during the execution of some mutator, but a handler for = was not specified, it can be autogenerated as a string copy provided the object is a plain scalar and not something fancier.

For example, the code actually executed for the sequence:

$copy = $original;
...
++$copy;
might end up as something like this:
$copy = $original;
...
$copy = $copy->clone(undef, "");
$copy->incr(undef, "");
This assumes $original points to an overloaded object, ++ was overloaded with \&incr, and = was overloaded with \&clone.

Similar behavior is triggered by $copy = $original++, which is interpreted as $copy = $original; ++$original.

Previous | Home | Next
13.3. Overloadable Operators | Book Index | 13.5. When an Overload Handler Is Missing (nomethod and fallback)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.5. When an Overload Handler Is Missing (nomethod and fallback)

If you apply an unoverloaded operator to an object, Perl first tries to autogenerate a behavior from other overloaded operators using the rules described earlier. If that fails, Perl looks for an overloading behavior for nomethod and uses that if available. That handler is to operators what an AUTOLOAD subroutine is to subroutines: it's what you do when you can't think of what else to do.

If used, the nomethod key should be followed by a reference to a handler that accepts four arguments, (not three as all the other handlers expect). The first three arguments are no different than in any other handler; the fourth is a string corresponding to the operator whose handler is missing. This serves the same purpose as the $AUTOLOAD variable does in AUTOLOAD subroutines.

If Perl has to look for a nomethod handler but can't find one, an exception is raised.

If you want to prevent autogeneration from occurring, or you want a failed autogeneration attempt to result in no overloading at all, you can define the special fallback overloading key. It has three useful states:

undef

If fallback is not set, or is explicitly set to undef, the sequence of overloading events is unaffected: handlers are sought, autogeneration is attempted, and finally the nomethod handler is invoked. If that fails, an exception is raised.

false

If fallback is set to a defined but false value (like 0), autogeneration is never attempted. Perl will call the nomethod handler if one exists, but raise an exception otherwise.

true

This is nearly the same behavior as for undef, but no exception is raised if an appropriate handler cannot be synthesized via autogeneration. Instead, Perl reverts to following the unoverloaded behavior for that operator, as though there were no use overload pragma in the class at all.

Previous | Home | Next
13.4. The Copy Constructor (=) | Book Index | 13.6. Overloading Constants
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.6. Overloading Constants

You can change how constants are interpreted by Perl with overload::constant, which is most usefully placed in a package's import method. (If you do this, you should properly invoke overload::remove_constant in the package's unimport method so that the package can clean up after itself when you ask it to.)

Both overload::constant and overload::remove_constant expect a list of key/value pairs. The keys should be any of integer, float, binary, q, and qr, and each value should be the name of a subroutine, an anonymous subroutine, or a code reference that will handle the constants.

sub import { overload::constant ( integer => \&integer_handler,
                                  float   => \&float_handler,
                                  binary  => \&base_handler,
                                  q       => \&string_handler,
                                  qr      => \&regex_handler ) }
Any handlers you provide for integer and float will be invoked whenever the Perl tokener encounters a constant number. This is independent of the use constant pragma; simple statements such as
$year = cube(12) + 1;        # integer
$pi   = 3.14159265358979;    # float
will trigger whatever handler you requested.

The binary key lets you intercept binary, octal, and hexadecimal constants. q handles single-quoted strings (including strings introduced with q) and constant substrings within qq- and qx-quoted strings and here documents. Finally, qr handles constant pieces within regular expressions, as described at the end of Chapter 5, "Pattern Matching".

The handler will be passed three arguments. The first argument is the original constant, in whatever form it was provided to Perl. The second argument is how Perl actually interpreted the constant; for instance, 123_456 will appear as 123456.

The third argument is defined only for strings handled by the q and qr handlers, and will be one of qq, q, s, or tr depending on how the string is to be used. qq means that the string is from an interpolated context, such as double quotes, backticks, an m// match, or the pattern of an s/// substitution. q means that the string is from an uninterpolated context, s means that the constant is a replacement string in an s/// substitution, and tr means that it's a component of a tr/// or y/// expression.

The handler should return a scalar, which will be used in place of the constant. Often, that scalar will be a reference to an overloaded object, but there's nothing preventing you from doing something more dastardly:

package DigitDoubler;    # A module to be placed in DigitDoubler.pm
use overload;

sub import { overload::constant ( integer => \&handler,
                                  float   => \&handler ) }

sub handler {
    my ($orig, $interp, $context) = @_;
    return $interp * 2;          # double all constants
}

1;
Note that handler is shared by both keys, which works okay in this case. Now when you say:
use DigitDoubler;

$trouble = 123;      # trouble is now 246
$jeopardy = 3.21;    # jeopardy is now 6.42
you redefine the world.

If you intercept string constants, it is recommended that you provide a concatenation operator (".") as well, since an interpolated expression like "ab$cd!!" is merely a shortcut for the longer 'ab' . $cd . '!!'. Similarly, negative numbers are considered negations of positive constants, so you should provide a handler for neg when you intercept integers or floats. (We didn't need to do that earlier, because we're returning actual numbers, not overloaded object references.)

Note that overload::constant does not propagate into run-time compilation inside eval, which can be either a bug or a feature depending on how you look at it.

Previous | Home | Next
13.5. When an Overload Handler Is Missing (nomethod and fallback) | Book Index | 13.7. Public Overload Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.7. Public Overload Functions

As of the 5.6 release of Perl, the use overload pragma provides the following functions for public consumption.

overload::StrVal(OBJ)

This function returns the string value that OBJ would have in absence of stringification overloading ("").

overload::Overloaded(OBJ)

This function returns a true value if OBJ is subject to any operator overloading at all, and false otherwise.

overload::Method(OBJ, OPERATOR)

This function returns a reference to whatever code implements the overloading for OPERATOR when it operates on OBJ, or undef if no such overloading exists.

Previous | Home | Next
13.6. Overloading Constants | Book Index | 13.8. Inheritance and Overloading
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.8. Inheritance and Overloading

Inheritance interacts with overloading in two ways. The first occurs when a handler is named as a string rather than provided as a code reference or anonymous subroutine. When named as a string, the handler is interpreted as a method, and can therefore be inherited from superclasses.

The second interaction between inheritance and overloading is that any class derived from a overloaded class is itself subject to that overloading. In other words, overloading is itself inherited. The set of handlers in a class is the union of handlers of all that class's ancestors, recursively. If a handler can be found in several different ancestors, the handler actually used is governed by the usual rules for method inheritance. For example, if class Alpha inherits from classes Beta and Gamma in that order, and class Beta overloads + with \&Beta::plus_sub, but class Gamma overloads + with the string "plus_meth", then Beta::plus_sub will be called when you try to apply + to an Alpha object.

Since the value of the fallback key is not a handler, its inheritance is not governed by the rules given above. In the current implementation, the fallback value from the first overloaded ancestor is used, but this is accidental and subject to change without notice (well, without much notice).

Previous | Home | Next
13.7. Public Overload Functions | Book Index | 13.9. Run-Time Overloading
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.9. Run-Time Overloading

Since use statements are executed at compile time, the only way to change overloading during run time is:

eval " use overload '+' => \&my_add ";
You can also say:
eval " no overload '+', '--', '<=' ";
although the use of these constructs during run time is questionable.

Previous | Home | Next
13.8. Inheritance and Overloading | Book Index | 13.10. Overloading Diagnostics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


13.10. Overloading Diagnostics

If your Perl was compiled with -DDEBUGGING, you can view diagnostic messages for overloading when you run a program with the -Do switch or its equivalent. You can also deduce which operations are overloaded using the m command of Perl's built-in debugger.

If you're feeling overloaded now, maybe the next chapter will tie things back together for you.

Previous | Home | Next
13.9. Run-Time Overloading | Book Index | 14. Tied Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 14. Tied Variables

Contents:

Tying Scalars
Tying Arrays
Tying Hashes
Tying Filehandles
A Subtle Untying Trap
Tie Modules on CPAN

Some human endeavors require a disguise. Sometimes the intent is to deceive, but more often, the intent is to communicate something true at a deeper level. For instance, many job interviewers expect you to dress up in a tie to indicate that you're seriously interested in fitting in, even though both of you know you'll never wear a tie on the job. It's odd when you think about it: tying a piece of cloth around your neck can magically get you a job. In Perl culture, the tie operator plays a similar role: it lets you create a seemingly normal variable that, behind the disguise, is actually a full-fledged Perl object that is expected to have an interesting personality of its own. It's just an odd bit of magic, like pulling Bugs Bunny out of a hat.

Put another way, the funny characters $, @, %, or * in front of a variable name tell Perl and its programmers a great deal--they each imply a particular set of archetypal behaviors. You can warp those behaviors in various useful ways with tie, by associating the variable with a class that implements a new set of behaviors. For instance, you can create a regular Perl hash, and then tie it to a class that makes the hash into a database, so that when you read values from the hash, Perl magically fetches data from an external database file, and when you set values in the hash, Perl magically stores data in the external database file. In this case, "magically" means "transparently doing something very complicated". You know the old saying: any technology sufficiently advanced is indistinguishable from a Perl script. (Seriously, people who play with the guts of Perl use magic as a technical term referring to any extra semantics attached to variables such as %ENV or %SIG. Tied variables are just an extension of that.)

Perl already has built-in dbmopen and dbmclose functions that magically tie hash variables to databases, but those functions date back to the days when Perl had no tie. Now tie provides a more general mechanism. In fact, Perl itself implements dbmopen and dbmclose in terms of tie.

You can tie a scalar, array, hash, or filehandle (via its typeglob) to any class that provides appropriately named methods to intercept and emulate normal accesses to those variables. The first of those methods is invoked at the point of the tie itself: tying a variable always invokes a constructor, which, if successful, returns an object that Perl squirrels away where you don't see it, down inside the "normal" variable. You can always retrieve that object later using the tied function on the normal variable:

tie VARIABLE, CLASSNAME, LIST;  # binds VARIABLE to CLASSNAME
$object = tied VARIABLE;
Those two lines are equivalent to:
$object = tie VARIABLE, CLASSNAME, LIST;
Once it's tied, you treat the normal variable normally, but each access automatically invokes methods on the underlying object; all the complexity of the class is hidden behind those method invocations. If later you want to break the association between the variable and the class, you can untie the variable:
untie VARIABLE;
You can almost think of tie as a funny kind of bless, except that it blesses a bare variable instead of an object reference. It also can take extra parameters, just as a constructor can--which is not terribly surprising, since it actually does invoke a constructor internally, whose name depends on which type of variable you're tying: either TIESCALAR, TIEARRAY, TIEHASH, or TIEHANDLE.[1] These constructors are invoked as class methods with the specified CLASSNAME as their invocant, plus any additional arguments you supplied in LIST. (The VARIABLE is not passed to the constructor.)

[1] Since the constructors have separate names, you could even provide a single class that implements all of them. That would allow you to tie scalars, arrays, hashes, and filehandles all to the same class, although this is not generally done, since it would make the other magical methods tricky to write.

These four constructors each return an object in the customary fashion. They don't really care whether they were invoked from tie, nor do any of the other methods in the class, since you can always invoke them directly if you'd like. In one sense, all the magic is in the tie, not in the class implementing the tie. It's just an ordinary class with funny method names, as far as the class is concerned. (Indeed, some tied modules provide extra methods that aren't visible through the tied variable; these methods must be called explicitly as you would any other object method. Such extra methods might provide services like file locking, transaction protection, or anything else an instance method might do.)

So these constructors bless and return an object reference just as any other constructor would. That reference need not refer to the same type of variable as the one being tied; it just has to be blessed, so that the tied variable can find its way back to your class for succor. For instance, our long TIEARRAY example will use a hash-based object, so it can conveniently hold additional information about the array it's emulating.

The tie function will not use or require a module for you--you must do that yourself explicitly, if necessary, before calling the tie. (On the other hand, the dbmopen function will, for backward compatibility, attempt to use one or another DBM implementation. But you can preempt its selection with an explicit use, provided the module you use is one of the modules in dbmopen's list of modules to try. See the online docs for the AnyDBM_File module for a fuller explanation.)

The methods called by a tied variable have predetermined names like FETCH and STORE, since they're invoked implicitly (that is, triggered by particular events) from within the innards of Perl. These names are in ALLCAPS, a convention we often follow for such implicitly called routines. (Other special names that follow this convention include BEGIN, CHECK, INIT, END, DESTROY, and AUTOLOAD, not to mention UNIVERSAL->VERSION. In fact, nearly all of Perl's predefined variables and filehandles are in uppercase: STDIN, SUPER, CORE, CORE::GLOBAL, DATA, @EXPORT, @INC, @ISA, @ARGV, and %ENV. Of course, built-in operators and pragmas go to the opposite extreme and have no capitals at all.)

The first thing we'll cover is extremely simple: how to tie a scalar variable.

14.1. Tying Scalars

To implement a tied scalar, a class must define the following methods: TIESCALAR, FETCH, and STORE (and possibly DESTROY). When you tie a scalar variable, Perl calls TIESCALAR. When you read the tied variable, it calls FETCH, and when you assign a value to the variable, it calls STORE. If you've kept the object returned by the initial tie (or if you retrieve it later using tied), you can access the underlying object yourself--this does not trigger its FETCH or STORE methods. As an object, it's not magical at all, but rather quite objective.

If a DESTROY method exists, Perl invokes it when the last reference to the tied object disappears, just as for any other object. That happens when your program ends or when you call untie, which eliminates the reference used by the tie. However, untie doesn't eliminate any outstanding references you might have stored elsewhere; DESTROY is deferred until those references are gone, too.

The Tie::Scalar and Tie::StdScalar packages, both found in the standard Tie::Scalar module, provide some simple base class definitions if you don't want to define all of these methods yourself. Tie::Scalar provides elemental methods that do very little, and Tie::StdScalar provides methods that make a tied scalar behave like a regular Perl scalar. (Which seems singularly useless, but sometimes you just want a bit of a wrapper around the ordinary scalar semantics, for example, to count the number of times a particular variable is set.)

Before we show you our elaborate example and complete description of all the mechanics, here's a taste just to whet your appetite--and to show you how easy it really is. Here's a complete program:

#!/usr/bin/perl
package Centsible;
sub TIESCALAR { bless \my $self, shift }
sub STORE { ${ $_[0] } = $_[1] }  # do the default thing
sub FETCH { sprintf "%.02f", ${ my $self = shift } } # round value

package main;
tie $bucks, "Centsible";
$bucks = 45.00;
$bucks *= 1.0715; # tax
$bucks *= 1.0715; # and double tax!
print "That will be $bucks, please.\n";
When run, that program produces:
That will be 51.67, please.
To see the difference it makes, comment out the call to tie; then you'll get:
That will be 51.66505125, please.
Admittedly, that's more work than you'd normally go through to round numbers.

14.1.1. Scalar-Tying Methods

Now that you've seen a sample of what's to come, let's develop a more elaborate scalar-tying class. Instead of using any canned package for the base class (especially since scalars are so simple), we'll look at each of the four methods in turn, building an example class named ScalarFile. Scalars tied to this class contain regular strings, and each such variable is implicitly associated with a file where that string is stored. (You might name your variables to remind you which file you're referring to.) Variables are tied to the class this way:

use ScalarFile;       # load ScalarFile.pm
tie $camel, "ScalarFile", "/tmp/camel.lot";
Once the variable has been tied, its previous contents are clobbered, and the internal connection between the variable and its object overrides the variable's normal semantics. When you ask for the value of $camel, it now reads the contents of /tmp/camel.lot, and when you assign a value to $camel, it writes the new contents out to /tmp/camel.lot, obliterating any previous occupants.

The tie is on the variable, not the value, so the tied nature of a variable does not propagate across assignment. For example, let's say you copy a variable that's been tied:

$dromedary = $camel;

Instead of reading the value in the ordinary fashion from the $camel scalar variable, Perl invokes the FETCH method on the associated underlying object. It's as though you'd written this:

$dromedary = (tied $camel)->FETCH():
Or if you remember the object returned by tie, you could use that reference directly, as in the following sample code:
$clot = tie $camel, "ScalarFile", "/tmp/camel.lot";
$dromedary = $camel;          # through the implicit interface
$dromedary = $clot->FETCH();  # same thing, but explicitly
If the class provides methods besides TIESCALAR, FETCH, STORE, and DESTROY, you could use $clot to invoke them manually. However, one normally minds one's own business and leaves the underlying object alone, which is why you often see the return value from tie ignored. You can still get at the object via tied if you need it later (for example, if the class happens to document any extra methods you need). Ignoring the returned object also eliminates certain kinds of errors, which we'll cover later.

Here's the preamble of our class, which we will put into ScalarFile.pm:

package ScalarFile;
use Carp;                # Propagate error messages nicely.
use strict;              # Enforce some discipline on ourselves.
use warnings;            # Turn on lexically scoped warnings.
use warnings::register;  # Allow user to say "use warnings 'ScalarFile'".
my $count = 0;           # Internal count of tied ScalarFiles.
The standard Carp module exports the carp, croak, and confess subroutines, which we'll use in the code later in this section. As usual, see Chapter 32, "Standard Modules", or the online docs for more about Carp.

The following methods are defined by the class.

CLASSNAME->TIESCALAR(LIST)

The TIESCALAR method of the class is triggered whenever you tie a scalar variable. The optional LIST contains any parameters needed to initialize the object properly. (In our example, there is only one parameter: the name of the file.) The method should return an object, but this doesn't have to be a reference to a scalar. In our example, though, it is.

sub TIESCALAR {           # in ScalarFile.pm
    my $class    = shift;
    my $filename = shift;
    $count++;             # A file-scoped lexical, private to class.
    return bless \$filename, $class;
}
Since there's no scalar equivalent to the anonymous array and hash composers, [] and {}, we merely bless a lexical variable's referent, which effectively becomes anonymous as soon as the name goes out of scope. This works fine (you could do the same thing with arrays and hashes) as long as the variable really is lexical. If you try this trick on a global, you might think you're getting away with it, until you try to create another camel.lot. Don't be tempted to write something like this:
sub TIESCALAR { bless \$_[1], $_[0] }    # WRONG, could refer to global.
A more robustly written constructor might check that the filename is accessible. We check first to see if the file is readable, since we don't want to clobber the existing value. (In other words, we shouldn't assume the user is going to write first. They might be treasuring their old Camel Lot file from a previous run of the program.) If we can't open or create the filename specified, we'll indicate the error gently by returning undef and optionally printing a warning via carp. (We could just croak instead--it's a matter of taste whether you prefer fish or frogs.) We'll use the warnings pragma to determine whether the user is interested in our warning:
sub TIESCALAR {           # in ScalarFile.pm
    my $class    = shift;
    my $filename = shift;
    my $fh;
    if (open $fh, "<", $filename or
        open $fh, ">", $filename)
    {
        close $fh;
        $count++;
        return bless \$filename, $class;
    }
    carp "Can't tie $filename: $!" if warnings::enabled();
    return;
}
Given such a constructor, we can now associate the scalar $string with the file camel.lot:

tie ($string, "ScalarFile", "camel.lot") or die;

(We're still assuming some things we shouldn't. In a production version of this, we'd probably open the filehandle once and remember the filehandle as well as the filename for the duration of the tie, keeping the handle exclusively locked with flock the whole time. Otherwise we're open to race conditions--see "Timing Glitches" in Chapter 23, "Security".)

SELF->FETCH

This method is invoked whenever you access the tied variable (that is, read its value). It takes no arguments beyond the object tied to the variable. In our example, that object contains the filename.

sub FETCH {
    my $self  = shift;
    confess "I am not a class method" unless ref $self;
    return unless open my $fh, $$self;
    read($fh, my $value, -s $fh);  # NB: don't use -s on pipes!
    return $value;
}
This time we've decided to blow up (raise an exception) if FETCH gets something other than a reference. (Either it was invoked as a class method, or someone miscalled it as a subroutine.) There's no other way for us to return an error, so it's probably the right thing to do. In fact, Perl would have raised an exception in any event as soon as we tried to dereference $self; we're just being polite and using confess to spew a complete stack backtrace onto the user's screen. (If that can be considered polite.)

We can now see the contents of camel.lot when we say this:

tie($string, "ScalarFile", "camel.lot");
print $string;

SELF->STORE(VALUE)

This method is run when the tied variable is set (assigned). The first argument, SELF, is as always the object associated with the variable; VALUE is whatever was assigned to the variable. (We use the term "assigned" loosely--any operation that modifies the variable can call STORE.)

sub STORE {
    my($self,$value) = @_;
    ref $self                   or confess "not a class method";
    open my $fh, ">", $$self    or croak "can't clobber $$self: $!";
    syswrite($fh, $value) == length $value
                                or croak "can't write to $$self: $!";
    close $fh                   or croak "can't close $$self: $!";
    return $value;
}
After "assigning" it, we return the new value--because that's what assignment does. If the assignment wasn't successful, we croak out the error. Possible causes might be that we didn't have permission to write to the associated file, or the disk filled up, or gremlins infested the disk controller. Sometimes you control the magic, and sometimes the magic controls you.

We can now write to camel.lot when we say this:

tie($string, "ScalarFile", "camel.lot");
$string  = "Here is the first line of camel.lot\n";
$string .= "And here is another line, automatically appended.\n";

SELF->DESTROY

This method is triggered when the object associated with the tied variable is about to be garbage collected, in case it needs to do something special to clean up after itself. As with other classes, such a method is seldom necessary, since Perl deallocates the moribund object's memory for you automatically. Here, we'll define a DESTROY method that decrements our count of tied files:

sub DESTROY {
    my $self = shift;
    confess "wrong type" unless ref $self;
    $count--;
}
We might then also supply an extra class method to retrieve the current count. Actually, it doesn't care whether it's called as a class method or an object method, but you don't have an object anymore after the DESTROY, now do you?
sub count {
    # my $invocant = shift;
    $count;
}
You can call this as a class method at any time like this:
if (ScalarFile->count) {
    warn "Still some tied ScalarFiles sitting around somewhere...\n";
}

That's about all there is to it. Actually, it's more than all there is to it, since we've done a few nice things here for the sake of completeness, robustness, and general aesthetics (or lack thereof). Simpler TIESCALAR classes are certainly possible.

14.1.2. Magical Counter Variables

Here's a simple Tie::Counter class, inspired by the CPAN module of the same name. Variables tied to this class increment themselves by 1 every time they're used. For example:

tie my $counter, "Tie::Counter", 100;
@array = qw /Red Green Blue/;
for my $color (@array) {               # Prints:
    print "  $counter  $color\n";      #   100  Red
}                                      #   101  Green
                                       #   102  Blue
The constructor takes as an optional extra argument the first value of the counter, which defaults to 0. Assigning to the counter will set a new value. Here's the class:
package Tie::Counter;
sub FETCH     { ++ ${ $_[0] } }
sub STORE     { ${ $_[0] } = $_[1] }
sub TIESCALAR {
    my ($class, $value) = @_;
    $value = 0 unless defined $value;
    bless \$value => $class;
}
1;  # if in module
See how small that is? It doesn't take much code to put together a class like this.

14.1.3. Magically Banishing $_

This curiously exotic tie class is used to outlaw unlocalized uses of $_. Instead of pulling in the module with use, which invokes the class's import method, this module should be loaded with no to call the seldom-used unimport method. The user says:

no Underscore;
And then all uses of $_ as an unlocalized global raise an exception.

Here's a little test suite for the module:

#!/usr/bin/perl
no Underscore;
@tests = (
    "Assignment"  => sub { $_ = "Bad" },
    "Reading"     => sub { print },
    "Matching"    => sub { $x = /badness/ },
    "Chop"        => sub { chop },
    "Filetest"    => sub { -x },
    "Nesting"     => sub { for (1..3) { print } },
);

while ( ($name, $code) = splice(@tests, 0, 2) ) {
    print "Testing $name: ";
    eval { &$code };
    print $@ ? "detected" : " missed!";
    print "\n";
}
which prints out the following:
Testing Assignment: detected
Testing Reading: detected
Testing Matching: detected
Testing Chop: detected
Testing Filetest: detected
Testing Nesting: 123 missed!
The last one was "missed" because it was properly localized by the for loop and thus safe to access.

Here's the curiously exotic Underscore module itself. (Did we mention that it's curiously exotic?) It works because tied magic is effectively hidden by a local. The module does the tie in its own initialization code so that a require also works.

package Underscore;
use Carp;
sub TIESCALAR { bless \my $dummy => shift }
sub FETCH { croak 'Read access to $_ forbidden'  }
sub STORE { croak 'Write access to $_ forbidden' }
sub unimport { tie($_, __PACKAGE__) }
sub import   { untie $_ }
tie($_, __PACKAGE__) unless tied $_;
1;
It's hard to usefully mix calls to use and no for this class in your program, because they all happen at compile time, not run time. You could call Underscore->import and Underscore->unimport directly, just as use and no do. Normally, though, to renege and let yourself freely use $_ again, you'd just use local on it, which is the whole point.

Previous | Home | Next
13.10. Overloading Diagnostics | Book Index | 14.2. Tying Arrays
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.2. Tying Arrays

A class implementing a tied array must define at least the methods TIEARRAY, FETCH, and STORE. There are many optional methods: the ubiquitous DESTROY method, of course, but also the STORESIZE and FETCHSIZE methods used to provide $#array and scalar(@array) access. In addition, CLEAR is triggered when Perl needs to empty the array, and EXTEND when Perl would have pre-extended allocation in a real array.

You may also define the POP, PUSH, SHIFT, UNSHIFT, SPLICE, DELETE, and EXISTS methods if you want the corresponding Perl functions to work on the tied array. The Tie::Array class can serve as a base class to implement the first five of those functions in terms of FETCH and STORE. (Tie::Array's default implementation of DELETE and EXISTS simply calls croak.) As long as you define FETCH and STORE, it doesn't matter what kind of data structure your object contains.

On the other hand, the Tie::StdArray class (defined in the standard Tie::Array module) provides a base class with default methods that assume the object contains a regular array. Here's a simple array-tying class that makes use of this. Because it uses Tie::StdArray as its base class, it only needs to define the methods that should be treated in a nonstandard way.

#!/usr/bin/perl
package ClockArray;
use Tie::Array;
our @ISA = 'Tie::StdArray';
sub FETCH {
    my($self,$place) = @_;
    $self->[ $place % 12 ];
}
sub STORE {
    my($self,$place,$value) = @_;
    $self->[ $place % 12 ] = $value;
}

package main;
tie my @array, 'ClockArray';
@array = ( "a" ... "z" );
print "@array\n";
When run, the program prints out "y z o p q r s t u v w x". This class provides an array with only a dozen slots, like hours of a clock, numbered 0 through 11. If you ask for the 15th array index, you really get the 3rd one. Think of it as a travel aid for people who haven't learned how to read 24-hour clocks.

14.2.1. Array-Tying Methods

That's the simple way. Now for some nitty-gritty details. To demonstrate, we'll implement an array whose bounds are fixed at its creation. If you try to access anything beyond those bounds, an exception is raised. For example:

use BoundedArray;
tie @array, "BoundedArray", 2;

$array[0] = "fine";
$array[1] = "good";
$array[2] = "great";
$array[3] = "whoa";   # Prohibited; displays an error message.
The preamble code for the class is as follows:
package BoundedArray;
use Carp;
use strict;
To avoid having to define SPLICE later, we'll inherit from the Tie::Array class:
use Tie::Array;
our @ISA = ("Tie::Array");

CLASSNAME->TIEARRAY(LIST)

As the constructor for the class, TIEARRAY should return a blessed reference through which the tied array will be emulated.

In this next example, just to show you that you don't really have to return an array reference, we'll choose a hash reference to represent our object. A hash works out well as a generic record type: the value in the hash's "BOUND" key will store the maximum bound allowed, and its "DATA" value will hold the actual data. If someone outside the class tries to dereference the object returned (doubtless thinking it an array reference), an exception is raised.

sub TIEARRAY {
    my $class = shift;
    my $bound = shift;
    confess "usage: tie(\@ary, 'BoundedArray', max_subscript)"
        if @_ || $bound =~ /\D/;
    return bless { BOUND => $bound, DATA => [] }, $class;
}
We can now say:
tie(@array, "BoundedArray", 3);  # maximum allowable index is 3
to ensure that the array will never have more than four elements. Whenever an individual element of the array is accessed or stored, FETCH and STORE will be called just as they were for scalars, but with an extra index argument.

SELF->FETCH(INDEX)

This method is run whenever an individual element in the tied array is accessed. It receives one argument after the object: the index of the value we're trying to fetch.

sub FETCH {
    my ($self, $index) = @_;
    if ($index > $self->{BOUND}) {
        confess "Array OOB: $index > $self->{BOUND}";
    }
    return $self->{DATA}[$index];
}

SELF->STORE(INDEX, VALUE)

This method is invoked whenever an element in the tied array is set. It takes two arguments after the object: the index at which we're trying to store something and the value we're trying to put there. For example:

sub STORE {
    my($self, $index, $value) = @_;
    if ($index > $self->{BOUND} ) {
        confess "Array OOB: $index > $self->{BOUND}";
    }
    return $self->{DATA}[$index] = $value;
}

SELF->DESTROY

Perl calls this method when the tied variable needs to be destroyed and its memory reclaimed. This is almost never needed in a language with garbage collection, so for this example we'll just leave it out.

SELF->FETCHSIZE

The FETCHSIZE method should return the total number of items in the tied array associated with SELF. It's equivalent to scalar(@array), which is usually equal to $#array + 1.

sub FETCHSIZE {
    my $self = shift;
    return scalar @{$self->{DATA}};
}

SELF->STORESIZE(COUNT)

This method sets the total number of items in the tied array associated with SELF to be COUNT. If the array shrinks, you should remove entries beyond COUNT. If the array grows, you should make sure the new positions are undefined. For our BoundedArray class, we also ensure that the array doesn't grow beyond the limit initially set.

sub STORESIZE {
    my ($self, $count) = @_;
    if ($count > $self->{BOUND}) {
        confess "Array OOB: $count > $self->{BOUND}";
    }
    $#{$self->{DATA}} = $count;
}

SELF->EXTEND(COUNT)

Perl uses the EXTEND method to indicate that the array is likely to expand to hold COUNT entries. That way you can can allocate memory in one big chunk instead of in many successive calls later on. Since our BoundedArrays have fixed upper bounds, we won't define this method.

SELF->EXISTS(INDEX)

This method verifies that the element at INDEX exists in the tied array. For our BoundedArray, we just employ Perl's built-in exists after verifying that it's not an attempt to look past the fixed upper bound.

sub EXISTS  {
    my ($self, $index) = @_;
    if ($index > $self->{BOUND}) {
        confess "Array OOB: $index > $self->{BOUND}";
    }
    exists $self->{DATA}[$index];
}

SELF->DELETE(INDEX)

The DELETE method removes the element at INDEX from the tied array SELF. For our BoundedArray class, the method looks nearly identical to EXISTS, but this is not the norm.

sub DELETE {
    my ($self, $index) = @_;
    print STDERR "deleting!\n";
    if ($index > $self->{BOUND}) {
        confess "Array OOB: $index > $self->{BOUND}";
    }
    delete $self->{DATA}[$index];
}

SELF->CLEAR

This method is called whenever the array has to be emptied. That happens when the array is set to a list of new values (or an empty list), but not when it's provided to the undef function. Since a cleared BoundedArray always satisfies the upper bound, we don't need check anything here:

sub CLEAR {
    my $self = shift;
    $self->{DATA} = [];
}
If you set the array to a list, CLEAR will trigger but won't see the list values. So if you violate the upper bound like so:
tie(@array, "BoundedArray", 2);
@array = (1, 2, 3, 4);
the CLEAR method will still return successfully. The exception will only be raised on the subsequent STORE. The assignment triggers one CLEAR and four STOREs.

SELF->PUSH(LIST)

This method appends the elements of LIST to the array. Here's how it might look for our BoundedArray class:

sub PUSH    {
    my $self = shift;
    if (@_ + $#{$self->{DATA}} > $self->{BOUND}) {
        confess "Attempt to push too many elements";
    }
    push @{$self->{DATA}}, @_;
}

SELF->UNSHIFT(LIST)

This method prepends the elements of LIST to the array. For our BoundedArray class, the subroutine would be similar to PUSH.

SELF->POP

The POP method removes the last element of the array and returns it. For BoundedArray, it's a one-liner:

sub POP { my $self = shift; pop @{$self->{DATA}} }

SELF->SHIFT

The SHIFT method removes the first element of the array and returns it. For BoundedArray, it's similar to POP.

SELF->SPLICE(OFFSET, LENGTH, LIST)

This method lets you splice the SELF array. To mimic Perl's built-in splice, OFFSET should be optional and default to zero, with negative values counting back from the end of the array. LENGTH should also be optional, defaulting to rest of the array. LIST can be empty. If it's properly mimicking the built-in, the method will return a list of the original LENGTH elements at OFFSET (that is, the list of elements to be replaced by LIST).

Since splicing is a somewhat complicated operation, we won't define it at all; we'll just use the SPLICE subroutine from the Tie::Array module that we got for free when we inherited from Tie::Array. This way we define SPLICE in terms of other BoundedArray methods, so the bounds checking will still occur.

That completes our BoundedArray class. It warps the semantics of arrays just a little. But we can do better, and in very much less space.

14.2.2. Notational Convenience

One of the nice things about variables is that they interpolate. One of the not-so-nice things about functions is that they don't. You can use a tied array to make a function that can be interpolated. Suppose you want to interpolate random integers in a string. You can just say:

#!/usr/bin/perl
package RandInterp;
sub TIEARRAY { bless \my $self };
sub FETCH { int rand $_[1] };

package main;
tie @rand, "RandInterp";

for (1,10,100,1000) {
    print "A random integer less than $_ would be $rand[$_]\n";
}
$rand[32] = 5;    # Will this reformat our system disk?
When run, this prints:
A random integer less than 1 would be 0
A random integer less than 10 would be 3
A random integer less than 100 would be 46
A random integer less than 1000 would be 755
Can't locate object method "STORE" via package "RandInterp" at foo line 10.
As you can see, it's no big deal that we didn't even implement STORE. It just blows up like normal.

Previous | Home | Next
14.1. Tying Scalars | Book Index | 14.3. Tying Hashes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.3. Tying Hashes

A class implementing a tied hash should define eight methods. TIEHASH constructs new objects. FETCH and STORE access the key/value pairs. EXISTS reports whether a key is present in the hash, and DELETE removes a key along with its associated value.[2] CLEAR empties the hash by deleting all key/value pairs. FIRSTKEY and NEXTKEY iterate over the key/value pairs when you call keys, values, or each. And as usual, if you want to perform particular actions when the object is deallocated, you may define a DESTROY method. (If this seems like a lot of methods, you didn't read the last section on arrays attentively. In any event, feel free to inherit the default methods from the standard Tie::Hash module, redefining only the interesting ones. Again, Tie::StdHash assumes the implementation is also a hash.)

[2] Remember that Perl distinguishes between a key not existing in the hash and a key existing in the hash but having a corresponding value of undef. The two possibilities can be tested with exists and defined, respectively.

For example, suppose you want to create a hash where every time you assign a value to a key, instead of overwriting the previous contents, the new value is appended to an array of values. That way when you say:

$h{$k} = "one";
$h{$k} = "two";
It really does:
push @{ $h{$k} }, "one";
push @{ $h{$k} }, "two";
That's not a very complicated idea, so you should be able to use a pretty simple module. Using Tie::StdHash as a base class, it is. Here's a Tie::AppendHash that does just that:
package Tie::AppendHash;
use Tie::Hash;
our @ISA = ("Tie::StdHash");
sub STORE {
    my ($self, $key, $value) = @_;
    push @{$self->{key}}, $value;
}
1;

14.3.1. Hash-Tying Methods

Here's an example of an interesting tied-hash class: it gives you a hash representing a particular user's dot files (that is, files whose names begin with a period, which is a naming convention for initialization files under Unix). You index into the hash with the name of the file (minus the period) and get back that dot file's contents. For example:

use DotFiles;
tie %dot, "DotFiles";
if ( $dot{profile} =~ /MANPATH/ or
     $dot{login}   =~ /MANPATH/ or
     $dot{cshrc}   =~ /MANPATH/    ) {
    print "you seem to set your MANPATH\n";
}
Here's another way to use our tied class:
# Third argument is the name of a user whose dot files we will tie to.
tie %him, "DotFiles", "daemon";
foreach $f (keys %him) {
    printf "daemon dot file %s is size %d\n", $f, length $him{$f};
}
In our DotFiles example we implement the object as a regular hash containing several important fields, of which only the {CONTENTS} field will contain what the user thinks of as the hash. Here are the object's actual fields:

Field | Contents
USER | Whose dot files this object represents.
HOME | Where those dot files live.
CLOBBER | Whether we are allowed to change or remove those dot files.
CONTENTS | The hash of dot file names and content mappings.

Here's the start of DotFiles.pm:

package DotFiles;
use Carp;
sub whowasi { (caller(1))[3] . "()" }
my $DEBUG = 0;
sub debug { $DEBUG = @_ ? shift : 1 }
For our example, we want to be able to turn on debugging output to help in tracing during development, so we set up $DEBUG for that. We also keep one convenience function around internally to help print out warnings: whowasi returns the name of the function that called the current function (whowasi's "grandparent" function).

Here are the methods for the DotFiles tied hash:

CLASSNAME->TIEHASH(LIST)

Here's the DotFiles constructor:

sub TIEHASH {
    my $self   = shift;
    my $user   = shift || $>;
    my $dotdir = shift || "";

    croak "usage: @{[ &whowasi ]} [USER [DOTDIR]]" if @_;

    $user = getpwuid($user) if $user =~ /^\d+$/;
    my $dir = (getpwnam($user))[7]
            or croak "@{ [&whowasi] }: no user $user";
    $dir .= "/$dotdir" if $dotdir;

    my $node = {
        USER        => $user,
        HOME        => $dir,
        CONTENTS    => {},
        CLOBBER     => 0,
    };

    opendir DIR, $dir
            or croak "@{[&whowasi]}: can't opendir $dir: $!";
    for my $dot ( grep /^\./ && -f "$dir/$_", readdir(DIR)) {
        $dot =~ s/^\.//;
        $node->{CONTENTS}{$dot} = undef;
    }
    closedir DIR;

    return bless $node, $self;
}
It's probably worth mentioning that if you're going to apply file tests to the values returned by the above readdir, you'd better prepend the directory in question (as we do). Otherwise, since no chdir was done, you'd likely be testing the wrong file.

SELF->FETCH(KEY)

This method implements reading an element from the tied hash. It takes one argument after the object: the key whose value we're trying to fetch. The key is a string, and you can do anything you like with it (consistent with its being a string).

Here's the fetch for our DotFiles example:

sub FETCH {
    carp &whowasi if $DEBUG;
    my $self = shift;
    my $dot = shift;
    my $dir = $self->{HOME};
    my $file = "$dir/.$dot";

    unless (exists $self->{CONTENTS}->{$dot} || -f $file) {
        carp "@{[&whowasi]}: no $dot file" if $DEBUG;
        return undef;
    }

    # Implement a cache.
    if (defined $self->{CONTENTS}->{$dot}) {
        return $self->{CONTENTS}->{$dot};
    } else {
        return $self->{CONTENTS}->{$dot} = `cat $dir/.$dot`;
    }
}
We cheated a little by running the Unix cat(1) command, but it would be more portable (and more efficient) to open the file ourselves. On the other hand, since dotfiles are a Unixy concept, we're not that concerned. Or shouldn't be. Or something...

SELF->STORE(KEY, VALUE)

This method does the dirty work whenever an element in the tied hash is set (written). It takes two arguments after the object: the key under which we're storing the new value, and the value itself.

For our DotFiles example, we won't let users overwrite a file without first invoking the clobber method on the original object returned by tie:

sub STORE {
    carp &whowasi if $DEBUG;
    my $self  = shift;
    my $dot   = shift;
    my $value = shift;
    my $file  = $self->{HOME} . "/.$dot";

    croak "@{[&whowasi]}: $file not clobberable"
        unless $self->{CLOBBER};

    open(F, "> $file") or croak "can't open $file: $!";
    print F $value;
    close(F);
}
If someone wants to clobber something, they can say:
$ob = tie %daemon_dots, "daemon";
$ob->clobber(1);
$daemon_dots{signature} = "A true daemon\n";
But they could alternatively set {CLOBBER} with tied:
tie %daemon_dots, "DotFiles", "daemon";
tied(%daemon_dots)->clobber(1);
or as one statement:
(tie %daemon_dots, "DotFiles", "daemon")->clobber(1);
The clobber method is simply:
sub clobber {
    my $self = shift;
    $self->{CLOBBER} = @_ ? shift : 1;
}

SELF->DELETE(KEY)

This method handles requests to remove an element from the hash. If your emulated hash uses a real hash somewhere, you can just call the real delete. Again, we'll be careful to check whether the user really wants to clobber files:

sub DELETE   {
    carp &whowasi if $DEBUG;
    my $self = shift;
    my $dot = shift;
    my $file = $self->{HOME} . "/.$dot";
    croak "@{[&whowasi]}: won't remove file $file"
        unless $self->{CLOBBER};
    delete $self->{CONTENTS}->{$dot};
    unlink $file or carp "@{[&whowasi]}: can't unlink $file: $!";
}

SELF->CLEAR

This method is run when the whole hash needs to be cleared, usually by assigning the empty list to it. In our example, that would remove all the user's dot files! It's such a dangerous thing that we'll require CLOBBER to be set higher than 1 before this can happen:

sub CLEAR {
    carp &whowasi if $DEBUG;
    my $self = shift;
    croak "@{[&whowasi]}: won't remove all dotfiles for $self->{USER}"
        unless $self->{CLOBBER} > 1;
    for my $dot ( keys %{$self->{CONTENTS}}) {
        $self->DELETE($dot);
    }
}

SELF->EXISTS(KEY)

This method runs when the user invokes the exists function on a particular hash. In our example, we'll look at the {CONTENTS} hash element to find the answer:

sub EXISTS   {
    carp &whowasi if $DEBUG;
    my $self = shift;
    my $dot  = shift;
    return exists $self->{CONTENTS}->{$dot};
}

SELF->FIRSTKEY

This method is called when the user begins to iterate through the hash, such as with a keys, values, or each call. By calling keys in a scalar context, we reset its internal state to ensure that the next each used in the return statement will get the first key.

sub FIRSTKEY {
    carp &whowasi if $DEBUG;
    my $self = shift;
    my $temp = keys %{$self->{CONTENTS}};
    return scalar each %{$self->{CONTENTS}};
}

SELF->NEXTKEY(PREVKEY)

This method is the iterator for a keys, values, or each function. PREVKEY is the last key accessed, which Perl knows to supply. This is useful if the NEXTKEY method needs to know its previous state to calculate the next state.

For our example, we are using a real hash to represent the tied hash's data, except that this hash is stored in the hash's CONTENTS field instead of in the hash itself. So we can just rely on Perl's each iterator:

sub NEXTKEY  {
    carp &whowasi if $DEBUG;
    my $self = shift;
    return scalar each %{ $self->{CONTENTS} }
}

SELF->DESTROY

This method is triggered when a tied hash's object is about to be deallocated. You don't really need it except for debugging and extra cleanup. Here's a very simple version:

sub DESTROY  {
    carp &whowasi if $DEBUG;
}

Now that we've given you all those methods, your homework is to go back and find the places we interpolated @{[&whowasi]} and replace them with a simple tied scalar named $whowasi that does the same thing.

Previous | Home | Next
14.2. Tying Arrays | Book Index | 14.4. Tying Filehandles
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.4. Tying Filehandles

A class implementing a tied filehandle should define the following methods: TIEHANDLE and at least one of PRINT, PRINTF, WRITE, READLINE, GETC, and READ. The class can also provide a DESTROY method, and BINMODE, OPEN, CLOSE, EOF, FILENO, SEEK, TELL, READ, and WRITE methods to enable the corresponding Perl built-ins for the tied filehandle. (Well, that isn't quite true: WRITE corresponds to syswrite and has nothing to do with Perl's built-in write function for printing with format declarations.)

Tied filehandles are especially useful when Perl is embedded in another program (such as Apache or vi) and output to STDOUT or STDERR needs to be redirected in some special way.

But filehandles don't actually have to be tied to a file at all. You can use output statements to build up an in-memory data structure and input statements to read them back in. Here's an easy way to reverse a sequence of print and printf statements without reversing the individual lines:

package ReversePrint;
use strict;
sub TIEHANDLE {
    my $class = shift;
    bless [], $class;
}
sub PRINT {
    my $self = shift;
    push @$self, join '', @_;
}
sub PRINTF {
    my $self = shift;
    my $fmt = shift;
    push @$self, sprintf $fmt, @_;
}
sub READLINE {
    my $self = shift;
    pop @$self;
}

package main;
my $m = "--MORE--\n";
tie *REV, "ReversePrint";

# Do some prints and printfs.
print REV "The fox is now dead.$m";

printf REV <<"END", int rand 10000000;
The quick brown fox jumps over
over the lazy dog %d times!
END

print REV <<"END";
The quick brown fox jumps
over the lazy dog.
END

# Now read back from the same handle.
print while <REV>;
This prints:
The quick brown fox jumps
over the lazy dog.
The quick brown fox jumps over
over the lazy dog 3179357 times!
The fox is now dead.--MORE--

14.4.1. Filehandle-Tying Methods

For our extended example, we'll create a filehandle that uppercases strings printed to it. Just for kicks, we'll begin the file with <SHOUT> when it's opened and end with </SHOUT> when it's closed. That way we can rant in well-formed XML.

Here's the top of our Shout.pm file that will implement the class:

package Shout;
use Carp;                # So we can croak our errors
We'll now list the method definitions in Shout.pm.

CLASSNAME->TIEHANDLE(LIST)

This is the constructor for the class, which as usual should return a blessed reference.

sub TIEHANDLE {
    my $class = shift;
    my $form = shift;
    open my $self, $form, @_   or croak "can't open $form@_: $!";
    if ($form =~ />/) {
        print $self  "<SHOUT>\n";
        $$self->{WRITING} = 1;     # Remember to do end tag
    }
    return bless $self, $class;    # $self is a glob ref
}
Here, we open a new filehandle according to the mode and filename passed to the tie operator, write <SHOUT> to the file, and return a blessed reference to it. There's a lot of stuff going on in that open statement, but we'll just point out that, in addition to the usual "open or die" idiom, the my $self furnishes an undefined scalar to open, which knows to autovivify it into a typeglob. The fact that it's a typeglob is also significant, because not only does the typeglob contain the real I/O object of the file, but it also contains various other handy data structures that come along for free, like a scalar ($$$self), an array (@$$self), and a hash (%$$self). (We won't mention the subroutine, &$$self.)

The $form is the filename-or-mode argument. If it's a filename, @_ is empty, so it behaves as a two-argument open. Otherwise, $form is the mode for the rest of the arguments.

After the open, we test to see whether we should write the beginning tag. If so, we do. And right away, we use one of those glob data structures we mentioned. That $$self->{WRITING} is an example of using the glob to store interesting information. In this case, we remember whether we did the beginning tag so we know whether to do the corresponding end tag. We're using the %$$self hash, so we can give the field a decent name. We could have used the scalar as $$$self, but that wouldn't be self-documenting. (Or it would only be self-documenting, depending on how you look at it.)

SELF->PRINT(LIST)

This method implements a print to the tied handle. The LIST is whatever was passed to print. Our method below uppercases each element of LIST:

sub PRINT {
    my $self = shift;
    print $self map {uc} @_;
}

SELF->READLINE

This method supplies the data when the filehandle is read from via the angle operator (<FH>) or readline. The method should return undef when there is no more data.

sub READLINE {
    my $self = shift;
    return <$self>;
}
Here, we simply return <$self> so that the method will behave appropriately depending on whether it was called in scalar or list context.

SELF->GETC

This method runs whenever getc is used on the tied filehandle.

sub GETC {
    my $self = shift;
    return getc($self);
}
Like several of the methods in our Shout class, the GETC method simply calls its corresponding Perl built-in and returns the result.

SELF->OPEN(LIST)

Our TIEHANDLE method itself opens a file, but a program using the Shout class that calls open afterward triggers this method.

sub OPEN {
    my $self = shift;
    my $form = shift;
    my $name = "$form@_";
    $self->CLOSE;
    open($self, $form, @_)      or croak "can't reopen $name: $!";
    if ($form =~ />/) {
        print $self "<SHOUT>\n" or croak "can't start print: $!";
        $$self->{WRITING} = 1;     # Remember to do end tag
    }
    else {
        $$self->{WRITING} = 0;     # Remember not to do end tag
    }
    return 1;
}
We invoke our own CLOSE method to explicitly close the file in case the user didn't bother to. Then we open a new file with whatever filename was specified in the open and shout at it.

SELF->CLOSE

This method deals with the request to close the handle. Here, we seek to the end of the file and, if that was successful, print </SHOUT> before using Perl's built-in close.

sub CLOSE {
    my $self = shift;
    if ($$self->{WRITING}) {
        $self->SEEK(0, 2)             or return;
        $self->PRINT("</SHOUT>\n")    or return;
    }
    return close $self;
}

SELF->SEEK(LIST)

When you seek on a tied filehandle, the SEEK method gets called.

sub SEEK {
    my $self = shift;
    my ($offset, $whence) = @_;
    return seek($self, $offset, $whence);
}

SELF->TELL

This method is invoked when tell is used on the tied handle.

sub TELL {
    my $self = shift;
    return tell $self;
}

SELF->PRINTF(LIST)

This method is run whenever printf is used on the tied handle. The LIST will contain the format and the items to be printed.

sub PRINTF {
    my $self = shift;
    my $template = shift;
    return $self->PRINT(sprintf $template, @_);
}
Here, we use sprintf to generate the formatted string and pass it to PRINT for uppercasing. There's nothing that requires you to use the built-in sprintf function though. You could interpret the percent escapes to suit your own purpose.

SELF->READ(LIST)

This method responds when the handle is read using read or sysread. Note that we modify the first argument of LIST "in-place", mimicking read's ability to fill in the scalar passed in as its second argument.

sub READ {
    my ($self, undef, $length, $offset) = @_;
    my $bufref = \$_[1];
    return read($self, $$bufref, $length, $offset);
}

SELF->WRITE(LIST)

This method gets invoked when the handle is written to with syswrite. Here, we uppercase the string to be written.

sub WRITE {
    my $self = shift;
    my $string = uc(shift);
    my $length = shift || length $string;
    my $offset = shift || 0;
    return syswrite $self, $string, $length, $offset;
}

SELF->EOF

This method returns a Boolean value when a filehandle tied to the Shout class is tested for its end-of-file status using eof.

sub EOF {
    my $self = shift;
    return eof $self;
}

SELF->BINMODE(DISC)

This method specifies the I/O discipline to be used on the filehandle. If none is specified, it puts the tied filehandle into binary mode (the :raw discipline), for filesystems that distinguish between text and binary files.

sub BINMODE {
    my $self = shift;
    my $disc = shift || ":raw";
    return binmode $self, $disc;
}
That's how you'd write it, but it's actually useless in our case because the open already wrote on the handle. So in our case we should probably make it say:
sub BINMODE { croak("Too late to use binmode") }

SELF->FILENO

This method should return the file descriptor (fileno) associated with the tied filehandle by the operating system.

sub FILENO {
    my $self = shift;
    return fileno $self;
}

SELF->DESTROY

As with the other types of ties, this method is triggered when the tied object is about to be destroyed. This is useful for letting the object clean up after itself. Here, we make sure that the file is closed, in case the program forgot to call close. We could just say close $self, but it's better to invoke the CLOSE method of the class. That way if the designer of the class decides to change how files are closed, this DESTROY method won't have to be modified.

sub DESTROY {
    my $self = shift;
    $self->CLOSE;      # Close the file using Shout's CLOSE method.
}

Here's a demonstration of our Shout class:

#!/usr/bin/perl
use Shout;
tie(*FOO, Shout::, ">filename");
print FOO "hello\n";            # Prints HELLO.
seek FOO, 0, 0;                 # Rewind to beginning.
@lines = <FOO>;                 # Calls the READLINE method.
close FOO;                      # Close file explicitly.
open(FOO, "+<", "filename");    # Reopen FOO, calling OPEN.
seek(FOO, 8, 0);                # Skip the "<SHOUT>\n".
sysread(FOO, $inbuf, 5);        # Read 5 bytes from FOO into $inbuf.
print "found $inbuf\n";         # Should print "hello".
seek(FOO, -5, 1);               # Back up over the "hello".
syswrite(FOO, "ciao!\n", 6);    # Write 6 bytes into FOO.
untie(*FOO);                    # Calls the CLOSE method implicitly.
After running this, the file contains:
<SHOUT>
CIAO!
</SHOUT>
Here are some more strange and wonderful things to do with that internal glob. We use the same hash as before, but with new keys PATHNAME and DEBUG. First we install a stringify overloading so that printing one of our objects reveals the pathname (see Chapter 13, "Overloading"):
# This is just so totally cool!
use overload q("") => sub { $_[0]->pathname };

# This is the stub to put in each function you want to trace.
sub trace {
    my $self = shift;
    local $Carp::CarpLevel = 1;
    Carp::cluck("\ntrace magical method") if $self->debug;
}

# Overload handler to print out our path.
sub pathname {
    my $self = shift;
    confess "i am not a class method" unless ref $self;
    $$self->{PATHNAME} = shift if @_;
    return $$self->{PATHNAME};
}
# Dual moded.
sub debug {
    my $self = shift;
    my $var = ref $self ? \$$self->{DEBUG} : \our $Debug;
    $$var = shift if @_;
    return ref $self ? $$self->{DEBUG} || $Debug : $Debug;
}
And then call trace on entry to all your ordinary methods like this:
sub GETC { $_[0]->trace;           # NEW
    my($self) = @_;
    getc($self);
}
And also set the pathname in TIEHANDLE and OPEN:
sub TIEHANDLE {
    my $class    = shift;
    my $form = shift;
    my $name = "$form@_";          # NEW
    open my $self, $form, @_   or croak "can't open $name: $!";
    if ($form =~ />/) {
        print $self  "<SHOUT>\n";
        $$self->{WRITING} = 1;     # Remember to do end tag
    }
    bless $self, $class;           # $fh is a glob ref
    $self->pathname($name);        # NEW
    return $self;
}

sub OPEN { $_[0]->trace;           # NEW
    my $self = shift;
    my $form = shift;
    my $name = "$form@_";
    $self->CLOSE;
    open($self, $form, @_)      or croak "can't reopen $name: $!";
    $self->pathname($name);        # NEW
    if ($form =~ />/) {
        print $self "<SHOUT>\n" or croak "can't start print: $!";
        $$self->{WRITING} = 1;     # Remember to do end tag
    }
    else {
        $$self->{WRITING} = 0;     # Remember not to do end tag
    }
    return 1;
}
Somewhere you also have to call $self->debug(1) to turn debugging on. When you do that, all your Carp::cluck calls will produce meaningful messages. Here's one that we get while doing the reopen above. It shows us three deep in method calls, as we're closing down the old file in preparation for opening the new one:
trace magical method at foo line 87
    Shout::SEEK('>filename', '>filename', 0, 2) called at foo line 81
    Shout::CLOSE('>filename') called at foo line 65
    Shout::OPEN('>filename', '+<', 'filename') called at foo line 141

14.4.2. Creative Filehandles

You can tie the same filehandle to both the input and the output of a two-ended pipe. Suppose you wanted to run the bc(1) (arbitrary precision calculator) program this way:

use Tie::Open2;

tie *CALC, 'Tie::Open2', "bc -l";
$sum = 2;
for (1 .. 7) {
    print CALC "$sum * $sum\n";
    $sum = <CALC>;
    print "$_: $sum";
    chomp $sum;
}
close CALC;
One would expect it to print this:
1: 4
2: 16
3: 256
4: 65536
5: 4294967296
6: 18446744073709551616
7: 340282366920938463463374607431768211456
One's expectations would be correct if one had the bc(1) program on one's computer, and one also had Tie::Open2 defined as follows. This time we'll use a blessed array for our internal object. It contains our two actual filehandles for reading and writing. (The dirty work of opening a double-ended pipe is done by IPC::Open2; we're just doing the fun part.)
package Tie::Open2;
use strict;
use Carp;
use Tie::Handle;  # do not inherit from this!
use IPC::Open2;

sub TIEHANDLE {
    my ($class, @cmd) = @_;
    no warnings 'once';
    my @fhpair = \do { local(*RDR, *WTR) };
    bless $_, 'Tie::StdHandle' for @fhpair;
    bless(\@fhpair => $class)->OPEN(@cmd) || die;
    return \@fhpair;
}

sub OPEN {
    my ($self, @cmd) = @_;
    $self->CLOSE if grep {defined} @{ $self->FILENO };
    open2(@$self, @cmd);
}

sub FILENO {
    my $self = shift;
    [ map { fileno $self->[$_] } 0,1 ];
}

for my $outmeth ( qw(PRINT PRINTF WRITE) ) {
    no strict 'refs';
    *$outmeth = sub {
        my $self = shift;
        $self->[1]->$outmeth(@_);
    };
}
for my $inmeth ( qw(READ READLINE GETC) ) {
    no strict 'refs';
    *$inmeth = sub {
        my $self = shift;
        $self->[0]->$inmeth(@_);
    };
}
for my $doppelmeth ( qw(BINMODE CLOSE EOF)) {
    no strict 'refs';
    *$doppelmeth = sub {
        my $self = shift;
        $self->[0]->$doppelmeth(@_) && $self->[1]->$doppelmeth(@_);
    };
}
for my $deadmeth ( qw(SEEK TELL)) {
    no strict 'refs';
    *$deadmeth = sub {
        croak("can't $deadmeth a pipe");
    };
}
1;
The final four loops are just incredibly snazzy, in our opinion. For an explanation of what's going on, look back at the section Section 14.3.7.1, "Closures as function templates" in Chapter 8, "References".

Here's an even wackier set of classes. The package names should give you a clue as to what they do.

use strict;
package Tie::DevNull;

    sub TIEHANDLE {
        my $class = shift;
        my $fh = local *FH;
        bless \$fh, $class;
    }
    for (qw(READ READLINE GETC PRINT PRINTF WRITE)) {
        no strict 'refs';
        *$_  = sub { return };
    }

package Tie::DevRandom;

    sub READLINE { rand() . "\n"; }
    sub TIEHANDLE {
        my $class = shift;
        my $fh = local *FH;
        bless \$fh, $class;
    }

    sub FETCH { rand() }
    sub TIESCALAR {
        my $class = shift;
        bless \my $self, $class;
    }

package Tie::Tee;

    sub TIEHANDLE {
        my $class = shift;
        my @handles;
        for my $path (@_) {
            open(my $fh, ">$path") || die "can't write $path";
            push @handles, $fh;
        }
        bless \@handles, $class;
    }

    sub PRINT {
        my $self = shift;
        my $ok = 0;
        for my $fh (@$self) {
            $ok += print $fh @_;
        }
        return $ok == @$self;
    }
The Tie::Tee class emulates the standard Unix tee(1) program, which sends one stream of output to multiple different destinations. The Tie::DevNull class emulates the null device, /dev/null on Unix systems. And the Tie::DevRandom class produces random numbers either as a handle or as a scalar, depending on whether you call TIEHANDLE or TIESCALAR! Here's how you call them:
package main;

tie *SCATTER,   "Tie::Tee", qw(tmp1 - tmp2 >tmp3 tmp4);
tie *RANDOM,    "Tie::DevRandom";
tie *NULL,      "Tie::DevNull";
tie my $randy,  "Tie::DevRandom";

for my $i (1..10) {
    my $line = <RANDOM>;
    chomp $line;
    for my $fh (*NULL, *SCATTER) {
        print $fh "$i: $line $randy\n";
    }
}
This produces something like the following on your screen:
1: 0.124115571686165 0.20872819474074
2: 0.156618299751194 0.678171662366353
3: 0.799749050426126 0.300184963960792
4: 0.599474551447884 0.213935286029916
5: 0.700232143543861 0.800773751296671
6: 0.201203608274334 0.0654303290639575
7: 0.605381294683365 0.718162304090487
8: 0.452976481105495 0.574026269121667
9: 0.736819876983848 0.391737610662044
10: 0.518606540417331 0.381805078272308
But that's not all! It wrote to your screen because of the - in the *SCATTERtie above. But that line also told it to create files tmp1, tmp2, and tmp4, as well as to append to file tmp3. (We also wrote to the *NULL filehandle in the loop, though of course that didn't show up anywhere interesting, unless you're interested in black holes.)

Previous | Home | Next
14.3. Tying Hashes | Book Index | 14.5. A Subtle Untying Trap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.5. A Subtle Untying Trap

If you intend to make use of the object returned from tie or tied, and the class defines a destructor, there is a subtle trap you must guard against. Consider this (admittedly contrived) example of a class that uses a file to log all values assigned to a scalar:

package Remember;

sub TIESCALAR {
    my $class = shift;
    my $filename = shift;
    open(my $handle, ">", $filename)
         or die "Cannot open $filename: $!\n";
    print $handle "The Start\n";
    bless {FH => $handle, VALUE => 0}, $class;
}

sub FETCH {
    my $self = shift;
    return $self->{VALUE};
}

sub STORE {
    my $self = shift;
    my $value = shift;
    my $handle = $self->{FH};
    print $handle "$value\n";
    $self->{VALUE} = $value;
}

sub DESTROY {
    my $self = shift;
    my $handle = $self->{FH};
    print $handle "The End\n";
    close $handle;
}

1;
Here is an example that makes use of our Remember class:
use strict;
use Remember;

my $fred;
$x = tie $fred, "Remember", "camel.log";
$fred = 1;
$fred = 4;
$fred = 5;
untie $fred;
system "cat camel.log";
This is the output when it is executed:
The Start
1
4
5
The End
So far, so good. Let's add an extra method to the Remember class that allows comments in the file--say, something like this:
sub comment {
    my $self = shift;
    my $message = shift;
    print { $self->{FH} } $handle $message, "\n";
}
And here is the previous example, modified to use the comment method:
use strict;
use Remember;

my ($fred, $x);
$x = tie $fred, "Remember", "camel.log";
$fred = 1;
$fred = 4;
comment $x "changing...";
$fred = 5;
untie $fred;
system "cat camel.log";
Now the file will be empty, which probably wasn't what you intended. Here's why. Tying a variable associates it with the object returned by the constructor. This object normally has only one reference: the one hidden behind the tied variable itself. Calling "untie" breaks the association and eliminates that reference. Since there are no remaining references to the object, the DESTROY method is triggered.

However, in the example above we stored a second reference to the object tied to $x. That means that after the untie there will still be a valid reference to the object. DESTROY won't get triggered, and the file won't get flushed and closed. That's why there was no output: the filehandle's buffer was still in memory. It won't hit the disk until the program exits.

To detect this, you could use the -w command-line flag, or include the use warnings "untie" pragma in the current lexical scope. Either technique would identify a call to untie while there were still references to the tied object remaining. If so, Perl prints this warning:

untie attempted while 1 inner references still exist
To get the program to work properly and silence the warning, eliminate any extra references to the tied object before calling untie. You can do that explicitly:
undef $x;
untie $fred;
Often though you can solve the problem simply by making sure your variables go out of scope at the appropriate time.

Previous | Home | Next
14.4. Tying Filehandles | Book Index | 14.6. Tie Modules on CPAN
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


14.6. Tie Modules on CPAN

Before you get all inspired to write your own tie module, you should check to see if someone's already done it. There are lots of tie modules on CPAN, with more every day. (Well, every month, anyway.) Table 14-1 lists some of them.

Table 14.1. Tie Modules on CPAN

Module | Description
GnuPG::Tie::Encrypt | Ties a filehandle interface to encryption with the GNU Privacy Guard.
IO::WrapTie | Wraps tied objects in an IO::Handle interface.
MLDBM | Transparently stores complex data values, not just flat strings, in a DBM file.
Net::NISplusTied | Ties hashes to NIS+ tables.
Tie::Cache::LRU | Implements a least-recently used cache.
Tie::Const | Provides constant scalars and hashes.
Tie::Counter | Enchants a scalar variable to increment upon each access.
Tie::CPHash | Implements a case-preserving but case-insensitive hash.
Tie::DB_FileLock | Provides locking access to Berkeley DB 1.x.
Tie::DBI | Ties hashes to DBI relational databases.
Tie::DB_Lock | Ties hashes to databases using shared and exclusive locks.
Tie::Dict | Ties a hash to an RPC dict server.
Tie::Dir | Ties a hash for reading directories.
Tie::DirHandle | Ties directory handles.
Tie::FileLRUCache | Implements a lightweight, filesystem-based, persistent LRU cache.
Tie::FlipFlop | Implements a tie that alternates between two values.
Tie::HashDefaults | Lets a hash have default values.
Tie::HashHistory | Tracks history of all changes to a hash.
Tie::IxHash | Provides ordered associative arrays for Perl.
Tie::LDAP | Implements an interface to an LDAP database.
Tie::Persistent | Provides persistent data structures via tie.
Tie::Pick | Randomly picks (and removes) an element from a set.
Tie::RDBM | Ties hashes to relational databases.
Tie::SecureHash | Supports namespace-based encapsulation.
Tie::STDERR | Sends output of your STDERR to another process such as a mailer.
Tie::Syslog | Ties a filehandle to automatically syslog its output.
Tie::TextDir | Ties a directory of files.
Tie::TransactHash | Edits a hash in transactions without changing the order during the transaction.
Tie::VecArray | Provides an array interface to a bit vector.
Tie::Watch | Places watch points on Perl variables.
Win32::TieRegistry | Provides powerful and easy ways to manipulate a Microsoft Windows registry.
Previous | Home | Next
14.5. A Subtle Untying Trap | Book Index | Part 3. Perl as Technology
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part III. Perl as Technology

Chapter 15: Unicode
Chapter 16: Interprocess Communication
Chapter 17: Threads
Chapter 18: Compiling
Chapter 19: The Command-Line Interface
Chapter 20: The Perl Debugger
Chapter 21: Internals and Externals

Previous | Home | Next
14.6. Tie Modules on CPAN | Book Index | 15. Unicode
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 15. Unicode

Contents:

Building Character
Effects of Character Semantics
Caution, [image] Working

If you do not yet know what Unicode is, you will soon--even if you skip reading this chapter--because working with Unicode is becoming a necessity. (Some people think of it as a necessary evil, but it's really more of a necessary good. In either case, it's a necessary pain.)

Historically, people made up character sets to reflect what they needed to do in the context of their own culture. Since people of all cultures are naturally lazy, they've tended to include only the symbols they needed, excluding the ones they didn't need. That worked fine as long as we were only communicating with other people of our own culture, but now that we're starting to use the Internet for cross-cultural communication, we're running into problems with the exclusive approach. It's hard enough to figure out how to type accented characters on an American keyboard. How in the world (literally) can one write a multilingual web page?

Unicode is the answer, or at least part of the answer (see also XML). Unicode is an inclusive rather than an exclusive character set. While people can and do haggle over the various details of Unicode (and there are plenty of details to haggle over), the overall intent is to make everyone sufficiently happy[1] with Unicode so that they'll willingly use Unicode as the international medium of exchange for textual data. Nobody is forcing you to use Unicode, just as nobody is forcing you to read this chapter (we hope). People will always be allowed to use their old exclusive character sets within their own culture. But in that case (as we say), portability suffers.

[1] Or in some cases, insufficiently unhappy.

The Law of Conservation of Suffering says that if we reduce the suffering in one place, suffering must increase elsewhere. In the case of Unicode, we must suffer the migration from byte semantics to character semantics. Since, through an accident of history, Perl was invented by an American, Perl has historically confused the notions of bytes and characters. In migrating to Unicode, Perl must somehow unconfuse them.

Paradoxically, by getting Perl itself to unconfuse bytes and characters, we can allow the Perl programmer to confuse them, relying on Perl to keep them straight, just as we allow programmers to confuse numbers and strings and rely on Perl to convert back and forth as necessary. To the extent possible, Perl's approach to Unicode is the same as its approach to everything else: Just Do The Right Thing. Ideally, we'd like to achieve these four Goals:

Goal #1:

Old byte-oriented programs should not spontaneously break on the old byte-oriented data they used to work on.

Goal #2:

Old byte-oriented programs should magically start working on the new character-oriented data when appropriate.

Goal #3:

Programs should run just as fast in the new character-oriented mode as in the old byte-oriented mode.

Goal #4:

Perl should remain one language, rather than forking into a byte-oriented Perl and a character-oriented Perl.

Taken together, these Goals are practically impossible to reach. But we've come remarkably close. Or rather, we're still in the process of coming remarkably close, since this is a work in progress. As Unicode continues to evolve, so will Perl. But our overarching plan is to provide a safe migration path that gets us where we want to go with minimal casualties along the way. How we do that is the subject of the next section.

15.1. Building Character

In releases of Perl prior to 5.6, all strings were viewed as sequences of bytes.[2] In versions 5.6 and later, however, a string may contain characters wider than a byte. We now view strings not as sequences of bytes, but as sequences of numbers in the range 0 .. 2**32-1 (or in the case of 64-bit computers, 0 .. 2**64-1). These numbers represent abstract characters, and the larger the number, the "wider" the character, in some sense; but unlike many languages, Perl is not tied to any particular width of character representation. Perl uses a variable-length encoding (based on UTF-8), so these abstract character numbers may, or may not, be packed one number per byte. Obviously, character number 18,446,744,073,709,551,615 (that is, "\x{ffff_ffff_ffff_ffff}") is never going to fit into a byte (in fact, it takes 13 bytes), but if all the characters in your string are in the range 0..127 decimal, then they are certainly packed one per byte, since UTF-8 is the same as ASCII in the lowest seven bits.

[2] You may prefer to call them "octets"; that's okay, but we think the two words are pretty much synonymous these days, so we'll stick with the blue-collar word.

Perl uses UTF-8 only when it thinks it is beneficial, so if all the characters in your string are in the range 0..255, there's a good chance the characters are all packed in bytes--but in the absence of other knowledge, you can't be sure because internally Perl converts between fixed 8-bit characters and variable-length UTF-8 characters as necessary. The point is, you shouldn't have to worry about it most of the time, because the character semantics are preserved at an abstract level regardless of representation.

In any event, if your string contains any character numbers larger than 255 decimal, the string is certainly stored in UTF-8. More accurately, it is stored in Perl's extended version of UTF-8, which we call utf8, in honor of a pragma by that name, but mostly because it's easier to type. (And because "real" UTF-8 is only allowed to contain character numbers blessed by the Unicode Consortium. Perl's utf8 is allowed to contain any character numbers you need to get your job done. Perl doesn't give a rip whether your character numbers are officially correct or just correct.)

We said you shouldn't worry about it most of the time, but people like to worry anyway. Suppose you use a v-string to represent an IPv4 address:

$locaddr = v127.0.0.1;     # Certainly stored as bytes.
$oreilly = v204.148.40.9;  # Might be stored as bytes or utf8.
$badaddr = v2004.148.40.9; # Certainly stored as utf8.
Everyone can figure out that $badaddr will not work as an IP address. So it's easy to think that if O'Reilly's network address gets forced into a UTF-8 representation, it will no longer work. But the characters in the string are abstract numbers, not bytes. Anything that uses an IPv4 address, such as the gethostbyaddr function, should automatically coerce the abstract character numbers back into a byte representation (and fail on $badaddr).

The interfaces between Perl and the real world have to deal with the details of the representation. To the extent possible, existing interfaces try to do the right thing without your having to tell them what to do. But you do occasionally have to give instructions to some interfaces (such as the open function), and if you write your own interface to the real world, it will need to be either smart enough to figure things out for itself or at least smart enough to follow instructions when you want it to behave differently than it would by default.[3]

[3] On some systems, there may be ways of switching all your interfaces at once. If the -C command-line switch is used, (or the global ${^WIDE_SYSTEM_CALLS} variable is set to 1), all system calls will use the corresponding wide character APIs. (This is currently only implemented on Microsoft Windows.) The current plan of the Linux community is that all interfaces will switch to UTF-8 mode if $ENV{LC_CTYPE} is set to "UTF-8". Other communities may take other approaches. Our mileage may vary.

Since Perl worries about maintaining transparent character semantics within the language itself, the only place you need to worry about byte versus character semantics is in your interfaces. By default, all your old Perl interfaces to the outside world are byte-oriented, so they produce and consume byte-oriented data. That is to say, on the abstract level, all your strings are sequences of numbers in the range 0..255, so if nothing in the program forces them into utf8 representations, your old program continues to work on byte-oriented data just as it did before. So put a check mark by Goal #1 above.

If you want your old program to work on new character-oriented data, you must mark your character-oriented interfaces such that Perl knows to expect character-oriented data from those interfaces. Once you've done this, Perl should automatically do any conversions necessary to preserve the character abstraction. The only difference is that you've introduced some strings into your program that are marked as potentially containing characters higher than 255, so if you perform an operation between a byte string and utf8 string, Perl will internally coerce the byte string into a utf8 string before performing the operation. Typically, utf8 strings are coerced back to byte strings only when you send them to a byte interface, at which point, if the string contains characters larger than 255, you have a problem that can be handled in various ways depending on the interface in question. So you can put a check mark by Goal #2.

Sometimes you want to mix code that understands character semantics with code that has to run with byte semantics, such as I/O code that reads or writes fixed-size blocks. In this case, you may put a use bytes declaration around the byte-oriented code to force it to use byte semantics even on strings marked as utf8 strings. You are then responsible for any necessary conversions. But it's a way of enforcing a stricter local reading of Goal #1, at the expense of a looser global reading of Goal #2.

Goal #3 has largely been achieved, partly by doing lazy conversions between byte and utf8 representations and partly by being sneaky in how we implement potentially slow features of Unicode, such as character property lookups in huge tables.

Goal #4 has been achieved by sacrificing a small amount of interface compatibility in pursuit of the other Goals. By one way of looking at it, we didn't fork into two different Perls; but by another way of looking at it, revision 5.6 of Perl is a forked version of Perl with regard to earlier versions, and we don't expect people to switch from earlier versions until they're sure the new version will do what they want. But that's always the case with new versions, so we'll allow ourselves to put a check mark by Goal #4 as well.

Previous | Home | Next
 | 15.2. Effects of Character Semantics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.2. Effects of Character Semantics

The upshot of all this is that a typical built-in operator will operate on characters unless it is in the scope of a use bytes pragma. However, even outside the scope of use bytes, if all of the operands of the operator are stored as 8-bit characters (that is, none of the operands are stored in utf8), then character semantics are indistinguishable from byte semantics, and the result of the operator will be stored in 8-bit form internally. This preserves backward compatibility as long as you don't feed your program any characters wider than Latin-1.

The utf8 pragma is primarily a compatibility device that enables recognition of UTF-8 in literals and identifiers encountered by the parser. It may also be used for enabling some of the more experimental Unicode support features. Our long-term goal is to turn the utf8 pragma into a no-op.

The use bytes pragma will never turn into a no-op. Not only is it necessary for byte-oriented code, but it also has the side effect of defining byte-oriented wrappers around certain functions for use outside the scope of use bytes. As of this writing, the only defined wrapper is for length, but there are likely to be more as time goes by. To use such a wrapper, say:

use bytes ();   # Load wrappers without importing byte semantics.
...
$charlen =        length("\x{ffff_ffff}");   # Returns 1.
$bytelen = bytes::length("\x{ffff_ffff}");   # Returns 7.
Outside the scope of a use bytes declaration, Perl version 5.6 works (or at least, is intended to work) like this:

  • Strings and patterns may now contain characters that have an ordinal value larger than 255:

    use utf8;
$convergence = "     ";
    Presuming you have a Unicode-capable editor to edit your program, such characters will typically occur directly within the literal strings as UTF-8 characters. For now, you have to declare a use utf8 at the top of your program to enable the use of UTF-8 in literals.

    If you don't have a Unicode editor, you can always specify a particular character in ASCII with an extension of the \x notation. A character in the Latin-1 range may be written either as \x{ab} or as \xab, but if the number exceeds two hexidecimal digits, you must use braces. Unicode characters are specified by putting the hexadecimal code within braces after the \x. For instance, a Unicode smiley face is \x{263A}. There is no syntactic construct in Perl that assumes Unicode characters are exactly 16 bits, so you may not use \u263A as you can in other languages; \x{263A} is the closest equivalent.

    For inserting named characters via \N{CHARNAME}, see the use charnames pragma in Chapter 31, "Pragmatic Modules".

  • Identifiers within the Perl script may contain Unicode alphanumeric characters, including ideographs:

    use utf8;
$   ++;        # A child is born.
    Again, use utf8 is needed (for now) to recognize UTF-8 in your script. You are currently on your own when it comes to using the canonical forms of characters--Perl doesn't (yet) attempt to canonicalize variable names for you. We recommend that you canonicalize your programs to Normalization Form C, since that's what Perl will someday canonicalize to by default. See www.unicode.org for the latest technical report on canonicalization.

  • Regular expressions match characters instead of bytes. For instance, dot matches a character instead of a byte. If the Unicode Consortium ever gets around to approving the Tengwar script, then (despite the fact that such characters are represented in four bytes of UTF-8), this matches:

    "\N{TENGWAR LETTER SILME NUQUERNA}" =~ /^.$/
    The \C pattern is provided to force a match on a single byte ("char" in C, hence \C). Use \C with care, since it can put you out of sync with the character boundaries in your string, and you may get "Malformed UTF-8 character" errors. You may not use \C in square brackets, since it doesn't represent any particular character or set of characters.

  • Character classes in regular expressions match characters instead of bytes and match against the character properties specified in the Unicode properties database. So \w can be used to match an ideograph:

    "   " =~ /\w/

  • Named Unicode properties and block ranges can be used as character classes via the new \p (matches property) and \P (doesn't match property) constructs. For instance, \p{Lu} matches any character with the Unicode uppercase property, while \p{M} matches any mark character. Single-letter properties may omit the brackets, so mark characters can be matched by \pM also. Many predefined character classes are available, such as \p{IsMirrored} and \p{InTibetan}:

    "\N{greek:Iota}" =~ /\p{Lu}/
    You may also use \p and \P within square bracket character classes. (In version 5.6.0 of Perl, you need to use utf8 for character properties to work right. This restriction will be lifted in the future.) See Chapter 5, "Pattern Matching", for details of matching on Unicode properties.

  • The special pattern \X matches any extended Unicode sequence (a "combining character sequence" in Standardese), where the first character is a base character and subsequent characters are mark characters that apply to the base character. It is equivalent to (?:\PM\pM*):

    "o\N{COMBINING TILDE BELOW}" =~ /\X/
    You may not use \X in square brackets, because it might match multiple characters and it doesn't match any particular character or set of characters.

  • The tr/// operator transliterates characters instead of bytes. To turn all characters outside the Latin-1 range into a question mark, you could say:

    tr/\0-\x{10ffff}/\0-\xff?/;       # utf8 to latin1 char

  • Case translation operators use the Unicode case translation tables when provided character input. Note that uc translates to uppercase, while ucfirst translates to titlecase (for languages that make the distinction). Naturally the corresponding backslash sequences have the same semantics:

    $x = "\u$word";       # titlecase first letter of $word
$x = "\U$word";       # uppercase $word
$x = "\l$word";       # lowercase first letter of $word
$x = "\L$word";       # lowercase $word
    Be careful, because the Unicode case translation tables don't attempt to provide round-trip mappings in every instance, particularly for languages that use different numbers of characters for titlecase or uppercase than they do for the equivalent lowercase letter. As they say in the standard, while the case properties themselves are normative, the case mappings are only informational.

  • Most operators that deal with positions or lengths in the string will automatically switch to using character positions, including chop, substr, pos, index, rindex, sprintf, write, and length. Operators that deliberately don't switch include vec, pack, and unpack. Operators that really don't care include chomp, as well as any other operator that treats a string as a bucket of bits, such as the default sort and the operators dealing with filenames.

    use bytes;
$bytelen = length("I do            .");   # 15 bytes
no bytes;
$charlen = length("I do          .");   # but 9 characters

  • The pack/unpack letters "c" and "C" do not change, since they're often used for byte-oriented formats. (Again, think "char" in the C language.) However, there is a new "U" specifier that will convert between UTF-8 characters and integers:

    pack("U*", 1, 20, 300, 4000) eq v1.20.300.4000

  • The chr and ord functions work on characters:

    chr(1).chr(20).chr(300).chr(4000) eq v1.20.300.4000
    In other words, chr and ord are like pack("U") and unpack("U"), not like pack("C") and unpack("C"). In fact, the latter two are how you now emulate byte-oriented chr and ord if you're too lazy to use bytes.

  • And finally, scalar reverse reverses by character rather than by byte:

    "     " eq reverse "     "

If you look in directory PATH_TO_PERLLIB/unicode, you'll find a number of files that have to do with defining the semantics above. The Unicode properties database from the Unicode Consortium is in a file called Unicode.300 (for Unicode 3.0). This file has already been processed by mktables.PL into lots of little .pl files in the same directory (and in subdirectories Is/, In/, and To/), some of which are automatically slurped in by Perl to implement things like \p (see the Is/ and In/ directories) and uc (see the To/ directory). Other files are slurped in by modules like the use charnames pragma (see Name.pl). But as of this writing, there are still a number of files that are just sitting there waiting for you to write an access module for them:

ArabLink.pl
ArabLnkGrp.pl
Bidirectional.pl
Block.pl
Category.pl
CombiningClass.pl
Decomposition.pl
JamoShort.pl
Number.pl
To/Digit.pl
A much more readable summary of Unicode, with many hyperlinks, is in PATH_TO_PERLLIB/unicode/Unicode3.html.

Note that when the Unicode consortium comes out with a new version, some of these filenames are likely to change, so you'll have to poke around. You can find PATH_TO_PERLLIB with the following incantation:

% perl -MConfig -le 'print $Config{privlib}'
To find out just about everything there is to find out about Unicode, you should check out The Unicode Standard, Version 3.0 (ISBN 0-201-61633-5).

Previous | Home | Next
15.1. Building Character | Book Index | 15.3. Caution, [image] Working
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


15.3. Caution,

 Programming Perl
Previous Next

15.3. Caution, Working

As of this writing (that is, with respect to version 5.6.0 of Perl), there are still some caveats on use of Unicode. (Check your online docs for updates.)

  • The existing regular expression compiler does not produce polymorphic opcodes. This means that the determination of whether a particular pattern will match Unicode characters is made when the pattern is compiled (based on whether the pattern contains Unicode characters) and not when the matching happens at run time. This needs to be changed to adaptively match Unicode if the string to be matched is Unicode.

  • There is currently no easy way to mark data read from a file or other external source as being utf8. This will be a major area of focus in the near future and is probably already fixed as you read this.

  • There is no method for automatically coercing input and output to some encoding other than UTF-8. This is planned in the near future, however, so check your online docs.

  • Use of locales with utf8 may lead to odd results. Currently, there is some attempt to apply 8-bit locale information to characters in the range 0..255, but this is demonstrably incorrect for locales that use characters above that range (when mapped into Unicode). It will also tend to run slower. Avoidance of locales is strongly encouraged.

Unicode is fun--you just have to define fun correctly.

Previous | Home | Next
15.2. Effects of Character Semantics | Book Index | 16. Interprocess Communication
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 16. Interprocess Communication

Contents:

Signals
Files
Pipes
System V IPC
Sockets

Computer processes have almost as many ways of communicating as people do. The difficulties of interprocess communication should not be underestimated. It doesn't do you any good to listen for verbal cues when your friend is using only body language. Likewise, two processes can communicate only when they agree on the means of communication, and on the conventions built on top of that. As with any kind of communication, the conventions to be agreed upon range from lexical to pragmatic: everything from which lingo you'll use, up to whose turn it is to talk. These conventions are necessary because it's very difficult to communicate bare semantics in the absence of context.

In our lingo, interprocess communication is usually pronounced IPC. The IPC facilities of Perl range from the very simple to the very complex. Which facility you should use depends on the complexity of the information to be communicated. The simplest kind of information is almost no information at all: just the awareness that a particular event has happened at a particular point in time. In Perl, these events are communicated via a signal mechanism modeled on the Unix signal system.

At the other extreme, the socket facilities of Perl allow you to communicate with any other process on the Internet using any mutually supported protocol you like. Naturally, this freedom comes at a price: you have to go through a number of steps to set up the connections and make sure you're talking the same language as the process on the other end. This may in turn require you to adhere to any number of other strange customs, depending on local conventions. To be protocoligorically correct, you might even be required to speak a language like XML, or Java, or Perl. Horrors.

Sandwiched in between are some facilities intended primarily for communicating with processes on the same machine. These include good old-fashioned files, pipes, FIFOs, and the various System V IPC syscalls. Support for these facilities varies across platforms; modern Unix systems (including Apple's Mac OS X) should support all of them, and, except for signals and SysV IPC, most of the rest are supported on any recent Microsoft operating systems, including pipes, forking, file locking, and sockets.[1]

[1] Well, except for AF_UNIX sockets.

More information about porting in general can be found in the standard Perl documentation set (in whatever format your system displays it) under perlport. Microsoft-specific information can be found under perlwin32 and perlfork, which are installed even on non-Microsoft systems. For textbooks, we suggest the following:

  • The Perl Cookbook, by Tom Christiansen and Nathan Torkington (O'Reilly and Associates, 1998), chapters 16 through 18.

  • Advanced Programming in the UNIX Environment, by W. Richard Stevens (Addison-Wesley, 1992).

  • TCP/IP Illustrated, by W. Richard Stevens, Volumes I-III (Addison-Wesley, 1992-1996).

16.1. Signals

Perl uses a simple signal-handling model: the %SIG hash contains references (either symbolic or hard) to user-defined signal handlers. Certain events cause the operating system to deliver a signal to the affected process. The handler corresponding to that event is called with one argument containing the name of the signal that triggered it. To send a signal to another process, you use the kill function. Think of it as sending a one-bit piece of information to the other process.[2] If that process has installed a signal handler for that signal, it can execute code when it receives the signal. But there's no way for the sending process to get any sort of return value, other than knowing that the signal was legally sent. The sender receives no feedback saying what, if anything, the receiving process did with the signal.

[2] Actually, it's more like five or six bits, depending on how many signals your OS defines and on whether the other process makes use of the fact that you didn't send a different signal.

We've classified this facility as a form of IPC, but in fact, signals can come from various sources, not just other processes. A signal might also come from your own process, or it might be generated when the user at the keyboard types a particular sequence like Control-C or Control-Z, or it might be manufactured by the kernel when a special event transpires, such as when a child process exits, or when your process runs out of stack space or hits a file size or memory limit. But your own process can't easily distinguish among these cases. A signal is like a package that arrives mysteriously on your doorstep with no return address. You'd best open it carefully.

Since entries in the %SIG array can be hard references, it's common practice to use anonymous functions for simple signal handlers:

$SIG{INT}  = sub { die "\nOutta here!\n" };
$SIG{ALRM} = sub { die "Your alarm clock went off" };
Or you could create a named function and assign its name or reference to the appropriate slot in the hash. For example, to intercept interrupt and quit signals (often bound to Control-C and Control-\ on your keyboard), set up a handler like this:
sub catch_zap {
    my $signame = shift;
    our $shucks++;
    die "Somebody sent me a SIG$signame!";
}
$shucks = 0;
$SIG{INT} = 'catch_zap';   # always means &main::catch_zap
$SIG{INT} = \&catch_zap;   # best strategy
$SIG{QUIT} = \&catch_zap;  # catch another, too
Notice how all we do in the signal handler is set a global variable and then raise an exception with die. Whenever possible, try to avoid anything more complicated than that, because on most systems the C library is not re-entrant. Signals are delivered asynchronously,[3] so calling any print functions (or even anything that needs to malloc(3) more memory) could in theory trigger a memory fault and subsequent core dump if you were already in a related C library routine when the signal was delivered. (Even the die routine is a bit unsafe unless the process is executing within an eval, which suppresses the I/O from die, which keeps it from calling the C library. Probably.)

[3]Synchronizing signal delivery with Perl-level opcodes is scheduled for a future release of Perl, which should solve the matter of signals and core dumps.

An even easier way to trap signals is to use the sigtrap pragma to install simple, default signal handlers:

use sigtrap qw(die INT QUIT);
use sigtrap qw(die untrapped normal-signals
   stack-trace any error-signals);
The pragma is useful when you don't want to bother writing your own handler, but you still want to catch dangerous signals and perform an orderly shutdown. By default, some of these signals are so fatal to your process that your program will just stop in its tracks when it receives one. Unfortunately, that means that any END functions for at-exit handling and DESTROY methods for object finalization are not called. But they are called on ordinary Perl exceptions (such as when you call die), so you can use this pragma to painlessly convert the signals into exceptions. Even though you aren't dealing with the signals yourself, your program still behaves correctly. See the description of use sigtrap in Chapter 31, "Pragmatic Modules", for many more features of this pragma.

You may also set the %SIG handler to either of the strings "IGNORE" or "DEFAULT", in which case Perl will try to discard the signal or allow the default action for that signal to occur (though some signals can be neither trapped nor ignored, such as the KILL and STOP signals; see signal(3), if you have it, for a list of signals available on your system and their default behaviors).

The operating system thinks of signals as numbers rather than names, but Perl, like most people, prefers symbolic names to magic numbers. To find the names of the signals, list out the keys of the %SIG hash, or use the kill -l command if you have one on your system. You can also use Perl's standard Config module to determine your operating system's mapping between signal names and signal numbers. See Config(3) for an example of this.

Because %SIG is a global hash, assignments to it affect your entire program. It's often more considerate to the rest of your program to confine your signal catching to a restricted scope. Do this with a local signal handler assignment, which goes out of effect once the enclosing block is exited. (But remember that local values are visible in functions called from within that block.)

{
    local $SIG{INT} = 'IGNORE';
    ...     # Do whatever you want here, ignoring all SIGINTs.
    fn();   # SIGINTs ignored inside fn() too!
    ...     # And here.
}           # Block exit restores previous $SIG{INT} value.

fn();       # SIGINTs not ignored inside fn() (presumably).

16.1.1. Signaling Process Groups

Processes (under Unix, at least) are organized into process groups, generally corresponding to an entire job. For example, when you fire off a single shell command that consists of a series of filter commands that pipe data from one to the other, those processes (and their child processes) all belong to the same process group. That process group has a number corresponding to the process number of the process group leader. If you send a signal to a positive process number, it just sends the signal to the process, but if you send a signal to a negative number, it sends that signal to every process whose process group number is the corresponding positive number, that is, the process number of the process group leader. (Conveniently for the process group leader, the process group ID is just $$.)

Suppose your program wants to send a hang-up signal to all child processes it started directly, plus any grandchildren started by those children, plus any greatgrandchildren started by those grandchildren, and so on. To do this, your program first calls setpgrp(0,0) to become the leader of a new process group, and any processes it creates will be part of the new group. It doesn't matter whether these processes were started manually via fork, automaticaly via piped opens, or as backgrounded jobs with system("cmd &"). Even if those processes had children of their own, sending a hang-up signal to your entire process group will find them all (except for processes that have set their own process group or changed their UID to give themselves diplomatic immunity to your signals).

{
    local $SIG{HUP} = 'IGNORE';   # exempt myself
    kill(HUP, -$$);               # signal my own process group
}

Another interesting signal is signal number 0. This doesn't actually affect the target process, but instead checks that it's alive and hasn't changed its UID. That is, it checks whether it's legal to send a signal, without actually sending one.

unless (kill 0 => $kid_pid) {
    warn "something wicked happened to $kid_pid";
}
Signal number 0 is the only signal that works the same under Microsoft ports of Perl as it does in Unix. On Microsoft systems, kill does not actually deliver a signal. Instead, it forces the target process to exit with the status indicated by the signal number. This may be fixed someday. The magic 0 signal, however, still behaves in the standard, nondestructive fashion.

16.1.2. Reaping Zombies

When a process exits, its parent is sent a CHLD signal by the kernel and the process becomes a zombie[4] until the parent calls wait or waitpid. If you start another process in Perl using anything except fork, Perl takes care of reaping your zombied children, but if you use a raw fork, you're expected to clean up after yourself. On many but not all kernels, a simple hack for autoreaping zombies is to set $SIG{CHLD} to 'IGNORE'. A more flexible (but tedious) approach is to reap them yourself. Because more than one child may have died before you get around to dealing with them, you must gather your zombies in a loop until there aren't any more:

use POSIX ":sys_wait_h";
sub REAPER { 1 until waitpid(-1, WNOHANG) == -1) }
To run this code as needed, you can either set a CHLD signal handler for it:
$SIG{CHLD} = \&REAPER;
or, if you're running in a loop, just arrange to call the reaper every so often. This is the best approach because it isn't subject to the occasional core dump that signals can sometimes trigger in the C library. However, it's expensive if called in a tight loop, so a reasonable compromise is to use a hybrid strategy where you minimize the risk within the handler by doing as little as possible and waiting until outside to reap zombies:
our $zombies = 0;
$SIG{CHLD} = sub { $zombies++ };
sub reaper {
    my $zombie;
    our %Kid_Status;  # store each exit status
    $zombies = 0;
    while (($zombie = waitpid(-1, WNOHANG)) != -1) {
        $Kid_Status{$zombie} = $?;
    }
}
while (1) {
    reaper() if $zombies;
    ...
}
This code assumes your kernel supports reliable signals. Old SysV traditionally didn't, which made it impossible to write correct signal handlers there. Ever since way back in the 5.003 release, Perl has used the sigaction(2) syscall where available, which is a lot more dependable. This means that unless you're running on an ancient operating system or with an ancient Perl, you won't have to reinstall your handlers and risk missing signals. Fortunately, all BSD-flavored systems (including Linux, Solaris, and Mac OS X) plus all POSIX-compliant systems provide reliable signals, so the old broken SysV behavior is more a matter of historical note than of current concern.

[4]Yes, that really is the technical term.

With these newer kernels, many other things will work better, too. For example, "slow" syscalls (those that can block, like read, wait, and accept) will restart automatically if interrupted by a signal. In the bad old days, user code had to remember to check explicitly whether each slow syscall failed with $! ($ERRNO) set to EINTR and, if so, restart. This wouldn't happen just from INT signals; even innocuous signals like TSTP (from a Control-Z) or CONT (from foregrounding the job) would abort the syscall. Perl now restarts the syscall for you automatically if the operating system allows it to. This is generally construed to be a feature.

You can check whether you have the more rigorous POSIX-style signal behavior by loading the Config module and checking whether $Config{d_sigaction} has a true value. To find out whether slow syscalls are restartable, check your system documentation on sigaction(2) or sigvec(3), or scrounge around your C sys/signal.h file for SV_INTERRUPT or SA_RESTART. If one or both symbols are found, you probably have restartable syscalls.

16.1.3. Timing Out Slow Operations

A common use for signals is to impose time limits on long-running operations. If you're on a Unix system (or any other POSIX-conforming system that supports the ALRM signal), you can ask the kernel to send your process an ALRM at some point in the future:

use Fcntl ':flock';
eval {
    local $SIG{ALRM} = sub { die "alarm clock restart" };
    alarm 10;               # schedule alarm in 10 seconds
    eval {
        flock(FH, LOCK_EX)  # a blocking, exclusive lock
            or die "can't flock: $!";
    };
    alarm 0;                # cancel the alarm
};
alarm 0;               # race condition protection
die if $@ && $@ !~ /alarm clock restart/; # reraise
If the alarm hits while you're waiting for the lock, and you simply catch the signal and return, you'll go right back into the flock because Perl automatically restarts syscalls where it can. The only way out is to raise an exception through die and then let eval catch it. (This works because the exception winds up calling the C library's longjmp(3) function, which is what really gets you out of the restarting syscall.)

The nested exception trap is included because calling flock would raise an exception if flock is not implemented on your platform, and you need to make sure to clear the alarm anyway. The second alarm 0 is provided in case the signal comes in after running the flock but before getting to the first alarm 0. Without the second alarm, you would risk a tiny race condition--but size doesn't matter in race conditions; they either exist or they don't. And we prefer that they don't.

16.1.4. Blocking Signals

Now and then, you'd like to delay receipt of a signal during some critical section of code. You don't want to blindly ignore the signal, but what you're doing is too important to interrupt. Perl's %SIG hash doesn't implement signal blocking, but the POSIX module does, through its interface to the sigprocmask(2) syscall:

use POSIX qw(:signal_h);
$sigset   = POSIX::SigSet->new;
$blockset = POSIX::SigSet->new(SIGINT, SIGQUIT, SIGCHLD);
sigprocmask(SIG_BLOCK, $blockset, $sigset)
    or die "Could not block INT,QUIT,CHLD signals: $!\n";
Once the three signals are all blocked, you can do whatever you want without fear of being bothered. When you're done with your critical section, unblock the signals by restoring the old signal mask:
sigprocmask(SIG_SETMASK, $sigset)
    or die "Could not restore INT,QUIT,CHLD signals: $!\n";
If any of the three signals came in while blocked, they are delivered immediately. If two or more different signals are pending, the order of delivery is not defined. Additionally, no distinction is made between having received a particular signal once while blocked and having received it many times.[5] For example, if nine child processes exited while you were blocking CHLD signals, your handler (if you had one) would still be called only once after you unblocked. That's why, when you reap zombies, you should always loop until they're all gone.

[5] Traditionally, that is. Countable signals may be implemented on some real-time systems according to the latest specs, but we haven't seen these yet.

Previous | Home | Next
15.3. Caution, [image] Working | Book Index | 16.2. Files
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.2. Files

Perhaps you've never thought about files as an IPC mechanism before, but they shoulder the lion's share of interprocess communication--far more than all other means combined. When one process deposits its precious data in a file and another process later retrieves that data, those processes have communicated. Files offer something unique among all forms of IPC covered here: like a papyrus scroll unearthed after millennia buried in the desert, a file can be unearthed and read long after its writer's personal end.[6] Factoring in persistence with comparative ease of use, it's no wonder that files remain popular.

[6] Presuming that a process can have a personal end.

Using files to transmit information from the dead past to some unknown future poses few surprises. You write the file to some permanent medium like a disk, and that's about it. (You might tell a web server where to find it, if it contains HTML.) The interesting challenge is when all parties are still alive and trying to communicate with one another. Without some agreement about whose turn it is to have their say, reliable communication is impossible; agreement may be achieved through file locking, which is covered in the next section. In the section after that, we discuss the special relationship that exists between a parent process and its children, which allows related parties to exchange information through inherited access to the same files.

Files certainly have their limitations when it comes to things like remote access, synchronization, reliability, and session management. Other sections of the chapter cover various IPC mechanisms invented to address such limitations.

16.2.1. File Locking

In a multitasking environment, you need to be careful not to collide with other processes that are trying to use the same file you're using. As long as all processes are just reading, there's no problem, but as soon as even one process needs to write to the file, complete chaos ensues unless some sort of locking mechanism acts as traffic cop.

Never use the mere existence of a filename (that is, -e $file) as a locking indication, because a race condition exists between the test for existence of that filename and whatever you plan to do with it (like create it, open it, or unlink it). See the section Section 16.2.2, "Handling Race Conditions" in Chapter 23, "Security", for more about this.

Perl's portable locking interface is the flock(HANDLE,FLAGS) function, described in Chapter 29, "Functions". Perl maximizes portability by using only the simplest and most widespread locking features found on the broadest range of platforms. These semantics are simple enough that they can be emulated on most systems, including those that don't support the traditional syscall of that name, such as System V or Windows NT. (If you're running a Microsoft system earlier than NT, though, you're probably out of luck, as you would be if you're running a system from Apple before Mac OS X.)

Locks come in two varieties: shared (the LOCK_SH flag) and exclusive (the LOCK_EX flag). Despite the suggestive sound of "exclusive", processes aren't required to obey locks on files. That is, flock only implements advisory locking, which means that locking a file does not stop another process from reading or even writing the file. Requesting an exclusive lock is just a way for a process to let the operating system suspend it until all current lockers, whether shared or exclusive, are finished with it. Similarly, when a process asks for a shared lock, it is just suspending itself until there is no exclusive locker. Only when all parties use the file-locking mechanism can a contended file be accessed safely.

Therefore, flock is a blocking operation by default. That is, if you can't get the lock you want immediately, the operating system suspends your process till you can. Here's how to get a blocking, shared lock, typically used for reading a file:

use Fcntl qw(:DEFAULT :flock);
open(FH, "< filename")  or die "can't open filename: $!";
flock(FH, LOCK_SH)      or die "can't lock filename: $!";
# now read from FH
You can try to acquire a lock in a nonblocking fashion by including the LOCK_NB flag in the flock request. If you can't be given the lock right away, the function fails and immediately returns false. Here's an example:
flock(FH, LOCK_SH | LOCK_NB)
    or die "can't lock filename: $!";
You may wish to do something besides raising an exception as we did here, but you certainly don't dare do any I/O on the file. If you are refused a lock, you shouldn't access the file until you can get the lock. Who knows what scrambled state you might find the file in? The main purpose of the nonblocking mode is to let you go off and do something else while you wait. But it can also be useful for producing friendlier interactions by warning users that it might take a while to get the lock, so they don't feel abandoned:
use Fcntl qw(:DEFAULT :flock);
open(FH, "< filename")  or die "can't open filename: $!";
unless (flock(FH, LOCK_SH | LOCK_NB)) {
    local $| = 1;
    print "Waiting for lock on filename...";
    flock(FH, LOCK_SH)  or die "can't lock filename: $!";
    print "got it.\n"
}
# now read from FH
Some people will be tempted to put that nonblocking lock into a loop. The main problem with nonblocking mode is that, by the time you get back to checking again, someone else may have grabbed the lock because you abandoned your place in line. Sometimes you just have to get in line and wait. If you're lucky there will be some magazines to read.

Locks are on filehandles, not on filenames.[7] When you close the file, the lock dissolves automatically, whether you close the file explicitly by calling close or implicitly by reopening the handle or by exiting your process.

[7] Actually, locks aren't on filehandles--they're on the file descriptors associated with the filehandles since the operating system doesn't know about filehandles. That means that all our die messages about failing to get a lock on filenames are technically inaccurate. But error messages of the form "I can't get a lock on the file represented by the file descriptor associated with the filehandle originally opened to the path filename, although by now filename may represent a different file entirely than our handle does" would just confuse the user (not to mention the reader).

To get an exclusive lock, typically used for writing, you have to be more careful. You cannot use a regular open for this; if you use an open mode of <, it will fail on files that don't exist yet, and if you use >, it will clobber any files that do. Instead, use sysopen on the file so it can be locked before getting overwritten. Once you've safely opened the file for writing but haven't yet touched it, successfully acquire the exclusive lock and only then truncate the file. Now you may overwrite it with the new data.

use Fcntl qw(:DEFAULT :flock);
sysopen(FH, "filename", O_WRONLY | O_CREAT)
    or die "can't open filename: $!";
flock(FH, LOCK_EX)
    or die "can't lock filename: $!";
truncate(FH, 0)
    or die "can't truncate filename: $!";
# now write to FH
If you want to modify the contents of a file in place, use sysopen again. This time you ask for both read and write access, creating the file if needed. Once the file is opened, but before you've done any reading or writing, get the exclusive lock and keep it around your entire transaction. It's often best to release the lock by closing the file because that guarantees all buffers are written before the lock is released.

An update involves reading in old values and writing out new ones. You must do both operations under a single exclusive lock, lest another process read the (imminently incorrect) value after (or even before) you do, but before you write. (We'll revisit this situation when we cover shared memory later in this chapter.)

use Fcntl qw(:DEFAULT :flock);

sysopen(FH, "counterfile", O_RDWR | O_CREAT)
    or die "can't open counterfile: $!";
flock(FH, LOCK_EX)
    or die "can't write-lock counterfile: $!";
$counter = <FH> || 0;  # first time would be undef
seek(FH, 0, 0)
    or die "can't rewind counterfile : $!";
print FH $counter+1, "\n"
    or die "can't write counterfile: $!";

# next line technically superfluous in this program, but
# a good idea in the general case
truncate(FH, tell(FH))
    or die "can't truncate counterfile: $!";
close(FH)
    or die "can't close counterfile: $!";
You can't lock a file you haven't opened yet, and you can't have a single lock that applies to more than one file. What you can do, though, is use a completely separate file to act as a sort of semaphore, like a traffic light, to provide controlled access to something else through regular shared and exclusive locks on the semaphore file. This approach has several advantages. You can have one lockfile that controls access to multiple files, avoiding the kind of deadlock that occurs when one process tries to lock those files in one order while another process is trying to lock them in a different order. You can use a semaphore file to lock an entire directory of files. You can even control access to something that's not even in the filesystem, like a shared memory object or the socket upon which several preforked servers would like to call accept.

If you have a DBM file that doesn't provide its own explicit locking mechanism, an auxiliary lockfile is the best way to control concurrent access by multiple agents. Otherwise, your DBM library's internal caching can get out of sync with the file on disk. Before calling dbmopen or tie, open and lock the semaphore file. If you open the database with O_RDONLY, you'll want to use LOCK_SH for the lock. Otherwise, use LOCK_EX for exclusive access to updating the database. (Again, this only works if all participants agree to pay attention to the semaphore.)

use Fcntl qw(:DEFAULT :flock);
use DB_File;  # demo purposes only; any db is fine

$DBNAME  = "/path/to/database";
$LCK     = $DBNAME . ".lockfile";

# use O_RDWR if you expect to put data in the lockfile
sysopen(DBLOCK, $LCK, O_RDONLY | O_CREAT)
    or die "can't open $LCK: $!";

# must get lock before opening database
flock(DBLOCK, LOCK_SH)
    or die "can't LOCK_SH $LCK: $!";

tie(%hash, "DB_File", $DBNAME, O_RDWR | O_CREAT)
    or die "can't tie $DBNAME: $!";
Now you can safely do whatever you'd like with the tied %hash. When you're done with your database, make sure you explicitly release those resources, and in the opposite order that you acquired them:
untie %hash;    # must close database before lockfile
close DBLOCK;   # safe to let go of lock now
If you have the GNU DBM library installed, you can use the standard GDBM_File module's implicit locking. Unless the initial tie contains the GDBM_NOLOCK flag, the library makes sure that only one writer may open a GDBM file at a time, and that readers and writers do not have the database open at the same time.

16.2.2. Passing Filehandles

Whenever you create a child process using fork, that new process inherits all its parent's open filehandles. Using filehandles for interprocess communication is easiest to illustrate by using plain files first. Understanding how this works is essential for mastering the fancier mechanisms of pipes and sockets described later in this chapter.

The simplest example opens a file and starts up a child process. The child then uses the filehandle already opened for it:

open(INPUT, "< /etc/motd")      or die "/etc/motd: $!";
if ($pid = fork) { waitpid($pid,0) }
else {
    defined($pid)         or die "fork: $!";
    while (<INPUT>) { print "$.: $_" }
    exit;  # don't let child fall back into main code
}
# INPUT handle now at EOF in parent
Once access to a file has been granted by open, it stays granted until the filehandle is closed; changes to the file's permissions or to the owner's access privileges have no effect on accessibility. Even if the process later alters its user or group IDs, or the file has its ownership changed to a different user or group, that doesn't affect filehandles that are already open. Programs running under increased permissions (like set-id programs or systems daemons) often open a file under their increased rights and then hand off the filehandle to a child process that could not have opened the file on its own.

Although this feature is of great convenience when used intentionally, it can also create security issues if filehandles accidentally leak from one program to the next. To avoid granting implicit access to all possible filehandles, Perl automatically closes any filehandles it has opened (including pipes and sockets) whenever you explicitly exec a new program or implicitly execute one through a call to a piped open, system, or qx// (backticks). The system filehandles STDIN, STDOUT, and STDERR are exempt from this because their main purpose is to provide communications linkage between programs. So one way of passing a filehandle to a new program is to copy the filehandle to one of the standard filehandles:

open(INPUT, "< /etc/motd")      or die "/etc/motd: $!";
if ($pid = fork) { wait }
else {
    defined($pid)               or die "fork: $!";
    open(STDIN, "<&INPUT")      or die "dup: $!";
    exec("cat", "-n")           or die "exec cat: $!";
}
If you really want the new program to gain access to a filehandle other than these three, you can, but you have to do one of two things. When Perl opens a new file (or pipe or socket), it checks the current setting of the $^F ($SYSTEM_FD_MAX) variable. If the numeric file descriptor used by that new filehandle is greater than $^F, the descriptor is marked as one to close. Otherwise, Perl leaves it alone, and new programs you exec will inherit access.

It's not always easy to predict what file descriptor your newly opened filehandle will have, but you can temporarily set your maximum system file descriptor to some outrageously high number for the duration of the open:

# open file and mark INPUT to be left open across execs
{
    local $^F = 10_000;
    open(INPUT, "< /etc/motd")   or die "/etc/motd: $!";
} # old value of $^F restored on scope exit
Now all you have to do is get the new program to pay attention to the descriptor number of the filehandle you just opened. The cleanest solution (on systems that support this) is to pass a special filename that equates to a file descriptor. If your system has a directory called /dev/fd or /proc/$$/fd containing files numbered from 0 through the maximum number of supported descriptors, you can probably use this strategy. (Many Linux operating systems have both, but only the /proc version tends to be correctly populated. BSD and Solaris prefer /dev/fd. You'll have to poke around at your system to see which looks better for you.) First, open and mark your filehandle as one to be left open across execs as shown in the previous code, then fork like this:
if ($pid = fork) { wait }
else {
    defined($pid)                or die "fork: $!";
    $fdfile = "/dev/fd/" . fileno(INPUT);
    exec("cat", "-n", $fdfile)   or die "exec cat: $!";
}
If your system supports the fcntl syscall, you may diddle the filehandle's close-on-exec flag manually. This is convenient for those times when you didn't realize back when you created the filehandle that you would want to share it with your children.
use Fcntl qw/F_SETFD/;

fcntl(INPUT, F_SETFD, 0)
    or die "Can't clear close-on-exec flag on INPUT: $!\n";
You can also force a filehandle to close:
fcntl(INPUT, F_SETFD, 1)
    or die "Can't set close-on-exec flag on INPUT: $!\n";
You can also query the current status:
use Fcntl qw/F_SETFD F_GETFD/;

printf("INPUT will be %s across execs\n",
    fcntl(INPUT, F_GETFD, 1) ? "closed" : "left open");
If your system doesn't support file descriptors named in the filesystem, and you want to pass a filehandle other than STDIN, STDOUT, or STDERR, you can still do so, but you'll have to make special arrangements with that program. Common strategies for this are to pass the descriptor number through an environment variable or a command-line option.

If the executed program is in Perl, you can use open to convert a file descriptor into a filehandle. Instead of specifying a filename, use "&=" followed by the descriptor number.

if (defined($ENV{input_fdno}) && $ENV{input_fdno}) =~ /^\d$/) {
    open(INPUT, "<&=$ENV{input_fdno}")
        or die "can't fdopen $ENV{input_fdno} for input: $!";
}
It gets even easier than that if you're going to be running a Perl subroutine or program that expects a filename argument. You can use the descriptor-opening feature of Perl's regular open function (but not sysopen or three-argument open) to make this happen automatically. Imagine you have a simple Perl program like this:
#!/usr/bin/perl -p
# nl - number input lines
printf "%6d  ", $.;
Presuming you've arranged for the INPUT handle to stay open across execs, you can call that program this way:
$fdspec = '<&=' . fileno(INPUT);
system("nl", $fdspec);
or to catch the output:
@lines = `nl '$fdspec'`;  # single quotes protect spec from shell
Whether or not you exec another program, if you use file descriptors inherited across fork, there's one small gotcha. Unlike variables copied across a fork, which actually get duplicate but independent copies, file descriptors really are the same in both processes. If one process reads data from the handle, the seek pointer (file position) advances in the other process, too, and that data is no longer available to either process. If they take turns reading, they'll leapfrog over each other in the file. This makes intuitive sense for handles attached to serial devices, pipes, or sockets, since those tend to be read-only devices with ephemeral data. But this behavior may surprise you with disk files. If this is a problem, reopen any files that need separate tracking after the fork.

The fork operator is a concept derived from Unix, which means it might not be implemented correctly on all non-Unix/non-POSIX platforms. Notably, fork works on Microsoft systems only if you're running Perl 5.6 (or better) on Windows 98 (or later). Although fork is implemented via multiple concurrent execution streams within the same program on these systems, these aren't the sort of threads where all data is shared by default; here, only file descriptors are. See also Chapter 17, "Threads".

Previous | Home | Next
16.1. Signals | Book Index | 16.3. Pipes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.3. Pipes

A pipe is a unidirectional I/O channel that can transfer a stream of bytes from one process to another. Pipes come in both named and nameless varieties. You may be more familiar with nameless pipes, so we'll talk about those first.

16.3.1. Anonymous Pipes

Perl's open function opens a pipe instead of a file when you append or prepend a pipe symbol to the second argument to open. This turns the rest of the arguments into a command, which will be interpreted as a process (or set of processes) that you want to pipe a stream of data either into or out of. Here's how to start up a child process that you intend to write to:

open SPOOLER, "| cat -v | lpr -h 2>/dev/null"
    or die "can't fork: $!";
local $SIG{PIPE} = sub { die "spooler pipe broke" };
print SPOOLER "stuff\n";
close SPOOLER or die "bad spool: $! $?";
This example actually starts up two processes, the first of which (running cat) we print to directly. The second process (running lpr) then receives the output of the first process. In shell programming, this is often called a pipeline. A pipeline can have as many processes in a row as you like, as long as the ones in the middle know how to behave like filters; that is, they read standard input and write standard output.

Perl uses your default system shell (/bin/sh on Unix) whenever a pipe command contains special characters that the shell cares about. If you're only starting one command, and you don't need--or don't want--to use the shell, you can use the multi-argument form of a piped open instead:

open SPOOLER, "|-", "lpr", "-h"    # requires 5.6.1
    or die "can't run lpr: $!";
If you reopen your program's standard output as a pipe to another program, anything you subsequently print to STDOUT will be standard input for the new program. So to page your program's output,[8] you'd use:
if (-t STDOUT) {             # only if stdout is a terminal
    my $pager = $ENV{PAGER} || 'more';
    open(STDOUT, "| $pager")    or die "can't fork a pager: $!";
}
END {
    close(STDOUT)               or die "can't close STDOUT: $!"
}
When you're writing to a filehandle connected to a pipe, always explicitly close that handle when you're done with it. That way your main program doesn't exit before its offspring.

[8]That is, let them view it one screenful at a time, not set off random bird calls.

Here's how to start up a child process that you intend to read from:

open STATUS, "netstat -an 2>/dev/null |"
    or die "can't fork: $!";
while (<STATUS>) {
    next if /^(tcp|udp)/;
    print;
}
close STATUS or die "bad netstat: $! $?";
You can open a multistage pipeline for input just as you can for output. And as before, you can avoid the shell by using an alternate form of open:
open STATUS, "-|", "netstat", "-an"      # requires 5.6.1
    or die "can't run netstat: $!";
But then you don't get I/O redirection, wildcard expansion, or multistage pipes, since Perl relies on your shell to do those.

You might have noticed that you can use backticks to accomplish the same effect as opening a pipe for reading:

print grep { !/^(tcp|udp)/ } `netstat -an 2>&1`;
die "bad netstat" if $?;
While backticks are extremely handy, they have to read the whole thing into memory at once, so it's often more efficient to open your own piped filehandle and process the file one line or record at a time. This gives you finer control over the whole operation, letting you kill off the child process early if you like. You can also be more efficient by processing the input as it's coming in, since computers can interleave various operations when two or more processes are running at the same time. (Even on a single-CPU machine, input and output operations can happen while the CPU is doing something else.)

Because you're running two or more processes concurrently, disaster can strike the child process any time between the open and the close. This means that the parent must check the return values of both open and close. Checking the open isn't good enough, since that will only tell you whether the fork was successful, and possibly whether the subsequent command was successfully launched. (It can tell you this only in recent versions of Perl, and only if the command is executed directly by the forked child, not via the shell.) Any disaster that happens after that is reported from the child to the parent as a nonzero exit status. When the close function sees that, it knows to return a false value, indicating that the actual status value should be read from the $? ($CHILD_ERROR) variable. So checking the return value of close is just as important as checking open. If you're writing to a pipe, you should also be prepared to handle the PIPE signal, which is sent to you if the process on the other end dies before you're done sending to it.

16.3.2. Talking to Yourself

Another approach to IPC is to make your program talk to itself, in a manner of speaking. Actually, your process talks over pipes to a forked copy of itself. It works much like the piped open we talked about in the last section, except that the child process continues executing your script instead of some other command.

To represent this to the open function, you use a pseudocommand consisting of a minus. So the second argument to open looks like either "-|" or "|-", depending on whether you want to pipe from yourself or to yourself. As with an ordinary fork command, the open function returns the child's process ID in the parent process but 0 in the child process. Another asymmetry is that the filehandle named by the open is used only in the parent process. The child's end of the pipe is hooked to either STDIN or STDOUT as appropriate. That is, if you open a pipe to minus with |-, you can write to the filehandle you opened, and your kid will find this in STDIN:

if (open(TO, "|-")) {
    print TO $fromparent;
}
else {
    $tochild = <STDIN>;
    exit;
}
If you open a pipe from minus with -|, you can read from the filehandle you opened, which will return whatever your kid writes to STDOUT:
if (open(FROM, "-|")) {
    $toparent = <FROM>;
}
else {
    print STDOUT $fromchild;
    exit;
}

One common application of this construct is to bypass the shell when you want to open a pipe from a command. You might want to do this because you don't want the shell to interpret any possible metacharacters in the filenames you're trying to pass to the command. If you're running release 5.6.1 or greater of Perl, you can use the multi-argument form of open to get the same result.

Another use of a forking open is to safely open a file or command even while you're running under an assumed UID or GID. The child you fork drops any special access rights, then safely opens the file or command and acts as an intermediary, passing data between its more powerful parent and the file or command it opened. Examples can be found in the section Section 16.1.3, "Accessing Commands and Files Under Reduced Privileges" in Chapter 23, "Security".

One creative use of a forking open is to filter your own output. Some algorithms are much easier to implement in two separate passes than they are in just one pass. Here's a simple example in which we emulate the Unix tee(1) program by sending our normal output down a pipe. The agent on the other end of the pipe (one of our own subroutines) distributes our output to all the files specified:

tee("/tmp/foo", "/tmp/bar", "/tmp/glarch");

while (<>) {
    print "$ARGV at line $. => $_";
}
close(STDOUT)  or die "can't close STDOUT: $!";

sub tee {
    my @output = @_;
    my @handles = ();
    for my $path (@output) {
        my $fh;  # open will fill this in
        unless (open ($fh, ">", $path)) {
            warn "cannot write to $path: $!";
            next;
        }
        push @handles, $fh;
    }

    # reopen STDOUT in parent and return
    return if my $pid = open(STDOUT, "|-");
    die "cannot fork: $!" unless defined $pid;

    # process STDIN in child
    while (<STDIN>) {
        for my $fh (@handles) {
            print $fh $_ or die "tee output failed: $!";
        }
    }
    for my $fh (@handles) {
        close($fh) or die "tee closing failed: $!";
    }
    exit;  # don't let the child return to main!
}
This technique can be applied repeatedly to push as many filters on your output stream as you wish. Just keep calling functions that fork-open STDOUT, and have the child read from its parent (which it sees as STDIN) and pass the massaged output along to the next function in the stream.

Another interesting application of talking to yourself with fork-open is to capture the output from an ill-mannered function that always splats its results to STDOUT. Imagine if Perl only had printf and no sprintf. What you'd need would be something that worked like backticks, but with Perl functions instead of external commands:

badfunc("arg");                       # drat, escaped!
$string = forksub(\&badfunc, "arg");  # caught it as string
@lines  = forksub(\&badfunc, "arg");  # as separate lines

sub forksub {
    my $kidpid = open my $self, "-|";
    defined $kidpid         or die "cannot fork: $!";
    shift->(@_), exit       unless $kidpid;
    local $/                unless wantarray;
    return <$self>;         # closes on scope exit
}
We're not claiming this is efficient; a tied filehandle would probably be a good bit faster. But it's a lot easier to code up if you're in more of a hurry than your computer is.

16.3.3. Bidirectional Communication

Although using open to connect to another command over a pipe works reasonably well for unidirectional communication, what about bidirectional communication? The obvious approach doesn't actually work:

open(PROG_TO_READ_AND_WRITE, "| some program |")  # WRONG!
and if you forget to enable warnings, then you'll miss out entirely on the diagnostic message:
Can't do bidirectional pipe at myprog line 3.

The open function doesn't allow this because it's rather prone to deadlock unless you're quite careful. But if you're determined, you can use the standard IPC::Open2 library module to attach two pipes to a subprocess's STDIN and STDOUT. There's also an IPC::Open3 module for tridirectional I/O (allowing you to also catch your child's STDERR), but this requires either an awkward select loop or the somewhat more convenient IO::Select module. But then you'll have to avoid Perl's buffered input operations like <> (readline).

Here's an example using open2:

use IPC::Open2;
local (*Reader, *Writer);
$pid = open2(\*Reader, \*Writer, "bc -l");
$sum = 2;
for (1 .. 5) {
    print Writer "$sum * $sum\n";
    chomp($sum = <Reader>);
}
close Writer;
close Reader;
waitpid($pid, 0);
print "sum is $sum\n";
You can also autovivify lexical filehandles:
my ($fhread, $fhwrite);
$pid = open2($fhread, $fhwrite, "cat -u -n");
The problem with this in general is that standard I/O buffering is really going to ruin your day. Even though your output filehandle is autoflushed (the library does this for you) so that the process on the other end will get your data in a timely manner, you can't usually do anything to force it to return the favor. In this particular case, we were lucky: bc expects to operate over a pipe and knows to flush each output line. But few commands are so designed, so this seldom works out unless you yourself wrote the program on the other end of the double-ended pipe. Even simple, apparently interactive programs like ftp fail here because they won't do line buffering on a pipe. They'll only do it on a tty device.

The IO::Pty and Expect modules from CPAN can help with this because they provide a real tty (actually, a real pseudo-tty, but it acts like a real one). This gets you line buffering in the other process without modifying its program.

If you split your program into several processes and want these to all have a conversation that goes both ways, you can't use Perl's high-level pipe interfaces, because these are all unidirectional. You'll need to use two low-level pipe function calls, each handling one direction of the conversation:

pipe(FROM_PARENT, TO_CHILD)     or die "pipe: $!";
pipe(FROM_CHILD,  TO_PARENT)    or die "pipe: $!";
select((select(TO_CHILD), $| = 1))[0]);   # autoflush
select((select(TO_PARENT), $| = 1))[0]);  # autoflush

if ($pid = fork) {
    close FROM_PARENT; close TO_PARENT;
    print TO_CHILD "Parent Pid $$ is sending this\n";
    chomp($line = <FROM_CHILD>);
    print "Parent Pid $$ just read this: `$line'\n";
    close FROM_CHILD; close TO_CHILD;
    waitpid($pid,0);
} else {
    die "cannot fork: $!" unless defined $pid;
    close FROM_CHILD; close TO_CHILD;
    chomp($line = <FROM_PARENT>);
    print "Child Pid $$ just read this: `$line'\n";
    print TO_PARENT "Child Pid $$ is sending this\n";
    close FROM_PARENT; close TO_PARENT;
    exit;
}
On many Unix systems, you don't actually have to make two separate pipe calls to achieve full duplex communication between parent and child. The socketpair syscall provides bidirectional connections between related processes on the same machine. So instead of two pipes, you only need one socketpair.
use Socket;
socketpair(Child, Parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
    or die "socketpair: $!";

# or letting perl pick filehandles for you
my ($kidfh, $dadfh);
socketpair($kidfh, $dadfh, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
    or die "socketpair: $!";
After the fork, the parent closes the Parent handle, then reads and writes via the Child handle. Meanwhile, the child closes the Child handle, then reads and writes via the Parent handle.

If you're looking into bidirectional communications because the process you'd like to talk to implements a standard Internet service, you should usually just skip the middleman and use a CPAN module designed for that exact purpose. (See the section Section 16.5, "Sockets" later for a list of a some of these.)

16.3.4. Named Pipes

A named pipe (often called a FIFO) is a mechanism for setting up a conversation between unrelated processes on the same machine. The names in a "named" pipe exist in the filesystem, which is just a funny way to say that you can put a special file in the filesystem namespace that has another process behind it instead of a disk.[9]

[9]You can do the same thing with Unix-domain sockets, but you can't use open on those.

A FIFO is convenient when you want to connect a process to an unrelated one. When you open a FIFO, your process will block until there's a process on the other end. So if a reader opens the FIFO first, it blocks until the writer shows up--and vice versa.

To create a named pipe, use the POSIX mkfifo function--if you're on a POSIX system, that is. On Microsoft systems, you'll instead want to look into the Win32::Pipe module, which, despite its possible appearance to the contrary, creates named pipes. (Win32 users create anonymous pipes using pipe just like the rest of us.)

For example, let's say you'd like to have your .signature file produce a different answer each time it's read. Just make it a named pipe with a Perl program on the other end that spits out random quips. Now every time any program (like a mailer, newsreader, finger program, and so on) tries to read from that file, that program will connect to your program and read in a dynamic signature.

In the following example, we use the rarely seen -p file test operator to determine whether anyone (or anything) has accidentally removed our FIFO.[10]If they have, there's no reason to try to open it, so we treat this as a request to exit. If we'd used a simple open function with a mode of "> $fpath", there would have been a tiny race condition that would have risked accidentally creating the signature as a plain file if it disappeared between the -p test and the open. We couldn't use a "+< $fpath" mode, either, because opening a FIFO for read-write is a nonblocking open (this is only true of FIFOs). By using sysopen and omitting the O_CREAT flag, we avoid this problem by never creating a file by accident.

use Fcntl;             # for sysopen
chdir;                 # go home
$fpath = '.signature';
$ENV{PATH} .= ":/usr/games";

unless (-p $fpath) {   # not a pipe
    if (-e _) {        # but a something else
        die "$0: won't overwrite .signature\n";
    } else {
        require POSIX;
        POSIX::mkfifo($fpath, 0666) or die "can't mknod $fpath: $!";
        warn "$0: created $fpath as a named pipe\n";
    }
}

while (1) {
    # exit if signature file manually removed
    die "Pipe file disappeared" unless -p $fpath;
    # next line blocks until there's a reader
    sysopen(FIFO, $fpath, O_WRONLY)
        or die "can't write $fpath: $!";
    print FIFO "John Smith (smith\@host.org)\n", `fortune -s`;
    close FIFO;
    select(undef, undef, undef, 0.2);  # sleep 1/5th second
}
The short sleep after the close is needed to give the reader a chance to read what was written. If we just immediately loop back up around and open the FIFO again before our reader has finished reading the data we just sent, then no end-of-file is seen because there's once again a writer. We'll both go round and round until during one iteration, the writer falls a little behind and the reader finally sees that elusive end-of-file. (And we were worried about race conditions?)

[10]Another use is to see if a filehandle is connected to a pipe, named or anonymous, as in -p STDIN.

Previous | Home | Next
16.2. Files | Book Index | 16.4. System V IPC
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.4. System V IPC

Everyone hates System V IPC. It's slower than paper tape, carves out insidious little namespaces completely unrelated to the filesystem, uses human-hostile numbers to name its objects, and is constantly losing track of its own mind. Every so often, your sysadmin has to go on a search-and-destroy mission to hunt down these lost SysV IPC objects with ipcs(1) and kill them with ipcrm(1), hopefully before the system runs out of memory.

Despite all this pain, ancient SysV IPC still has a few valid uses. The three kinds of IPC objects are shared memory, semaphores, and messages. For message passing, sockets are the preferred mechanisms these days, and they're a lot more portable, too. For simple uses of semaphores, the filesystem tends to get used. As for shared memory--well, now there's a problem for you. If you have it, the more modern mmap(2) syscall fits the bill,[11] but the quality of the implementation varies from system to system. It also requires a bit of care to avoid letting Perl reallocate your strings from where mmap(2) put them. But when programmers look into using mmap(2), they hear these incoherent mumbles from the resident wizards about how it suffers from dodgy cache coherency issues on systems without something called a "unified buffer cache"--or maybe it was a "flycatcher unibus"--and, figuring the devil they know is better than the one they don't, run quickly back to the SysV IPC they know and hate for all their shared memory needs.

[11]There's even an Mmap module on CPAN.

Here's a little program that demonstrates controlled access to a shared memory buffer by a brood of sibling processes. SysV IPC objects can also be shared among unrelated processes on the same computer, but then you have to figure out how they're going to find each other. To mediate safe access, we'll create a semaphore per piece.[12]

[12]It would be more realistic to create a pair of semaphores for each bit of shared memory, one for reading and the other for writing, and in fact, that's what the IPC::Shareable module on CPAN does. But we're trying to keep things simple here. It's worth admitting, though, that with a couple of semaphores, you could then make use of pretty much the only redeeming feature of SysV IPC: you could perform atomic operations on entire sets of semaphores as one unit, which is occasionally useful.

Every time you want to get or put a new value into the shared memory, you have to go through the semaphore first. This can get pretty tedious, so we'll wrap access in an object class. IPC::Shareable goes one step further, wrapping its object class in a tie interface.

This program runs until you interrupt it with a Control-C or equivalent:

#!/usr/bin/perl -w
use v5.6.0;   # or better
use strict;
use sigtrap qw(die INT TERM HUP QUIT);
my $PROGENY = shift(@ARGV) || 3;
eval { main() };   # see DESTROY below for why
die if $@ && $@ !~ /^Caught a SIG/;
print "\nDone.\n";
exit;

sub main {
    my $mem = ShMem->alloc("Original Creation at " . localtime);
    my(@kids, $child);
    $SIG{CHLD} = 'IGNORE';
    for (my $unborn = $PROGENY; $unborn > 0; $unborn--) {
        if ($child = fork) {
            print "$$ begat $child\n";
            next;
        }
        die "cannot fork: $!" unless defined $child;
        eval {
            while (1) {
                $mem->lock();
                $mem->poke("$$ " . localtime)
                    unless $mem->peek =~ /^$$\b/o;
                $mem->unlock();
            }
        };

        die if $@ && $@ !~ /^Caught a SIG/;
        exit;  # child death

    }
    while (1) {
        print "Buffer is ", $mem->get, "\n";
        sleep 1;
    }
}
And here's the ShMem package, which that program uses. You can just tack it on to the end of the program, or put it in its own file (with a "1;" at the end) and require it from the main program. (The two IPC modules it uses in turn are found in the standard Perl distribution.)
package ShMem;
use IPC::SysV qw(IPC_PRIVATE IPC_RMID IPC_CREAT S_IRWXU);
use IPC::Semaphore;
sub MAXBUF() { 2000 }

sub alloc {    # constructor method
    my $class = shift;
    my $value = @_ ? shift : '';

    my $key = shmget(IPC_PRIVATE, MAXBUF, S_IRWXU) or die "shmget: $!";
    my $sem = IPC::Semaphore->new(IPC_PRIVATE, 1, S_IRWXU | IPC_CREAT)
                         or die "IPC::Semaphore->new: $!";
    $sem->setval(0,1)    or die "sem setval: $!";

    my $self = bless {
        OWNER   => $$,
        SHMKEY  => $key,
        SEMA    => $sem,
    } => $class;

    $self->put($value);
    return $self;
}
Now for the fetch and store methods. The get and put methods lock the buffer, but peek and poke don't, so the latter two should be used only while the object is manually locked--which you have to do when you want to retrieve an old value and store back a modified version, all under the same lock. The demo program does this in its while (1) loop. The entire transaction must occur under the same lock, or the testing and setting wouldn't be atomic and might bomb.
sub get {
    my $self = shift;
    $self->lock;
    my $value = $self->peek(@_);
    $self->unlock;
    return $value;
}
sub peek {
    my $self = shift;
    shmread($self->{SHMKEY}, my $buff='', 0, MAXBUF) or die "shmread: $!";
    substr($buff, index($buff, "\0")) = '';
    return $buff;
}
sub put {
    my $self = shift;
    $self->lock;
    $self->poke(@_);
    $self->unlock;
}
sub poke {
    my($self,$msg) = @_;
    shmwrite($self->{SHMKEY}, $msg, 0, MAXBUF) or die "shmwrite: $!";
}
sub lock {
    my $self = shift;
    $self->{SEMA}->op(0,-1,0) or die "semop: $!";
}
sub unlock {
    my $self = shift;
    $self->{SEMA}->op(0,1,0) or die "semop: $!";
}
Finally, the class needs a destructor so that when the object goes away, we can manually deallocate the shared memory and the semaphore stored inside the object. Otherwise, they'll outlive their creator, and you'll have to resort to ipcs and ipcrm (or a sysadmin) to get rid of them. That's why we went through the elaborate wrappers in the main program to convert signals into exceptions: it that all destructors get run, SysV IPC objects get deallocated, and sysadmins get off our case.
sub DESTROY {
    my $self = shift;
    return unless $self->{OWNER} == $$;  # avoid dup dealloc
    shmctl($self->{SHMKEY}, IPC_RMID, 0)    or warn "shmctl RMID: $!";
    $self->{SEMA}->remove()                 or warn "sema->remove: $!";
}

Previous | Home | Next
16.3. Pipes | Book Index | 16.5. Sockets
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


16.5. Sockets

The IPC mechanisms discussed earlier all have one severe restriction: they're designed for communication between processes running on the same computer. (Even though files can sometimes be shared across machines through mechanisms like NFS, locking fails miserably on many NFS implementations, which takes away most of the fun of concurrent access.) For general-purpose networking, sockets are the way to go. Although sockets were invented under BSD, they quickly spread to other forms of Unix, and nowadays you can find a socket interface on nearly every viable operating system out there. If you don't have sockets on your machine, you're going to have tremendous difficulty using the Internet.

With sockets, you can do both virtual circuits (as TCP streams) and datagrams (as UDP packets). You may be able to do even more, depending on your system. But the most common sort of socket programming uses TCP over Internet-domain sockets, so that's the kind we cover here. Such sockets provide reliable connections that work a little bit like bidirectional pipes that aren't restricted to the local machine. The two killer apps of the Internet, email and web browsing, both rely almost exclusively on TCP sockets.

You also use UDP heavily without knowing it. Every time your machine tries to find a site on the Internet, it sends UDP packets to your DNS server asking it for the actual IP address. You might use UDP yourself when you want to send and receive datagrams. Datagrams are cheaper than TCP connections precisely because they aren't connection oriented; that is, they're less like making a telephone call and more like dropping a letter in the mailbox. But UDP also lacks the reliability that TCP provides, making it more suitable for situations where you don't care whether a packet or two gets folded, spindled, or mutilated. Or for when you know that a higher-level protocol will enforce some degree of redundancy or fail-softness (which is what DNS does.)

Other choices are available but far less common. You can use Unix-domain sockets, but they only work for local communication. Various systems support various other non-IP-based protocols. Doubtless these are somewhat interesting to someone somewhere, but we'll restrain ourselves from talking about them somehow.

The Perl functions that deal with sockets have the same names as the corresponding syscalls in C, but their arguments tend to differ for two reasons: first, Perl filehandles work differently from C file descriptors; and second, Perl already knows the length of its strings, so you don't need to pass that information. See Chapter 29, "Functions" for details on each socket-related syscall.

One problem with ancient socket code in Perl was that people would use hard-coded values for constants passed into socket functions, which destroys portability. Like most syscalls, the socket-related ones quietly but politely return undef when they fail, instead of raising an exception. It is therefore essential to check these functions' return values, since if you pass them garbage, they aren't going to be very noisy about it. If you ever see code that does anything like explicitly setting $AF_INET = 2, you know you're in for big trouble. An immeasurably superior approach is to use the Socket module or the even friendlier IO::Socket module, both of which are standard. These modules provide various constants and helper functions you'll need for setting up clients and servers. For optimal success, your socket programs should always start out like this (and don't forget to add the -T taint-checking switch to the shebang line for servers):

#!/usr/bin/perl -w
use strict;
use sigtrap;
use Socket;  # or IO::Socket
As noted elsewhere, Perl is at the mercy of your C libraries for much of its system behavior, and not all systems support all sorts of sockets. It's probably safest to stick with normal TCP and UDP socket operations. For example, if you want your code to stand a chance of being portable to systems you haven't thought of, don't expect there to be support for a reliable sequenced-packet protocol. Nor should you expect to pass open file descriptors between unrelated processes over a local Unix-domain socket. (Yes, you can really do that on many Unix machines--see your local recvmsg(2) manpage.)

If you just want to use a standard Internet service like mail, news, domain name service, FTP, Telnet, the Web, and so on, then instead of starting from scratch, try using existing CPAN modules for these. Prepackaged modules designed for these include Net::SMTP (or Mail::Mailer), Net::NNTP, Net::DNS, Net::FTP, Net::Telnet, and the various HTTP-related modules. The libnet and libwww module suites both comprise many individual networking modules. Module areas on CPAN you'll want to look at are section 5 on Networking and IPC, section 15 on WWW-related modules, and section 16 on Server and Daemon Utilities.

In the sections that follow, we present several sample clients and servers without a great deal of explanation of each function used, as that would mostly duplicate the descriptions we've already provided in Chapter 29, "Functions".

16.5.1. Networking Clients

Use Internet-domain sockets when you want reliable client-server communication between potentially different machines.

To create a TCP client that connects to a server somewhere, it's usually easiest to use the standard IO::Socket::INET module:

use IO::Socket::INET;

$socket = IO::Socket::INET->new(PeerAddr => $remote_host,
                                PeerPort => $remote_port,
                                Proto    => "tcp",
                                Type     => SOCK_STREAM)
    or die "Couldn't connect to $remote_host:$remote_port : $!\n";

# send something over the socket,
print $socket "Why don't you call me anymore?\n";

# read the remote answer,
$answer = <$socket>;

# and terminate the connection when we're done.
close($socket);
A shorthand form of the call is good enough when you just have a host and port combination to connect to, and are willing to use defaults for all other fields:
$socket = IO::Socket::INET->new("www.yahoo.com:80")
    or die "Couldn't connect to port 80 of yahoo: $!";
To connect using the basic Socket module:
use Socket;

# create a socket
socket(Server, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

# build the address of the remote machine
$internet_addr = inet_aton($remote_host)
    or die "Couldn't convert $remote_host into an Internet address: $!\n";
$paddr = sockaddr_in($remote_port, $internet_addr);

# connect
connect(Server, $paddr)
    or die "Couldn't connect to $remote_host:$remote_port: $!\n";

select((select(Server), $| = 1)[0]);  # enable command buffering

# send something over the socket
print Server "Why don't you call me anymore?\n";

# read the remote answer
$answer = <Server>;

# terminate the connection when done
close(Server);
If you want to close only your side of the connection, so that the remote end gets an end-of-file, but you can still read data coming from the server, use the shutdown syscall for a half-close:
# no more writing to server
shutdown(Server, 1);    # Socket::SHUT_WR constant in v5.6

16.5.2. Networking Servers

Here's a corresponding server to go along with it. It's pretty easy with the standard IO::Socket::INET class:

use IO::Socket::INET;

$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM,
                                Reuse     => 1,
                                Listen    => 10 )   # or SOMAXCONN
    or die "Couldn't be a tcp server on port $server_port: $!\n";

while ($client = $server->accept()) {
    # $client is the new connection
}

close($server);
You can also write that using the lower-level Socket module:
use Socket;

# make the socket
socket(Server, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

# so we can restart our server quickly
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1);

# build up my socket address
$my_addr = sockaddr_in($server_port, INADDR_ANY);
bind(Server, $my_addr)
    or die "Couldn't bind to port $server_port: $!\n";

# establish a queue for incoming connections
listen(Server, SOMAXCONN)
    or die "Couldn't listen on port $server_port: $!\n";

# accept and process connections
while (accept(Client, Server)) {
    # do something with new Client connection
}

close(Server);
The client doesn't need to bind to any address, but the server does. We've specified its address as INADDR_ANY, which means that clients can connect from any available network interface. If you want to sit on a particular interface (like the external side of a gateway or firewall machine), use that interface's real address instead. (Clients can do this, too, but rarely need to.)

If you want to know which machine connected to you, call getpeername on the client connection. This returns an IP address, which you'll have to translate into a name on your own (if you can):

use Socket;
$other_end = getpeername(Client)
    or die "Couldn't identify other end: $!\n";
($port, $iaddr) = unpack_sockaddr_in($other_end);
$actual_ip = inet_ntoa($iaddr);
$claimed_hostname = gethostbyaddr($iaddr, AF_INET);
This is trivially spoofable because the owner of that IP address can set up their reverse tables to say anything they want. For a small measure of additional confidence, translate back the other way again:
@name_lookup = gethostbyname($claimed_hostname)
    or die "Could not reverse $claimed_hostname: $!\n";
@resolved_ips = map { inet_ntoa($_) } @name_lookup[ 4 .. $#name_lookup ];
$might_spoof = !grep { $actual_ip eq $_ } @resolved_ips;
Once a client connects to your server, your server can do I/O both to and from that client handle. But while the server is so engaged, it can't service any further incoming requests from other clients. To avoid getting locked down to just one client at a time, many servers immediately fork a clone of themselves to handle each incoming connection. (Others fork in advance, or multiplex I/O between several clients using the select syscall.)
REQUEST:
while (accept(Client, Server)) {
    if ($kidpid = fork) {
        close Client;         # parent closes unused handle
        next REQUEST;
    }
    defined($kidpid)   or die "cannot fork: $!" ;

    close Server;             # child closes unused handle

    select(Client);           # new default for prints
    $| = 1;                   # autoflush

    # per-connection child code does I/O with Client handle
    $input = <Client>;
    print Client "output\n";  # or STDOUT, same thing

    open(STDIN, "<<&Client")    or die "can't dup client: $!";
    open(STDOUT, ">&Client")    or die "can't dup client: $!";
    open(STDERR, ">&Client")    or die "can't dup client: $!";

    # run the calculator, just as an example
    system("bc -l");     # or whatever you'd like, so long as
                         # it doesn't have shell escapes!
    print "done\n";      # still to client

    close Client;
    exit;  # don't let the child back to accept!
}
This server clones off a child with fork for each incoming request. That way it can handle many requests at once, as long as you can create more processes. (You might want to limit this.) Even if you don't fork, the listen will allow up to SOMAXCONN (usually five or more) pending connections. Each connection uses up some resources, although not as much as a process. Forking servers have to be careful about cleaning up after their expired children (called "zombies" in Unix-speak) because otherwise they'd quickly fill up your process table. The REAPER code discussed in the section Section 16.1, "Signals" will take care of that for you, or you may be able to assign $SIG{CHLD} = 'IGNORE'.

Before running another command, we connect the standard input and output (and error) up to the client connection. This way any command that reads from STDIN and writes to STDOUT can also talk to the remote machine. Without the reassignment, the command couldn't find the client handle--which by default gets closed across the exec boundary, anyway.

When you write a networking server, we strongly suggest that you use the -T switch to enable taint checking even if you aren't running setuid or setgid. This is always a good idea for servers and any other program that runs on behalf of someone else (like all CGI scripts), because it lessens the chances that people from the outside will be able to compromise your system. See the section Section 16.1, "Handling Insecure Data" in Chapter 23, "Security" for much more about all this.

One additional consideration when writing Internet programs: many protocols specify that the line terminator should be CRLF, which can be specified various ways: "\015\12", or "\xd\xa", or even chr(13).chr(10). As of version 5.6 of Perl, saying v13.10 also produces the same string. (On many machines, you can also use "\r\n" to mean CRLF, but don't use "\r\n" if you want to be portable to Macs, where the meanings of \r and \n are reversed!) Many Internet programs will in fact accept a bare "\012" as a line terminator, but that's because Internet programs usually try to be liberal in what they accept and strict in what they emit. (Now if only we could get people to do the same...)

16.5.3. Message Passing

As we mentioned earlier, UDP communication involves much lower overhead but provides no reliability, since there are no promises that messages will arrive in a proper order--or even that they will arrive at all. UDP is often said to stand for Unreliable Datagram Protocol.

Still, UDP offers some advantages over TCP, including the ability to broadcast or multicast to a whole bunch of destination hosts at once (usually on your local subnet). If you find yourself getting overly concerned about reliability and starting to build checks into your message system, then you probably should just use TCP to start with. True, it costs more to set up and tear down a TCP connection, but if you can amortize that over many messages (or one long message), it doesn't much matter.

Anyway, here's an example of a UDP program. It contacts the UDP time port of the machines given on the command line, or everybody it can find using the universal broadcast address if no arguments were supplied.[13] Not all machines have a time server enabled, especially across firewall boundaries, but those that do will send you back a 4-byte integer packed in network byte order that represents what time that machine thinks it is. The time returned, however, is in the number of seconds since 1900. You have to subtract the number of seconds between 1900 and 1970 to feed that time to the localtime or gmtime conversion functions.

#!/usr/bin/perl
# clockdrift - compare other systems' clocks with this one
#              without arguments, broadcast to anyone listening.
#              wait one-half second for an answer.

use v5.6.0;  # or better
use warnings;
use strict;
use Socket;

unshift(@ARGV, inet_ntoa(INADDR_BROADCAST))
    unless @ARGV;

socket(my $msgsock, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
    or die "socket: $!";

# Some borked machines need this.  Shouldn't hurt anyone else.
setsockopt($msgsock, SOL_SOCKET, SO_BROADCAST, 1)
    or die "setsockopt: $!";

my $portno = getservbyname("time", "udp")
    or die "no udp time port";

for my $target (@ARGV) {
    print "Sending to $target:$portno\n";
    my $destpaddr = sockaddr_in($portno, inet_aton($target));
    send($msgsock, "x", 0, $destpaddr)
        or die "send: $!";
}

# daytime service returns 32-bit time in seconds since 1900
my $FROM_1900_TO_EPOCH = 2_208_988_800;
my $time_fmt = "N";   # and it does so in this binary format
my $time_len = length(pack($time_fmt, 1));  # any number's fine

my $inmask = '';  # string to store the fileno bits for select
vec($inmask, fileno($msgsock), 1) = 1;

# wait only half a second for input to show up
while (select(my $outmask = $inmask, undef, undef, 0.5)) {
    defined(my $srcpaddr = recv($msgsock, my $bintime, $time_len, 0))
        or die "recv: $!";
    my($port, $ipaddr) = sockaddr_in($srcpaddr);
    my $sendhost = sprintf "%s [%s]",
                    gethostbyaddr($ipaddr, AF_INET) || 'UNKNOWN',
                    inet_ntoa($ipaddr);
    my $delta = unpack($time_fmt, $bintime) -
                      $FROM_1900_TO_EPOCH - time();
    print "Clock on $sendhost is $delta seconds ahead of this one.\n";
}

[13] If that doesn't work, run ifconfig -a to find the proper local broadcast address.

Previous | Home | Next
16.4. System V IPC | Book Index | 17. Threads
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 17. Threads

Contents:

The Process Model
The Thread Model

Parallel programming is much harder than it looks. Imagine taking a recipe from a cookbook and converting it into something that several dozen chefs can work on all at the same time. You can take two approaches.

One approach is to give each chef a private kitchen, complete with its own supply of raw materials and utensils. For recipes that can be divided up into parts easily, and for foods that can be transported from kitchen to kitchen easily, this approach works well because it keeps the chefs out of each other's kitchens.

Alternatively, you can just put all the chefs into one kitchen, and let them work things out, like who gets to use the mixer when. This can get messy, especially when the meat cleavers start to fly.

These two approaches correspond to two models of parallel programming on computers. The first is the multiprocessing model typical of traditional Unix systems, in which each thread of control has its own set of resources, which taken together we call a process. The second model is the multithreading model, in which each thread of control shares resources with all other threads of control. Or doesn't share, as the case may be (and upon occasion must be).

We all know that chefs like to be in control; that's okay, because chefs need to be in control in order to accomplish what we want them to accomplish. But chefs need to be organized, one way or another.

Perl supports both models of organization. In this chapter we'll call them the process model and the thread model.

17.1. The Process Model

We'll not discuss the process model in great detail here, simply because it's pervasive throughout the rest of this book. Perl originated on Unix systems, so it is steeped in the notion that each process does its own thing. If a process wants to start some parallel processing, then logically it has to start a parallel process; that is, it must fork a new heavyweight process, which by default shares little with the parent process except some file descriptors. (It may seem like parent and child are sharing a lot more, but most of the state of the parent process is merely duplicated in the child process and not really shared in a logical sense. The operating system may of course exhibit laziness in enforcing that logical separation, in which case we call it copy-on-write semantics, but we wouldn't be doing the copy at all unless there were a logical separation first.)

Historically, this industrial-strength view of multiprocessing has posed a bit of a problem on Microsoft systems, because Windows has not had a well-developed multiprocessing model (and what it does have in that regard, it doesn't often rely on for parallel programming). It has typically taken a multithreading approach instead.

However, through heroic efforts, version 5.6 of Perl now implements the fork operation on Windows by cloning a new interpreter object within the same process. That means that most examples using fork in the rest of the book will now work on Windows. The cloned interpreter shares immutable code with other interpreters but gets its own copy of data to play with. (There can still be problems with C libraries that don't understand threads, of course.)

This approach to multiprocessing has been christened ithreads, short for "interpreter threads". The initial impetus for implementing ithreads was to emulate fork for Microsoft systems. However, we quickly realized that, although the other interpreters are running as distinct threads, they're running in the same process, so it would be easy to make these separate interpreters share data, even though they don't share by default.

This is the opposite of the typical threading model, in which everything is shared by default, and you have to take pains not to share something. But you should not view these two models as totally distinct from each other, because they are both trying to bridge the same river; they're just building from opposite shores. The actual solution to any parallel processing problem is going to involve some degree of sharing, together with some degree of selfishness.

So over the long run, the intent is to extend the ithreads model to allow as much sharing as you need or want. However, as of this writing, the only user-visible interface for ithreads is the fork call under Microsoft ports of Perl. We think that, eventually, this approach will produce cleaner programs than the standard threading approach. Basically, it's easier to run an economy where you assume everyone owns what they own, rather than assuming that everyone owns everything. Not that people aren't expected to share in a capitalist economy, or peculate[1] in a communist economy. These things tend toward the middle. Socialism happens. But with large groups of people, sharing everything by default only works when you have a "head chef" with a big meat cleaver who thinks he owns everything.

[1] peculate: v.i., to swipe the People's Property from the commons in the middle of the night; to embezzle from the public something that is not necessarily money (~L. peculiar, "not common"), cf embrace, extend, GPL.

Of course, the actual government of any computer is run by that fascist dictator known as the operating system. But a wise dictator knows when to let the people think they're capitalists--and when to let them think they're communists.

Previous | Home | Next
16.5. Sockets | Book Index | 17.2. The Thread Model
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


17.2. The Thread Model

The thread model of multiprocessing was first introduced to Perl as an experimental feature in version 5.005. (By "thread model", we mean threads that share data resources by default, not the new ithreads of version 5.6.) In some senses, this thread model is still an experimental feature even in 5.6, because Perl is a rich language and multithreading can make a muddle of even the simplest language. There are still various nooks and crannies of Perl semantics that don't interact very well with the notion of everything being shared. The new ithreads model is an attempt to bypass these problems, and at some future point, the current thread model may be subsumed under the ithread model (when we get an interface to ithreads that says "share everything you can by default"). But despite its warts, the current "experimental" thread model continues to be useful in many real-world situations where the only alternative to being a guinea pig is even less desirable. Reasonably robust applications can be written in threaded Perl, but you have to be very careful. You should at least consider using fork instead, if you can think of a way to solve your problem with pipes instead of shared data structures.

But some algorithms are easier to express if multiple tasks have easy and efficient access to the same pool of data.[2] This makes for code that can be smaller and simpler. And because the kernel does not have to copy page tables for data (even if doing copy-on-write) at thread creation time, it should be faster to start a task this way. Likewise, context switches can be faster if the kernel doesn't need to swap page tables. (In fact, for user-level threads, the kernel doesn't get involved at all--though of course user-level threads have issues that kernel threads don't.)

[2] The System V shared memory model discussed in the last chapter does not exactly qualify as "easy and efficient".

That's the good news. Now for some more disclaimers. We already mentioned that threading is somewhat experimental in Perl, but even if it weren't, programming with threads is treacherous. The ability of one execution stream to poke holes willy-nilly into the data space of another exposes more opportunity for disaster than you can possibly imagine. You might say to yourself, "That's easy to fix, I'll just put locks on any shared data." Okay, locking of shared data is indispensable, but getting the locking protocols correct is notoriously difficult, with errors producing deadlock or nondeterministic results. If you have timing problems in your program, using threads will not only exacerbate them, but it will make them harder to locate.

Not only are you responsible for keeping your own shared data straight, but you are required to keep the data straight of all the Perl modules and C libraries you call into. Your Perl code can be 100% threadsafe, and if you call into a nonthreadsafe module or C subroutine without providing your own semaphore protection, you're toast. You should assume any module is not threadsafe until proven otherwise. That even includes some of the standard modules. Maybe even most of them.

Have we discouraged you yet? No? Then we'll point out that you're pretty much at the mercy of your operating system's threading library when it comes to scheduling and preemption policies. Some thread libraries only do thread switching on blocking system calls. Some libraries block the whole process if a single thread makes a blocking system call. Some libraries only switch threads on quantum expiration (either thread or process). Some libraries only switch threads explicitly.

Oh, and by the way, if your process receives a signal, which thread the signal is delivered to is completely system dependent.

To do thread programming in Perl, you must build a special version of Perl following the directions given in the README.threads file in the Perl source directory. This special Perl is pretty much guaranteed to run a bit slower than your standard Perl executable.

Do not assume that just because you know how threads are programmed in other models (POSIX, DEC, Microsoft, etc.) you know how threads work with Perl. As with other things in Perl, Perl is Perl, not C++ or Java or whatnot. For example, there are no real-time thread priorities (and no way to work around their absence). There are also no mutexes. Just use regular locking or perhaps the Thread::Semaphore module or the cond_wait facilities.

Still not discouraged? Good, because threads are really cool. You're scheduled to have some fun.

17.2.1. The Thread Module

The current interface for Perl threads is defined by the Thread module. Additionally, one new Perl keyword was added, the lock operator. We'll talk about lock later in this chapter. Other standard thread modules build on this basic interface.

The Thread module provides these class methods:

Method | Use
new | Construct a new Thread.
self | Return my current Thread object.
list | Return list of Thread objects.

And, for Thread objects, it provides these object methods:

Method | Use
join | Harvest a thread (propagate errors).
eval | Harvest a thread (trap errors).
equal | Compare two threads for identity.
tid | Return the internal thread ID.

In addition, the Thread module provides these importable functions:

Function | Use
yield | Tell the scheduler to run a different thread.
async | Construct a Thread via closure.
cond_signal | Wake up exactly one thread that is cond_wait()ing on a variable.
cond_broadcast | Wake up all threads that may be cond_wait()ing on a variable.
cond_wait | Wait on a variable until awakened by a cond_signal() or cond_broadcast() on that variable.

17.2.1.1. Thread creation

You can spawn a thread in one of two ways, either by using the Thread->new class method or by using the async function. In either case, the returned value is a Thread object. Thread->new takes a code reference indicating a function to run and arguments to pass to that function:

use Thread;
...
$t = Thread->new( \&func, $arg1, $arg2);
Often you'll find yourself wanting to pass a closure as the first argument without supplying any additional arguments:
my $something;
$t = Thread->new( sub { say($something) } );
For this special case, the async function provides some notational relief (that is, syntactic sugar):
use Thread qw(async);
...
my $something;
$t = async {
    say($something);
};
You'll note that we explicitly import the async function. You may, of course, use the fully qualified name Thread::async instead, but then your syntactic sugar isn't so sweet. Since async takes only a closure, anything you want to pass to it must be a lexical variable in scope at the time.

17.2.1.2. Thread destruction

Once begun--and subject to the whims of your threading library--the thread will keep running on its own until its top-level function (the function you passed to the constructor) returns. If you want to terminate a thread early, just return from within that top-level function.[3]

[3] Don't call exit! That would try to take down your entire process, and possibly succeed. But the process won't actually exit until all threads exit, and some of them may refuse to exit on an exit. More on that later.

Now it's all very well for your top-level subroutine to return, but who does it return to? The thread that spawned this thread has presumably gone on to do other things and is no longer waiting at a method call for a response. The answer is simple enough: the thread waits until someone issues a method call that does wait for a return value. That method call is called join, because it conceptually joins two threads back into one:

$retval = $t->join();    # harvest thread $t
The operation of join is reminiscent of waitpid on a child process. If the thread has already shut down, the join method returns immediately with the return value of the thread's top-level subroutine. If the thread is not done, join acts as a blocking call that suspends the calling thread indefinitely. (There is no time-out facility.) When the thread eventually completes, the join returns.

Unlike waitpid, however, which can only harvest the process's own children, any thread can join any other thread within the process. That is, it is not a necessity for the joining thread be the main thread or the parent thread. The only restrictions are that a thread can't join itself (which would be like officiating at your own funeral), and a thread can't join a thread that has already been joined (which would be like two funeral directors fighting each other over the body). If you try to do either of those things, an exception will be raised.

The return value of join doesn't have to be a scalar value--it can also be a list:

use Thread 'async';

$t1 = async {
    my @stuff = getpwuid($>);
    return @stuff;
};

$t2 = async {
    my $motd = `cat /etc/motd`;
    return $motd;
};

@retlist = $t1->join();
$retval  = $t2->join();

print "1st kid returned @retlist\n";
print "2nd kid returned $retval\n";
In fact, the return expression of a thread is always evaluated in list context, even if join is called in a scalar context, in which case the last value of the list is returned.

17.2.1.3. Catching exceptions from join

If a thread terminates with an uncaught exception, this does not immediately kill the whole program. That would be naughty. Instead, when a join is run on that thread, the join itself raises the exception. Using join on a thread indicates a willingness to propagate any exceptions raised by that thread. If you'd rather trap the exception right then and there, use the eval method, which, like its built-in counterpart, causes the exception to be put into $@:

$retval = $t->eval();   # catch join errors
if ($@) {
    warn "thread failed: $@";
}
else {
    print "thread returned $retval\n";
}
Although there's no rule to this effect, you might want to adopt a practice of joining a thread only from within the thread that created the one you're joining. That is, you harvest a child thread only from the parent thread that spawned it. This makes it a little easier to keep track of which exceptions you might need to handle where.

17.2.1.4. The detach method

As another alternative method of shutting down threads, if you don't plan to join a thread later to get its return value, you can call the detach method on it so that Perl will clean it up for you. It can no longer be joined. It's a little bit like when a process is inherited by the init program under Unix, except that the only way to do that under Unix is for the parent process to die.

The detach method does not "background" the thread; if you try to exit the main program and a detached thread is still running, the exit will hang until the thread exits on its own. Rather, detach just spares you from clean up. It merely tells Perl not to keep the return value and exit status of the thread after it finishes. In a sense, detach tells Perl to do an implicit join when the thread finishes and then throw away the results. That can be important: if you neither join nor detach a thread that returns some very large list, that storage will be lost until the end, because Perl would have to hang onto it on the off chance (very off, in this case) that someone would want to join that thread sometime in the future.

An exception raised in a detached child thread also no longer propagates up through a join, since there will never be one. Use eval {} wisely in the top-level function, and find some other way to report errors.

17.2.1.5. Identifying threads

Every Perl thread has a distinguishing thread identification number, which the tid object method returns:

$his_tidno = $t1->tid();
A thread can access its own thread object through the Thread->self call. Don't confuse that with the thread ID: to figure out its own thread ID, a thread does this:
$mytid = Thread->self->tid();   # $$ for threads, as it were.
To compare one thread object with another, do any of these:
Thread::equal($t1, $t2)
$t1->equal($t2)
$t1->tid() == $td->tid()

17.2.1.6. Listing current threads

You can get a list of current thread objects in the current process using the Thread->list class method call. The list includes both running threads and threads that are done but haven't been joined yet. You can do this from any thread.

for my $t (Thread->list()) {
    printf "$t has tid = %d\n", $t->tid();
}

17.2.1.7. Yielding the processor

The Thread module supports an importable function named yield. Its job is to cause the calling thread to surrender the processor. Unfortunately, details of what this really does are completely dependent on which flavor of thread implementation you have. Nevertheless, it's considered a nice gesture to relinquish control of the CPU occasionally:

use Thread 'yield';
yield();
You don't have to use parentheses. This is even safer, syntactically speaking, because it catches the seemingly inevitable "yeild" typo:
use strict;
use Thread 'yield';
yeild;          # Compiler wails, then bails.
yield;          # Ok.

17.2.2. Data Access

What we've gone over so far isn't really too hard, but we're about to fix that. Nothing we've done has actually exercised the parallel nature of threads. Accessing shared data changes all that.

Threaded code in Perl has the same constraints regarding data visibility as any other bit of Perl code. Globals are still accessed via global symbol tables, and lexicals are still accessed via some containing lexical scope (scratchpad).

However, the fact that multiple threads of control exist in the program throws a clinker into the works. Two threads can't be allowed to access the same global variable simultaneously, or they may tromp on each other. (The result of the tromping depends on the nature of the access.) Similarly, two threads can't be allowed to access the same lexical variable simultaneously, because lexical variables also behave like globals if they are declared outside the scope of closures being used by threads. Starting threads via subroutine references (using Thread->new) rather than via closures (using async) can help limit access to lexicals, if that's what you want. (Sometimes it isn't, though.)

Perl solves the problem for certain built-in special variables, like $! and $_ and @_ and the like, by making them thread-specific data. The bad news is that all your basic, everyday package variables are unprotected from tromping.

The good news is that you don't generally have to worry about your lexical variables at all, presuming they were declared inside the current thread, since each thread will instantiate its own lexical scope upon entry, separate from any other thread. You only have to worry about lexicals if they're shared between threads, by passing references around, for example, or by referring to lexicals from within closures running under multiple threads.

17.2.2.1. Synchronizing access with lock

When more than one agent can access the same item at the same time, collisions happen, just like at an intersection. Careful locking is your only defense.

The built-in lock function is Perl's red-light/green-light mechanism for access control. Although lock is a keyword of sorts, it's a shy one, in that the built-in function is not used if the compiler has already seen a sub lock {} definition in user code. This is for backward compatibility. CORE::lock is always the built-in, though. (In a perl not built for threading, calling lock is not an error; it's a harmless no-op, at least in recent versions.)

Just as the flock operator only blocks other instances of flock, not the actual I/O, so too the lock operator only blocks other instances of lock, not regular data access. They are, in effect, advisory locks. Just like traffic lights.[4]

[4] Some railroad crossing signals are mandatory (the ones with gates), and some folks think locks should be mandatory too. But just picture a world in which every intersection has arms that go up and down whenever the lights change.

You can lock individual scalar variables and entire arrays and hashes as well.

lock $var;
lock @values;
lock %table;
However, using lock on an aggregate does not implicitly lock all that aggregate's scalar components:
lock @values;       # in thread 1
...
lock $values[23];   # in thread 2 -- won't block!
If you lock a reference, this automatically locks access to the referent. That is, you get one dereference for free. This is handy because objects are always hidden behind a reference, and you often want to lock objects. (And you almost never want to lock references.)

The problem with traffic lights, of course, is that they're red half the time, and then you have to wait. Likewise, lock is a blocking call--your thread will hang there until the lock is granted. There is no time-out facility. There is no unlock facility, either, because locks are dynamically scoped. They persist until their block, file, or eval has finished. When they go out of scope, they are freed automatically.

Locks are also recursive. That means that if you lock a variable in one function, and that function recurses while holding the lock, the same thread can successfully lock the same variable again. The lock is finally dropped when all frames owning the locks have exited.

Here's a simple demo of what can happen if you don't have locking. We'll force a context switch using yield to show the kind of problem that can also happen accidentally under preemptive scheduling:

use Thread qw/async yield/;
my $var = 0;
sub abump {
    if ($var == 0) {
        yield;
        $var++;
    }
}

my $t1 = new Thread \&abump;
my $t2 = new Thread \&abump;

for my $t ($t1, $t2) { $t->join }
print "var is $var\n";
That code always prints 2 (for some definition of always) because we decided to do the bump after seeing its value was 0, but before we could do so, another thread decided the same thing.

We can fix that collision by the trivial addition of a lock before we examine $var. Now this code always prints 1:

sub abump {
    lock $var;
    if ($var == 0) {
        yield;
        $var++;
    }
}
Remember that there's no explicit unlock function. To control unlocking, just add another, nested scoping level so the lock is released when that scope terminates:
sub abump {
    {
        lock $var;
        if ($var == 0) {
            yield;
            $var++;
        }
    }  # lock released here!
    # other code with unlocked $var
}

17.2.2.2. Deadlock

Deadlock is the bane of thread programmers because it's easy to do by accident and hard to avoid even when you try to. Here's a simple example of deadlock:

my $t1 = async {
    lock $a; yield; lock $b;
    $a++; $b++
};
my $t2 = async {
    lock $b; yield; lock $a;
    $b++; $a++
};
The solution here is for all parties who need a particular set of locks to grab them in the same order.

It's also good to minimize the duration of time you hold locks. (At least, it's good to do so for performance reasons. But if you do it to reduce the risk of deadlock, all you're doing is making it harder to reproduce and diagnose the problem.)

17.2.2.3. Locking subroutines

You can also put a lock on a subroutine:

lock &func;
Unlike locks on data, which are advisory only, subroutine locks are mandatory. No one else but the thread with the lock may enter the subroutine.

Consider the following code, which contains race conditions involving the $done variable. (The yields are for demonstration purposes only).

use Thread qw/async yield/;
my $done = 0;
sub frob {
    my $arg = shift;
    my $tid = Thread->self->tid;
    print "thread $tid: frob $arg\n";
    yield;
    unless ($done) {
        yield;
        $done++;
        frob($arg + 10);
    }
}
If you run it this way:
my @t;
for my $i (1..3) {
    push @t, Thread->new(\&frob, $i);
}
for (@t) { $_->join }
print "done is $done\n";
here's the output (well, sometimes--it's not deterministic):
thread 1: frob 1
thread 2: frob 2
thread 3: frob 3
thread 1: frob 11
thread 2: frob 12
thread 3: frob 13
done is 3
However, if you run it this way:
for my $i (1..3) {
    push @t, async {
        lock &frob;
        frob($i);
    };
}
for (@t) { $_->join }
print "done is $done\n";
here's the output:
thread 1: frob 1
thread 1: frob 11
thread 2: frob 2
thread 3: frob 3
done is 1

17.2.2.4. The locked attribute

Although obeying a subroutine lock is mandatory, nothing forces anyone to lock them in the first place. You could say that the placement of the lock is advisory. But some subroutines would really like to be able to require that they be locked before being called.

The locked subroutine attribute addresses this. It's faster than calling lock &sub because it's known at compile time, not just at run time. But the behavior is the same as when we locked it explicitly earlier. The syntax is as follows:

sub frob : locked {
    # as before
}
If you have a function prototype, it comes between the name and any attributes:
sub frob ($) : locked {
    # as before
}

17.2.2.5. Locking methods

Automatic locking on a subroutine is really cool, but sometimes it's overkill. When you're invoking an object method, it doesn't generally matter if multiple methods are running simultaneously as long as they're all running on behalf of different objects. So you'd really like to lock the object that the method is being called on instead. Adding a method attribute to the subroutine definition does this:

sub frob : locked method {
    # as before
}
If called as a method, the invoking object is locked, providing serial access to that object, but allowing the method to be called on other objects. If the method isn't called on an object, the attribute still tries to do the right thing: if you call a locked method as a class method (Package->new rather than $obj->new) the package's symbol table is locked. If you call a locked method as a normal subroutine, Perl will raise an exception.

17.2.2.6. Condition variables

A condition variable allows a thread to give up the processor until some criterion is satisfied. Condition variables are meant as points of coordination between threads when you need more control than a mere lock provides. On the other hand, you don't really need more overhead than the lock provides, and condition variables are designed with this in mind. You just use ordinary locks plus ordinary conditionals. If the condition fails, then you'll have to take extraordinary measures via the cond_wait function; but we optimize for success, since in a well-designed application, we shouldn't be bottlenecking on the current condition anyway.

Besides locking and testing, the basic operations on condition variables consist of either sending or receiving a "signal" event (not a real signal in the %SIG sense). Either you suspend your own execution to wait for an event to be received, or you send an event to wake up other threads waiting for the particular condition. The Thread module provides three importable functions to do this: cond_wait, cond_signal, and cond_broadcast. These are the primitive mechanisms upon which more abstract modules like Thread::Queue and Thread::Semaphore are based. It's often more convenient to use those abstractions, when possible.

The cond_wait function takes a variable already locked by the current thread, unlocks that variable, and then blocks until another thread does a cond_signal or cond_broadcast for that same locked variable.

The variable blocked by cond_wait is relocked after cond_wait returns. If multiple threads are cond_waiting the same variable, all but one reblock because they can't regain the lock on the variable. Therefore, if you're only using cond_wait for synchronization, give up the lock as soon as possible.

The cond_signal function takes a variable already locked by the current thread and unblocks one thread that's currently in a cond_wait on that variable. If more than one thread is blocked in a cond_wait on that variable, only one is unblocked, and you can't predict which one. If no threads are blocked in a cond_wait on that variable, the event is discarded.

The cond_broadcast function works like cond_signal, but unblocks all threads blocked in a cond_wait on the locked variable, not just one. (Of course, it's still the case that only one thread can have the variable locked at a time.)

The cond_wait function is intended to be a last-resort kind of thing that a thread does only if the condition it wants isn't met. The cond_signal and cond_broadcast indicate that the condition is changing. The scheme is supposed to be this: lock, then check to see whether the condition you want is met; if it is, fine, and if it isn't, cond_wait until it is fine. The emphasis should be on avoiding blocking if at all possible. (Generally a good piece of advice when dealing with threads.)

Here's an example of passing control back and forth between two threads. Don't be fooled by the fact that the actual conditions are over on the right in statement modifiers; cond_wait is never called unless the condition we're waiting for is false.

use Thread qw(async cond_wait cond_signal);
my $wait_var = 0;
async {
    lock $wait_var;
    $wait_var = 1;
    cond_wait $wait_var  until $wait_var == 2;
    cond_signal($wait_var);
    $wait_var = 1;
    cond_wait $wait_var  until $wait_var == 2;
    $wait_var = 1;
    cond_signal($wait_var);
};

async {
    lock $wait_var;
    cond_wait $wait_var  until $wait_var == 1;
    $wait_var = 2;
    cond_signal($wait_var);
    cond_wait $wait_var  until $wait_var == 1;
    $wait_var = 2;
    cond_signal($wait_var);
    cond_wait $wait_var  until $wait_var == 1;
};

17.2.3. Other Thread Modules

Several modules are built on top of the cond_wait primitive.

17.2.3.1. Queues

The standard Thread::Queue module provides a way to pass objects between threads without worrying about locks or synchronization. This interface is much easier:

Method | Use
new | Construct a new Thread::Queue.
enqueue | Push one or more scalars on to the end of the queue.
dequeue | Shift the first scalar off the front of the queue. The dequeue method blocks if there are no items present.

Notice how similar a queue is to a regular pipe, except that instead of sending bytes, you get to pass around full scalars, including references and blessed objects!

Here's an example derived from the perlthrtut manpage:

use Thread qw/async/;
use Thread::Queue;

my $Q = Thread::Queue->new();
async {
    while (defined($datum = $Q->dequeue)) {
       print "Pulled $datum from queue\n";
    }
};

$Q->enqueue(12);
$Q->enqueue("A", "B", "C");
$Q->enqueue($thr);
sleep 3;
$Q->enqueue(\%ENV);
$Q->enqueue(undef);
Here's what you get for output:
Pulled 12 from queue
Pulled A from queue
Pulled B from queue
Pulled C from queue
Pulled Thread=SCALAR(0x8117200) from queue
Pulled HASH(0x80dfd8c) from queue
Notice how $Q was in scope when the asynchronous thread was launched via an async closure. Threads are under the same scoping rules as anything else in Perl. The example above would not have worked had $Q been declared after the call to async.

17.2.3.2. Semaphores

Thread::Semaphore provides you with threadsafe, counting semaphore objects to implement your favorite p() and v() operations. Because most of us don't associate these operations with the Dutch words passeer ("pass") and verlaat ("leave"), the module calls these operations "down" and "up" respectively. (In some of the literature, they're called "wait" and "signal".) The following methods are supported:

Method | Use
new | Construct a new Thread::Semaphore.
down | Allocate one or more items.
up | Deallocate one or more items.

The new method creates a new semaphore and initializes its count to the specified number. If no number is specified, the semaphore's count is set to 1. (The number represents some pool of items that can "run out" if they're all allocated.)

use Thread::Semaphore;
$mutex = Thread::Semaphore->new($MAX);
The down method decreases the semaphore's count by the specified number, or by 1 if no number is given. It can be interpreted as an attempt to allocate some or all of a resource. If the semaphore's count drops below zero, this method blocks until the semaphore's count is equal to or larger than the amount you're requesting. Call it like this:
$mutex->down();
The up method increases the semaphore's count by the specified number, or 1 if no number is given. It can be interpreted as freeing up some quantity of a previously allocated resource. This unblocks at least one thread that was blocked trying to down the semaphore, provided that the up raises the semaphore count above what the down is trying to decrement it by. Call it like this:
$mutex->up();

17.2.3.3. Other standard threading modules

Thread::Signal allows you to start up a thread that is designated to receive your process's %SIG signals. This addresses the still-vexing problem that signals are unreliable as currently implemented in Perl and their imprudent use can cause occasional core dumps.

These modules are still in development and may not produce the desired results on your system. Then again, they may. If they don't, it's because someone like you hasn't fixed them yet. Perhaps someone like you should pitch in and help.

Previous | Home | Next
17.1. The Process Model | Book Index | 18. Compiling
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 18. Compiling

Contents:

The Life Cycle of a Perl Program
Compiling Your Code
Executing Your Code
Compiler Backends
Code Generators
Code Development Tools
Avant-Garde Compiler, Retro Interpreter

If you came here looking for a Perl compiler, you may be surprised to discover that you already have one--your perl program (typically /usr/bin/perl) already contains a Perl compiler. That might not be what you were thinking, and if it wasn't, you may be pleased to know that we do also provide code generators (which some well-meaning folks call "compilers"), and we'll discuss those toward the end of this chapter. But first we want to talk about what we think of as The Compiler. Inevitably there's going to be a certain amount of low-level detail in this chapter that some people will be interested in, and some people will not. If you find that you're not, think of it as an opportunity to practice your speed-reading skills.

Imagine that you're a conductor who's ordered the score for a large orchestral work. When the box of music arrives, you find several dozen booklets, one for each member of the orchestra with just their part in it. But curiously, your master copy with all the parts is missing. Even more curiously, the parts you do have are written out using plain English instead of musical notation. Before you can put together a program for performance, or even give the music to your orchestra to play, you'll first have to translate the prose descriptions into the normal system of notes and bars. Then you'll need to compile the individual parts into one giant score so that you can get an idea of the overall program.

Similarly, when you hand the source code of your Perl script over to perl to execute, it is no more useful to the computer than the English description of the symphony was to the musicians. Before your program can run, Perl needs to compile[1] these English-looking directions into a special symbolic representation. Your program still isn't running, though, because the compiler only compiles. Like the conductor's score, even after your program has been converted to an instruction format suitable for interpretation, it still needs an active agent to interpret those instructions.

[1]Or translate, or transform, or transfigure, or transmute, or transmogrify.

18.1. The Life Cycle of a Perl Program

You can break up the life cycle of a Perl program into four distinct phases, each with separate stages of its own. The first and the last are the most interesting ones, and the middle two are optional. The stages are depicted in Figure 18-1.

Figure 18.1. The life cycle of a Perl program

  1. The Compilation Phase

    During phase 1, the compile phase, the Perl compiler converts your program into a data structure called a parse tree. Along with the standard parsing techniques, Perl employs a much more powerful one: it uses BEGIN blocks to guide further compilation. BEGIN blocks are handed off to the interpreter to be run as as soon as they are parsed, which effectively runs them in FIFO order (first in, first out). This includes any use and no declarations; these are really just BEGIN blocks in disguise. Any CHECK, INIT, and END blocks are scheduled by the compiler for delayed execution.

    Lexical declarations are noted, but assignments to them are not executed. All eval BLOCKs, s///e constructs, and noninterpolated regular expressions are compiled here, and constant expressions are pre-evaluated. The compiler is now done, unless it gets called back into service later. At the end of this phase, the interpreter is again called up to execute any scheduled CHECK blocks in LIFO order (last in, first out). The presence or absence of a CHECK block determines whether we next go to phase 2 or skip over to phase 4.

  2. The Code Generation Phase (optional)

    CHECK blocks are installed by code generators, so this optional phase occurs when you explicitly use one of the code generators (described later in "Code Generators"). These convert the compiled (but not yet run) program into either C source code or serialized Perl bytecodes--a sequence of values expressing internal Perl instructions. If you choose to generate C source code, it can eventually produce a file called an executable image in native machine language.[2]

    [2] Your original script is an executable file too, but it's not machine language, so we don't call it an image. An image file is called that because it's a verbatim copy of the machine codes your CPU knows how to execute directly.

    At this point, your program goes into suspended animation. If you made an executable image, you can go directly to phase 4; otherwise, you need to reconstitute the freeze-dried bytecodes in phase 3.

  3. The Parse Tree Reconstruction Phase (optional)

    To reanimate the program, its parse tree must be reconstructed. This phase exists only if code generation occurred and you chose to generate bytecode. Perl must first reconstitute its parse trees from that bytecode sequence before the program can run. Perl does not run directly from the bytecodes; that would be slow.

  4. The Execution Phase

    Finally, what you've all been waiting for: running your program. Hence, this is also called the run phase. The interpreter takes the parse tree (which it got either directly from the compiler or indirectly from code generation and subsequent parse tree reconstruction) and executes it. (Or, if you generated an executable image file, it can be run as a standalone program since it contains an embedded Perl interpreter.)

    At the start of this phase, before your main program gets to run, all scheduled INIT blocks are executed in FIFO order. Then your main program is run. The interpreter can call back into the compiler as needed upon encountering an eval STRING, a do FILE or require statement, an s///ee construct, or a pattern match with an interpolated variable that is found to contain a legal code assertion.

    When your main program finishes, any delayed END blocks are finally executed, this time in LIFO order. The very first one seen will execute last, and then you're done. (END blocks are skipped only if you exec or your process is blown away by an uncaught catastrophic error. Ordinary exceptions are not considered catastrophic.

Now we'll discuss these phases in greater detail, and in a different order.

Previous | Home | Next
17.2. The Thread Model | Book Index | 18.2. Compiling Your Code
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.2. Compiling Your Code

Perl is always in one of two modes of operation: either it is compiling your program, or it is executing it--never both at the same time. Throughout this book, we refer to certain events as happening at compile time, or we say that "the Perl compiler does this and that". At other points, we mention that something else occurs at run time, or that "the Perl interpreter does this and that". Although you can get by with thinking of both the compiler and interpreter as simply "Perl", understanding which of these two roles Perl is playing at any given point is essential to understanding why many things happen as they do. The perl executable implements both roles: first the compiler, then the interpreter. (Other roles are possible, too; perl is also an optimizer and a code generator. Occasionally, it's even a trickster--but all in good fun.)

It's also important to understand the distinction between compile phase and compile time, and between run phase and run time. A typical Perl program gets one compile phase, and then one run phase. A "phase" is a large-scale concept. But compile time and run time are small-scale concepts. A given compile phase does mostly compile-time stuff, but it also does some run-time stuff via BEGIN blocks. A given run phase does mostly run-time stuff, but it can do compile-time stuff through operators like eval STRING.

In the typical course of events, the Perl compiler reads through your entire program source before execution starts. This is when Perl parses the declarations, statements, and expressions to make sure they're syntactically legal.[3] If it finds a syntax error, the compiler attempts to recover from the error so it can report any other errors later in the source. Sometimes this works, and sometimes it doesn't; syntax errors have a noisy tendency to trigger a cascade of false alarms. Perl bails out in frustration after about 10 errors.

[3] No, there's no formal syntax diagram like a BNF, but you're welcome to peruse the perly.y file in the Perl source tree, which contains the yacc(1) grammar Perl uses. We recommend that you stay out of the lexer, which has been known to induce eating disorders in lab rats.

In addition to the interpreter that processes the BEGIN blocks, the compiler processes your program with the connivance of three notional agents. The lexer scans for each minimal unit of meaning in your program. These are sometimes called "lexemes", but you'll more often hear them referred to as tokens in texts about programming languages. The lexer is sometimes called a tokener or a scanner, and what it does is sometimes called lexing or tokenizing. The parser then tries to make sense out of groups of these tokens by assembling them into larger constructs, such as expressions and statements, based on the grammar of the Perl language. The optimizer rearranges and reduces these larger groupings into more efficient sequences. It picks its optimizations carefully, not wasting time on marginal optimizations, because the Perl compiler has to be blazing fast when used as a load-and-go compiler.

This doesn't happen in independent stages, but all at once with a lot of cross talk between the agents. The lexer occasionally needs hints from the parser to know which of several possible token types it's looking at. (Oddly, lexical scope is one of the things the lexical analyzer doesn't understand, because that's the other meaning of "lexical".) The optimizer also needs to keep track of what the parser is doing, because some optimizations can't happen until the parse has reached a certain point, like finishing an expression, statement, block, or subroutine.

You may think it odd that the Perl compiler does all these things at once instead of one after another, but it's really just the same messy process you go through to understand natural language on the fly, while you're listening to it or reading it. You don't wait till the end of a chapter to figure out what the first sentence meant. You could think of the following correspondences:

Computer Language | Natural Language
Character | Letter
Token | Morpheme
Term | Word
Expression | Phrase
Statement | Sentence
Block | Paragraph
File | Chapter
Program | Story

Assuming the parse goes well, the compiler deems your input a valid story, er, program. If you use the -c switch when running your program, it prints out a "syntax OK" message and exits. Otherwise, the compiler passes the fruits of its efforts on to other agents. These "fruits" come in the form of a parse tree. Each fruit on the tree--or node, as it's called--represents one of Perl's internal opcodes, and the branches on the tree represent that tree's historical growth pattern. Eventually, the nodes will be strung together linearly, one after another, to indicate the execution order in which the run-time system will visit those nodes.

Each opcode is the smallest unit of executable instruction that Perl can think about. You might see an expression like $a = -($b + $c) as one statement, but Perl thinks of it as six separate opcodes. Laid out in a simplified format, the parse tree for that expression would look like Figure 18-2. The numbers represent the visitation order that the Perl run-time system will eventually follow.

Figure 18.2. Opcode visitation order of $a = -($b + $c)

Perl isn't a one-pass compiler as some might imagine. (One-pass compilers are great at making things easy for the computer and hard for the programmer.) It's really a multipass, optimizing compiler consisting of at least three different logical passes that are interleaved in practice. Passes 1 and 2 run alternately as the compiler repeatedly scurries up and down the parse tree during its construction; pass 3 happens whenever a subroutine or file is completely parsed. Here are those passes:

Pass 1: Bottom-Up Parsing

During this pass, the parse tree is built up by the yacc(1) parser using the tokens it's fed from the underlying lexer (which could be considered another logical pass in its own right). Bottom-up just means that the parser knows about the leaves of the tree before it knows about its branches and root. It really does figure things out from bottom to top in Figure 18-2, since we drew the root at the top, in the idiosyncratic fashion of computer scientists. (And linguists.)

As each opcode node is constructed, per-opcode sanity checks verify correct semantics, such as the correct number and types of arguments used to call built-in functions. As each subsection of the tree takes shape, the optimizer considers what transformations it can apply to the entire subtree now beneath it. For instance, once it knows that a list of values is being fed to a function that takes a specific number of arguments, it can throw away the opcode that records the number of arguments for functions that take a varying number of arguments. A more important optimization, known as constant folding, is described later in this section.

This pass also constructs the node visitation order used later for execution, which is a really neat trick because the first place to visit is almost never the top node. The compiler makes a temporary loop of opcodes, with the top node pointing to the first opcode to visit. When the top-level opcode is incorporated into something bigger, that loop of opcodes is broken, only to make a bigger loop with the new top node. Eventually the loop is broken for good when the start opcode gets poked into some other structure such as a subroutine descriptor. The subroutine caller can still find that first opcode despite its being way down at the bottom of the tree, as it is in Figure 18-2. There's no need for the interpreter to recurse back down the parse tree to figure out where to start.

Pass 2: Top-Down Optimizer

A person reading a snippet of Perl code (or of English code, for that matter) cannot determine the context without examining the surrounding lexical elements. Sometimes you can't decide what's really going on until you have more information. Don't feel bad, though, because you're not alone: neither can the compiler. In this pass, the compiler descends back down the subtree it's just built to apply local optimizations, the most notable of which is context propagation. The compiler marks subjacent nodes with the appropriate contexts (void, scalar, list, reference, or lvalue) imposed by the current node. Unwanted opcodes are nulled out but not deleted, because it's now too late to reconstruct the execution order. We'll rely on the third pass to remove them from the provisional execution order determined by the first pass.

Pass 3: Peephole Optimizer

Certain units of code have their own storage space in which they keep lexically scoped variables. (Such a space is called a scratchpad in Perl lingo.) These units include eval STRINGs, subroutines, and entire files. More importantly from the standpoint of the optimizer, they each have their own entry point, which means that while we know the execution order from here on, we can't know what happened before, because the construct could have been called from anywhere. So when one of these units is done being parsed, Perl runs a peephole optimizer on that code. Unlike the previous two passes, which walked the branch structure of the parse tree, this pass traverses the code in linear execution order, since this is basically the last opportunity to do so before we cut the opcode list off from the parser. Most optimizations were already performed in the first two passes, but some can't be.

Assorted late-term optimizations happen here, including stitching together the final execution order by skipping over nulled out opcodes, and recognizing when various opcode juxtapositions can be reduced to something simpler. The recognition of chained string concatenations is one important optimization, since you'd really like to avoid copying a string back and forth each time you add a little bit to the end. This pass doesn't just optimize; it also does a great deal of "real" work: trapping barewords, generating warnings on questionable constructs, checking for code unlikely to be reached, resolving pseudohash keys, and looking for subroutines called before their prototypes had been compiled.

Pass 4: Code Generation

This pass is optional; it isn't used in the normal scheme of things. But if any of the three code generators--B::Bytecode, B::C, and B::CC--are invoked, the parse tree is accessed one final time. The code generators emit either serialized Perl bytecodes used to reconstruct the parse tree later or literal C code representing the state of the compile-time parse tree.

Generation of C code comes in two different flavors. B::C simply reconstructs the parse tree and runs it using the usual runops() loop that Perl itself uses during execution. B::CC produces a linearized and optimized C equivalent of the run-time code path (which resembles a giant jump table) and executes that instead.

During compilation, Perl optimizes your code in many, many ways. It rearranges code to make it more efficient at execution time. It deletes code that can never be reached during execution, like an if (0) block, or the elsifs and the else in an if (1) block. If you use lexically typed variables declared with my ClassName $var or our ClassName $var, and the ClassName package was set up with the use fields pragma, accesses to constant fields from the underlying pseudohash are typo-checked at compile time and converted into array accesses instead. If you supply the sort operator with a simple enough comparison routine, such as {$a <=> $b} or {$b cmp $a}, this is replaced by a call to compiled C code.

Perl's most dramatic optimization is probably the way it resolves constant expressions as soon as possible. For example, consider the parse tree shown in Figure 18-2. If nodes 1 and 2 had both been literals or constant functions, nodes 1 through 4 would have been replaced by the result of that computation, something like Figure 18-3.

Figure 18.3. Constant folding

This is called constant folding. Constant folding isn't limited to simple cases such as turning 2**10 into 1024 at compile time. It also resolves function calls--both built-ins and user-declared subroutines that meet the criteria from the section Section 18.4.1, "Inlining Constant Functions" in Chapter 6, "Subroutines". Reminiscent of FORTRAN compilers' notorious knowledge of their own intrinsic functions, Perl also knows which of its own built-ins to call during compilation. That's why if you try to take the log of 0.0 or the sqrt of a negative constant, you'll incur a compilation error, not a run-time error, and the interpreter is never run at all.[4]

[4] Actually, we're oversimplifying here. The interpreter does get run, because that's how the constant folder is implemented. But it is run immediately at compile time, similar to how BEGIN blocks are executed.

Even arbitrarily complicated expressions are resolved early, sometimes triggering the deletion of complete blocks such as the one here:

if (2 * sin(1)/cos(1) < 3 && somefn()) { whatever() }
No code is generated for what can never be evaluated. Because the first part is always false, neither somefn nor whatever can ever be called. (So don't expect to goto labels inside that block, because it won't even exist at run time.) If somefn were an inlinable constant function, then even switching the evaluation order like this:
if (somefn() && 2 * sin(1)/cos(1) < 3)) { whatever() }
wouldn't change the outcome, since the entire expression still resolves at compile time. If whatever were inlinable, it wouldn't be called at run time, nor even during compilation; its value would just be inserted as though it were a literal constant. You would then incur a warning about a "Useless use of a constant in void context". This might surprise you if you didn't realize it was a constant. However, if whatever were the last statement evaluated in a function called in a nonvoid context (as determined by the optimizer), you wouldn't see the warning.

You can see the final result of the constructed parse tree after all optimization stages with perl -Dx. (The -D switch requires a special, debugging-enabled build of Perl). Also see the section on B::Deparse described below.

All in all, the Perl compiler works hard (but not too hard) to optimize code so that, come run time, overall execution is sped up. It's about time to get your program running, so let's do that now.

Previous | Home | Next
18.1. The Life Cycle of a Perl Program | Book Index | 18.3. Executing Your Code
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.3. Executing Your Code

To the first approximation, Sparc programs only run on Sparc machines, Intel programs only run on Intel machines, and Perl programs only run on Perl machines. A Perl machine possesses those attributes that a Perl program would find ideal in a computer: memory that is automatically allocated and deallocated, fundamental data types that are dynamic strings, arrays, and hashes, and have no size limits, and systems that all behave pretty much the same way. The job of the Perl interpreter is to make whatever computer it happens to be running on appear to be one of these idealistic Perl machines.

This fictitious machine presents the illusion of a computer specially designed to do nothing but run Perl programs. Each opcode produced by the compiler is a fundamental command in this emulated instruction set. Instead of a hardware program counter, the interpreter just keeps track of the current opcode to execute. Instead of a hardware stack pointer, the interpreter has its own virtual stack. This stack is very important because the Perl virtual machine (which we refuse to call a PVM) is a stack-based machine. Perl opcodes are internally called PP codes (short for "push-pop codes") because they manipulate the interpreter's virtual stack to find all operands, process temporary values, and store all results.

If you've ever programmed in Forth or PostScript, or used an HP scientific calculator with RPN ("Reverse Polish Notation") entry, you know how a stack machine works. Even if you haven't, the concept is simple: to add 3 and 4, you do things in the order 3 4 + instead of the more conventional 3 + 4. What this means in terms of the stack is that you push 3 and then 4 onto the stack, and + then pops both arguments off the stack, adds them, and pushes 7 back onto the stack, where it will sit until you do something else with it.

Compared with the Perl compiler, the Perl interpreter is a straightforward, almost boring, program. All it does is step through the compiled opcodes, one at a time, and dispatch them to the Perl run-time environment, that is, the Perl virtual machine. It's just a wad of C code, right?

Actually, it's not boring at all. A Perl virtual machine keeps track of a great deal of dynamic context on your behalf so that you don't have to. Perl maintains quite a few stacks, which you don't have to understand, but which we'll list here anyway just to impress you:

operand stack

That's the stack we already talked about.

save stack

Where localized values are saved pending restoration. Many internal routines also localize values without your knowing it.

scope stack

The lightweight dynamic context that controls when the save stack should be "popped".

context stack

The heavyweight dynamic context; who called whom to get where you are now. The caller function traverses this stack. Loop-control functions scan this stack to find out which loop to control. When you peel back the context stack, the scope stack gets peeled back appropriately, which restores all your local variables from the save stack, even if you left the earlier context by nefarious methods such as raising an exception and longjmp(3)ing out.

jumpenv stack

The stack of longjmp(3) contexts that allows us to raise exceptions or exit expeditiously.

return stack

Where we came from when we entered this subroutine.

mark stack

Where the current variadic argument list on the operand stack starts.

recursive lexical pad stacks

Where the lexical variables and other "scratch register" storage is kept when subroutines are called recursively.

And of course, there's the C stack on which all the C variables are stored. Perl actually tries to avoid relying on C's stack for the storage of saved values, since longjmp(3) bypasses the proper restoration of such values.

All this is to say that the usual view of an interpreter, a program that interprets another program, is really woefully inadequate to describe what's going on here. Yes, there's some C code implementing some opcodes, but when we say "interpreter", we mean something more than that, in the same way that when we say "musician", we mean something more than a set of DNA instructions for turning notes into sounds. Musicians are real, live organisms and have "state". So do interpreters.

Specifically, all this dynamic and lexical context, along with the global symbol tables, plus the parse trees, plus a thread of execution, is what we call an interpreter. As a context for execution, an interpreter really starts its existence even before the compiler starts, and can run in rudimentary form even as the compiler is building up the interpreter's context. In fact, that's precisely what's happening when the compiler calls into the interpreter to execute BEGIN blocks and such. And the interpreter can turn around and use the compiler to build itself up further. Every time you define another subroutine or load another module, the particular virtual Perl machine we call an interpreter is redefining itself. You can't really say that either the compiler or the interpreter is in control, because they're cooperating to control the bootstrap process we commonly call "running a Perl script". It's like bootstrapping a child's brain. Is it the DNA doing it or is it the neurons? A little of both, we think, with some input from external programmers.

It's possible to run multiple interpreters in the same process; they may or may not share parse trees, depending on whether they were started by cloning an existing interpreter or by building a new interpreter from scratch. It's also possible to run multiple threads in a single interpreter, in which case they share not only parse trees but also global symbols--see Chapter 17, "Threads".

But most Perl programs use only a single Perl interpreter to execute their compiled code. And while you can run multiple, independent Perl interpreters within one process, the current API for this is only accessible from C.[5] Each individual Perl interpreter serves the role of a completely separate process, but doesn't cost as much to create as a whole new process does. That's how Apache's mod_perl extension gets such great performance: when you launch a CGI script under mod_perl, that script has already been compiled into Perl opcodes, eliminating the need for recompilation--but more importantly, eliminating the need to start a new process, which is the real bottleneck. Apache initializes a new Perl interpreter in an existing process and hands that interpreter the previously compiled code to execute. Of course, there's much more to it than that--there always is. For more about mod_perl, see Writing Apache Modules with Perl and C (O'Reilly, 1999).

[5] With one exception, so far: revision 5.6.0 of Perl can do cloned interpreters in support of fork emulation on Microsoft Windows. There may well be a Perl API to "ithreads", as they're called, by the time you read this.

Many other applications such as nvi, vim, and innd can embed Perl interpreters; we can't hope to list them all here. There are a number of commercial products that don't even advertise that they have embedded Perl engines. They just use it internally because it gets their job done in style.

Previous | Home | Next
18.2. Compiling Your Code | Book Index | 18.4. Compiler Backends
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.4. Compiler Backends

So, if Apache can compile a Perl program now and execute it later, why can't you? Apache and other programs that contain embedded Perl interpreters have it easy--they never store the parse tree to an external file. If you're content with that approach, and don't mind using the C API to get at it, you can do the same thing. See the section Section 18.4, "Embedding Perl (Using Perl from C)" in Chapter 21, "Internals and Externals", to learn how to access Perl from an enclosing C framework.

If you don't want to go that route, or have other needs, then there are a few options available. Instead of feeding the opcode output from the Perl compiler immediately into a Perl interpreter, you can invoke any of several alternative backends instead. These backends can serialize and store the compiled opcodes to an external file or even convert them into a couple different flavors of C code.

Please be aware that the code generators are all extremely experimental utilities that shouldn't be expected to work in a production environment. In fact, they shouldn't even be expected to work in a nonproduction environment except maybe once in a blue moon. Now that we've set your expectations low enough that any success at all will necessarily surpass them, it's safe to tell you how the backends work.

Some of the backend modules are code generators, like
B::Bytecode, B::C, and
B::CC.  Others are really code-analysis and
debugging tools, like B::Deparse,
B::Lint, and B::Xref.  Beyond
those backends, the standard release includes several other low-level
modules of potential interest to would-be authors of Perl
code-development tools.  Other backend modules can be found on CPAN,
including (as of this writing) B::Fathom,
B::Graph, B::JVM::Jasmin, and
B::Size.

When you're using the Perl compiler for anything other than feeding the interpreter, the O module (that is, using the O.pm file) stands between the compiler and assorted backend modules. You don't call the backends directly; instead, you call the middle end, which in turn calls the designated backend. So, if you had a module called B::Backend, you would invoke it on a given script this way:

% perl -MO=Backend SCRIPTNAME
Some backends take options, specified as:
% perl -MO=Backend,OPTS SCRIPTNAME
Some backends already have their own frontends to invoke their middle ends for you so you don't have to remember their M.O. In particular, perlcc(1) invokes that code generator, which can be cumbersome to fire up.

Previous | Home | Next
18.3. Executing Your Code | Book Index | 18.5. Code Generators
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.5. Code Generators

The three current backends that convert Perl opcodes into some other format are all emphatically experimental. (Yes, we said this before, but we don't want you to forget.) Even when they happen to produce output that runs correctly, the resulting programs may take more disk space, more memory, and more CPU time than than they would ordinarily. This is an area of ongoing research and development. Things will get better.

18.5.1. The Bytecode Generator

The B::Bytecode module writes the parse tree's opcodes out in a platform-independent encoding. You can take a Perl script compiled down to bytecodes and copy that to any other machine with Perl installed on it.

The standard but currently experimental perlcc(1) command knows how to convert Perl source code into a byte-compiled Perl program. All you have to do is:

% perlcc -b -o pbyscript srcscript
And now you should be able to directly "execute" the resulting pbyscript. The start of that file looks somewhat like this:
#!/usr/bin/perl
use ByteLoader 0.03;
^C^@^E^A^C^@^@^@^A^F^@^C^@^@^@^B^F^@^C^@^@^@^C^F^@^C^@^@^@
B^@^@^@^H9^A8M-^?M-^?M-^?M-^?7M-^?M-^?M-^?M-^?6^@^@^@^A6^@
^G^D^D^@^@^@^KR^@^@^@^HS^@^@^@^HV^@M-2W<^FU^@^@^@^@X^Y@Z^@
...
There you find a small script header followed by purely binary data. This may seem like deep magic, but its dweomer, er, dwimmer is at most a minor one. The ByteLoader module uses a technique called a source filter to alter the source code before Perl gets a chance to see it. A source filter is a kind of preprocessor that applies to everything below it in the current file. Instead of being limited to simplistic transformations the way macro processors like cpp(1) and m4(1) are, here there are no constraints. Source filters have been used to augment Perl's syntax, to compress or encrypt source code, even to write Perl programs in Latin. E perlibus unicode; cogito, ergo substr; carp dbm, et al. Er, caveat scriptor.

The ByteLoader module is a source filter that knows how to disassemble the serialized opcodes produced by B::Bytecode to reconstruct the original parse tree. The reconstituted Perl code is spliced into the current parse tree without using the compiler. When the interpreter hits those opcodes, it just executes them as though they'd been there waiting for it all along.

18.5.2. The C Code Generators

The remaining code generators, B::C and B::CC, both produce C code instead of serialized Perl opcodes. The code they generate is far from readable, and if you try to read it you'll just go blind. It's not something you can use to plug little translated Perl-to-C bits into a larger C program. For that, see Chapter 21, "Internals and Externals".

The B::C module just writes out the C data structures needed to recreate the entire Perl run-time environment. You get a dedicated interpreter with all the compiler-built data structures pre-initialized. In some senses, the code generated is like what B::Bytecode produces. Both are a straight translation of the opcode trees that the compiler built, but where B::Bytecode lays them out in symbolic form to be recreated later and plugged into a running Perl interpreter, B::C lays those opcodes down in C. When you compile this C code with your C compiler and link in the Perl library, the resulting program won't need a Perl interpreter installed on the target system. (It might need some shared libraries, though, if you didn't link everything statically.) However, this program isn't really any different than the regular Perl interpreter that runs your script. It's just precompiled into a standalone executable image.

The B::CC module, however, tries to do more than that. The beginning of the C source file it generates looks pretty much like what B::C produced,[6] but eventually, any similarity ends. In the B::C code, you have a big opcode table in C that's manipulated just as the interpreter would do on its own, whereas in the C code generated by B::CC is laid out in the order corresponding to the run-time flow of your program. It even has a C function corresponding to each function in your program. Some amount of optimization based on variable types is done; a few benchmarks can run twice as fast as in the standard interpreter. This is the most ambitious of the current code generators, the one that holds the greatest promise for the future. By no coincidence, it is also the least stable of the three.

[6]But then, so does everything once you've gone blind. Didn't we warn you not to peek?

Computer science students looking for graduate thesis projects need look no further. There are plenty of diamonds in the rough waiting to be polished off here.

Previous | Home | Next
18.4. Compiler Backends | Book Index | 18.6. Code Development Tools
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.6. Code Development Tools

The O module has many interesting Modi Operandi beyond feeding the exasperatingly experimental code generators. By providing relatively painless access to the Perl compiler's output, this module makes it easy to build other tools that need to know everything about a Perl program.

The B::Lint module is named after lint(1), the C program verifier. It inspects programs for questionable constructs that often trip up beginners but don't normally trigger warnings. Call the module directly:

% perl -MO=Lint,all myprog
Only a few checks are currently defined, such as using an array in an implicit scalar context, relying on default variables, and accessing another package's (nominally private) identifiers that start with _. See B::Lint(3) for details.

The B::Xref module generates cross-reference listings of the declaration and use of all variables (both global and lexically scoped), subroutines, and formats in a program, broken down by file and subroutine. Call the module this way:

% perl -MO=Xref myprog > myprof.pxref
For instance, here's a partial report:
Subroutine parse_argv
  Package (lexical)
    $on               i113, 114
    $opt              i113, 114
    %getopt_cfg       i107, 113
    @cfg_args         i112, 114, 116, 116
  Package Getopt::Long
    $ignorecase       101
    &GetOptions       &124
  Package main
    $Options          123, 124, 141, 150, 165, 169
    %$Options         141, 150, 165, 169
    &check_read       &167
    @ARGV             121, 157, 157, 162, 166, 166
This shows that the parse_argv subroutine had four lexical variables of its own; it also accessed global identifiers from both the main package and from Getopt::Long. The numbers are the lines where that item was used: a leading i indicates that the item was first introduced at the following line number, and a leading & means a subroutine was called there. Dereferences are listed separately, which is why both $Options and %$Options are shown.

The B::Deparse is a pretty printer that can demystify Perl code and help you understand what transformations the optimizer has taken with your code. For example, this shows what defaults Perl uses for various constructs:

% perl -MO=Deparse -ne 'for (1 .. 10) { print if -t }'
LINE: while (defined($_ = <ARGV>)) {
    foreach $_ (1 .. 10) {
        print $_ if -t STDIN;
    }
}
The -p switch adds parentheses so you can see Perl's idea of precedence:
% perl -MO=Deparse,-p -e 'print $a ** 3 + sqrt(2) / 10 ** -2 ** $c'
print((($a ** 3) + (1.4142135623731 / (10 ** (-(2 ** $c))))));
You can use -q to see what primitives interpolated strings are compiled into:
% perl -MO=Deparse,-q -e '"A $name and some @ARGV\n"'
'A ' . $name . ' and some ' . join($", @ARGV) . "\n";
And this shows how Perl really compiles a three-part for loop into a while loop:
% perl -MO=Deparse -e 'for ($i=0;$i<10;$i++) { $x++ }'
$i = 0;
while ($i < 10) {
    ++$x;
}
continue {
    ++$i
}
You could even call B::Deparse on a Perl bytecode file produced by perlcc -b, and have it decompile that binary file for you. Serialized Perl opcodes may be a tad tough to read, but strong encryption they are not.

Previous | Home | Next
18.5. Code Generators | Book Index | 18.7. Avant-Garde Compiler, Retro Interpreter
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


18.7. Avant-Garde Compiler, Retro Interpreter

There's a right time to think about everything; sometimes that time is beforehand, and sometimes it's after. Sometimes it's somewhere in the middle. Perl doesn't presume to know when it's the right time to think, so it gives the programmer a number of options for telling it when to think. Other times it knows that some sort of thinking is necessary but doesn't have any idea what it ought to think, so it needs ways of asking your program. Your program answers these kinds of questions by defining subroutines with names appropriate to what Perl is trying to find out.

Not only can the compiler call into the interpreter when it wants to be forward thinking, but the interpreter can also call back to the compiler when it wants to revise history. Your program can use several operators to call back into the compiler. Like the compiler, the interpreter can also call into named subroutines when it wants to find things out. Because of all this give and take between the compiler, the interpreter, and your program, you need to be aware of what things happen when. First we'll talk about when these named subroutines are triggered.

In Chapter 10, "Packages", we saw how a package's AUTOLOAD subroutine is triggered when an undefined function in that package is called. In Chapter 12, "Objects", we met the DESTROY method which is invoked when an object's memory is about to be automatically reclaimed by Perl. And in Chapter 14, "Tied Variables", we encountered the many functions implicitly called when a tied variable is accessed.

These subroutines all follow the convention that, if a subroutine is triggered automatically by either the compiler or the interpreter, we write its name in uppercase. Associated with the different stages of your program's lifetime are four other such subroutines, named BEGIN, CHECK, INIT, and END. The sub keyword is optional before their declarations. Perhaps they are better called "blocks", because they're in some ways more like named blocks than real subroutines.

For instance, unlike regular subroutines, there's no harm in declaring these blocks multiple times, since Perl keeps track of when to call them, so you never have to call them by name. (They are also unlike regular subroutines in that shift and pop act as though you were in the main program, and so they act on @ARGV by default, not @_.)

These four block types run in this order:

BEGIN

Runs ASAP (as soon as parsed) whenever encountered during compilation, before compiling the rest of the file.

CHECK

Runs when compilation is complete, but before the program starts. (CHECK can mean "checkpoint" or "double-check" or even just "stop".)

INIT

Runs at the beginning of execution right before the main flow of your program starts.

END

Runs at the end of execution right after the program finishes.

If you declare more than one of these by the same name, even in separate modules, the BEGINs all run before any CHECKs, which all run before any INITs, which all run before any ENDs--which all run dead last, after your main program has finished. Multiple BEGINs and INITs run in declaration order (FIFO), and the CHECKs and ENDs run in inverse declaration order (LIFO).

This is probably easiest to see in a demo:

#!/usr/bin/perl -l
print       "start main running here";
die         "main now dying here\n";
die         "XXX: not reached\n";
END         { print "1st END: done running"   }
CHECK       { print "1st CHECK: done compiling" }
INIT        { print "1st INIT: started running"  }
END         { print "2nd END: done running"   }
BEGIN       { print "1st BEGIN: still compiling" }
INIT        { print "2nd INIT: started running"  }
BEGIN       { print "2nd BEGIN: still compiling" }
CHECK       { print "2nd CHECK: done compiling" }
END         { print "3rd END: done running"   }
When run, that demo program produces this output:
1st BEGIN: still compiling
2nd BEGIN: still compiling
2nd CHECK: done compiling
1st CHECK: done compiling
1st INIT: started running
2nd INIT: started running
start main running here
main now dying here
3rd END: done running
2nd END: done running
1st END: done running
Because a BEGIN block executes immediately, it can pull in subroutine declarations, definitions, and importations before the rest of the file is even compiled. These can alter how the compiler parses the rest of the current file, particularly if you import subroutine definitions. At the very least, declaring a subroutine lets it be used as a list operator, making parentheses optional. If the imported subroutine is declared with a prototype, calls to it can be parsed like built-ins and can even override built-ins of the same name in order to give them different semantics. The use declaration is just a BEGIN block with an attitude.

END blocks, by contrast, are executed as late as possible: when your program exits the Perl interpreter, even if as a result of an untrapped die or other fatal exception. There are two situations in which an END block (or a DESTROY method) is skipped. It isn't run if, instead of exiting, the current process just morphs itself from one program to another via exec. A process blown out of the water by an uncaught signal also skips its END routines. (See the use sigtrap pragma described in Chapter 31, "Pragmatic Modules", for an easy way to convert catchable signals into exceptions. For general information on signal handling, see "Signals" in Chapter 16, "Interprocess Communication".) To avoid all END processing, you can call POSIX::_exit, say kill -9, $$, or just exec any innocuous program, such as /bin/true on Unix systems.

Inside an END block, $? contains the status the program is going to exit with. You can modify $? from within the END block to change the exit value of the program. Beware of changing $? accidentally by running another program with system or backticks.

If you have several END blocks within a file, they execute in reverse order of their definition. That is, the last END block defined is the first one executed when your program finishes. This reversal enables related BEGIN and END blocks to nest the way you'd expect, if you pair them up. For example, if the main program and a module it loads both have their own paired BEGIN and END subroutines, like so:

BEGIN { print "main begun" }
END { print "main ended" }
use Module;
and in that module, these declarations:
BEGIN { print "module begun" }
END { print "module ended" }
then the main program knows that its BEGIN will always happen first, and its END will always happen last. (Yes, BEGIN is really a compile-time block, but similar arguments apply to paired INIT and END blocks at run time.) This principle is recursively true for any file that includes another when both have declarations like these. This nesting property makes these blocks work well as package constructors and destructors. Each module can have its own set-up and tear-down functions that Perl will call automatically. This way the programmer doesn't have to remember that if a particular library is used, what special initialization or clean-up code ought to be invoked, and when. The module's declarations assure these events.

If you think of an eval STRING as a call back from the interpreter to the compiler, then you might think of a BEGIN as a call forward from the compiler into the interpreter. Both temporarily put the current activity on hold and switch modes of operation. When we say that a BEGIN block is executed as early as possible, we mean it's executed just as soon as it is completely defined, even before the rest of the containing file is parsed. BEGIN blocks are therefore executed during compile time, never during run time. Once a BEGIN block has run, it is immediately undefined and any code it used is returned to Perl's memory pool. You couldn't call a BEGIN block as a subroutine even if you tried, because by the time it's there, it's already gone.

Similar to BEGIN blocks, INIT blocks are run just before the Perl run time begins execution, in "first in, first out" (FIFO) order. For example, the code generators documented in perlcc make use of INIT blocks to initialize and resolve pointers to XSUBs. INIT blocks are really just like BEGIN blocks, except they let the programmer distinguish construction that must happen at compile phase from construction that must happen at run phase. When you're running a script directly, that's not terribly important because the compiler gets invoked every time anyway; but when compilation is separate from execution, the distinction can be crucial. The compiler may only be invoked once, and the resulting executable may be invoked many times.

Similar to END blocks, CHECK blocks are run just after the Perl compile phase ends but before run phase begins, in LIFO order. CHECK blocks are useful for "winding down" the compiler just as END blocks are useful for winding down your program. In particular, the backends all use CHECK blocks as the hook from which to invoke their respective code generators. All they need to do is put a CHECK block into their own module, and it will run at the right time, so you don't have to install a CHECK into your program. For this reason, you'll rarely write a CHECK block yourself, unless you're writing such a module.

Putting it all together, Table 18-1 lists various constructs with details on when they compile and when they run the code represented by "...".

Table 18.1. What Happens When

Block | Compiles | Traps | Runs | Traps | Call
or | During | Compile | During | Run | Trigger
Expression | Phase | Errors | Phase | Errors | Policy
use ... | C | No | C | No | Now
no ... | C | No | C | No | Now
BEGIN {...} | C | No | C | No | Now
CHECK {...} | C | No | C | No | Late
INIT {...} | C | No | R | No | Early
END {...} | C | No | R | No | Late
eval {...} | C | No | R | Yes | Inline
eval "..." | R | Yes | R | Yes | Inline
foo(...) | C | No | R | No | Inline
sub foo {...} | C | No | R | No | Call anytime
eval "sub {...}" | R | Yes | R | No | Call later
s/pat/.../e | C | No | R | No | Inline
s/pat/"..."/ee | R | Yes | R | Yes | Inline

Now that you know the score, we hope you'll be able to compose and perform your Perl pieces with greater confidence.

Previous | Home | Next
18.6. Code Development Tools | Book Index | 19. The Command-Line Interface
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 19. The Command-Line Interface

Contents:

Command Processing
Environment Variables

This chapter is about aiming Perl in the right direction before you fire it off. There are various ways to aim Perl, but the two primary ways are through switches on the command line and through environment variables. Switches are the more immediate and precise way to aim a particular command. Environment variables are more often used to set general policy.

19.1. Command Processing

It is fortunate that Perl grew up in the Unix world, because that means its invocation syntax works pretty well under the command interpreters of other operating systems, too. Most command interpreters know how to deal with a list of words as arguments and don't care if an argument starts with a minus sign. There are, of course, some sticky spots where you'll get fouled up if you move from one system to another. You can't use single quotes under MS-DOS as you do under Unix, for instance. And on systems like VMS, some wrapper code has to jump through hoops to emulate Unix I/O redirection. Wildcard interpretation is a wildcard. Once you get past those issues, however, Perl treats its switches and arguments much the same on any operating system.

Even when you don't have a command interpreter per se, it's easy to execute a Perl program from another program written in any language. Not only can the calling program pass arguments in the ordinary way, it can also pass information via environment variables and, if your operating system supports them, inherited file descriptors (see "Passing Filehandles" in Chapter 16, "Interprocess Communication". Even exotic argument-passing mechanisms can easily be encapsulated in a module, then brought into your Perl program via a simple use directive.

Perl parses command-line switches in the standard fashion.[1] That is, it expects any switches (words beginning with a minus) to come first on the command line. After that usually comes the name of the script, followed by any additional arguments to be passed into the script. Some of these additional arguments may themselves look like switches, but if so, they must be processed by the script, because Perl quits parsing switches as soon as it sees a nonswitch, or the special "--" switch that says, "I am the last switch."

[1] Presuming you agree that Unix is both standard and fashionable.

Perl gives you some flexibility in where you place the source code for your program. For small, quick-and-dirty jobs, you can program Perl entirely from the command line. For larger, more permanent jobs, you can supply a Perl script as a separate file. Perl looks for a script to compile and run in any one of these three ways:

  1. Specified line by line via -e switches on the command line. For example:

    % perl -e "print 'Hello, World.'"
Hello, World.

  2. Contained in the file specified by the first filename on the command line. Systems supporting the #! notation on the first line of an executable script invoke interpreters this way on your behalf.

  3. Passed in implicitly via standard input. This method works only when there are no filename arguments; to pass arguments to a standard-input script you must use method 2, explicitly specifying a "-" for the script name. For example:

    % echo "print qq(Hello, @ARGV.)" | perl - World
Hello, World.

With methods 2 and 3, Perl starts parsing the input file from the beginning--unless you've specified a -x switch, in which case it scans for the first line starting with #! and containing the word "perl", and starts there instead. This is useful for running a script embedded in a larger message. If so, you might indicate the end of the script using the __END__ token.

Whether or not you use -x, the #! line is always examined for switches when the line is parsed. That way, if you're on a platform that allows only one argument with the #! line, or worse, doesn't even recognize the #! line as special, you can still get consistent switch behavior regardless of how Perl was invoked, even if -x was used to find the beginning of the script.

Warning: because older versions of Unix silently chop off kernel interpretation of the #! line after 32 characters, some switches may end up getting to your program intact, and others not; you could even get a "-" without its letter, if you're not careful. You probably want to make sure that all your switches fall either before or after that 32-character boundary. Most switches don't care whether they're processed redundantly, but getting a "-" instead of a complete switch would cause Perl to try to read its source code from the standard input instead of from your script. And a partial -I switch could also cause odd results. However, some switches do care if they are processed twice, like combinations of -l and -0. Either put all the switches after the 32-character boundary (if applicable), or replace the use of -0 DIGITS with BEGIN{ $/ = "\0 DIGITS"; }. Of course, if you're not on a Unix system, you're guaranteed not to have this particular problem.

Parsing of #! switches starts from where "perl" is first mentioned in the line. The sequences "-*" and "- " are specifically ignored for the benefit of emacs users, so that, if you're so inclined, you can say:

#!/bin/sh -- # -*- perl -*- -p
eval 'exec perl -S $0 ${1+"$@"}'
    if 0;

and Perl will see only the -p switch. The fancy "-*- perl -*-" gizmo tells emacs to start up in Perl mode; you don't need it if you don't use emacs. The -S mess is explained later under the description of that switch.

A similar trick involves the env(1) program, if you have it:

#!/usr/bin/env perl
The previous examples use a relative path to the Perl interpreter, getting whatever version is first in the user's path. If you want a specific version of Perl, say, perl5.6.1, place it directly in the #! line's path, whether with the env program, with the -S mess, or with a regular #! processing.

If the #! line does not contain the word "perl", the program named after the #! is executed instead of the Perl interpreter. For example, suppose you have an ordinary Bourne shell script out there that says:

#!/bin/sh
echo "I am a shell script"

If you feed that file to Perl, then Perl will run /bin/sh for you. This is slightly bizarre, but it helps people on machines that don't recognize #!, because--by setting their SHELL environment variable--they can tell a program (such as a mailer) that their shell is /usr/bin/perl, and Perl will then dispatch the program to the correct interpreter for them, even though their kernel is too stupid to do so.

But back to Perl scripts that are really Perl scripts. After locating your script, Perl compiles the entire program into an internal form (see Chapter 18, "Compiling"). If any compilation errors arise, execution does not even begin. (This is unlike the typical shell script or command file, which might run part-way through before finding a syntax error.) If the script is syntactically correct, it is executed. If the script runs off the end without hitting an exit or die operator, an implicit exit(0) is supplied by Perl to indicate successful completion to your caller. (This is unlike the typical C program, where you're likely to get a random exit status if your program just terminates in the normal way.)

19.1.1. #! and Quoting on Non-Unix Systems

Unix's #! technique can be simulated on other systems:

Macintosh

A Perl program on a Macintosh will have the appropriate Creator and Type, so that double-clicking them will invoke the Perl application.

MS-DOS

Create a batch file to run your program, and codify it in ALTERNATIVE_SHEBANG. See the dosish.h file in the top level of the Perl source distribution for more information about this.

OS/2

Put this line:

extproc perl -S -your_switches
as the first line in *.cmd file (-S works around a bug in cmd.exe's "extproc" handling).

VMS

Put these lines:

% perl -mysw 'f$env("procedure")' 'p1' 'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8' !
$ exit++ + ++$status != 0 and $exit = $status = undef;
at the top of your program, where -mysw are any command-line switches you want to pass to Perl. You can now invoke the program directly by typing perl program, as a DCL procedure by saying @program, or implicitly via DCL$PATH by using just the name of the program. This incantation is a bit much to remember, but Perl will display it for you if you type in perl "-V:startperl". If you can't remember that--well, that's why you bought this book.

Win??

When using the ActiveState distribution of Perl under some variant of Microsoft's Windows suite of operating systems (that is, Win95, Win98, Win00,[2] WinNT, but not Win3.1), the installation procedure for Perl modifies the Windows Registry to associate the .pl extension with the Perl interpreter.

[2]Er, pardon the technical difficulties...

If you install another port of Perl, including the one in the Win32 directory of the Perl distribution, then you'll have to modify the Windows Registry yourself.

Note that using a .pl extension means you can no longer tell the difference between an executable Perl program and a "perl library" file. You could use .plx for a Perl program instead to avoid this. This is much less of an issue these days, since most Perl modules are now in .pm files.

Command interpreters on non-Unix systems often have extraordinarily different ideas about quoting than Unix shells have. You'll need to learn the special characters in your command interpreter (*, \, and " are common) and how to protect whitespace and these special characters to run one-liners via the -e switch. You might also have to change a single % to a %%, or otherwise escape it, if that's a special character for your shell.

On some systems, you may have to change single quotes to double quotes. But don't do that on Unix or Plan9 systems, or anything running a Unix-style shell, such as systems from the MKS Toolkit or from the Cygwin package produced by the Cygnus folks, now at Redhat. Microsoft's new Unix emulator called Interix is also starting to look, ahem, interixing.

For example, on Unix and Mac OS X, use:

% perl -e 'print "Hello world\n"'

On Macintosh (pre Mac OS X), use:

print "Hello world\n"

then run "Myscript" or Shift-Command-R.

On VMS, use:

$ perl -e "print ""Hello world\n"""

or again with qq//:

$ perl -e "print qq(Hello world\n)"

And on MS-DOS et al., use:

A:> perl -e "print \"Hello world\n\""

or use qq// to pick your own quotes:

A:> perl -e "print qq(Hello world\n)"

The problem is that neither of those is reliable: it depends on the command interpreter you're using there. If 4DOS were the command shell, this would probably work better:

perl -e "print <Ctrl-x>"Hello world\n<Ctrl-x>""
The CMD.EXE program seen on Windows NT seems to have slipped a lot of standard Unix shell functionality in when nobody was looking, but just try to find documentation for its quoting rules.

On the Macintosh,[3] all this depends on which environment you are using. The MacPerl shell, or MPW, is much like Unix shells in its support for several quoting variants, except that it makes free use of the Macintosh's non-ASCII characters as control characters.

[3]At least, prior to release of Mac OS X, which, happily enough, is a BSD-derived system.

There is no general solution to all of this. It's just a mess. If you aren't on a Unix system but want to do command-line things, your best bet is to acquire a better command interpreter than the one your vendor supplied you, which shouldn't be too hard.

Or just write it all in Perl, and forget the one-liners.

19.1.2. Location of Perl

Although this may seem obvious, Perl is useful only when users can easily find it. When possible, it's good for both /usr/bin/perl and /usr/local/bin/perl to be symlinks to the actual binary. If that can't be done, system administrators are strongly encouraged to put Perl and its accompanying utilities into a directory typically found along a user's standard PATH, or in some other obvious and convenient place.

In this book, we use the standard #!/usr/bin/perl notation on the first line of the program to mean whatever particular mechanism works on your system. If you care about running a specific version of Perl, use a specific path:

#!/usr/local/bin/perl5.6.0
If you just want to be running at least some version number, but don't mind higher ones, place a statement like this near the top of your program:
use v5.6.0;
(Note: earlier versions of Perl use numbers like 5.005 or 5.004_05. Nowadays we would think of those as 5.5.0 and 5.4.5, but versions of Perl older than 5.6.0 won't understand that notation.)

19.1.3. Switches

A single-character command-line switch without its own argument may always be combined (bundled) with a switch following it.

#!/usr/bin/perl -spi.bak    # same as -s -p -i.bak
Switches are also known as options or flags. Whatever you call them, here are the ones Perl recognizes:

--

Terminates switch processing, even if the next argument starts with a minus. It has no other effect.

-0 OCTNUM
-0

Specifies the record separator ($/) as an octal number. If OCTNUM is not present, the NUL character (that's ASCII character 0, Perl's "\0") is the separator. Other switches may precede or follow the octal number. For example, if you have a version of find(1) that can print filenames terminated by the null character, you can say this:

% find . -name '*.bak' -print0 | perl -n0e unlink

The special value 00 makes Perl read files in paragraph mode, equivalent to setting the $/ variable to "". The value 0777 makes Perl slurp in whole files at once. This is equivalent to undefining the $/ variable. We use 0777 since there is no ASCII character with that value. (Unfortunately, there is a Unicode character with that value, \N{LATIN SMALL LETTER O WITH STROKE AND ACUTE}, but something tells us you won't be delimiting your records with that.)

-a

Turns on autosplit mode, but only when used with -n or -p. An implicit split command to the @F array is done as the first thing inside the implicit while loop produced by the -n and -p switches. So:

% perl -ane 'print pop(@F), "\n";'
is equivalent to:
LINE: while (<>) {
    @F = split(' ');
    print pop(@F), "\n";
}
A different field separator may be specified by passing a regular expression for split to the -F switch. For example, these two calls are equivalent:
% awk -F: '$7 && $7 !~ /^\/bin/' /etc/passwd
% perl -F: -lane 'print if $F[6] && $F[6] !~ m(^/bin)' /etc/passwd

-c

Causes Perl to check the syntax of the script and then exit without executing what it's just compiled. Technically, it does a bit more than that: it will execute any BEGIN or CHECK blocks and any use directives, since these are considered to occur before the execution of your program. It no longer executes any INIT or END blocks, however. The older but rarely useful behavior may still be obtained by putting:

BEGIN { $^C = 0; exit; }
at the end of your main script.

-C

Enables Perl to use the native wide-character APIs on the target system, if supported (as of version 5.6.0 it works on Microsoft platforms only). The special variable ${^WIDE_SYSTEM_CALLS} reflects the state of this switch.

-d

Runs the script under the Perl debugger. See Chapter 20, "The Perl Debugger".

-d:MODULE

Runs the script under the control of a debugging or tracing module installed in the Perl library as Devel::MODULE. For example, -d:DProf executes the script using the Devel::DProf profiler. See also the debugging section in Chapter 20, "The Perl Debugger".

-D LETTERS
-D NUMBER

Sets debugging flags. (This only works if debugging is compiled into your version of Perl as described below.) You may specify either a NUMBER that is the sum of the bits you want, or a list of LETTERS. To see how it executes your script, for instance, use -D14 or -Dslt. Another useful value is -D1024 or -Dx, which lists your compiled syntax tree. And -D512 or -Dr displays compiled regular expressions. The numeric value is available internally as the special variable $^D. Table 19-1 lists the assigned bit values.

Table 19.1. -D Options

Bit | Letter | Meaning
1 | p | Tokenizing and parsing
2 | s | Stack snapshots
4 | l | Label stack processing
8 | t | Trace execution
16 | o | Method and overloading resolution
32 | c | String/numeric conversions
64 | P | Print preprocessor command for -P
128 | m | Memory allocation
256 | f | Format processing
512 | r | Regex parsing and execution
1024 | x | Syntax tree dump
2048 | u | Tainting checks
4096 | L | Memory leaks (needs -DLEAKTEST when compiling Perl)
8192 | H | Hash dump--usurps values()
16384 | X | Scratchpad allocation
32768 | D | Cleaning up
65536 | S | Thread synchronization

All these flags require a Perl executable that was specially built for debugging. However, because this is not the default, you won't be able to use the -D switch at all unless you or your sysadmin built this special debugging version of Perl. See the INSTALL file in the Perl source directory for details, but the short story is that you need to pass -DDEBUGGING to your C compiler when compiling Perl itself. This flag is automatically set if you include the -g option when Configure asks you about optimizer and debugger flags.

If you're just trying to get a printout of each line of Perl code as it executes (the way that sh -x provides for shell scripts), you can't use Perl's -D switch. Instead do this:

# Bourne shell syntax
$ PERLDB_OPTS="NonStop=1 AutoTrace=1 frame=2" perl -dS program

# csh syntax
% (setenv PERLDB_OPTS "NonStop=1 AutoTrace=1 frame=2"; perl -dS program)
See Chapter 20, "The Perl Debugger" for details and variations.

-e PERLCODE

May be used to enter one or more lines of script. If -e is used, Perl will not look for the program's filename in the argument list. The PERLCODE argument is treated as if it ended with a newline, so multiple -e commands may be given to build up a multiline program. (Make sure to use semicolons where you would in a normal program stored in a file.) Just because -e supplies a newline on each argument doesn't imply that you must use multiple -e switches; if your shell supports multiline quoting like sh, ksh, or bash, you may pass a multiline script as one -e argument:

$ perl -e 'print "Howdy, ";
           print "@ARGV!\n";' world
Howdy, world!
With csh it's probably better to use multiple -e switches:
% perl -e 'print "Howdy, ";' \
       -e 'print "@ARGV!\n";' world
Howdy, world!
Both implicit and explicit newlines count in the line numbering, so the second print is on line 2 of the -e script in either case.

-F PATTERN

Specifies the pattern to split on when autosplitting via the -a switch (has no effect otherwise). The pattern may be surrounded by slashes (//), double quotes (""), or single quotes (''). Otherwise, it will be automatically put in single quotes. Remember that to pass quotes through a shell, you'll have to quote your quotes, and how you can do that depends on the shell.

-h

Prints a summary of Perl's command-line options.

-i EXTENSION
-i

Specifies that files processed by the <> construct are to be edited in place. It does this by renaming the input file, opening the output file by the original name, and selecting that output file as the default for calls to print, printf, and write.[4]

[4]Technically, this isn't really "in place". It's the same filename, but a different physical file.

The EXTENSION is used to modify the name of the old file to make a backup copy. If no EXTENSION is supplied, no backup is made and the current file is overwritten. If the EXTENSION doesn't contain a *, then that string is appended to the end of the current filename. If the EXTENSION does contain one or more * characters, then each * is replaced by the filename currently being processed. In Perl terms, you could think of this as:

($backup = $extension) =~ s/\*/$file_name/g;
This allows you to use a prefix for the backup file, instead of--or even in addition to--a suffix:
% perl -pi'orig_*' -e 's/foo/bar/' xyx     # backup to 'orig_xyx'
You can even put backup copies of the original files into another directory (provided that the directory already exists):
% perl -pi'old/*.orig' -e 's/foo/bar/' xyx # backup to 'old/xyx.orig'
These pairs of one-liners are equivalent:
% perl -pi -e 's/foo/bar/' xyx             # overwrite current file
% perl -pi'*' -e 's/foo/bar/' xyx          # overwrite current file

% perl -pi'.orig' -e 's/foo/bar/' xyx      # backup to 'xyx.orig'
% perl -pi'*.orig' -e 's/foo/bar/' xyx     # backup to 'xyx.orig'
From the shell, saying:
% perl -p -i.orig -e "s/foo/bar/;"
is the same as using the program:
#!/usr/bin/perl -pi.orig
s/foo/bar/;
which is convenient shorthand for the remarkably longer:
#!/usr/bin/perl
$extension = '.orig';
LINE: while (<>) {
    if ($ARGV ne $oldargv) {
        if ($extension !~ /\*/) {
            $backup = $ARGV . $extension;
        }
        else {
            ($backup = $extension) =~ s/\*/$ARGV/g;
        }
        unless (rename($ARGV, $backup)) {
            warn "cannot rename $ARGV to $backup: $!\n";
            close ARGV;
            next;
        }
        open(ARGVOUT, ">$ARGV");
        select(ARGVOUT);
        $oldargv = $ARGV;
    }
    s/foo/bar/;
}
continue {
    print;  # this prints to original filename
}
select(STDOUT);
This long code is virtually identical to the simple one-liner with the -i switch, except that the -i form doesn't need to compare $ARGV to $oldargv to know when the filename has changed. It does, however, use ARGVOUT for the selected filehandle and restore the old STDOUT as the default output filehandle after the loop. Like the code above, Perl creates the backup file irrespective of whether any output has truly changed. See the description of the eof function for examples of how to use use eof without parentheses to locate the end of each input file, in case you want to append to each file or to reset line numbering.

If, for a given file, Perl is unable to create the backup file as specified in the EXTENSION, it will issue a warning to that effect and continue processing any other remaining files listed.

You cannot use -i to create directories or to strip extensions from files. Nor can you use it with a ~ to indicate a home directory--which is just as well, since some folks like to use that character for their backup files:

% perl -pi~ -e 's/foo/bar/' file1 file2 file3...
Finally, the -i switch does not stop Perl from running if no filenames are given on the command line. When this happens, no backup is made since the original file cannot be determined, and processing proceeds from STDIN to STDOUT as might be expected.

-I DIRECTORY

Directories specified by -I are prepended to @INC, which holds the search path for modules. -I also tells the C preprocessor where to search for include files. The C preprocessor is invoked with -P; by default it searches /usr/include and /usr/lib/perl. Unless you're going to be using the C preprocessor (and almost no one does any more), you're better off using the use lib directive within your script. Like use lib, however, the -I switch implicitly adds platform-specific directories. See use lib in Chapter 31, "Pragmatic Modules", for details.

-l OCTNUM
-l

Enables automatic line-end processing. It has two effects: first, it automatically chomps the line terminator when used with -n or -p, and second, it sets $\ to the value of OCTNUM so that any print statements will have a line terminator of ASCII value OCTNUM added back on. If OCTNUM is omitted, -l sets $\ to the current value of $/, typically newline. So, to trim lines to 80 columns, say this:

% perl -lpe 'substr($_, 80) = ""'
Note that the assignment $\ = $/ is done when the switch is processed, so the input record separator can be different from the output record separator if the -l switch is followed by a -0 switch:
% gnufind / -print0 | perl -ln0e 'print "found $_" if -p'
This sets $\ to newline and later sets $/ to the null character. (Note that 0 would have been interpreted as part of the -l switch had it followed the -l directly. That's why we bundled the -n switch between them.)

-m and -M

These switches load a MODULE as if you'd executed a use, unless you specify -MODULE instead of MODULE, in which case they invoke no. For example, -Mstrict is like use strict, while -M-strict is like no strict.

-m MODULE

Executes use MODULE() before executing your script.

-M MODULE
-M'MODULE ...'

Executes use MODULE before executing your script. The command is formed by mere interpolation of the rest of the argument after the -M, so you can use quotes to add extra code after the module name, for example, -M'MODULE qw(foo bar)'.

-M MODULE=arg1,arg2...

A little built-in syntactic sugar means you can also say -Mmodule=foo,bar as a shortcut for -M'module qw(foo bar)'. This avoids the need to use quotes when importing symbols. The actual code generated by -Mmodule=foo,bar is:

use module split(/,/, q{foo,bar})
Note that the = form removes the distinction between -m and -M, but it's better to use the uppercase form to avoid confusion.

You may only use the -M and -m switches from a real command-line invocation of Perl, not as options picked up on the #! line. (Hey, if you're gonna put it in the file, why not just write the equivalent use or no instead?)

-n

Causes Perl to assume the following loop around your script, which makes it iterate over filename arguments much as sed -n or awk do:

LINE:
while (<>) {
    ...                # your script goes here
}
You may use LINE as a loop label from within you script, even though you can't see the actual label in your file.

Note that the lines are not printed by default. See -p to have lines printed. Here is an efficient way to delete all files older than a week:

find . -mtime +7 -print | perl -nle unlink
This is faster than using the -exec switch of find(1) because you don't have to start a process on every filename found. By an amazing coincidence, BEGIN and END blocks may be used to capture control before or after the implicit loop, just as in awk.

-p

Causes Perl to assume the following loop around your script, which makes it iterate over filename arguments much as sed does:

LINE:
while (<>) {
    ...         # your script goes here
}
continue {
    print or die "-p destination: $!\n";
}
You may use LINE as a loop label from within you script, even though you can't see the actual label in your file.

If a file named by an argument cannot be opened for some reason, Perl warns you about it, and moves on to the next file. Note that the lines are printed automatically. An error occurring during printing is treated as fatal. By yet another amazing coincidence, BEGIN and END blocks may be used to capture control before or after the implicit loop, just as in awk.

-P

Causes your script to be run through the C preprocessor before compilation by Perl. (Since both comments and cpp(1) directives begin with the # character, you should avoid starting comments with any words recognized by the C preprocessor such as "if", "else" or "define".) Whether you use -P switch or not, Perl still pays attention to #line directives to control the line number and filename, so any preprocessor can apprise Perl of these things. See the section Section 19.5.2, "Generating Perl in Other Languages" in Chapter 24, "Common Practices".

-s

Enables rudimentary switch-parsing for switches on the command line after the script name but before any filename arguments or a "--" switch-processing terminator. Any switch found is removed from @ARGV, and a variable by the same name as the switch is set in Perl. Switch bundling is not allowed because multicharacter switches are permitted.

The following script prints "true" only when the script is invoked with a -foo switch.

#!/usr/bin/perl -s
if ($foo) { print "true\n" }
If the switch is of the form -xxx=yyy, the $xxx variable is set to whatever follows the equals sign in that argument ("yyy" in this case). The following script prints "true" if and only if the script is invoked with a -foo=bar switch.
#!/usr/bin/perl -s
if ($foo eq 'bar') { print "true\n" }

-S

Makes Perl use the PATH environment variable to search for the script (unless the name of the script contains directory separators).

Typically, this switch is used to help emulate #! startup on platforms that don't support #!. On many platforms that have a shell compatible with Bourne or C shell, you can use this:

#!/usr/bin/perl
eval "exec /usr/bin/perl -S $0 $*"
        if $running_under_some_shell;
The system ignores the first line and feeds the script to /bin/sh, which proceeds to try to execute the Perl script as a shell script. The shell executes the second line as a normal shell command, and thus starts up the Perl interpreter. On some systems, $0 doesn't always contain the full pathname, so -S tells Perl to search for the script if necessary. After Perl locates the script, it parses the lines and ignores them because the variable $running_under_some_shell is never true. A better construct than $* would be ${1+"$@"}, which handles embedded spaces and such in the filenames but doesn't work if the script is being interpreted by csh. In order to start up sh instead of csh, some systems have to replace the #! line with a line containing just a colon, which Perl will politely ignore. Other systems can't control that and need a totally devious construct that will work under any of csh, sh, or perl, such as the following:
eval '(exit $?0)' && eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    & eval 'exec /usr/bin/perl -S $0 $argv:q'
                   if 0;
Yes, it's ugly, but so are the systems that work[5] this way.

[5] We use the term advisedly.

On some platforms, the -S switch also makes Perl append suffixes to the filename while searching for it. For example, on Win32 platforms, the .bat and .cmd suffixes are appended if a lookup for the original name fails and the name does not already end in one of those suffixes. If your Perl was built with debugging enabled, you can use Perl's -Dp switch to watch how the search progresses.

If the filename supplied contains directory separators (even as just a relative pathname, not an absolute one), and if the file is not found, those platforms that implicitly append file extensions (not Unix) will do so and look for the file with those extensions added, one by one.

On DOS-like platforms, if the script does not contain directory separators, it will first be searched for in the current directory before being searched for in the PATH. On Unix platforms, the script will be searched for strictly on the PATH, due to security concerns about accidentally executing something in the current working directory without explicitly requesting this.

-T

Forces "taint" checks to be turned on so you can test them. Ordinarily these checks are done only when running setuid or setgid. It's a good idea to turn them on explicitly for programs run on another's behalf, such as CGI programs. See Chapter 23, "Security".

Note that, for security reasons, Perl must see this option quite early; usually this means it must appear early on the command line or in the #! line. If it's not early enough, Perl complains.

-u

Causes Perl to dump core after compiling your script. You can then in theory take this core dump and turn it into an executable file by using the undump program (not supplied). This speeds startup at the expense of some disk space (which you can minimize by stripping the executable). If you want to execute a portion of your script before dumping, use Perl's dump operator instead. Note: availability of undump is platform specific; it may not be available for a specific port of Perl. It has been superseded by the new Perl-to-C code generator, which is much more portable (but still experimental).

-U

Allows Perl to do unsafe operations. Currently the only "unsafe" operations are unlinking directories while running as superuser, and running setuid programs with fatal taint checks turned into warnings. Note that warnings must be enabled to actually produce the taint-check warnings.

-v

Prints the version and patch level of your Perl executable, along with a bit of extra information.

-V

Prints a summary of the major Perl configuration values and the current value of @INC.

-V:NAME

Prints to STDOUT the value of the named configuration variable. The NAME may contain regex characters, like "." to match any character, or ".*" to match any optional sequence of characters.

% perl -V:man.dir
man1dir='/usr/local/man/man1'
man3dir='/usr/local/man/man3'

% perl -V:'.*threads'
d_oldpthreads='undef'
use5005threads='define'
useithreads='undef'
usethreads='define'
If you ask for a configuration variable that doesn't exist, its value will be reported as "UNKNOWN". Configuration information is available from within a program using the Config module, although patterns are not supported for the hash subscripts:
% perl -MConfig -le 'print $Config{man1dir}'
/usr/local/man/man1
See the Config module in Chapter 32, "Standard Modules".

-w

Prints warnings about variables that are mentioned only once and scalar values that are used before being set. Also warns about redefined subroutines, and references to undefined filehandles or filehandles opened read-only that you are attempting to write on. Also warns you if you use values as numbers that don't look like numbers, if you use an array as though it were a scalar, if your subroutines recurse more than 100 deep, and innumerable other things. See every entry labelled "(W)" in Chapter 33, "Diagnostic Messages".

This switch just sets the global $^W variable. It has no effect on lexical warnings--see the -W and -X switches for that. You can enable or disable specific warnings via the use warnings pragma, described in Chapter 31, "Pragmatic Modules".

-W

Unconditionally and permanently enables all warnings throughout the program, even if warnings were disabled locally using no warnings or $^W = 0. This includes all files loaded via use, require, or do. Think of it as the Perl equivalent of the lint(1) command.

-x DIRECTORY
-x

Tells Perl to extract a script that is embedded in a message. Leading garbage will be discarded until the first line that starts with #! and contains the string "perl". Any meaningful switches on that line after the word "perl" will be applied. If a directory name is specified, Perl will switch to that directory before running the script. The -x switch controls the disposal of leading garbage only, not trailing garbage. The script must be terminated with __END__ or __DATA__ if there is trailing garbage to be ignored. (The script can process any or all of the trailing garbage via the DATA filehandle if desired. It could even in theory seek to the beginning of the file and process the leading garbage.)

-X

Unconditionally and permanently disables all warnings, the exact opposite of what the -W flag does.

Previous | Home | Next
18.7. Avant-Garde Compiler, Retro Interpreter | Book Index | 19.2. Environment Variables
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


19.2. Environment Variables

In addition to the various switches that explicitly modify Perl's behavior, you can set various environment variables to influence various underlying behaviors. How you set up these environment variables is system dependent, but one trick you should know if you use sh, ksh, or bash is that you can temporarily set an environment variable for a single command, as if it were a funny kind of switch. It has to be set in front of the command:

$ PATH='/bin:/usr/bin' perl myproggie
You can do something similar with a subshell in csh and tcsh:
% (setenv PATH "/bin:/usr/bin"; perl myproggie)
Otherwise, you'd typically set environment variables in some file with a name resembling .chsrc or .profile in your home directory. Under csh and tcsh you'd say:
% setenv PATH '/bin:/usr/bin'
And under sh, ksh, and bash you'd say:
$ PATH='/bin:/usr/bin'; export PATH
Other systems will have other ways of setting these on a semi-permanent basis. Here are the environment variables Perl pays attention to:

HOME

Used if chdir is called without an argument.

LC_ALL, LC_CTYPE, LC_COLLATE, LC_NUMERIC, PERL_BADLANG

Environment variables that control how Perl handles data specific to particular natural languages. See the online docs for perllocale.

LOGDIR

Used if chdir has no argument, but HOME is not set.

PATH

Used in executing subprocesses, and for finding the program if the -S switch is used.

PERL5LIB

A colon-separated list of directories in which to look for Perl library files before looking in the standard library and the current directory. Any architecture-specific directories under the specified locations are automatically included if they exist. If PERL5LIB is not defined, PERLLIB is consulted for backward compatibility with older releases.

When running taint checks (either because the program was running setuid or setgid, or the -T switch was used), neither of these library variables is used. Such programs must employ the use lib pragma for that purpose.

PERL5OPT

Default command-line switches. Switches in this variable are taken as if they were on every Perl command line. Only the -[DIMUdmw] switches are allowed. When running taint checks (because the program was running setuid or setgid, or the -T switch was used), this variable is ignored. If PERL5OPT begins with -T, tainting will be enabled, causing any subsequent options to be ignored.

PERL5DB

The command used to load the debugger code. The default is:

BEGIN { require 'perl5db.pl' }
See Chapter 20, "The Perl Debugger" for more uses of this variable.

PERL5SHELL (Microsoft ports only)

May be set to an alternative shell that Perl must use internally for executing commands via backticks or system. Default is cmd.exe /x/c on WinNT and command.com /c on Win95. The value is considered to be space separated. Precede any character that needs to be protected (like a space or backslash) with a backslash.

Note that Perl doesn't use COMSPEC for this purpose because COMSPEC has a high degree of variability among users, leading to portability concerns. Besides, Perl can use a shell that may not be fit for interactive use, and setting COMSPEC to such a shell may interfere with the proper functioning of other programs (which usually look in COMSPEC to find a shell fit for interactive use).

PERLLIB

A colon-separated list of directories in which to look for Perl library files before looking in the standard library and the current directory. If PERL5LIB is defined, PERLLIB is not used.

PERL_DEBUG_MSTATS

Relevant only if Perl is compiled with the malloc function included with the Perl distribution (that is, if perl -V:d_mymalloc yields "define"). If set, this causes memory statistics to be displayed after execution. If set to an integer greater than one, also causes memory statistics to be displayed after compilation.

PERL_DESTRUCT_LEVEL

Relevant only if your Perl executable was built with debugging enabled, this controls the behavior of global destruction of objects and other references.

Apart from these, Perl itself uses no other environment variables, except to make them available to the program being executed and to any child processes that program launches. Some modules, standard or otherwise, may care about other environment variables. For example, the use re pragma uses PERL_RE_TC and PERL_RE_COLORS, the Cwd module uses PWD, and the CGI module uses the many environment variables set by your HTTP daemon (that is, your web server) to pass information to the CGI script.

Programs running setuid would do well to execute the following lines before doing anything else, just to keep people honest:

$ENV{PATH}  = '/bin:/usr/bin';    # or whatever you need
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
See Chapter 23, "Security" for details.

Previous | Home | Next
19.1. Command Processing | Book Index | 20. The Perl Debugger
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 20. The Perl Debugger

Contents:

Using the Debugger
Debugger Commands
Debugger Customization
Unattended Execution
Debugger Support
The Perl Profiler

First of all, have you tried the use warnings pragma?

If you invoke Perl with the -d switch, your program will be run inside the Perl debugger. This works like an interactive Perl environment, prompting for debugger commands that let you examine source code, set breakpoints, dump out your function-call stack, change the values of variables, and so on. Any command not recognized by the debugger is directly executed (using eval) as Perl code in the package of the code currently being debugged. (The debugger uses the DB package for its own state information, to avoid trampling yours.) This is so wonderfully convenient that people often fire up the debugger just to test out Perl constructs interactively. In that case, it doesn't matter what program you tell Perl to debug, so we'll choose one without much meaning:

% perl -de 42
In Perl, the debugger is not a program completely separate from the one being debugged, the way it usually is in a typical programming environment. Instead, the -d flag tells the compiler to insert source information into the parse trees it's about to hand off to the interpreter. That means your code must first compile correctly for the debugger to work on it. If that is successful, the intrepreter preloads a special Perl library file containing the debugger itself.
% perl -d /path/to/program
The program will halt immediately before the first run-time executable statement (but see the section Section 20.1, "Using the Debugger" regarding compile-time statements) and ask you to enter a debugger command. Whenever the debugger halts and shows you a line of code, it displays the line that it's about to execute, not the one just executed.

As the debugger encounters a line, it first checks for a breakpoint, prints it (if the debugger is in trace mode), performs any actions (created with the a command described later in "Debugger Commands"), and finally prompts the user if a breakpoint is present or if the debugger is in single-step mode. If not, it evaluates the line normally and continues to the next line.

20.1. Using the Debugger

The debugger prompt is something like:

DB<8>
or even:
DB<<17>>

where the number shows how many commands you've executed. A csh-like history mechanism allows you to access previous commands by number. For example, !17 would repeat command number 17. The number of angle brackets indicates the depth of the debugger. For example, you get more than one set of brackets if you're already at a breakpoint and then print out the result of a function call that itself also has a breakpoint.

If you want to enter a multiline command, such as a subroutine definition with several statements, you may escape the newline that would normally end the debugger command with a backslash. Here's an example:

DB<1> for (1..3) {         \
  cont:     print "ok\n";    \
  cont: }
  ok
  ok
  ok
Let's say you want to fire up the debugger on a little program of yours (let's call it camel_flea) and stop it as soon as it gets down to a function named infested. Here's how you'd do that:
% perl -d camel_flea

Loading DB routines from perl5db.pl version 1.07
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(camel_flea:2):     pests('bactrian', 4);
  DB<1>
The debugger halts your program right before the first run-time executable statement (but see below about compile-time statements) and asks you to enter a command. Again, whenever the debugger stops to show you a line of code, it displays the line it's about to execute, not the one it just executed. The line displayed may not look exactly like it did in your source file, particularly if you've run it through any kind of preprocessor.

Now, you'd like to stop as soon as your program gets to the infested function, so you establish a breakpoint there like so:

DB<1> b infested
DB<2> c
The debugger now continues until it hits that function, at which point it says this:
main::infested(camel_flea:8):       my $bugs = int rand(3);

To look at a "window" of source code around the breakpoint, use the w command:

DB<2> w
5     }
6
7       sub infested {
8==>b       my $bugs = int rand(3);
9:          our $Master;
10:         contaminate($Master);
11:         warn "needs wash"
12              if $Master && $Master->isa("Human");
13
14:         print "got $bugs\n";

DB<2>
As you see by the ==> marker, your current line is line 8, and by the b there, you know it has a breakpoint on it. If you'` had set an action, there also would also have been an a there. The line numbers with colons are breakable; the rest are not.

To see who called whom, ask for a stack backtrace using the T command:

DB<2> T
$ = main::infested called from file `Ambulation.pm' line 4
@ = Ambulation::legs(1, 2, 3, 4) called from file `camel_flea' line 5
. = main::pests('bactrian', 4) called from file `camel_flea' line 2

The initial character ($, @, or .) tells whether the function was called in a scalar, list, or void context, respectively. There are three lines because you were three functions deep when you ran the stack backtrace. Here's what each line means:

  • The first line says you were in the function main::infested when you ran the stack trace. It tells you the function was called in a scalar context from line 4 of the file Ambulation.pm. It also shows that it was called without any arguments whatsoever, meaning it was called as &infested instead of the normal way, as infested().

  • The second line shows that the function Ambulation::legs was called in list context from line number 5 of the camel_flea file, with those four arguments.

  • The third line shows that main::pests was called in void context from line 2 of camel_flea.

If you have compile-phase executable statements such as code from BEGIN and CHECK blocks or use statements, these will not ordinarily be stopped by the debugger, although requires and INIT blocks will, since they happen after the transition to run phase (see Chapter 18, "Compiling"). Compile-phase statements can be traced with the AutoTrace option set in PERLDB_OPTS.

You can exert a little control over the Perl debugger from within your Perl program itself. You might do this, for example, to set an automatic breakpoint at a certain subroutine whenever a particular program is run under the debugger. From your own Perl code, however, you can transfer control back to the debugger using the following statement, which is harmless if the debugger is not running:

$DB::single = 1;
If you set $DB::single to 2, it's equivalent to the n command, whereas a value of 1 emulates the s command. The $DB::trace variable should be set to 1 to simulate the t command.

Another way to debug a module is to set breakpoint on loading:

DB<7> b load c:/perl/lib/Carp.pm
Will stop on load of `c:/perl/lib/Carp.pm'.
and then restart the debugger using the R command. For finer control, you can use the b compile subname to stop as soon as possible after a particular subroutine is compiled.

Previous | Home | Next
19.2. Environment Variables | Book Index | 20.2. Debugger Commands
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.2. Debugger Commands

When you type commands into the debugger, you don't need to terminate them with a semicolon. Use a backslash to continue lines (but only in the debugger).

Since the debugger uses eval to execute commands, my, our, and local settings will disappear once the command returns. If a debugger command coincides with some function in your own program, simply precede the function call with anything that doesn't look like a debugger command, such as a leading ; or a +.

If the output of a debugger built-in command scrolls past your screen, just precede the command with a leading pipe symbol so it's run through your pager:

DB<1> |h

The debugger has plenty of commands, and we divide them (somewhat arbitrarily) into stepping and running, breakpoints, tracing, display, locating code, automatic command execution, and, of course, miscellaneous.

Perhaps the most important command is h, which provides help. If you type h h at the debugger prompt, you'll get a compact help listing designed to fit on one screen. If you type h COMMAND, you'll get help on that debugger command.

20.2.1. Stepping and Running

The debugger operates by stepping through your program line by line. The following commands let you control what you skip over and where you stop.

s
s EXPR

The s debugger command single-steps through the program. That is, the debugger will execute the next line of your program until another statement is reached, descending into subroutine calls as necessary. If the next line to execute involves a function call, then the debugger stops at the first line inside that function. If an EXPR is supplied that includes function calls, these will be single-stepped, too.

n
n EXPR

The n command executes subroutine calls, without stepping through them, until the beginning of the next statement at this same level (or higher). If an EXPR is supplied that includes function calls, those functions will be executed with stops before each statement.

<ENTER>

If you just hit enter at the debugger prompt, the previous n or s command is repeated.

.

The . command returns the internal debugger pointer to the line last executed and prints out that line.

r

This command continues until the currently executing subroutine returns. It displays the return value if the PrintRet option is set, which it is by default.

20.2.2. Breakpoints

b
b LINE
b CONDITION
b LINE CONDITION
b SUBNAME
b SUBNAME CONDITION
b postpone SUBNAME
b postpone SUBNAME CONDITION
b compile SUBNAME
b load FILENAME

The b debugger command sets a breakpoint before LINE, telling the debugger to stop the program at that point so that you can poke around. If LINE is omitted, sets a breakpoint on the line that's about to execute. If CONDITION is specified, it's evaluated each time the statement is reached: a breakpoint is triggered only if CONDITION is true. Breakpoints may only be set on lines that begin an executable statement. Note that conditions don't use if:

b 237 $x > 30
b 237 ++$count237 < 11
b 33 /pattern/i
The b SUBNAME form sets a (possibly conditional) breakpoint before the first line of the named subroutine. SUBNAME may be a variable containing a code reference; if so, CONDITION is not supported.

There are several ways to set a breakpoint on code that hasn't even been compiled yet. The b postpone form sets a (possibly conditional) breakpoint at the first line of SUBNAME after it is compiled.

The b compile form sets a breakpoint on the first statement to be executed after SUBNAME is compiled. Note that unlike the postpone form, this statement is outside the subroutine in question because the subroutine hasn't been called yet, only compiled.

The b load form sets a breakpoint on the first executed line of the file. The FILENAME should be a full pathname as found in the %INC values.

d
d LINE

This command deletes the breakpoint at LINE; if omitted, it deletes the breakpoint on the line about to execute.

D

This command deletes all breakpoints.

L

This command lists all the breakpoints and actions.

c
c LINE

This command continues execution, optionally inserting a one-time-only breakpoint at the specified LINE.

20.2.3. Tracing

T

This command produces a stack backtrace.

t
t EXPR

This command toggles trace mode, which prints out every line in your program as it is evaluated. See also the AutoTrace option discussed later in this chapter. If an EXPR is provided, the debugger will trace through its execution. See also the later section Section 20.4, "Unattended Execution".

W
W EXPR

This command adds EXPR as a global watch expression. (A watch expression is an expression that will cause a breakpoint when its value changes.) If no EXPR is provided, all watch expressions are deleted.

20.2.4. Display

Perl's debugger has several commands for examining data structures while your program is stopped at a breakpoint.

p
p EXPR

This command is the same as print DB::OUT EXPR in the current package. In particular, since this is just Perl's own print function, nested data structures and objects are not shown--use the x command for that. The DB::OUT handle prints to your terminal (or perhaps an editor window) no matter where standard output may have been redirected.

x
x EXPR

The x command evaluates its expression in list context and displays the result, pretty-printed. That is, nested data structures are printed out recursively and with unviewable characters suitably encoded.

V
V PKG
V PKG VARS

This command displays all (or when you specify VARS, some) variables in the specified PKG (defaulting to the main package) using a pretty printer. Hashes show their keys and values, control characters are rendered legibly, nested data structures print out in a legible fashion, and so on. This is similar to calling the x command on each applicable variable, except that x works with lexical variables, too. Also, here you type the identifiers without a type specifier such as $ or @, like this:

V Pet::Camel SPOT FIDO
In place of a variable name in VARS, you can use ~PATTERN or !PATTERN to print existing variables whose names either match or don't match the specified pattern.

X
X VARS

This command is the same as V CURRENTPACKAGE, where CURRENTPACKAGE is the package that the current line was compiled into.

H
H -NUMBER

This command displays the last NUMBER commands. Only commands longer than one character are stored in the history. (Most of them would be s or n, otherwise.) If NUMBER is omitted, all commands are listed.

20.2.5. Locating Code

Inside the debugger, you can extract and display parts of your program with these commands.

l
l LINE
l SUBNAME
l MIN+INCR
l MIN-MAX

The l command lists next the few lines of your program, or the specified LINE if provided, or the first few lines of the SUBNAME subroutine or code reference.

The l MIN+INCR form lists INCR+1 lines, starting at MIN. The l MIN-MAX form lists lines MIN through MAX.

-

This command lists the previous few lines of your program.

w
w LINE

Lists a window (a few lines) around the given source LINE, or the current line if no LINE is supplied.

f FILENAME

This command lets you view a different program or eval statement. If the FILENAME is not a full pathname as found in the values of %INC, it is interpreted as a regular expression to find the filename you mean.

/PATTERN/

This command searches forward in the program for PATTERN; the final / is optional. The entire PATTERN is optional, too, and if omitted, repeats the previous search.

?PATTERN?

This command searches backward for PATTERN; the final ? is optional. It repeats the previous search if PATTERN is omitted.

S
S PATTERN
S !PATTERN

The S command lists those subroutine names matching (or, with !, those not matching) PATTERN. If no PATTERN is provided, all subroutines are listed.

20.2.6. Actions and Command Execution

From inside the debugger, you can specify actions to be taken at particular times. You can also launch external programs.

a
a COMMAND
a LINE
a LINE COMMAND

This command sets an action to take before LINE executes, or the current line if LINE is omitted. For example, this prints out $foo every time line 53 is reached:

a 53 print "DB FOUND $foo\n"
If no COMMAND is specified, the action on the specified LINE is deleted. With neither LINE nor COMMAND, the action on the current line is deleted.

A

The A debugger command deletes all actions.

<
< ?
< EXPR
<< EXPR

The <EXPR form specifies a Perl expression to be evaluated before every debugger prompt. You can add another expression with the <<EXPR form, list them with < ?, and delete them all with a plain <.

>
> ?
> EXPR
>> EXPR

The > commands behave just like their < cousins but are executed after the debugger prompt instead of before.

{
{ ?
{ COMMAND
{{ COMMAND

The { debugger commands behave just like < but specify a debugger command to be executed before the debugger prompt instead of a Perl expression. A warning is issued if you appear to have accidentally entered a block of code instead. If that's what you really mean to do, write it with ;{ ... } or even do { ... }.

!
! NUMBER
! -NUMBER
!PATTERN

A lone ! repeats the previous command. The NUMBER specifies which command from the history to execute; for instance, ! 3 executes the third command typed into the debugger. If a minus sign precedes the NUMBER, the commands are counted backward: ! -3 executes the third-to-last command. If a PATTERN (no slashes) is provided instead of a NUMBER, the last command that began with PATTERN is executed. See also the recallCommand debugger option.)

!! CMD

This debugger command runs the external command CMD in a subprocess, which will read from DB::IN and write to DB::OUT. See also the shellBang debugger option. This command uses whatever shell is named in $ENV{SHELL}, which can sometimes interfere with proper interpretation of status, signal, and core dump information. If you want a consistent exit value from the command, set $ENV{SHELL} to /bin/sh.

|
|DBCMD
||PERLCMD

The |DBCMD command runs the debugger command DBCMD, piping DB::OUT to $ENV{PAGER}. This is often used with commands that would otherwise produce long output, such as:

DB<1> |V main
Note that this is for debugger commands, not commands you'd type from your shell. If you wanted to pipe the external command who through your pager, you could do something like this:

DB<1> !!who | more

The ||PERLCMD command is like |DBCMD, but DB::OUT is temporarily selected as well, so any commands that call print, printf, or write without a filehandle will also be sent down the pipe. For example, if you had a function that generated loads of output by calling print, you'd use this command instead of the previous one to page through that output:

DB<1> sub saywho { print "Users: ", `who` }
DB<2> ||sawwho()

20.2.7. Miscellaneous Commands

q and ^D

These commands quit the debugger. This is the recommended way to exit, although typing exit twice sometimes works. Set the inhibit_exit option to 0 if you want to be able to step off the end of the program and remain in the debugger anyway. You may also need to set $DB::finished to 0 if you want to step through global destruction.

R

Restart the debugger by execing a new session. The debugger tries to maintain your history across sessions, but some internal settings and command-line options may be lost. The following settings are currently preserved: history, breakpoints, actions, debugger options, and the Perl command-line options -w, -I, and -e.

=
= ALIAS
= ALIAS VALUE

This command prints out the current value of ALIAS if no VALUE is given. With a VALUE, it defines a new debugger command with the name ALIAS. If both ALIAS and VALUE are omitted, all current aliases are listed. For example:

= quit q
An ALIAS should be a simple identifier, and should translate to a simple identifier as well. You can do more sophisticated aliasing by adding your own entries to %DB::aliases directly. See "Debugger Customization" later in this chapter.

man
man MANPAGE

This command calls your system's default documentation viewer on the given page or on the viewer itself if MANPAGE is omitted. If that viewer is man, the current %Config information is used to invoke it. The "perl" prefix will be automatically supplied for you when necessary; this lets you type man debug and man op from the debugger.

On systems that do not normally have the man utility, the debugger invokes perldoc; if you want to change that behavior, set $DB::doccmd to whatever viewer you like. This may be set in an rc file or through direct assignment.

O
O OPTION ...
O OPTION? ...
O OPTION=VALUE...

The O command lets you manipulate debugger options, which are listed in Section 20.3.3, "Debugger Options" later in this chapter. The O OPTION form sets each of the listed debugger options to 1. If a question mark follows an OPTION, its current value is displayed.

The O OPTION=VALUE form sets the values; if VALUE has internal whitespace, it should be quoted. For example, you could set O pager="less -MQeicsNfr" to use less with those specific flags. You may use either single or double quotes, but if you do, you must escape embedded instances of the same sort of quote that you began with. You must also escape any backslash that immediately precedes the quote but is not meant to escape the quote itself. In other words, just follow single-quoting rules irrespective of the quote actually used. The debugger responds by showing you the value of the option just set, always using single-quoted notation for its output:

DB<1> O OPTION='this isn\'t bad'
               OPTION = 'this isn\'t bad'

DB<2> O OPTION="She said, \" Isn't it?\""
               OPTION = 'She said, "Isn\'t it?"'
For historical reasons, the =VALUE is optional, but defaults to 1 only where safe to do so--that is, mostly for Boolean options. It is better to assign a specific VALUE using =. The OPTION can be abbreviated, but unless you're trying to be intentionally cryptic, it probably should not be. Several options can be set together. See the section Section 20.3.3, "Debugger Options" for a list of these.

Previous | Home | Next
20.1. Using the Debugger | Book Index | 20.3. Debugger Customization
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.3. Debugger Customization

The debugger probably contains enough configuration hooks that you'll never have to modify it yourself. You may change the behavior of debugger from within the debugger using its O command, from the command line via the PERLDB_OPTS environment variable, and by running any preset commands stored in rc files.

20.3.1. Editor Support for Debugging

The debugger's command-line history mechanism doesn't provide command-line editing like many shells do: you can't retrieve previous lines with ^p, or move to the beginning of the line with ^a, although you can execute previous lines with using the exclamation point syntax familiar to shell users. However, if you install the Term::ReadKey and Term::ReadLine modules from CPAN, you will have full editing capabilities similar to what GNU readline(3) provides.

If you have emacs installed on your system, it can interact with the Perl debugger to provide an integrated software development environment reminiscent of its interactions with C debuggers. Perl comes with a start file for making emacs act like a syntax-directed editor that understands (some of) Perl's syntax. Look in the emacs directory of the Perl source distribution. Users of vi should also look into vim (and gvim, the mousey and windy version) for coloring of Perl keywords.

A similar setup by one of us (Tom) for interacting with any vendor-shipped vi and the X11 window system is also available. This works similarly to the integrated multiwindow support that emacs provides, where the debugger drives the editor. However, at the time of this writing, its eventual location in the Perl distribution is uncertain. But we thought you should know of the possibility.

20.3.2. Customizing with Init Files

You can do some customization by setting up either a .perldb or perldb.ini file (depending on your operating system), which contains initialization code. This init file holds Perl code, not debugger commands, and is processed before the PERLDB_OPTS environment variable is looked at. For instance, you could make aliases by adding entries to the %DB::alias hash this way:

$alias{len}  = 's/^len(.*)/p length($1)/';
$alias{stop} = 's/^stop (at|in)/b/';
$alias{ps}   = 's/^ps\b/p scalar /';
$alias{quit} = 's/^quit(\s*)/exit/';
$alias{help} = 's/^help\s*$/|h/';
You can change options from within your init file using function calls into the debugger's internal API:
parse_options("NonStop=1 LineInfo=db.out AutoTrace=1 frame=2");
If your init file defines the subroutine afterinit, that function is called after debugger initialization ends. The init file may be located in the current directory or in the home directory. Because this file contains arbitrary Perl commands, for security reasons, it must be owned by the superuser or the current user, and writable by no one but its owner.

If you want to modify the debugger, copy perl5db.pl from the Perl library to another name and hack it to your heart's content. You'll then want to set your PERL5DB environment variable to say something like this:

BEGIN { require "myperl5db.pl" }
As a last resort, you could also use PERL5DB to customize the debugger by directly setting internal variables or calling internal debugger functions. Be aware, though, that any variables and functions not documented either here or else in the online perldebug, perldebguts, or DB manpages are considered to be for internal use only and are subject to change without notice.

20.3.3. Debugger Options

The debugger has numerous options that you can set with the O command, either interactively or from the environment or from an init file.

recallCommand, ShellBang

The characters used to recall a command or spawn a shell. By default, both are set to !.

pager

Program to use for output of pager-piped commands (those beginning with a | character.) By default, $ENV{PAGER} will be used. Because the debugger uses your current terminal characteristics for bold and underlining, if the chosen pager does not pass escape sequences through unchanged, the output of some debugger commands will not be readable when sent through the pager.

tkRunning

Run under the Tk module while prompting (with ReadLine).

signalLevel, warnLevel, dieLevel

Set the level of verbosity. By default, the debugger leaves your exceptions and warnings alone because altering them can break correctly running programs.

To disable this default safe mode, set these values to something higher than 0. At a level of 1, you get backtraces upon receiving any kind of warning (this is often annoying) or exception (this is often valuable). Unfortunately, the debugger cannot distinguish fatal exceptions from nonfatal ones. If dieLevel is 1, then your nonfatal exceptions are also traced and unceremoniously altered if they came from evaled strings or from any kind of eval within modules you're attempting to load. If dieLevel is 2, the debugger doesn't care where they came from: it usurps your exception handler and prints out a trace, and then modifies all exceptions with its own embellishments. This may perhaps be useful for some tracing purposes, but it tends to hopelessly confuse any program that takes its exception handling seriously.

The debugger will attempt to print a message when any uncaught INT, BUS, or SEGV signal arrives. If you're in a slow syscall (like a wait or an accept, or a read from your keyboard or a socket) and haven't set up your own $SIG{INT} handler, then you won't be able to Control-C your way back to the debugger, because the debugger's own $SIG{INT} handler doesn't understand that it needs to raise an exception to longjmp(3) out of slow syscalls.

AutoTrace

Set the trace mode (similar to t command, but can be put into PERLDB_OPTS).

LineInfo

Assign the file or pipe to print line number info to. If it is a pipe (say, |visual_perl_db), then a short message is used. This is the mechanism used to interact with a slave editor or visual debugger, such as the special vi or emacs hooks, or the ddd graphical debugger.

inhibit_exit

If 0, allows stepping off the end of the program.

PrintRet

Print return value after r command if set (default).

ornaments

Affects screen appearance of the command line (see the online docs for Term::ReadLine). There is currently no way to disable ornaments, which can render some output illegible on some displays or with some pagers. This is considered a bug.

frame

Affects printing of messages on entry and exit from subroutines. If frame & 2 is false, messages are printed on entry only. (Printing on exit might be useful if interspersed with other messages.)

If frame & 4, arguments to functions are printed, plus context and caller info. If frame & 8, overloaded stringify and tied FETCH are enabled on the printed arguments. If frame & 16, the return value from the subroutine is printed.

The length at which the argument list is truncated is governed by the next option.

maxTraceLen

Length to truncate the argument list when the frame option's bit 4 is set.

The following options affect what happens with the V, X, and x commands:

arrayDepth, hashDepth

Print only the first n elements. If n is omitted, all of the elements will be printed.

compactDump, veryCompact

Change the style of array and hash output. If compactDump is enabled, short arrays may be printed on one line.

globPrint

Print contents of typeglobs.

DumpDBFiles

Display arrays holding debugged files.

DumpPackages

Display symbol tables of packages.

DumpReused

Display contents of "reused" addresses.

quote, HighBit, undefPrint

Change the style of string display. The default value for quote is auto; you can enable double-quotish or single-quotish format by setting it to " or ', respectively. By default, characters with their high bit set are printed verbatim.

UsageOnly

Instead of showing the contents of a package's variables, with this option enabled, you get a rudimentary per-package memory usage dump based on the total size of the strings found in package variables. Because the package symbol table is used, lexical variables are ignored.

Previous | Home | Next
20.2. Debugger Commands | Book Index | 20.4. Unattended Execution
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.4. Unattended Execution

During startup, options are initialized from $ENV{PERLDB_OPTS}. You may place the initialization options TTY, noTTY, ReadLine, and NonStop there.

If your init file contains:

parse_options("NonStop=1 LineInfo=tperl.out AutoTrace");
then your program will run without human intervention, putting trace information into the file db.out. (If you interrupt it, you'd better reset LineInfo to /dev/tty if you expect to see anything.)

The following options can be specified only at startup. To set them in your init file, call parse_options("OPT=VAL").

TTY

The terminal to use for debugging I/O.

noTTY

If set, the debugger goes into NonStop mode and will not connect to a terminal. If interrupted (or if control goes to the debugger via explicit setting of $DB::signal or $DB::single from the Perl program), it connects to a terminal specified in the TTY option at startup, or to a terminal found at run time using the Term::Rendezvous module of your choice.

This module should implement a method named new that returns an object with two methods: IN and OUT. These should return filehandles for the debugger to use its input and output correspondingly. The new method should inspect an argument containing the value of $ENV{PERLDB_NOTTY} at startup, or "/tmp/perldbtty$$" otherwise. This file is not inspected for proper ownership or wide-open write access, so security hazards are theoretically possible.

ReadLine

If false, ReadLine support in the debugger is disabled in order to debug applications that themselves use a ReadLine module.

NonStop

If set, the debugger goes into noninteractive mode until interrupted, or your program sets $DB::signal or $DB::single.

Options can sometimes be uniquely abbreviated by the first letter, but we recommend that you always spell them out in full, for legibility and future compatibility.

Here's an example of using the PERLDB_OPTS environment variable to set options automatically.[1] It runs your program noninteractively, printing information on each entry into a subroutine and for each line executed. Output from the debugger's trace are placed into the tperl.out file. This lets your program still use its regular standard input and output, without the trace information getting in the way.

$ PERLDB_OPTS="NonStop frame=1 AutoTrace LineInfo=tperl.out" perl -d myprog
If you interrupt the program, you'll need to quickly reset to O LineInfo=/dev/tty or whatever makes sense on your platform. Otherwise, you won't see the debugger's prompting.

[1] We're using sh shell syntax to show environment variable settings. Users of other shells should adjust accordingly.

Previous | Home | Next
20.3. Debugger Customization | Book Index | 20.5. Debugger Support
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.5. Debugger Support

Perl provides special debugging hooks at both compile time and run time for creating debugging environments such as the standard debugger. These hooks are not to be confused with the perl -D options, which are usable only if your Perl was built with -DDEBUGGING support.

For example, whenever you call Perl's built-in caller function from the package DB, the arguments that the corresponding stack frame was called with are copied to the the @DB::args array. When you invoke Perl with the -d switch, the following additional features are enabled:

  • Perl inserts the contents of $ENV{PERL5DB} (or BEGIN {require 'perl5db.pl'} if not present) before the first line of your program.

  • The array @{"_<$filename"} holds the lines of $filename for all files compiled by Perl. The same for evaled strings that contain subroutines or are currently being executed. The $filename for evaled strings looks like (eval 34). Code assertions in regular expressions look like (re_eval 19).

  • The hash %{"_<$filename"} contains breakpoints and actions keyed by line number. You can set individual entries as opposed to the whole hash. Perl only cares about Boolean truth here, although the values used by perl5db.pl have the form "$break_condition\0$action". Values in this hash are magical in numeric context: they are zeros if the line is not breakable.

    The same holds for evaluated strings that contain subroutines or are currently being executed. The $filename for evaled strings looks like (eval 34) or (re_eval 19).

  • The scalar ${"_<$filename"} contains "_<$filename". This is also the case for evaluated strings that contain subroutines or are currently being executed. The $filename for evaled strings looks like (eval 34) or (re_eval 19).

  • After each required file is compiled, but before it is executed, DB::postponed(*{"_<$filename"}) is called if the subroutine DB::postponed exists. Here, the $filename is the expanded name of the required file, as found in the values of %INC.

  • After each subroutine subname is compiled, the existence of $DB::postponed{subname} is checked. If this key exists, DB::postponed(subname) is called if the DB::postponed subroutine also exists.

  • A hash %DB::sub is maintained, whose keys are subroutine names and whose values have the form filename:startline-endline. filename has the form (eval 34) for subroutines defined inside evals, or (re_eval 19) for those within regular expression code assertions.

  • When the execution of your program reaches a point that might hold a breakpoint, the DB::DB() subroutine is called if any of the variables $DB::trace, $DB::single, or $DB::signal is true. These variables are not localizable. This feature is disabled when executing inside DB::DB(), including functions called from it unless $^D & (1<<30) holds true.

  • When execution of the program reaches a subroutine call, a call to &DB::sub(args) is made instead, with $DB::sub holding the name of the called subroutine. This doesn't happen if the subroutine was compiled in the DB package.

Note that if &DB::sub needs external data for it to work, no subroutine call is possible until this is done. For the standard debugger, the $DB::deep variable (how many levels of recursion deep into the debugger you can go before a mandatory break) gives an example of such a dependency.

20.5.1. Writing Your Own Debugger

The minimal working debugger consists of one line:

sub DB::DB {}
which, since it does nothing whatsoever, can easily be defined via the PERL5DB environment variable:
% PERL5DB="sub DB::DB {}" perl -d your-program
Another tiny debugger, slightly more useful, could be created like this:
sub DB::DB {print ++$i; scalar <STDIN>}
This little debugger would print the sequential number of each encountered statement and would wait for you to hit a newline before continuing.

The following debugger, small though it may appear, is really quite functional:

{
    package DB;
    sub DB  {}
    sub sub {print ++$i, " $sub\n"; &$sub}
}
It prints the sequential number of the subroutine call and the name of the called subroutine. Note that &DB::sub must be compiled from the package DB, as we've done here.

If you base your new debugger on the current debugger, there are some hooks that can help you customize it. At startup, the debugger reads your init file from the current directory or your home directory. After the file is read, the debugger reads the PERLDB_OPTS environment variable and parses this as the remainder of an O ... line such as you might enter at the debugger prompt.

The debugger also maintains magical internal variables, such as @DB::dbline, %DB::dbline, which are aliases for @{":::_<current_file"} %{"::_<current_file"}. Here current_file is the currently selected file, either explicitly chosen with the debugger's f command or implicitly by flow of execution.

Some functions can help with customization. DB::parse_options(STRING) parses a line like the O option. DB::dump_trace(SKIP[,COUNT]) skips the specified number of frames and returns a list containing information about the calling frames (all of them, if COUNT is missing). Each entry is a reference to a hash with keys "context" (either ., $, or @), "sub" (subroutine name, or info about eval), "args" (undef or a reference to an array), "file", and "line". DB::print_trace(FH,SKIP[,COUNT[,SHORT]]) prints formatted info about caller frames to the supplied filehandle. The last two functions may be convenient as arguments to the debugger's < and << commands.

You don't need to learn all that--most of us haven't. In fact, when we need to debug a program, we usually just insert a few print statements here and there and rerun the program.

On our better days, we'll even remember to turn on warnings first. That often spotlights the problem right away, thus saving a great deal of wear and tear on our hair (what's left of it). But when that doesn't work, it's nice to know that, waiting for you patiently behind that -d switch, there is a lovely debugger that can do darn near anything except find your bug for you.

But if you're going to remember one thing about customizing the debugger, perhaps it is this: don't limit your notion of bugs to things that make Perl unhappy. It's also a bug if your program makes you unhappy. Earlier, we showed you a couple of really simple custom debuggers. In the next section, we'll show you an example of a different sort of custom debugger, one that may (or may not) help you debug the bug known as "Is this thing ever gonna finish?"

Previous | Home | Next
20.4. Unattended Execution | Book Index | 20.6. The Perl Profiler
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


20.6. The Perl Profiler

Do you want to make your program faster? Well, of course you do. But first you should stop and ask yourself, "Do I really need to spend time making this program faster?" Recreational optimization can be fun,[2] but normally there are better uses for your time. Sometimes you just need to plan ahead and start the program when you're going on a coffee break. (Or use it as an excuse for one.) But if your program absolutely must run faster, you should begin by profiling it. A profiler can tell you which parts of your program take the most time to execute, so you won't waste time optimizing a subroutine that has an insignificant effect on the overall execution time.

[2] Or so says Nathan Torkington, who contributed this section of the book.

Perl comes with a profiler, the Devel::DProf module. You can use it to profile the Perl program in mycode.pl by typing:

perl -d:DProf mycode.pl
Even though we've called it a profiler--since that's what it does--the mechanism DProf employs is the very same one we discussed earlier in this chapter. DProf is just a debugger that records the time Perl entered and left each subroutine.

When your profiled script terminates, DProf will dump the timing information to a file called tmon.out. The dprofpp program that came with Perl knows how to analyze tmon.out and produce a report. You may also use dprofpp as a frontend for the whole process with the -p switch (see described later).

Given this program:

outer();

sub outer {
  for (my $i=0; $i < 100; $i++) { inner() }
}

sub inner {
  my $total = 0;
  for (my $i=0; $i < 1000; $i++) { $total += $i }
}

inner();
the output of dprofpp is:
Total Elapsed Time = 0.537654 Seconds
  User+System Time = 0.317552 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 85.0   0.270  0.269    101   0.0027 0.0027  main::inner
 2.83   0.009  0.279      1   0.0094 0.2788  main::outer
Note that the percentage numbers don't add up to 100. In fact, in this case, they're pretty far off, which should tip you off that you need to run the program longer. As a general rule, the more profiling data you can collect, the better your statistical sample. If we increase the outer loop to run 1000 times instead of 100 times, we'll get more accurate results:
Total Elapsed Time = 2.875946 Seconds
  User+System Time = 2.855946 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 99.3   2.838  2.834   1001   0.0028 0.0028  main::inner
 0.14   0.004  2.828      1   0.0040 2.8280  main::outer
The first line reports how long the program took to run, from start to finish. The second line displays the total of two different numbers: the time spent executing your code ("user") and the time spent in the operating system executing system calls made by your code ("system"). (We'll have to forgive a bit of false precision in these numbers--the computer's clock almost certainly does not tick every millionth of a second. It might tick every hundredth of a second if you're lucky.)

The "user+system" times can be changed with command-line options to dprofpp. -r displays elapsed time, -s displays system time only, and -u displays user time only.

The rest of the report is a breakdown of the time spent in each subroutine. The "Exclusive Times" line indicates that when subroutine outer called subroutine inner, the time spent in inner didn't count towards outer's time. To change this, causing inner's time to be counted towards outer's, give the -I option to dprofpp.

For each subroutine, the following is reported: %Time, the percentage of time spent in this subroutine call; ExclSec, the time in seconds spent in this subroutine not including those subroutines called from it; CumulS, the time in seconds spent in this subroutine and those called from it; #Calls, the number of calls to the subroutine; sec/call, the average time in seconds of each call to the subroutine not including those called from it; Csec/c, the average time in seconds of each call to the subroutine and those called from it.

Of those, the most useful figure is %Time, which will tell you where your time goes. In our case, the inner subroutine takes the most time, so we should try to optimize that subroutine, or find an algorithm that will call it less. :-)

Options to dprofpp provide access to other information or vary the way the times are calculated. You can also make dprofpp run the script for you in the first place, so you don't have to remember the -d:DProf switch:

-p SCRIPT

Tells dprofpp that it should profile the given SCRIPT and then interpret its profile data. See also -Q.

-Q

Used with -p to tell dprofpp to quit after profiling the script, without interpreting the data.

-a

Sort output alphabetically by subroutine name rather than by decreasing percentage of time.

-R

Count anonymous subroutines defined in the same package separately. The default behavior is to count all anonymous subroutines as one, named main::__ANON__.

-I

Display all subroutine times inclusive of child subroutine times.

-l

Sort by number of calls to the subroutines. This may help identify candidates for inlining.

-O COUNT

Show only the top COUNT subroutines. The default is 15.

-q

Do not display column headers.

-T

Display the subroutine call tree to standard output. Subroutine statistics are not displayed.

-t

Display the subroutine call tree to standard output. Subroutine statistics are not displayed. A function called multiple (consecutive) times at the same calling level is displayed once, with a repeat count.

-S

Produce output structured by the way your subroutines call one another:

main::inner x 1         0.008s
main::outer x 1         0.467s = (0.000 + 0.468)s
  main::inner x 100     0.468s
Read this as follows: the top level of your program called inner once, and it ran for 0.008s elapsed time, and the top level called outer once and it ran for 0.467s inclusively (0s in outer itself, 0.468s in the subroutines called from outer) calling inner 100 times (which ran for 0.468s). Whew, got that?

Branches at the same level (for example, inner called once and outer called once) are sorted by inclusive time.

-U

Do not sort. Display in the order found in the raw profile.

-v

Sort by average time spent in subroutines during each call. This may help identify candidates for hand optimization by inlining subroutine bodies.

-g subroutine

Ignore subroutines except subroutine and whatever is called from it.

Other options are described in dprofpp(1), its standard manpage.

DProf is not your only choice for profiler. CPAN also holds Devel::SmallProf, which reports the time spent in each line of your program. That can help you figure out if you're using some particular Perl construct that is being surprisingly expensive. Most of the built-in functions are pretty efficient, but it's easy to accidentally write a regular expression whose overhead increases exponentially with the size of the input. See also the section Section 20.2, "Efficiency" in Chapter 24, "Common Practices", for other helpful hints.

Now go take that coffee break. You'll need it for the next chapter.

Previous | Home | Next
20.5. Debugger Support | Book Index | 21. Internals and Externals
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 21. Internals and Externals

Contents:

How Perl Works
Internal Data Types
Extending Perl (Using C from Perl)
Embedding Perl (Using Perl from C)
The Moral of the Story

As we discussed in Chapter 18, "Compiling", perl (the program) contains both a compiler and an interpreter for programs written in Perl (the language). The Perl compiler/interpreter is itself written in C. In this chapter, we'll sketch how that C program works from the perspective of someone who wants either to extend or to embed Perl. When you extend Perl, you're putting a chunk of C code (called the extension) under the control of Perl, and when you embed Perl you're putting a Perl interpreter[1] under the control of a larger C program.

[1] While we are careful to distinguish the compiler from the interpreter when that distinction is important, it gets a bit wearisome to keep saying "compiler/interpreter", so we often just shorten that to "interpreter" to mean the whole glob of C code and data that functions like one instance of perl (the program); when you're embedding Perl, you can have multiple instances of the interpreter, but each behaves like its own little perl.

The brief coverage we provide here is no substitute for the online documentation of Perl's innards: see the documentation for perlguts, perlxs, perlxstut, perlcall, perlapi, and h2xs, all bundled with Perl. Again, unless you're extending or embedding Perl, you will never need to know any of this stuff.

Presuming you need to know, what you need to know first is a bit about Perl's guts. You'll also need to know C for most of what follows. You'll need a C compiler to run the examples. If your end goal is to create a module for other people to use, they'll need a C compiler too. Many of these examples will only run on Unix-like systems. Oh, and this material is subject to change in future releases of Perl.

In other words, here be dragons.

21.1. How Perl Works

When the Perl compiler is fed a Perl program, the first task it performs is lexical analysis: breaking down the program into its basic syntactic elements (often called tokens). If the program is:

print "Hello, world!\n";
the lexical analyzer breaks it down into three tokens: print, "Hello, world!\n", and the final semicolon. The token sequence is then parsed, fixing the relationship between the tokens. In Perl, the boundary between lexical analysis and parsing is blurred more than in other languages. (Other computer languages, that is. If you think about all the different meanings new Critter might have depending on whether there's a Critter package or a subroutine named new, you'll understand why. On the other hand, we disambiguate these kinds of things all the time in English.)

Once a program has been parsed and (presumably) understood, it is compiled into a tree of opcodes representing low-level operations, and finally that tree of operations is executed--unless you invoked Perl with the -c ("check syntax") switch, which exits upon completing the compilation phase. It is during compilation, not execution, that BEGIN blocks, CHECK blocks, and use statements are executed.

Previous | Home | Next
20.6. The Perl Profiler | Book Index | 21.2. Internal Data Types
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.2. Internal Data Types

As the tree of opcodes constituting a compiled Perl program is executed, Perl values are created, manipulated, and destroyed. The data types you're familiar with in Perl all have corresponding data types in the C under Perl's hood, and you'll need to know about those types when you pass data between the two languages.

Three C typedefs correspond to Perl's three basic data types: the SV (scalar value), AV (array value), and HV (hash value). In addition, an IV is a simple signed integer type guaranteed to be large enough to hold either a pointer or an integer; and I32 and I16 are types guaranteed to be large enough to hold 32 bits and 16 bits, respectively. For storing unsigned versions of these last three typedefs, there exist UV, U32, and U16 typedefs as well. All of these typedefs can be manipulated with the C functions described in the perlguts documentation. We sketch the behaviors of some of those functions below:

  • There are four types of values that can be copied into an SV: an integer value (IV), a double (NV), a string (PV), and another scalar (SV). There are dozens of functions for SVs to let you create, modify, grow, and check for the truth or definedness of the Perl scalars they represent. Perl references are implemented as an RV, a special type of SV.

  • When an AV is created, it can be created empty or populated with SVs, which makes sense since an array is a collection of scalars.

  • The HV has associated C functions for storing, fetching, deleting, and checking for the existence of key/value pairs in the hash the HV represents.

  • There is also a GV (glob value), which can hold references to any of the values associated with a variable identifier: a scalar value, an array value, a hash value, a subroutine, an I/O handle, or a format.

When you extend Perl, you will sometimes need to know about these values when you create bindings to C functions. When you embed Perl, you'll need to know about these values when you exchange data with the Perl interpreter included in your C program.

Previous | Home | Next
21.1. How Perl Works | Book Index | 21.3. Extending Perl (Using C from Perl)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.3. Extending Perl (Using C from Perl)

If you want to use C source code (or a C library) from Perl, you need to create a library that can be either dynamically loaded or statically linked into your perl executable. (Dynamic loading is usually preferred, to minimize the number of different perl executables sitting around being different.) You create that library by creating an XS file (ending in .xs) containing a series of wrapper subroutines. The wrapper subroutines are not Perl subroutines, however; they are in the XS language, and we call such a subroutine an XSUB, for "eXternal SUBroutine". An XSUB can wrap a C function from an external library, a C function elsewhere in the XS file, or naked C code in the XSUB itself. You then use the xsubpp utility bundled with Perl to take the XS file and translate it into C code that can be compiled into a library that Perl will understand.

Assuming your operating system supports dynamic linking, the end result will be a Perl module that behaves like any other module written in 100% pure Perl, but runs compiled C code under the hood. It does this by pulling arguments from Perl's argument stack, converting the Perl values to the formats expected by a particular C function (specified through an XSUB declaration), calling the C function, and finally transferring the return values of the C function back to Perl. These return values may be passed back to Perl either by putting them on the Perl stack or by modifying the arguments supplied from the Perl side. (If your system doesn't support dynamic linking, you have another hoop to jump through, and we'll discuss that in the next section.)

The previous description is a somewhat simplified view of what really happens. Since Perl allows more flexible calling conventions than C, XSUBs can do much more in practice, such as checking input parameters for validity, throwing exceptions, returning undef or an empty list, calling different C functions based on numbers and types of the arguments, or providing an object-oriented interface. Again, see the perlxs and perlxstut manpages.

21.3.1. XS and XSUBs

XS is a convenience: there's nothing stopping you from writing glue code directly in C and linking it into your Perl executable. However, this would be tedious, especially if you need to write glue for multiple C functions, or if you're not familiar with the Perl stack discipline and other arcana. XS lets you write a concise description of what should be done by the glue, and the XS compiler xsubpp handles the rest.

For people who don't find XS convenient enough, the SWIG system automatically generates simple XSUBs. See http://www.swig.org for more information.

The XS language allows you to describe the mapping between a C function and a Perl function. It also allows you to create a Perl function that is a wrapper around pure C code that you write yourself. When XS is used merely to map between C and Perl, the XSUB declaration is almost identical to a declaration of a C function. In such circumstances, a tool called h2xs (bundled with Perl) is able to translate an entire C header file into a corresponding XS file that provides glue to the C functions and macros.

The xsubpp tool creates the constructs necessary to let an XSUB manipulate Perl values and the glue necessary to let Perl call the XSUB.

An XS file begins with any C code you want to include, which will often be nothing more than a set of #include directives. After a MODULE keyword, the remainder of the file should be in the XS "language", a combination of XS directives and XSUB definitions. We'll see an example of an entire XS file soon, but in the meantime here is a simple XSUB definition that allows a Perl program to access a C library function called sin(3). The XSUB specifies the return type (a double length floating-point number), the function name and argument list (with one argument dubbed x), and the type of the argument (another double):

double
sin(x)
    double x
More complicated XSUBs will often contain other bits of XS code. Each section of an XSUB starts with a keyword followed by a colon, such as INIT: or CLEANUP:. However, the first two lines of an XSUB always contain the same data: a description of the return type and the name of the function and its parameters. Whatever immediately follows these is considered to be an INPUT: section unless explicitly marked with another keyword. The various keywords are all explained in the perlxs manpage, which you should read to learn about everything you can do with XSUBs.

If your system does not have the capability to dynamically load shared libraries, you can still use XSUBs, but you must statically link the XSUBs with the rest of Perl, creating a new Perl executable (to sit around and be different). The XSUB build mechanism will check the system and build a shared library if possible, or else a static library. Optionally, it can build a new statically linked executable with that static library linked in. (But you might want to delay that to bundle all your new extensions into a single executable sitting around being the same, as it were.)

If your system can link libraries dynamically but you still want to build a statically linked executable, you can run make perl instead of make in the following examples. You should then run make test_static instead of make test to test your extension.

The xsubpp program also needs to know how to convert from Perl's data types to C's data types. Often it can guess, but with user-defined types you may need to help it out by specifying the conversion in a typemap file. The default conversions are stored in PATH-TO-PERLLIB/ExtUtils/typemap.

The typemap is split into three sections. The first section, labeled TYPEMAP, tells the compiler which of the code fragments in the following two sections should be used to map between C types and Perl values. The second section, INPUT, contains C code specifying how Perl values should be converted to C types. The third section, OUTPUT, contains C code specifying how to translate C types into Perl values.

21.3.2. Creating Extensions

A proper extension consists of several files: one containing the XS code, plus other supporting files that help Perl figure out what to do with the XS code. You can create all of these files by hand, but it's easier to use the h2xs tool, which creates a skeletal extension that you can then flesh out:

h2xs -A -n Mytest
This creates a directory named Mytest, possibly under ext/ if that directory exists in the current directory. Six files will be created in the Mytest directory: MANIFEST, Makefile.PL, Mytest.pm, Mytest.xs, test.pl, and Changes. We describe the first four below.

MANIFEST

The MANIFEST file contains the names of all the files just created in the Mytest directory. If you add more files to your extension and intend to distribute it to the wide world, add the filenames here. This is tested by some systems to ensure that your distribution is complete.

Makefile.PL

This is a Perl program that generates a Makefile (which is then passed to make or an equivalent). Makefile.PL is described further in "Creating CPAN Modules" in Chapter 22, "CPAN".

Mytest.pm

Users will use this module when they want to load your extension. You're expected to fill in the blanks in the skeletal module created for you by h2xs:

package Mytest;

use strict;
use warnings;

require Exporter;
require DynaLoader;

our @ISA = qw(Exporter DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
our @EXPORT = qw(

);
our $VERSION = '0.01';

bootstrap Mytest $VERSION;

# Preloaded methods go here.

# Autoload methods go after __END__, and are processed by the autosplit program.

1;
__END__
# Below is the stub of documentation for your module. You better edit it!

Most extension modules will require the Exporter and DynaLoader extensions. After setting @ISA (for inheritance) and @EXPORT (to make functions available to the package using the module), the initialization code tells Perl to bootstrap the XS code. Perl then dynamically links the shared library into the perl process at run time.

Mytest.xs

The Mytest.xs file contains the XSUBs that tell Perl how to pass data to the compiled C routines. Initially, Mytest.xs will look something like this:

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

MODULE = Mytest                PACKAGE = Mytest
Let's edit the XS file by adding this to the end of the file:
void
hello()
    CODE:
        printf("Hello, world!\n");

When you run perl Makefile.PL, the Makefile that make needs will be created:

% perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Mytest
Running make will now produce output that looks something like this (some long lines have been shortened for clarity and some extraneous lines have been deleted):
% make
umask 0 && cp Mytest.pm ./blib/Mytest.pm
perl xsubpp -typemap typemap Mytest.xs >Mytest.tc && mv Mytest.tc Mytest.c
cc -c Mytest.c
Running Mkbootstrap for Mytest ()
chmod 644 Mytest.bs
LD_RUN_PATH="" ld -o ./blib/PA-RISC1.1/auto/Mytest/Mytest.sl -b Mytest.o
chmod 755 ./blib/PA-RISC1.1/auto/Mytest/Mytest.sl
cp Mytest.bs ./blib/PA-RISC1.1/auto/Mytest/Mytest.bs
chmod 644 ./blib/PA-RISC1.1/auto/Mytest/Mytest.bs
Manifying ./blib/man3/Mytest.3
We assume that the make program that Perl uses to build programs is called make. Instead of running make in these examples, you may have to substitute whatever make program Perl has been configured to use. You can find out what that program is with:
% perl -V:make

Running make created a directory called blib (for "build library") in the current working directory. This directory will contain the shared library that we will build. Once we're sure we know what we're doing, we can install it from that directory into its final resting place. Until then, we'll have to explicitly add the blib directory to Perl's @INC array by using the ExtUtils::testlib module. If we now create a file called hello that looks like this:

use ExtUtils::testlib;   # adds blib/* directories to @INC
use Mytest;
Mytest::hello();

we can burrow down from Perl into C:

% perl hello
Hello, world!

Once your extension is complete and passes all its tests, you can install it with make install.

You will need write permission for your Perl library. (If you don't have permission, you can specify another directory as shown in "Installing CPAN modules" in Chapter 22, "CPAN".)

21.3.3. XSUB Input and Output

Continuing with the previous example, we'll add a second XSUB, which takes a single numeric argument as input and returns 0 if the number is even, or 1 if the number is odd:

int
is_even(x)
        int x
    CODE:
        RETVAL = (x % 2 == 0);
    OUTPUT:
        RETVAL
The list of output parameters occurs at the very end of the function, just after the OUTPUT: directive. The use of RETVAL tells Perl that you wish to send this value back as the return value of the XSUB. Had we wanted the function to modify its input parameter, we would have used x in place of RETVAL.

We can rebuild our new shared library with the same steps as before, generating a Makefile from the Makefile.PL file and running make.

In order to verify that our extension works, we'll create a test suite in test.pl. This file is set up by h2xs to mimic the test script that Perl itself has. Within the script, you may run tests to confirm that the extension behaves properly, printing ok when it does and not ok when it doesn't. Change the print statement in the BEGIN block of test.pl to print "1..4\n";, and add the following code to the end of the file:

print Mytest::is_even(0) == 1 ? "ok 2" : "not ok 2", "\n";
print Mytest::is_even(1) == 0 ? "ok 3" : "not ok 3", "\n";
print Mytest::is_even(2) == 1 ? "ok 4" : "not ok 4", "\n";
The test script will be executed when you type make test.

21.3.4. Using Functions from an External C Library

So far, our two examples haven't relied on any C code outside of the XS file. Now we'll use some functions from the C math library:

void
round(arg)
        double  arg
    CODE:
        if (arg > 0.0) {
                arg = floor(arg + 0.5);
        } else if (arg < 0.0) {
                arg = ceil(arg - 0.5);
        } else {
                arg = 0.0;
        }
    OUTPUT:
        arg
Note that the round we define above does not return a value, but instead changes the value of its argument in place.

The floor(3) and ceil(3) functions are part of the C math library. If you were compiling a C program and needed to link in the math library, you'd append -lm to the command line, so that's what you put into the LIBS line in Makefile.PL:

'LIBS'  => ['-lm'],   # Link in the 'm' math library
Generate the Makefile and run make. Change the BEGIN block to run nine tests and add the following to test.pl:
$i = -1.5; Mytest::round($i); print $i == -2.0 ? "ok 5" : "not ok 5", "\n";
$i = -1.1; Mytest::round($i); print $i == -1.0 ? "ok 6" : "not ok 6", "\n";
$i = 0.0; Mytest::round($i); print $i == 0.0 ? "ok 7" : "not ok 7", "\n";
$i = 0.5; Mytest::round($i); print $i == 1.0 ? "ok 8" : "not ok 8", "\n";
$i = 1.2; Mytest::round($i); print $i == 1.0 ? "ok 9" : "not ok 9", "\n";
Running make test should now print out that all nine tests are okay.

The perlxstut documentation bundled with Perl has several more examples of Perl extensions, including an example that uses h2xs to automatically make an entire C library available to Perl.

Previous | Home | Next
21.2. Internal Data Types | Book Index | 21.4. Embedding Perl (Using Perl from C)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.4. Embedding Perl (Using Perl from C)

You can access a Perl interpreter from C by embedding Perl inside your C program. Since Perl is itself a C program, embedding consists of taking the important chunks of Perl and integrating them into yours.

Note that embedding isn't necessary if your only goal is to use a standalone Perl program and you don't mind launching a separate process to do so. You can use a function like C's popen(3) to exchange data between your C program and any external Perl program, just like you can use Perl's open(PIPE, "| program") or the IPC::Open2 and IPC::Open3 modules to exchange data between your Perl program and any other program. But if you want to avoid the overhead of launching a separate process, you can embed an interpreter into your C program.

When developing long-running applications (say, for embedding in a web server), it's a good idea to maintain a single persistent interpreter rather than creating and destroying interpreters over and over again. The major reason is speed, since Perl will only be loaded into memory once. By using a persistent Perl interpreter, Apache's mod_perl module avoids loading Perl into memory anew every time someone hits an Apache web page. The perlembed manpage provides an example of a persistent interpreter, as well as an example of how a Perl program can manage multiple simultaneous interpreters (another big plus for web servers).

21.4.1. Compiling Embedded Programs

When you embed Perl in C, your C program will usually allocate, "run", and deallocate a PerlInterpreter object, which is a C struct defined in the libperl library that was built in the process of configuring Perl for your system. The libperl library (along with EXTERN.h and perl.h, which you'll also need) resides in a directory that will vary from system to system. You should be able to find out the name of that directory with:

% perl -MConfig -e "print $Config{archlib}"
You should compile your program in exactly the same way that your perl executable was compiled. First, you'll need to know what C compiler was used to build Perl on your machine. You can learn that from:
% perl -MConfig -e "print $Config{cc}"
You can figure out what to put on the rest of the command line with the standard ExtUtils::Embed module. If you had a C program named interp.c and your C compiler was cc, you could compile it for embedding as follows:
% cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

21.4.2. Adding a Perl Interpreter to Your C Program

As it turns out, perl (the C program) is a good example of embedding Perl (the language), so a simple demonstration of embedding can be found in the file miniperlmain.c, included with the Perl source code. Here's a nonportable version of miniperlmain.c containing the essentials of embedding:

#include <EXTERN.h>               /* from the Perl distribution     */
#include <perl.h>                 /* from the Perl distribution     */

static PerlInterpreter *my_perl;  /***    The Perl interpreter    ***/

int main(int argc, char **argv, char **env)
{
    my_perl = perl_alloc();
    perl_construct(my_perl);
    perl_parse(my_perl, NULL, argc, argv, (char **)NULL);
    perl_run(my_perl);
    perl_destruct(my_perl);
    perl_free(my_perl);
}
When this is compiled with the command line above, you'll be able to use interp just like a regular Perl interpreter:
% interp -e "printf('%x', 3735928559)"
deadbeef
You can also execute Perl statements stored in a file by placing the filename in argv[1] before calling perl_run.

21.4.3. Calling a Perl Subroutine from C

If a Perl program contains a subroutine that you want to call from a C program, you can create a Perl interpreter and then use one of the functions beginning with call_ documented in the perlcall manpage to invoke the subroutine. Let's assume this is our Perl program, called showtime.pl:

print "I shan't be printed.";

sub showtime {
    print time;
}
In this example, we'll use call_argv to invoke the showtime subroutine from this C program, called showtime.c:
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)
{
    char *args[] = { NULL };
    my_perl = perl_alloc();
    perl_construct(my_perl);

    perl_parse(my_perl, NULL, argc, argv, NULL);

    /*** skipping perl_run() ***/

    call_argv("showtime", G_DISCARD | G_NOARGS, args);

    perl_destruct(my_perl);
    perl_free(my_perl);
}
Here, we assume showtime is a Perl subroutine that takes no arguments (that's the G_NOARGS) and for which we can ignore the return value (that's the G_DISCARD). Those flags, and others, are discussed in perlcall. We compile and run showtime as follows:
% cc -o showtime showtime.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
% showtime showtime.pl
963852741
In this particular case, we don't call perl_run, but in general it's considered good form so that DESTROY methods and END blocks are executed at the right time.

If you want to pass arguments to the Perl subroutine, you can add strings to the NULL-terminated args list passed to call_argv. For other data types, or to examine return values, you'll need to manipulate the Perl stack. That's touched on lightly later; for the down and dirty, read the perlcall manpage bundled with Perl.

21.4.4. Evaluating a Perl Statement from C

Perl provides two functions for evaluating snippets of Perl code: eval_sv and eval_pv, described in the perlapi manpage. Arguably, these are the only routines you'll ever need to execute Perl code from within your C program. The code executed can be as long as you wish, contain multiple statements, and employ use, require, or do to include other Perl files.

eval_pv lets you evaluate individual Perl strings and then extract variables for coercion into C types. The following program, string.c, executes three Perl strings, extracting an int from the first, a float from the second, and a char * from the third:

#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

main (int argc, char **argv, char **env)
{
   STRLEN n_a;
   char *embedding[] = { "", "-e", "0" };

   my_perl = perl_alloc();
   perl_construct( my_perl );

   perl_parse(my_perl, NULL, 3, embedding, NULL);
   perl_run(my_perl);

   /** Treat $a as an integer **/
   eval_pv("$a = 3; $a **= 2", TRUE);
   printf("a = %d\n", SvIV(get_sv("a", FALSE)));

   /** Treat $a as a float **/
   eval_pv("$a = 3.14; $a **= 2", TRUE);
   printf("a = %f\n", SvNV(get_sv("a", FALSE)));

   /** Treat $a as a string **/
   eval_pv("$a = 'relreP kcaH rehtonA tsuJ'; $a = reverse($a);", TRUE);
   printf("a = %s\n", SvPV(get_sv("a", FALSE), n_a));

   perl_destruct(my_perl);
   perl_free(my_perl);
}

All of the functions with Sv in their names convert Perl scalars to C types. They're described in the perlguts and perlapi manpages. If you compile and run this program, you'll see the results of using SvIV to create an int, SvNV to create a float, and SvPV to create a C string:

a = 9
a = 9.859600
a = Just Another Hack Perler
In the previous example, we've created a global variable to temporarily store the computed value of our evaluated expression. It is also possible (and in most cases better form) to use the return value of eval_pv instead of throwing it away:
SV *val = eval_pv("reverse 'relreP kcaH rehtonA tsuJ'", TRUE);
printf("%s\n", SvPV(val,n_a));
The perlembed manpage bundled with Perl includes a demonstration of eval_sv that lets you make use of Perl's regular expression capabilities from your C program.

21.4.5. Fiddling with the Perl Stack from C

When trying to explain stacks, most computer science textbooks[2] mumble something about spring-loaded columns of cafeteria plates: the last thing you pushed on the stack is the first thing you pop off. That'll do for our purposes: your C program will push some arguments onto "the Perl stack", shut its eyes while some magic happens, and then pop the results--the return value of your Perl subroutine--off the stack.

[2] Plus the occasional Perl book.

We'll present an example here without much explanation. To really understand what's going on, you'll need to know how to convert between C types and Perl types, with newSViv and sv_setnv and newAV and all their friends described in the perlguts and perlapi manpages. Then you'll need to read perlcall to learn how to manipulate the Perl stack.

Because C has no built-in function for integer exponentiation, let's make Perl's ** operator available to it. (This is less useful than it sounds, since Perl implements ** with C's pow(3) function.) First we'll create an exponentiation function in a library file called power.pl:

sub expo {
    my ($a, $b) = @_;
    return $a ** $b;
}
Now we'll create a C program, power.c, with a function called PerlPower that pushes the two arguments onto the stack, invokes expo, and pops the return value out:
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

/* "Real programmers can write assembly code in any language." */

static void
PerlPower(int a, int b)
{
  dSP;                            /* initialize stack pointer         */
  ENTER;                          /* everything created after here    */
  SAVETMPS;                       /* ...is a temporary variable.      */
  PUSHMARK(SP);                   /* remember the stack pointer       */
  XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack     */
  XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack     */
  PUTBACK;                        /* make local stack pointer global  */
  call_pv("expo", G_SCALAR);      /* call the function                */
  SPAGAIN;                        /* refresh stack pointer            */
                                  /* pop the return value from stack  */
  printf ("%d to the %dth power is %d.\n", a, b, POPi);
  PUTBACK;
  FREETMPS;                       /* free that return value           */
  LEAVE;                          /* ...and the XPUSHed "mortal" args */
}

int main (int argc, char **argv, char **env)
{
  char *my_argv[] = { "", "power.pl" };

  my_perl = perl_alloc();
  perl_construct( my_perl );

  perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
  perl_run(my_perl);

  PerlPower(3, 4);                      /*** Compute 3 ** 4 ***/

  perl_destruct(my_perl);
  perl_free(my_perl);
}
You can compile power.c into power like so:
% cc -o power power.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
% power
3 to the 4th power is 81.
Now your power program can sit around being different too.

Previous | Home | Next
21.3. Extending Perl (Using C from Perl) | Book Index | 21.5. The Moral of the Story
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


21.5. The Moral of the Story

You can sometimes write faster code in C, but you can always write code faster in Perl. Since you can use each from the other, just combine their strengths as you see fit. (And tell the dragons we said "Hi.")

Previous | Home | Next
21.4. Embedding Perl (Using Perl from C) | Book Index | Part 4. Perl as Culture
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part IV. Perl as Culture

Chapter 22: CPAN
Chapter 23: Security
Chapter 24: Common Practices
Chapter 25: Portable Perl
Chapter 26: Plain Old Documentation
Chapter 27: Perl Culture

Previous | Home | Next
21.5. The Moral of the Story | Book Index | 22. CPAN
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 22. CPAN

Contents:

The CPAN modules Directory
Using CPAN Modules
Creating CPAN Modules

CPAN (the Comprehensive Perl Archive Network) is the central repository for everything Perl. It contains the collected wisdom of the entire Perl community: hundreds of Perl modules and scripts, several books' worth of documentation, and the entire Perl distribution. If it's written in Perl, and it's helpful and free, it's probably on CPAN. CPAN is mirrored worldwide, and you can find a nearby mirror with the CPAN multiplexer at http://www.perl.com/CPAN. The multiplexer will remember which mirror you choose so that when you visit http://www.perl.com/CPAN/ (note the trailing slash) you'll be automatically redirected to that mirror. Alternatively, you can start at www.cpan.org. The interface is different, but the data is the same.

Once you get to the main CPAN directory, you'll see some subdirectories:

authors

This directory contains numerous subdirectories, one for each contributor of software. For example, if you wanted to find Lincoln Stein's great CGI module[1] and you happened to know for a fact that he wrote it, you could look in authors/Lincoln_Stein. If you didn't know he wrote it, you could look in the modules directory described below.

[1]Now part of the standard Perl distribution.

doc

This directory holds all manner of Perl documentation, including all of Perl's official manpages in several different arrangements and formats, such as text, HTML, PostScript, and Perl's native pod format, documented in Chapter 26, "Plain Old Documentation".

modules

This directory contains modules written either in Perl or in a combination of both Perl and C. See the discussion of the modules directory below.

ports

This directory contains the source code and sometimes also precompiled executable images of Perl ports to operating systems that are not directly supported in the standard distribution, or for which compilers are notoriously hard to come by. These ports are the individual efforts of their respective authors and may not all function precisely as described in this book. These days few systems should require special ports. The index document of this directory is interesting to look through anyway because it also includes information detailing when each system vendor began shipping Perl.

scripts

This directory contains a small collection of diverse Perl programs from all over the world. These are useful as standalone programs and perhaps as examples (although the code isn't subject to quality control checks). Right now, there aren't many programs listed, but we hope this area will become richer in time. The Perl Power Tools project (PPT) is also to be found here. PPT aims to recreate all the standard Unix utilities in Perl. Most of the standard ones are done already, plus some that aren't standard.

src

Within this directory, you will find the source code for the standard Perl distribution. Actually, for two standard Perl distributions. One is marked stable, and the other devel. (The index page for this directory explains the details.) These are really just links to the appropriate versions. As of this writing, stable.tar.gz is a symbolic link to perl-5.6.0.tar.gz,[2] but it will likely point to a higher version number by the time you read this. This giant file contains the full source code and documentation for Perl. Configuration and installation should be relatively straightforward on most platforms. If not, see ports described earlier.

[2] The general scheme is that if the second number in the version is even, it's a maintenance release; if it's odd, it's a development release. The trailing .tar.gz extension, which is sometimes written .tgz, indicates that it's in the standard Internet format of a GNU-zipped tar archive, commonly known as a "tarball".

22.1. The CPAN modules Directory

Although CPAN contains the complete source code for Perl, plus a few binary distributions for systems bereft of C compilers, as well as a smattering of programs, CPAN is best known for its collection of modules.

When we say "modules", we mean three things: 100% pure Perl modules (described in Chapter 11, "Modules", and Chapter 12, "Objects"), extensions (modules depending on C code, described in Chapter 21, "Internals and Externals"), and pragmas (modules containing special instructions for the Perl compiler, described in Chapter 31, "Pragmatic Modules"). There are also module bundles on CPAN. Bundles are collections of modules that interoperate somehow and are typically the result of a module developer wanting to provide a turnkey solution to a set of problems. If one module depends on another module (and possibly a particular version), developers will often bundle the modules together. See Bundle-XML, for instance.

One way to browse the CPAN modules is to visit http://search.cpan.org, which provides a search engine frontend to CPAN. Another way is to visit your local CPAN mirror and enter the modules directory, where you'll see three subdirectories: by-authors, by-category, and by-name. The by-name directory may be the most useful if your browser has search capabilities--although (lamentably) some modules are only available in the author directories. If you search by category, you'll have the following choices:

Perl core modules, language extensions, and documentation tools

This includes pragmas and other standard modules, modules that help you write Perl differently, modules related to the Perl compiler, source filters, and modules related to Perl's pod documentation format. This category also includes modules for generating Java bytecode.

Development support

This category includes modules for creating modules and examining how Perl runs programs.

Operating system interfaces and hardware drivers

Here you'll find modules for interacting with strange entities like operating systems, PalmPilots, and serial ports.

Networking, device control, and interprocess communication

This includes modules that implement network protocols, manipulate network data, operate modems, and control the appliances in your house.

Data types and data type utilities

This category has modules for math, statistics, algorithms, data structures (and their persistent storage), dates and times, object-oriented programming, PDL (the Perl Data Language, for serious number crunching), and POE (the Perl Object Environment, an object-oriented, event-driven scheduler).

Database interfaces

Here you'll find modules that let you operate several dozen database systems from Perl, most of them with Perl's DBI system. This includes the database-specific DBD modules.

User interfaces (character and graphical)

This includes modules for manipulating user terminals (command-line editing and curses(3)-style character graphics), as well as Perl/Tk and bindings to Gtk, Gnome, Sx, and Qt for writing your own GUIs in Perl.

Interfaces to or emulations of other programming languages

This category has modules for using other programming languages from Perl or letting you pretend that Perl is something it isn't. If you're interested in using Perl from C or C from Perl, see Chapter 21, "Internals and Externals".

Filenames, filesystems, and file locking

This includes modules for inspecting, creating, locking, and otherwise manipulating files and directories.

String processing, language text processing, parsing, and searching

This category contains modules for manipulating text: hyphenating, wrapping, parsing, stemming, and searching. This includes modules for manipulating PostScript, fonts, XML, and RTF.

Option, argument, parameter, and configuration file processing

This category contains modules for processing command-line arguments (the -x in myperlprog -x) and for managing configuration files (like dot files).

Internationalization and locale

This includes modules for tailoring your Perl program for a particular country and language.

Authentication, security, and encryption

Here you'll find modules for managing user passwords, computing message digests, encrypting data, and authenticating users.

World Wide Web, HTML, HTTP, CGI, MIME

This category has modules that let you create CGI-based web pages, web robots, and web-based content management systems. Other modules let you manage cookies, parse HTML and MIME messages, and manipulate web caches. There is also a special section just for Perl modules that you can embed into the Apache web server.

Server and daemon utilities

This includes modules for creating network and event servers.

Archiving, compression, and conversion

Here you'll find modules for zipping and tarring files, and converting between file formats (even the Apple II file format).

Images, pixmap, and bitmap manipulation, drawing, and graphing

This category contains modules for creating graphs, GIFs, VRML, and for working with the Gimp.

Mail and Usenet news

In this category, you'll find modules for sending, receiving, and filtering mail and netnews.

Control flow utilities

This category contains modules for executing Perl code at odd times.

Filehandle, directory handle, and input/output stream utilities

Here are modules for input from and output to files, including log files. Includes all IO:: modules and an Expect module for automating conversations with network services or other interactive programs.

Microsoft Windows modules

This includes modules for manipulating the Windows registry, ASP, ODBC, OLE, and other technologies specific to Windows.

Miscellaneous modules

Here you'll find modules for astronomy, biology, chemistry, validating credit cards (or invalidating credit cards), mortgage amortizations, audio, video, MIDI, weather, and games.

Previous | Home | Next
 | 22.2. Using CPAN Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.2. Using CPAN Modules

Most modules that you'll find on CPAN are in "tarball" form. That is, they have a file extension ending in .tar.gz, and expand into a directory with the module code and any auxiliary files, usually including a README and a Makefile.PL file.

There are four steps for making CPAN modules available to your programs: decompression, unpacking, building, and installation. How each of those steps work depend on your operating system and the module being installed, so we can't give you a foolproof recipe that will work all the time. When in doubt, read the README and INSTALL files that were hopefully distributed with the module. Also read the perlmodinstall manpage.

But you may never have to think about the installation procedure if you use the CPAN module (bundled with the Perl distribution) or PPM (the Perl Package Manager, bundled with the ActiveState distribution of Perl). To use the CPAN module (not to be confused with CPAN itself), type:

% perl -MCPAN -e "shell"
at your command line to begin the configuration process. After you've answered a variety of questions about how you'd like to retrieve files, you can install a module by typing:
install Some::Module
in the CPAN module's shell, or by typing:
% perl -MCPAN -e "install 'Some::Module'"
from your normal command line.

If you don't have the convenience of either the CPAN module or PPM, you'll need to go through the steps in the following sections by hand. Instructions are provided for Unix, Windows, and Macintosh; for other operating systems, consult the perlmodinstall manpage.

22.2.1. Decompressing and Unpacking CPAN Modules

Most of the thousands of utilities on CPAN are compressed so that they take up less space. Once you've retrieved a module tarball, you first need to turn it into a directory tree on your system by decompressing ("unzipping") and unpacking the tarball. On Unix, you can use gzip and tar to do this. (On many systems, tar will do both.) On Windows, WinZip will both decompress and unpack tarballs. On a Macintosh, you can either use StuffIt and DropStuff, MacGzip, or suntar.

22.2.2. Building CPAN Modules

A minority of CPAN modules come with C code that you'll need to compile for your system, which is naturally a problem for systems that lack a C compiler. The standard procedure for building a CPAN module (with or without C code) is the following three commands, executed from the command line. (If you don't have a command line, or a make-equivalent, you'll need to resort to more drastic, system-dependent measures. Windows users have a command line but might need to use the nmake utility instead of make.)

% perl Makefile.PL

% make

% make test
The perl Makefile.PL command will try to create a Makefile, which the subsequent make command uses to determine what utilities need to be built and in what order. The final command, make test, runs the test suite that the module author hopefully included.

22.2.3. Installing CPAN Modules into the Perl Library

Presuming you've followed the previous steps, you now have a module that has been built and tested, but not yet installed into Perl's library. When Perl was installed on your system, a lib directory was created to hold modules, pragmas, and related files. That's the Perl library, which is usually something like /usr/local/lib/perl5 on Unix systems and C:\PERL\LIB by default on Windows systems. Modules installed after Perl was built are stored in the site_perl subdirectory of the Perl library. You can see the names of all your library directories (and a bunch of other stuff) by saying:

% perl -V
To install the module, type:
% make install
Superuser access is normally required, even for installing modules into your site-specific Perl library directories.

With a little work, you can install the module in a directory outside your Perl library (such as your home directory). If you would normally have typed perl Makefile.PL to create a Makefile, you could instead use this incantation:

% perl Makefile.PL LIB=/my/dir/perllib  \
        INSTALLMAN1DIR=/my/dir/man/man1 \
        INSTALLMAN3DIR=/my/dir/man/man3 \
            INSTALLBIN=/my/dir/bin      \
         INSTALLSCRIPT=/my/dir/scripts
This will install the modules somewhere in the /my/dir/perllib directory and any remaining files where they need to go. (If you find yourself typing this a lot, you could even write a little Perl program to do it for you. Perl is good for things like that.)

Then you can have Perl search your special directory for modules by adding:

use lib "/my/dir/perllib";
before your program attempts to load in the module. You may also set the PERL5LIB environment variable to that directory, or use Perl's -I switch. See the use lib pragma in Chapter 31, "Pragmatic Modules" for examples of doing this.

Previous | Home | Next
22.1. The CPAN modules Directory | Book Index | 22.3. Creating CPAN Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


22.3. Creating CPAN Modules

If you have a module that you think others might find useful, consider making the world a better place by uploading it to CPAN. The server that handles new module submissions is called PAUSE (the Perl Authors Upload Server) and can be found at https://pause.kbx.de/pause/. Before you can upload your module, you'll have to get a PAUSE account. This is about as close as you can get to being a "registered Perl developer".

If you call yourself a registered Perl developer, you should know enough to document your modules. Perl has a convention of embedding documentation inside your source code. (That way, you never lose it.) This embedded documentation is in a format called "pod" (for Plain Old Documentation) and is described in Chapter 26, "Plain Old Documentation".

You should consider making your module thread safe. See Chapter 17, "Threads".

You should also worry a little bit about whether your cute little module does things that could break the security of people who use it, because other folks may have some Really Good Reasons to be more concerned about security than you are (yet). See Chapter 23, "Security", for all about how to avoid being responsible for the outbreak of World War III and other such nuisances.

Modules meant to be distributed on CPAN should include a Perl program named Makefile.PL that, when run, generates a Makefile, and a README file briefly explaining what the module is and how to install it. The Makefile will expect your module to include a test suite as well. You can create all these files at once with the h2xs utility:

h2xs -X -n Foo::Bar
(Substitute -A for -X if you're building a module that has an XS component. XS is described in Chapter 21, "Internals and Externals".) The h2xs program creates a single directory with skeletal files for you to flesh out. When you've finished, you can upload the tarballed directory to PAUSE.

The Makefile.PL generated by h2xs will look something like this:

use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME         => 'Mytest',
    VERSION_FROM => 'Mytest.pm', # finds $VERSION
    LIBS         => [''],   # e.g., '-lm'
    DEFINE       => '',     # e.g., '-DHAVE_SOMETHING'
    INC          => '',     # e.g., '-I/usr/include/other'
);
The first thing Makefile.PL does is to pull in the ExtUtils::MakeMaker module. MakeMaker's WriteMakefile function has oodles of options (where oodles is defined as approximately 88) to help you customize what happens after the user downloads your module from CPAN and types perl MakeFile.PL to begin building it. The nice thing about all this is that, since the user is presumably running the perl that will be used later, you have a wealth of configuration information available (via the Config module or the $^O special variable) to help you decide how to drive MakeMaker. On the other hand, MakeMaker is really good at finding decent defaults for almost everything, so the skeletal file written h2xs may well be all you need, with perhaps a tweak or two. For more on this, see the extensive online docs for ExtUtils::MakeMaker.

When writing a Perl module for general consumption, you should allow for the possibility that the user's version of Perl may differ from yours. You should always put an English description of any dependencies (particular versions of Perl, or system requirements, or other modules) into the README file. However, even that may not be sufficient, since someone using the slick CPAN module to automatically download and install your module might never see the warning. So you should check those dependencies in Makefile.PL. Here's how you might ensure that the person who downloaded your module is running Perl 5.6 or greater:

eval { require 5.6.0 }
    or die <<'EOD';
############
### This module requires lvaluable subroutines, which are not available
### in versions of Perl earlier than 5.6.  Please upgrade!
############
EOD

22.3.1. Internal Testing

The standard instructions for installing a module tell the user to run make test after building the module with make. So please include a decent test script with any module that you upload to CPAN. You should emulate the ok/not ok style that Perl uses in its own test suite, so that it's easy for the user to determine the outcome of each test case. The test.pl file generated by h2xs will help get you started. Chapter 21, "Internals and Externals" has some examples of tests that you can add to the end of test.pl.

If you have many test cases, you might want to mimic Perl's test suite by creating a subdirectory named t/ in the module's directory and appending .t to the names of your different test scripts. When you run make test, all test files will be executed automatically.

22.3.2. External Testing

Modules uploaded to CPAN are tested by a variety of volunteers on different platforms. These CPAN testers are notified by mail of each new upload, and reply to the list with PASS, FAIL, NA (not applicable to this platform), or UNKNOWN (unknown), along with any relevant notations. You can find the mailing list for CPAN testers at cpan-testers@perl.org; test results are posted at http://testers.cpan.org/.

That's all just the preliminary testing, of course. The real testing begins when someone plugs your little module into a web server that's cranking out a million pages a day. Or uses your module to help design the airplane you'll be riding in someday soon.

So go ahead, skip writing those pesky little tests. See if we care...

Previous | Home | Next
22.2. Using CPAN Modules | Book Index | 23. Security
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 23. Security

Contents:

Handling Insecure Data
Handling Timing Glitches
Handling Insecure Code

Whether you're dealing with a user sitting at the keyboard typing commands or someone sending information across the network, you need to be careful about the data coming into your programs, since the other person may, either maliciously or accidentally, send you data that will do more harm than good. Perl provides a special security-checking mechanism called taint mode, whose purpose is to isolate tainted data so that you won't use it to do something you didn't intend to do. For instance, if you mistakenly trust a tainted filename, you might end up appending an entry to your password file when you thought you were appending to a log file. The mechanism of tainting is covered in the section Section 23.1, "Handling Insecure Data".

In multitasking environments, offstage actions by unseen actors can affect the security of your own program. If you presume exclusive ownership of external objects (especially files) as though yours were the only process on the system, you expose yourself to errors substantially subtler than those that come from directly handling data or code of dubious provenance. Perl helps you out a little here by detecting some situations that are beyond your control, but for those that you can control, the key is understanding which approaches are proof against unseen meddlers. The section Section 23.2, "Handling Timing Glitches" discusses these matters.

If the data you get from a stranger happens to be a bit of source code to execute, you need to be even more careful than you would with their data. Perl provides checks to intercept stealthy code masquerading as data so you don't execute it unintentionally. If you do want to execute foreign code, though, the Safe module lets you quarantine suspect code where it can't do any harm and might possibly do some good. These are the topics of the section Section 23.3, "Handling Insecure Code".

23.1. Handling Insecure Data

Perl makes it easy to program securely even when your program is being used by someone less trustworthy than the program itself. That is, some programs need to grant limited privileges to their users, without giving away other privileges. Setuid and setgid programs fall into this category on Unix, as do programs running in various privileged modes on other operating systems that support such notions. Even on systems that don't, the same principle applies to network servers and to any programs run by those servers (such as CGI scripts, mailing list processors, and daemons listed in /etc/inetd.conf). All such programs require a higher level of scrutiny than normal.

Even programs run from the command line are sometimes good candidates for taint mode, especially if they're meant to be run by a privileged user. Programs that act upon untrusted data, like those that generate statistics from log files or use LWP::* or Net::* to fetch remote data, should probably run with tainting explicitly turned on; programs that are not prudent risk being turned into "Trojan horses". Since programs don't get any kind of thrill out of risk taking, there's no particular reason for them not to be careful.

Compared with Unix command-line shells, which are really just frameworks for calling other programs, Perl is easy to program securely because it's straightforward and self-contained. Unlike most shell programming languages, which are based on multiple, mysterious substitution passes on each line of the script, Perl uses a more conventional evaluation scheme with fewer hidden snags. Additionally, because the language has more built-in functionality, it can rely less upon external (and possibly untrustworthy) programs to accomplish its purposes.

Under Unix, Perl's home town, the preferred way to compromise system security was to cajole a privileged program into doing something it wasn't supposed to do. To stave off such attacks, Perl developed a unique approach for coping with hostile environments. Perl automatically enables taint mode whenever it detects its program running with differing real and effective user or group IDs.[1] Even if the file containing your Perl script doesn't have the setuid or setgid bits turned on, that script can still find itself executing in taint mode. This happens if your script was invoked by another program that was itself running under differing IDs. Perl programs that weren't designed to operate under taint mode tend to expire prematurely when caught violating safe tainting policy. This is just as well, since these are the sorts of shenanigans that were historically perpetrated on shell scripts to compromise system security. Perl isn't that gullible.

[1] The setuid bit in Unix permissions is mode 04000, and the setgid bit is 02000; either or both may be set to grant the user of the program some of the privileges of the owner (or owners) of the program. (These are collectively known as set-id programs.) Other operating systems may confer special privileges on programs in other ways, but the principle is the same.

You can also enable taint mode explicitly with the -T command-line switch. You should do this for daemons, servers, and any programs that run on behalf of someone else, such as CGI scripts. Programs that can be run remotely and anonymously by anyone on the Net are executing in the most hostile of environments. You should not be afraid to say "No!" occasionally. Contrary to popular belief, you can exercise a great deal of prudence without dehydrating into a wrinkled prude.

On the more security-conscious sites, running all CGI scripts under the -T flag isn't just a good a idea: it's the law. We're not claiming that running in taint mode is sufficient to make your script secure. It's not, and it would take a whole book just to mention everything that would. But if you aren't executing your CGI scripts under taint mode, you've needlessly abandoned the strongest protection Perl can give you.

While in taint mode, Perl takes special precautions called taint checks to prevent traps both obvious and subtle. Some of these checks are reasonably simple, such as verifying that dangerous environment variables aren't set and that directories in your path aren't writable by others; careful programmers have always used checks like these. Other checks, however, are best supported by the language itself, and it is these checks especially that contribute to making a privileged Perl program more secure than the corresponding C program, or a Perl CGI script more secure than one written in any language without taint checks. (Which, as far as we know, is any language other than Perl.)

The principle is simple: you may not use data derived from outside your program to affect something else outside your program--at least, not by accident. Anything that comes from outside your program is marked as tainted, including all command-line arguments, environment variables, and file input. Tainted data may not be used directly or indirectly in any operation that invokes a subshell, nor in any operation that modifies files, directories, or processes. Any variable set within an expression that has previously referenced a tainted value becomes tainted itself, even if it is logically impossible for the tainted value to influence the variable. Because taintedness is associated with each scalar, some individual values in an array or hash might be tainted and others might not. (Only the values in a hash can be tainted, though, not the keys.)

The following code illustrates how tainting would work if you executed all these statements in order. Statements marked "Insecure" will trigger an exception, whereas those that are "OK" will not.

$arg = shift(@ARGV);          # $arg is now tainted (due to @ARGV).
$hid = "$arg, 'bar'";         # $hid also tainted (due to $arg).
$line = <>;                   # Tainted (reading from external file).
$path = $ENV{PATH};           # Tainted due to %ENV, but see below.
$mine = 'abc';                # Not tainted.

system "echo $mine";          # Insecure until PATH set.
system "echo $arg";           # Insecure: uses sh with tainted $arg.
system "echo", $arg;          # OK once PATH set (doesn't use sh).
system "echo $hid";           # Insecure two ways: taint, PATH.

$oldpath = $ENV{PATH};        # $oldpath is tainted (due to $ENV).
$ENV{PATH} = '/bin:/usr/bin'; # (Makes it OK to execute other programs.)
$newpath = $ENV{PATH};        # $newpath is NOT tainted.

delete @ENV{qw{IFS
               CDPATH
               ENV
               BASH_ENV}};    # Makes %ENV safer.

system "echo $mine";          # OK, is secure once path is reset.
system "echo $hid";           # Insecure via tainted $hid.

open(OOF, "< $arg");          # OK (read-only opens not checked).
open(OOF, "> $arg");          # Insecure (trying to write to tainted arg).

open(OOF, "echo $arg|")       # Insecure due to tainted $arg, but...
    or die "can't pipe from echo: $!";

open(OOF,"-|")                # Considered OK: see below for taint
    or exec "echo", $arg      #   exemption on exec'ing a list.
    or die "can't exec echo: $!";

open(OOF,"-|", "echo", $arg   # Same as previous, likewise OKish.
    or die "can't pipe from echo: $!";

$shout = `echo $arg`;         # Insecure via tainted $arg.
$shout = `echo abc`;          # $shout is tainted due to backticks.
$shout2 = `echo $shout`;      # Insecure via tainted $shout.

unlink $mine, $arg;           # Insecure via tainted $arg.
umask $arg;                   # Insecure via tainted $arg.

exec "echo $arg";             # Insecure via tainted $arg passed to shell.
exec "echo", $arg;            # Considered OK! (But see below.)
exec "sh", '-c', $arg;        # Considered OK, but isn't really!

If you try to do something insecure, you get an exception (which unless trapped, becomes a fatal error) such as "Insecure dependency" or "Insecure $ENV{PATH}". See the section Section 23.1.2, "Cleaning Up Your Environment" later.

If you pass a LIST to a system, exec, or pipe open, the arguments are not inspected for taintedness, because with a LIST of arguments, Perl doesn't need to invoke the potentially dangerous shell to run the command. You can still easily write an insecure system, exec, or pipe open using the LIST form, as demonstrated in the final example above. These forms are exempt from checking because you are presumed to know what you're doing when you use them.

Sometimes, though, you can't tell how many arguments you're passing. If you supply these functions with an array[2] that contains just one element, then it's just as though you passed one string in the first place, so the shell might be used. The solution is to pass an explicit path in the indirect-object slot:

system @args;                 # Won't call the shell unless @args == 1.
system { $args[0] } @args;    # Bypasses shell even with one-argument list.

[2]Or a function that produces a list.

23.1.1. Detecting and Laundering Tainted Data

To test whether a scalar variable contains tainted data, you can use the following is_tainted function. It makes use of the fact that eval STRING raises an exception if you try to compile tainted data. It doesn't matter that the $nada variable used in the expression to compile will always be empty; it will still be tainted if $arg is tainted. The outer eval BLOCK isn't doing any compilation. It's just there to catch the exception raised if the inner eval is given tainted data. Since the $@ variable is guaranteed to be nonempty after each eval if an exception was raised and empty otherwise, we return the result of testing whether its length was zero:

sub is_tainted {
    my $arg = shift;
    my $nada = substr($arg, 0, 0);  # zero-length
    local $@;  # preserve caller's version
    eval { eval "# $nada" };
    return length($@) != 0;
}
But testing for taintedness only gets you so far. Usually you know perfectly well which variables contain tainted data--you just have to clear the data's taintedness. The only official way to bypass the tainting mechanism is by referencing submatches returned by an earlier regular expression match.[3] When you write a pattern that contains capturing parentheses, you can access the captured substrings through match variables like $1, $2, and $+, or by evaluating the pattern in list context. Either way, the presumption is that you knew what you were doing when you wrote the pattern and wrote it to weed out anything dangerous. So you need to give it some real thought--never blindly untaint, or else you defeat the entire mechanism.

[3]An unofficial way is by storing the tainted string as the key to a hash and fetching back that key. Because keys aren't really full SVs (internal name scalar values), they don't carry the taint property. This behavior may be changed someday, so don't rely on it. Be careful when handling keys, lest you unintentionally untaint your data and do something unsafe with them.

It's better to verify that the variable contains only good characters than to check whether it contains any bad characters. That's because it's far too easy to miss bad characters that you never thought of. For example, here's a test to make sure $string contains nothing but "word" characters (alphabetics, numerics, and underscores), hyphens, at signs, and dots:

if ($string =~ /^([-\@\w.]+)$/) {
    $string = $1;                     # $string now untainted.
}
else {
    die "Bad data in $string";        # Log this somewhere.
}

This renders $string fairly secure to use later in an external command, since /\w+/ doesn't normally match shell metacharacters, nor are those other characters going to mean anything special to the shell.[4] Had we used /(.+)/s instead, it would have been unsafe because that pattern lets everything through. But Perl doesn't check for that. When untainting, be exceedingly careful with your patterns. Laundering data by using regular expressions is the only approved internal mechanism for untainting dirty data. And sometimes it's the wrong approach entirely. If you're in taint mode because you're running set-id and not because you intentionally turned on -T, you can reduce your risk by forking a child of lesser privilege; see the section Section 23.1.2, "Cleaning Up Your Environment".

[4] Unless you were using an intentionally broken locale. Perl assumes that your system's locale definitions are potentially compromised. Hence, when running under the use locale pragma, patterns with a symbolic character class in them, such as \w or [[:alpha:]], produce tainted results.

The use re 'taint' pragma disables the implicit untainting of any pattern matches through the end of the current lexical scope. You might use this pragma if you just want to extract a few substrings from some potentially tainted data, but since you aren't being mindful of security, you'd prefer to leave the substrings tainted to guard against unfortunate accidents later.

Imagine you're matching something like this, where $fullpath is tainted:

($dir, $file) = $fullpath =~ m!(.*/)(.*)!s;
By default, $dir and $file would now be untainted. But you probably didn't want to do that so cavalierly, because you never really thought about the security issues. For example, you might not be terribly happy if $file contained the string "; rm -rf * ;", just to name one rather egregious example. The following code leaves the two result variables tainted if $fullpath was tainted:
{
    use re 'taint';
    ($dir, $file) = $fullpath =~ m!(.*/)(.*)!s;
}
A good strategy is to leave submatches tainted by default over the whole source file and only selectively permit untainting in nested scopes as needed:
use re 'taint';
# remainder of file now leaves $1 etc tainted
{
    no re 'taint';
    # this block now untaints re matches
    if ($num =~ /^(\d+)$/) {
        $num = $1;
    }
}
Input from a filehandle or a directory handle is automatically tainted, except when it comes from the special filehandle, DATA. If you want to, you can mark other handles as trusted sources via the IO::Handle module's untaint function:
use IO::Handle;

IO::Handle::untaint(*SOME_FH);          # Either procedurally
SOME_FH->untaint();                     # or using the OO style.
Turning off tainting on an entire filehandle is a risky move. How do you really know it's safe? If you're going to do this, you should at least verify that nobody but the owner can write to the file.[5] If you're on a Unix filesystem (and one that prudently restricts chown(2) to the superuser), the following code works:
use File::stat;
use Symbol 'qualify_to_ref';
sub handle_looks_safe(*) {
    my $fh = qualify_to_ref(shift, caller);
    my $info = stat($fh);
    return unless $info;

    # owner neither superuser nor "me", whose
    # real uid is in the $< variable
    if ($info->uid != 0 && $info->uid != $<) {
        return 0;
    }

    # check whether group or other can write file.
    # use 066 to detect for readability also
    if ($info->mode & 022) {
        return 0;
    }
    return 1;
}

use IO::Handle;
SOME_FH->untaint() if handle_looks_safe(*SOME_FH);
We called stat on the filehandle, not the filename, to avoid a dangerous race condition. See the section Section 23.2.2, "Handling Race Conditions" later in this chapter.

[5] Although you can untaint a directory handle, too, this function only works on a filehandle. That's because given a directory handle, there's no portable way to extract its file descriptor to stat.

Note that this routine is only a good start. A slightly more paranoid version would check all parent directories as well, even though you can't reliably stat a directory handle. But if any parent directory is world-writable, you know you're in trouble whether or not there are race conditions.

Perl has its own notion of which operations are dangerous, but it's still possible to get into trouble with other operations that don't care whether they use tainted values. It's not always enough to be careful of input. Perl output functions don't test whether their arguments are tainted, but in some environments, this matters. If you aren't careful of what you output, you might just end up spitting out strings that have unexpected meanings to whoever is processing the output. If you're running on a terminal, special escape and control codes could cause the viewer's terminal to act strangely. If you're in a web environment and you blindly spit back out data that was given to you, you could unknowingly produce HTML tags that would drastically alter the page's appearance. Worse still, some markup tags can even execute code back on the browser.

Imagine the common case of a guest book where visitors enter their own messages to be displayed when others come calling. A malicious guest could supply unsightly HTML tags or put in <SCRIPT>...</SCRIPT> sequences that execute code (like JavaScript) back in the browsers of subsequent guests.

Just as you should carefully check for only good characters when inspecting tainted data that accesses resources on your own system, you should apply the same care in a web environment when presenting data supplied by a user. For example, to strip the data of any character not in the specified list of good characters, try something like this:

$new_guestbook_entry =~ tr[_a-zA-Z0-9 ,./!?()@+*-][]dc;
You certainly wouldn't use that to clean up a filename, since you probably don't want filenames with spaces or slashes, just for starters. But it's enough to keep your guest book free of sneaky HTML tags and entities. Each data-laundering case is a little bit different, so always spend time deciding what is and what is not permitted. The tainting mechanism is intended to catch stupid mistakes, not to remove the need for thought.

23.1.2. Cleaning Up Your Environment

When you execute another program from within your Perl script, no matter how, Perl checks to make sure your PATH environment variable is secure. Since it came from your environment, your PATH starts out tainted, so if you try to run another program, Perl raises an "Insecure $ENV{PATH}" exception. When you set it to a known, untainted value, Perl makes sure that each directory in that path is nonwritable by anyone other than the directory's owner and group; otherwise, it raises an "Insecure directory" exception.

You may be surprised to find that Perl cares about your PATH even when you specify the full pathname of the command you want to execute. It's true that with an absolute filename, the PATH isn't used to find the executable to run. But there's no reason to trust the program you're running not to turn right around and execute some other program and get into trouble because of the insecure PATH. So Perl forces you to set a secure PATH before you call any program, no matter how you say to call it.

The PATH isn't the only environment variable that can bring grief. Because some shells use the variables IFS, CDPATH, ENV, and BASH_ENV, Perl makes sure that those are all either empty or untainted before it will run another command. Either set these variables to something known to be safe, or else delete them from the environment altogether:

delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};   # Make %ENV safer
Features convenient in a normal environment can become security concerns in a hostile one. Even if you remember to disallow filenames containing newlines, it's important to understand that open accesses more than just named files. Given appropriate ornamentation on the filename argument, one- or two-argument calls to open can also run arbitrary external commands via pipes, fork extra copies of the current process, duplicate file descriptors, and interpret the special filename "-" as an alias for standard input or output. It can also ignore leading and trailing whitespace that might disguise such fancy arguments from your check patterns. While it's true that Perl's taint checking will catch tainted arguments used for pipe opens (unless you use a separated argument list) and any file opens that aren't read-only, the exception this raises is still likely to make your program misbehave.

If you intend to use any externally derived data as part of a filename to open, at least include an explicit mode separated by a space. It's probably safest, though, to use either the low-level sysopen or the three-argument form of open:

# Magic open--could be anything
open(FH, $file)             or die "can't magic open $file: $!";

# Guaranteed to be a read-only file open and not a pipe
# or fork, but still groks file descriptors and "-",
# and ignores whitespace at either end of name.
open(FH, "< $file")         or die "can't open $file: $!";

# WYSIWYG open: disables all convenience features.
open(FH, "<", $file)        or die "can't open $file: $!";

# Same properties as WYSIWYG 3-arg version.
require Fcntl;
sysopen(FH, $file, O_RDONLY)        or die "can't sysopen $file: $!";
Even these steps aren't quite good enough. Perl doesn't prevent you from opening tainted filenames for reading, so you need to be careful of what you show people. A program that opens an arbitrary, user-supplied filename for reading and then reveals that file's contents is still a security problem. What if it's a private letter? What if it's your system password file? What if it's salary information or your stock portfolio?

Look closely at filenames provided by a potentially hostile user[6] before opening them. For example, you might want to verify that there are no sneaky directory components in the path. Names like "../../../../../../../etc/passwd" are notorious tricks of this sort. You can protect yourself by making sure there are no slashes in the pathname (assuming that's your system's directory separator). Another common trick is to put newlines or semicolons into filenames that will later be interpreted by some poor, witless command-line interpreter that can be fooled into starting a new command in the middle of the filename. This is why taint mode discourages uninspected external commands.

[6]And on the Net, the only users you can trust not to be potentially hostile are the ones who are being actively hostile instead.

23.1.3. Accessing Commands and Files Under Reduced Privileges

The following discussion pertains to some nifty security facilities of Unix-like systems. Users of other systems may safely (or rather, unsafely) skip this section.

If you're running set-id, try to arrange that, whenever possible, you do dangerous operations with the privileges of the user, not the privileges of the program. That is, whenever you're going to call open, sysopen, system, backticks, and any other file or process operations, you can protect yourself by setting your effective UID or GID back to the real UID or GID. In Perl, you can do this for setuid scripts by saying $> = $< (or $EUID = $UID if you use English) and for setgid scripts by saying $( = $) ($EGID = $GID). If both IDs are set, you should reset both. However, sometimes this isn't feasible, because you might still need those increased privileges later in your program.

For those cases, Perl provides a reasonably safe way to open a file or pipe from within a set-id program. First, fork a child using the special open syntax that connects the parent and child by a pipe. In the child, reset the user and group IDs back to their original or known safe values. You also get to modify any of the child's per-process attributes without affecting the parent, letting you change the working directory, set the file creation mask, or fiddle with environment variables. No longer executing under extra privileges, the child process at last calls open and passes whatever data it manages to access on behalf of the mundane but demented user back up to its powerful but justly paranoid parent.

Even though system and exec don't use the shell when you supply them with more than one argument, the backtick operator admits no such alternative calling convention. Using the forking technique, we easily emulate backticks without fear of shell escapes, and with reduced (and therefore safer) privileges:

use English;   # to use $UID, etc
die "Can't fork open: $!"   unless defined($pid = open(FROMKID, "-|"));
if ($pid) {           # parent
    while (<FROMKID>) {
        # do something
    }
    close FROMKID;
}
else {
    $EUID = $UID;  # setuid(getuid())
    $EGID = $GID;  # setgid(getgid()), and initgroups(2) on getgroups(2)
    chdir("/")      or die "can't chdir to /: $!";
    umask(077);
    $ENV{PATH} = "/bin:/usr/bin";
    exec 'myprog', 'arg1', 'arg2';
    die "can't exec myprog: $!";
}
This is by far the best way to call other programs from a set-id script. You make sure never to use the shell to execute anything, and you drop your privileges before you yourself exec the program. (But because the list forms of system, exec, and pipe open are specifically exempted from taint checks on their arguments, you must still be careful of what you pass in.)

If you don't need to drop privileges, and just want to implement backticks or a pipe open without risking the shell intercepting your arguments, you could use this:

open(FROMKID, "-|") or exec("myprog", "arg1", "arg2")
    or die "can't run myprog: $!";
and then just read from FROMKID in the parent. As of the 5.6.1 release of Perl, you can write that as:
open(FROMKID, "-|", "myprog", "arg1", "arg2");
The forking technique is useful for more than just running commands from a set-id program. It's also good for opening files under the ID of whoever ran the program. Suppose you had a setuid program that needed to open a file for writing. You don't want to run the open under your extra privileges, but you can't permanently drop them, either. So arrange for a forked copy that's dropped its privileges to do the open for you. When you want to write to the file, write to the child, and it will then write to the file for you.
use English;

defined ($pid = open(SAFE_WRITER, "|-"))
    or die "Can't fork: $!";

if ($pid) {
    # you're the parent. write data to SAFE_WRITER child
    print SAFE_WRITER "@output_data\n";
    close SAFE_WRITER
        or die $! ? "Syserr closing SAFE_WRITER writer: $!"
                  : "Wait status $? from SAFE_WRITER writer";
}
else {
    # you're the child, so drop extra privileges
    ($EUID, $EGID) = ($UID, $GID);

    # open the file under original user's rights
    open(FH, "> /some/file/path")
        or die "can't open /some/file/path for writing: $!";

    # copy from parent (now stdin) into the file
    while (<STDIN>) {
        print FH $_;
    }
    close(FH)   or die "close failed: $!";
    exit;       # Don't forget to make the SAFE_WRITER disappear.
}
Upon failing to open the file, the child prints an error message and exits. When the parent writes to the now-defunct child's filehandle, it triggers a broken pipe signal (SIGPIPE), which is fatal unless trapped or ignored. See the section Section 23.1, "Signals" in Chapter 16, "Interprocess Communication".

Previous | Home | Next
22.3. Creating CPAN Modules | Book Index | 23.2. Handling Timing Glitches
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


23.2. Handling Timing Glitches

Sometimes your program's behavior is exquisitely sensitive to the timing of external events beyond your control. This is always a concern when other programs, particularly inimical ones, might be vying with your program for the same resources (such as files or devices). In a multitasking environment, you cannot predict the order in which processes waiting to run will be granted access to the processor. Instruction streams among all eligible processes are interleaved, so first one process gets some CPU, and then another process, and so on. Whose turn it is to run, and how long they're allowed to run, appears to be random. With just one program that's not a problem, but with several programs sharing common resources, it can be.

Thread programmers are especially sensitive to these issues. They quickly learn not to say:

$var++ if $var == 0;
when they should say:
{
    lock($var);
    $var++ if $var == 0;
}
The former produces unpredictable results when multiple execution threads attempt to run this code at the same time. (See Chapter 17, "Threads".) If you think of files as shared objects, and processes as threads contending for access to those shared objects, you can see how the same issues arise. A process, after all, is really just a thread with an attitude. Or vice versa.

Timing unpredictabilities affect both privileged and nonprivileged situations. We'll first describe how to cope with a long-standing bug in old Unix kernels that affects any set-id program. Then we'll move on to discuss race conditions in general, how they can turn into security holes, and steps you can take to avoid falling into these holes.

23.2.1. Unix Kernel Security Bugs

Beyond the obvious problems that stem from giving special privileges to interpreters as flexible and inscrutable as shells, older versions of Unix have a kernel bug that makes any set-id script insecure before it ever gets to the interpreter. The problem is not the script itself, but a race condition in what the kernel does when it finds a set-id executable script. (The bug doesn't exist on machines that don't recognize #! in the kernel.) When a kernel opens such a file to see which interpreter to run, there's a delay before the (now set-id) interpreter starts up and reopens the file. That delay gives malicious entities a chance to change the file, especially if your system supports symbolic links.

Fortunately, sometimes this kernel "feature" can be disabled. Unfortunately, there are a couple of different ways to disable it. The system can outlaw scripts with the set-id bits set, which doesn't help much. Alternatively, it can ignore the set-id bits on scripts. In the latter case, Perl can emulate the setuid and setgid mechanism when it notices the (otherwise useless) set-id bits on Perl scripts. It does this via a special executable called suidperl, which is automatically invoked for you if it's needed.[7]

[7]Needed and permitted--if Perl detects that the filesystem on which the script resides was mounted with the nosuid option, that option will still be honored. You can't use Perl to sneak around your sysadmin's security policy this way.

However, if the kernel set-id script feature isn't disabled, Perl will complain loudly that your setuid script is insecure. You'll either need to disable the kernel set-id script "feature", or else put a C wrapper around the script. A C wrapper is just a compiled program that does nothing except call your Perl program. Compiled programs are not subject to the kernel bug that plagues set-id scripts.

Here's a simple wrapper, written in C:

#define REAL_FILE "/path/to/script"
main(ac, av)
    char **av;
{
    execv(REAL_FILE, av);
}
Compile this wrapper into an executable image and then make it rather than your script set-id. Be sure to use an absolute filename, since C isn't smart enough to do taint checking on your PATH.

(Another possible approach is to use the experimental C code generator for the Perl compiler. A compiled image of your script will not have the race condition. See Chapter 18, "Compiling".)

Vendors in recent years have finally started to provide systems free of the set-id bug. On such systems, when the kernel gives the name of the set-id script to the interpreter, it no longer uses a filename subject to meddling, but instead passes a special file representing the file descriptor, like /dev/fd/3. This special file is already opened on the script so that there can be no race condition for evil scripts to exploit.[8] Most modern versions of Unix use this approach to avoid the race condition inherent in opening the same filename twice.

[8]On these systems, Perl should be compiled with -DSETUID_SCRIPTS_ARE_SECURE_NOW. The Configure program that builds Perl tries to figure this out for itself, so you should never have to specify this explicitly.

23.2.2. Handling Race Conditions

Which runs us right into the topic of race conditions. What are they really? Race conditions turn up frequently in security discussions. (Although less often than they turn up in insecure programs. Unfortunately.) That's because they're a fertile source of subtle programming errors, and such errors can often be turned into security exploits (the polite term for screwing up someone's security). A race condition exists when the result of several interrelated events depends on the ordering of those events, but that order cannot be guaranteed due to nondeterministic timing effects. Each event races to be the first one done, and the final state of the system is anybody's guess.

Imagine you have one process overwriting an existing file, and another process reading that same file. You can't predict whether you read in old data, new data, or a haphazard mixture of the two. You can't even know whether you've read all the data. The reader could have won the race to the end of the file and quit. Meanwhile, if the writer kept going after the reader hit end-of-file, the file would grow past where the reader stopped reading, and the reader would never know it.

Here the solution is simple: just have both parties flock the file. The reader typically requests a shared lock, and the writer typically requests an exclusive one. So long as all parties request and respect these advisory locks, reads and writes cannot be interleaved, and there's no chance of mutilated data. See the section Section 23.2.1, "File Locking" in Chapter 16, "Interprocess Communication".

You risk a far less obvious form of race condition every time you let operations on a filename govern subsequent operations on that file. When used on filenames rather than filehandles, the file test operators represent something of a garden path leading straight into a race condition. Consider this code:

if (-e $file) {
    open(FH, "< $file")
        or die "can't open $file for reading: $!";
}
else {
    open(FH, "> $file")
        or die "can't open $file for writing: $!";
}
The code looks just about as straightforward as it gets, but it's still subject to races. There's no guarantee that the answer returned by the -e test will still be valid by the time either open is called. In the if block, another process could have removed the file before it could be opened, and you wouldn't find the file you thought was going to be there. In the else block, another process could have created the file before the second open could get its turn to create the file, so the file that you thought would not be there, would be. The simple open function creates new files but overwrites existing ones. You may think you want to overwrite any existing file, but consider that the existing file might be a newly created alias or symbolic link to a file elsewhere on the system that you very much don't want to overwrite. You may think you know what a filename means at any particular instant, but you can never really be sure, as long as any other processes with access to the file's directory are running on the same system.

To fix this problem of overwriting, you'll need to use sysopen, which provides individual controls over whether to create a new file or to clobber an existing one. And we'll ditch that -e file existence test since it serves no useful purpose here and only increases our exposure to race conditions.

use Fcntl qw/O_WRONLY O_CREAT O_EXCL/;
open(FH, "<", $file)
    or sysopen(FH, $file, O_WRONLY | O_CREAT | O_EXCL)
    or die "can't create new file $file: $!";
Now even if the file somehow springs into existence between when open fails and when sysopen tries to open a new file for writing, no harm is done, because with the flags provided, sysopen will refuse to open a file that already exists.

If someone is trying to trick your program into misbehaving, there's a good chance they'll go about it by having files appear and disappear when you're not expecting. One way to reduce the risk of deception is by promising yourself you'll never operate on a filename more than once. As soon as you have the file opened, forget about the filename (except maybe for error messages), and operate only on the handle representing the file. This is much safer because, even though someone could play with your filenames, they can't play with your filehandles. (Or if they can, it's because you let them--see "Passing Filehandles" in Chapter 16, "Interprocess Communication".)

Earlier in this chapter, we showed a handle_looks_safe function which called Perl's stat function on a filehandle (not a filename) to check its ownership and permissions. Using the filehandle is critical to correctness--if we had used the name of the file, there would have been no guarantee that the file whose attributes we were inspecting was the same one we just opened (or were about to open). Some pesky evil doer could have deleted our file and quickly replaced it with a file of nefarious design, sometime between the stat and the open. It wouldn't matter which was called first; there'd still be the opportunity for foul play between the two. You may think that the risk is very small because the window is very short, but there are many cracking scripts out in the world that will be perfectly happy to run your program thousands of times to catch it the one time it wasn't careful enough. A smart cracking script can even lower the priority of your program so it gets interrupted more often than usual, just to speed things up a little. People work hard on these things--that's why they're called exploits.

By calling stat on a filehandle that's already open, we only access the filename once and so avoid the race condition. A good strategy for avoiding races between two events is to somehow combine both into one, making the operation atomic.[9] Since we access the file by name only once, there can't be any race condition between multiple accesses, so it doesn't matter whether the name changes. Even if our cracker deletes the file we opened (yes, that can happen) and puts a different one there to trick us with, we still have a handle to the real, original file.

[9] Yes, you may still perform atomic operations in a nuclear-free zone. When Democritus gave the word "atom" to the indivisible bits of matter, he meant literally something that could not be cut: a- (not) + tomos (cuttable). An atomic operation is an action that can't be interrupted. (Just you try interrupting an atomic bomb sometime.)

23.2.3. Temporary Files

Apart from allowing buffer overruns (which Perl scripts are virtually immune to) and trusting untrustworthy input data (which taint mode guards against), creating temporary files improperly is one of the most frequently exploited security holes. Fortunately, temp file attacks usually require crackers to have a valid user account on the system they're trying to crack, which drastically reduces the number of potential bad guys.

Careless or casual programs use temporary files in all kinds of unsafe ways, like placing them in world-writable directories, using predictable filenames, and not making sure the file doesn't already exist. Whenever you find a program with code like this:

open(TMP, ">/tmp/foo.$$")
    or die "can't open /tmp/foo.$$: $!";
you've just found all three of those errors at once. That program is an accident waiting to happen.

The way the exploit plays out is that the cracker first plants a file with the same name as the one you'll use. Appending the PID isn't enough for uniqueness; surprising though it may sound, guessing PIDs really isn't difficult.[10] Now along comes the program with the careless open call, and instead of creating a new temporary file for its own purposes, it overwrites the cracker's file instead.

[10]Unless you're on a system like OpenBSD, which randomizes new PID assignments.

So what harm can that do? A lot. The cracker's file isn't really a plain file, you see. It's a symbolic link (or sometimes a hard link), probably pointing to some critical file that crackers couldn't normally write to on their own, such as /etc/passwd. The program thought it opened a brand new file in /tmp, but it clobbered an existing file somewhere else instead.

Perl provides two functions that address this issue, if properly used. The first is POSIX::tmpnam, which just returns a filename that you're expected to open for yourself:

# Keep trying names until we get one that's brand new.
use POSIX;
do {
    $name = tmpnam();
} until sysopen(TMP, $name, O_RDWR | O_CREAT | O_EXCL, 0600);
# Now do I/O using TMP handle.
The second is IO::File::new_tmpfile, which gives you back an already opened handle:
# Or else let the module do that for us.
use IO::File;
my $fh = IO::File::new_tmpfile();  # this is POSIX's tmpfile(3)
# Now do I/O using $fh handle.
Neither approach is perfect, but of the two, the first is the better approach. The major problem with the second one is that Perl is subject to the foibles of whatever implementation of tmpfile(3) happens to be in your system's C library, and you have no guarantee that this function doesn't do something just as dangerous as the open we're trying to fix. (And some, sadly enough, do.) A minor problem is that it doesn't give you the name of the file at all. Although it's better if you can handle a temp file without a name--because that way you'll never provoke a race condition by trying to open it again--often you can't.

The major problem with the first approach is that you have no control over the location of the pathname, as you do with the C library's mkstemp(3) function. For one thing, you never want to put the file on an NFS-mounted filesystem. The O_EXCL flag is not guaranteed to work correctly under NFS, so multiple processes that request an exclusive create at nearly the same time might all succeed. For another, because the path returned is probably in a directory others can write to, someone could plant a symbolic link pointing to a nonexistent file, forcing you to create your file in a location they prefer.[11] If you have any say in it, don't put temp files in a directory that anyone else can write to. If you must, make sure to use the O_EXCL flag to sysopen, and try to use directories with the owner-delete-only flag (the sticky bit) set on them.

[11]A solution to this, which works only under some operating systems, is to call sysopen and OR in the O_NOFOLLOW flag. This makes the function fail if the final component of the path is a symbolic link.

As of version 5.6.1 of Perl, there is a third way. The standard File::Temp module takes into account all the difficulties we've mentioned. You might use the default options like this:

use File::Temp "tempfile";
$handle = tempfile();

Or you might specify some of the options like this:

use File::Temp "tempfile";
($handle, $filename) = tempfile("plughXXXXXX",
                                DIR => "/var/spool/adventure",
                                SUFFIX = '.dat');

The File::Temp module also provides security-conscious emulations of the other functions we've mentioned (though the native interface is better because it gives you an opened filehandle, not just a filename, which is subject to race conditions). See Chapter 32, "Standard Modules", for a longer description of the options and semantics of this module.

Once you have your filehandle, you can do whatever you want with it. It's open for both reading and writing, so you can write to the handle, seek back to the beginning, and then if you want, overwrite what you'd just put there or read it back again. The thing you really, really want to avoid doing is ever opening that filename again, because you can't know for sure that it's really the same file you opened the first time around.[12]

[12] Except afterwards by doing a stat on both filehandles and comparing the first two return values of each (the device/inode pair). But it's too late by then because the damage is already done. All you can do is detect the damage and abort (and maybe sneakily send email to the system administrator).

When you launch another program from within your script, Perl normally closes all filehandles for you to avoid another vulnerability. If you use fcntl to clear your close-on-exec flag (as demonstrated at the end of the entry on open in Chapter 29, "Functions"), other programs you call will inherit this new, open file descriptor. On systems that support the /dev/fd/ directory, you could provide another program with a filename that really means the file descriptor by constructing it this way:

$virtname = "/dev/fd/" . fileno(TMP);
If you only needed to call a Perl subroutine or program that's expecting a filename as an argument, and you knew that subroutine or program used regular open for it, you could pass the handle using Perl's notation for indicating a filehandle:
$virtname = "=&" . fileno(TMP);
When that file "name" is passed with a regular Perl open of one or two arguments (not three, which would dispel this useful magic), you gain access to the duplicated descriptor. In some ways, this is more portable than passing a file from /dev/fd/, because it works everywhere that Perl works; not all systems have a /dev/fd/ directory. On the other hand, the special Perl open syntax for accessing file descriptors by number works only with Perl programs, not with programs written in other languages.

Previous | Home | Next
23.1. Handling Insecure Data | Book Index | 23.3. Handling Insecure Code
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


23.3. Handling Insecure Code

Taint checking is just the sort of security blanket you need if you want to catch bogus data you ought to have caught yourself, but didn't think to catch before passing off to the system. It's a bit like the optional warnings Perl can give you--they may not indicate a real problem, but on average the pain of dealing with the false positives is less than the pain of not dealing with the false negatives. With tainting, the latter pain is even more insistent, because using bogus data doesn't just give the wrong answers; it can blow your system right out of the water, along with your last two years of work. (And maybe your next two, if you didn't make good backups.) Taint mode is useful when you trust yourself to write honest code but don't necessarily trust whoever is feeding you data not to try to trick you into doing something regrettable.

Data is one thing. It's quite another matter when you don't even trust the code you're running. What if you fetch an applet off the Net and it contains a virus, or a time bomb, or a Trojan horse? Taint checking is useless here because the data you're feeding the program may be fine--it's the code that's untrustworthy. You're placing yourself in the position of someone who receives a mysterious device from a stranger, with a note that says, "Just hold this to your head and pull the trigger." Maybe you think it will dry your hair, but you might not think so for very long.

In this realm, prudence is synonymous with paranoia. What you want is a system that lets you impose a quarantine on suspicious code. The code can continue to exist, and even perform certain functions, but you don't let it wander around doing just anything it feels like. In Perl, you can impose a kind of quarantine using the Safe module.

23.3.1. Safe Compartments

The Safe module lets you set up a sandbox, a special compartment in which all system operations are trapped, and namespace access is carefully controlled. The low-level, technical details of this module are in a state of flux, so here we'll take a more philosophical approach.

23.3.1.1. Restricting namespace access

At the most basic level, a Safe object is like a safe, except the idea is to keep the bad people in, not out. In the Unix world, there is a syscall known as chroot(2) that can permanently consign a process to running only in a subdirectory of the directory structure--in its own private little hell, if you will. Once the process is put there, there is no way for it to reach files outside, because there's no way for it to name files outside.[13] A Safe object is a little like that, except that instead of being restricted to a subset of the filesystem's directory structure, it's restricted to a subset of Perl's package structure, which is hierarchical just as the filesystem is.

[13]Some sites do this for executing all CGI scripts, using loopback, read-only mounts. It's something of a pain to set up, but if someone ever escapes, they'll find there's nowhere to go.

Another way to look at it is that the Safe object is like one of those observation rooms with one-way mirrors that the police put suspicious characters into. People on the outside can look into the room, but those inside can't see out.

When you create a Safe object, you may give it a package name if you want. If you don't, a new one will be chosen for you:

use Safe;
my $sandbox = Safe->new("Dungeon");
$Dungeon::foo = 1;  # Direct access is discouraged, though.
If you fully qualify variables and functions using the package name supplied to the new method, you can access them in that package from the outside, at least in the current implementation. This may change however, since the current plan is to clone the symbol table into a new interpreter. Slightly more upward compatible might be to set things up first before creating the Safe, as shown below. This is likely to continue working and is a handy way to set up a Safe that has to start off with a lot of "state". (Admittedly, $Dungeon::foo isn't a lot of state.)
use Safe;
$Dungeon::foo = 1;  # Still direct access, still discouraged.
my $sandbox = Safe->new("Dungeon");
But Safe also provides a way to access the compartment's globals even if you don't know the name of the compartment's package. So for maximal upward compatibility (though less than maximal speed), we suggest you use the reval method:
use Safe;
my $sandbox = Safe->new();
$sandbox->reval('$foo = 1');
(In fact, that's the same method you'll use to run suspicious code.) When you pass code into the compartment to compile and run, that code thinks that it's really living in the main package. What the outside world calls $Dungeon::foo, the code inside thinks of as $main::foo, or $::foo, or just $foo if you aren't running under use strict. It won't work to say $Dungeon::foo inside the compartment, because that would really access $Dungeon::Dungeon::foo. By giving the Safe object its own notion of main, variables and subroutines in the rest of your program are protected.

To compile and run code inside the compartment, use the reval ("restricted eval") method, passing the code string as its argument. Just as with any other eval STRING construct, compilation errors and run-time exceptions in reval don't kill your program. They just abort the reval and leave the exception in $@, so make sure to check it after every reval call.

Using the initializations given earlier, this code will print out that "foo is now 2":

$sandbox->reval('$foo++; print "foo is now $main::foo\n"');
if ($@) {
    die "Couldn't compile code in box: $@";
}
If you just want to compile code and not run it, wrap your string in a subroutine declaration:
$sandbox->reval(q{
    our $foo;
    sub say_foo {
        print "foo is now $main::foo\n";
    }
}, 1);
die if $@;      # check compilation
This time we passed reval a second argument which, since it's true, tells reval to compile the code under the strict pragma. From within the code string, you can't disable strictness, either, because importing and unimporting are just two of the things you can't normally do in a Safe compartment. There are a lot of things you can't do normally in a Safe compartment--see the next section.

Once you've created the say_foo function in the compartment, these are pretty much the same:

$sandbox->reval('say_foo()');       # Best way.
die if $@;

$sandbox->varglob('say_foo')->();   # Call through anonymous glob.

Dungeon::say_foo();                 # Direct call, strongly discouraged.

23.3.1.2. Restricting operator access

The other important thing about a Safe object is that Perl limits the available operations within the sandbox. (You might well let your kid take a bucket and shovel into the sandbox, but you'd probably draw the line at a bazooka.) It's not enough to protect just the rest of your program; you need to protect the rest of your computer, too.

When you compile Perl code in a Safe object, either with reval or rdo (the restricted version of the do FILE operator), the compiler consults a special, per-compartment access-control list to decide whether each individual operation is deemed safe to compile. This way you don't have to stress out (much) worrying about unforeseen shell escapes, opening files when you didn't mean to, strange code assertions in regular expressions, or most of the external access problems folks normally fret about. (Or ought to.)

The interface for specifying which operators should be permitted or restricted is currently under redesign, so we only show how to use the default set of them here. For details, consult the online documentation for the Safe module.

The Safe module doesn't offer complete protection against denial-of-service attacks, especially when used in its more permissive modes. Denial-of-service attacks consume all available system resources of some type, denying other processes access to essential system facilities. Examples of such attacks include filling up the kernel process table, dominating the CPU by running forever in a tight loop, exhausting available memory, and filling up a filesystem. These problems are very difficult to solve, especially portably. See the end of the section Section 23.3.2, "Code Masquerading as Data" for more discussion of denial-of-service attacks.

23.3.1.3. Safe examples

Imagine you've got a CGI program that manages a form into which the user may enter an arbitrary Perl expression and get back the evaluated result.[14] Like all external input, the string comes in tainted, so Perl won't let you eval it yet--you'll first have to untaint it with a pattern match. The problem is that you'll never be able to devise a pattern that can detect all possible threats. And you don't dare just untaint whatever you get and send it through the built-in eval. (If you do that, we will be tempted to break into your system and delete the script.)

[14]Please don't laugh. We really have seen web pages that do this. Without a Safe!

That's where reval comes in. Here's a CGI script that processes a form with a single form field, evaluates (in scalar context) whatever string it finds there, and prints out the formatted result:

#!/usr/bin/perl -lTw
use strict;
use CGI::Carp 'fatalsToBrowser';
use CGI qw/:standard escapeHTML/;
use Safe;

print header(-type => "text/html;charset=UTF-8"),
      start_html("Perl Expression Results");
my $expr = param("EXPR") =~ /^([^;]+)/
            ? $1 # return the now-taintless portion
            : croak("no valid EXPR field in form");
my $answer = Safe->new->reval($expr);
die if $@;

print p("Result of", tt(escapeHTML($expr)),
               "is", tt(escapeHTML($answer)));
Imagine some evil user feeding you "print `cat /etc/passwd`" (or worse) as the input string. Thanks to the restricted environment that disallows backticks, Perl catches the problem during compilation and returns immediately. The string in $@ is "quoted execution (``, qx) trapped by operation mask", plus the customary trailing information identifying where the problem happened.

Because we didn't say otherwise, the compartments we've been creating all used the default set of allowable operations. How you go about declaring specific operations permitted or forbidden isn't important here. What is important is that this is completely under the control of your program. And since you can create multiple Safe objects in your program, you can confer various degrees of trust upon various chunks of code, depending on where you got them from.

If you'd like to play around with Safe, here's a little interactive Perl calculator. It's a calculator in that you can feed it numeric expressions and immediately see their results. But it's not limited to numbers alone. It's more like the looping example under eval in Chapter 29, "Functions", where you can take whatever they give you, evaluate it, and give them back the result. The difference is that the Safe version doesn't execute just anything you feel like. You can run this calculator interactively at your terminal, typing in little bits of Perl code and checking the answers, to get a feel for what sorts of protection Safe provides.

#!/usr/bin/perl -w
# safecalc - demo program for playing with Safe
use strict;
use Safe;
my $sandbox = Safe->new();
while (1) {
    print "Input: ";
    my $expr = <STDIN>;
    exit unless defined $expr;
    chomp($expr);
    print "$expr produces ";
    local $SIG{__WARN__} = sub { die @_ };
    my $result = $sandbox->reval($expr, 1);
    if ($@ =~ s/at \(eval \d+\).*//) {
        printf "[%s]: %s", $@ =~ /trapped by operation mask/
            ? "Security Violation" : "Exception", $@;
    }
    else {
        print "[Normal Result] $result\n";
    }
}

Warning: the Safe module is currently being redesigned to run each compartment within a completely independent Perl interpreter inside the same process. (This is the strategy that Apache's mod_perl employs when running precompiled Perl scripts.) Details are still hazy at this time, but our crystal ball suggests that blindly poking at things inside the compartment using a named package won't get you very far after the impending rewrite. If you're running a version of Perl later than 5.6, check the release notes in perldelta(1) to see what's changed, or consult the documentation for the Safe module itself. (Of course, you always do that anyway, right?)

23.3.2. Code Masquerading as Data

Safe compartments are available for when the really scary stuff is going down, but that doesn't mean you should let down your guard totally when you're doing the everyday stuff around home. You need to cultivate an awareness of your surroundings and look at things from the point of view of someone wanting to break in. You need to take proactive steps like keeping things well lit and trimming the bushes that can hide various lurking problems.

Perl tries to help you in this area, too. Perl's conventional parsing and execution scheme avoids the pitfalls that shell programming languages often fall prey to. There are many extremely powerful features in the language, but by design, they're syntactically and semantically bounded in ways that keep things under the control of the programmer. With few exceptions, Perl evaluates each token only once. Something that looks like it's being used as a simple data variable won't suddenly go rooting around in your filesystem.

Unfortunately, that sort of thing can happen if you call out to the shell to run other programs for you, because then you're running under the shell's rules instead of Perl's. The shell is easy to avoid, though--just use the list argument forms of the system, exec, or piped open functions. Although backticks don't have a list-argument form that is proof against the shell, you can always emulate them as described in the section Section 23.1.3, "Accessing Commands and Files Under Reduced Privileges". (While there's no syntactic way to make backticks take an argument list, a multi-argument form of the underlying readpipe operator is in development; but as of this writing, it isn't quite ready for prime time.)

When you use a variable in an expression (including when you interpolate it into a double-quoted string), there's No Chance that the variable will contain Perl code that does something you aren't intending.[15] Unlike the shell, Perl never needs defensive quotes around variables, no matter what might be in them.

$new = $old;                # No quoting needed.
print "$new items\n";       # $new can't hurt you.

$phrase = "$new items\n";   # Nor here, neither.
print $phrase;              # Still perfectly ok.
Perl takes a "what you see is what you get" approach. If you don't see an extra level of interpolation, then it doesn't happen. It is possible to interpolate arbitrary Perl expressions into strings, but only if you specifically ask Perl to do that. (Even so, the contents are still subject to taint checking if you're in taint mode.)
$phrase = "You lost @{[ 1 + int rand(6) ]} hit points\n";
Interpolation is not recursive, however. You can't just hide an arbitrary expression in a string:
$count = '1 + int rand(6)';             # Some random code.
$saying = "$count hit points";          # Merely a literal.
$saying = "@{[$count]} hit points";     # Also a literal.
Both assignments to $saying would produce "1 + int rand(6) hit points", without evaluating the interpolated contents of $count as code. To get Perl to do that, you have to call eval STRING explicitly:
$code = '1 + int rand(6)';
$die_roll = eval $code;
die if $@;
If $code were tainted, that eval STRING would raise its own exception. Of course, you almost never want to evaluate random user code--but if you did, you should look into using the Safe module. You may have heard of it.

[15]Although if you're generating a web page, it's possible to emit HTML tags, including JavaScript code, that might do something that the remote browser isn't expecting.

There is one place where Perl can sometimes treat data as code; namely, when the pattern in a qr//, m//, or s/// operator contains either of the new regular expression assertions, (?{CODE}) or (??{CODE}). These pose no security issues when used as literals in pattern matches:

$cnt = $n = 0;
while ($data =~ /( \d+ (?{ $n++ }) | \w+ )/gx) {
    $cnt++;
}
print "Got $cnt words, $n of which were digits.\n";
But existing code that interpolates variables into matches was written with the assumption that the data is data, not code. The new constructs might have introduced a security hole into previously secure programs. Therefore, Perl refuses to evaluate a pattern if an interpolated string contains a code assertion, and raises an exception instead. If you really need that functionality, you can always enable it with the lexically scoped use re 'eval' pragma. (You still can't use tainted data for an interpolated code assertion, though.)

A completely different sort of security concern that can come up with regular expressions is denial-of-service problems. These can make your program quit too early, or run too long, or exhaust all available memory--and sometimes even dump core, depending on the phase of the moon.

When you process user-supplied patterns, you don't have to worry about interpreting random Perl code. However, the regular expression engine has its own little compiler and interpreter, and the user-supplied pattern is capable of giving the regular expression compiler heartburn. If an interpolated pattern is not a valid pattern, a run-time exception is raised, which is fatal unless trapped. If you do try to trap it, make sure to use only eval BLOCK, not eval STRING, because the extra evaluation level of the latter would in fact allow the execution of random Perl code. Instead, do something like this:

if (not eval { "" =~ /$match/; 1 }) {
    # (Now do whatever you want for a bad pattern.)
}
else {
    # We know pattern is at least safe to compile.
    if ($data =~ /$match/) { ... }
}
A more troubling denial-of-service problem is that given the right data and the right search pattern, your program can appear to hang forever. That's because some pattern matches require exponential time to compute, and this can easily exceed the MTBF rating on our solar system. If you're especially lucky, these computationally intensive patterns will also require exponential storage. If so, your program will exhaust all available virtual memory, bog down the rest of the system, annoy your users, and either die with an orderly "Out of memory!" error or else leave behind a really big core dump file, though perhaps not as large as the solar system.

Like most denial-of-service attacks, this one is not easy to solve. If your platform supports the alarm function, you could time out the pattern match. Unfortunately, Perl cannot (currently) guarantee that the mere act of handling a signal won't ever trigger a core dump. (This is scheduled to be fixed in a future release.) You can always try it, though, and even if it the signal isn't handled gracefully, at least the program won't run forever.

If your system supports per-process resource limits, you could set these in your shell before calling the Perl program, or use the BSD::Resource module from CPAN to do so directly from Perl. The Apache web server allows you to set time, memory, and file size limits on CGI scripts that it launches.

Finally, we hope we've left you with some unresolved feelings of insecurity. Remember, just because you're paranoid doesn't mean they're not out to get you. So you might as well enjoy it.

Previous | Home | Next
23.2. Handling Timing Glitches | Book Index | 24. Common Practices
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 24. Common Practices

Contents:

Common Goofs for Novices
Efficiency
Programming with Style
Fluent Perl
Program Generation

Ask almost any Perl programmer, and they'll be glad to give you reams of advice on how to program. We're no different (in case you hadn't noticed). In this chapter, rather than trying to tell you about specific features of Perl, we'll go at it from the other direction and use a more scattergun approach to describe idiomatic Perl. Our hope is that, by putting together various bits of things that seemingly aren't related, you can soak up some of the feeling of what it's like to actually "think Perl". After all, when you're programming, you don't write a bunch of expressions, then a bunch of subroutines, then a bunch of objects. You have to go at everything all at once, more or less. So this chapter is a bit like that.

There is, however, a rudimentary organization to the chapter, in that we'll start with the negative advice and work our way towards the positive advice. We don't know if that will make you feel any better, but it makes us feel better.

24.1. Common Goofs for Novices

The biggest goof of all is forgetting to use warnings, which identifies many errors. The second biggest goof is forgetting to use strict when it's appropriate. These two pragmas can save you hours of head-banging when your program starts getting bigger. (And it will.) Yet another faux pas is to forget to consult the online FAQ. Suppose you want to find out if Perl has a round function. You might try searching the FAQ first:

% perlfaq round
Apart from those "metagoofs", there are several kinds of programming traps. Some traps almost everyone falls into, and other traps you'll fall into only if you come from a particular culture that does things differently. We've separated these out in the following sections.

24.1.1. Universal Blunders

  • Putting a comma after the filehandle in a print statement. Although it looks extremely regular and pretty to say:

    print STDOUT, "goodbye", $adj, "world!\n";    # WRONG
    this is nonetheless incorrect, because of that first comma. What you want instead is the indirect object syntax:
    print STDOUT "goodbye", $adj, "world!\n";     # ok
    The syntax works this way so that you can say:
    print $filehandle "goodbye", $adj, "world!\n";
    where $filehandle is a scalar holding the name of a filehandle at run time. This is distinct from:
    print $notafilehandle, "goodbye", $adj, "world!\n";
    where $notafilehandle is simply a string that is part of the list of things to be printed. See "indirect object" in the Glossary.

  • Using == instead of eq and != instead of ne. The == and != operators are numeric tests. The other two are string tests. The strings "123" and "123.00" are equal as numbers, but not equal as strings. Also, any nonnumeric string is numerically equal to zero. Unless you are dealing with numbers, you almost always want the string comparison operators instead.

  • Forgetting the trailing semicolon. Every statement in Perl is terminated by a semicolon or the end of a block. Newlines aren't statement terminators as they are in awk, Python, or FORTRAN. Remember that Perl is like C.

    A statement containing a here document is particularly prone to losing its semicolon. It ought to look like this:

    print <<'FINIS';
A foolish consistency is the hobgoblin of little minds,
adored by little statesmen and philosophers and divines.
                                       --Ralph Waldo Emerson
FINIS

  • Forgetting that a BLOCK requires braces. Naked statements are not BLOCKs. If you are creating a control structure such as a while or an if that requires one or more BLOCKs, you must use braces around each BLOCK. Remember that Perl is not like C.

  • Not saving $1, $2, and so on, across regular expressions. Remember that every new m/atch/ or s/ubsti/tution/ will set (or clear, or mangle) your $1, $2...variables, as well as $`, $&, and $'. One way to save them right away is to evaluate the match within a list context, as in:

    my ($one, $two) = /(\w+) (\w+)/;

  • Not realizing that a local also changes the variable's value as seen by other subroutines called within the scope of the local. It's easy to forget that local is a run-time statement that does dynamic scoping, because there's no equivalent in languages like C. See the section "Scoped Declarations" in Chapter 4, "Statements and Declarations". Usually you want a my anyway.

  • Losing track of brace pairings. A good text editor will help you find the pairs. Get one. (Or two.)

  • Using loop control statements in do {} while. Although the braces in this control structure look suspiciously like part of a loop BLOCK, they aren't.

  • Saying @foo[1] when you mean $foo[1]. The @foo[1] reference is an array slice, meaning an array consisting of the single element $foo[1]. Sometimes this doesn't make any difference, as in:

    print "the answer is @foo[1]\n";
    but it makes a big difference for things like:
    @foo[1] = <STDIN>;
    which will slurp up all the rest of STDIN, assign the first line to $foo[1], and discard everything else. This is probably not what you intended. Get into the habit of thinking that $ means a single value, while @ means a list of values, and you'll do okay.

  • Forgetting the parentheses of a list operator like my:

    my  $x, $y  = (4, 8);     # WRONG
my ($x, $y) = (4, 8);     # ok

  • Forgetting to select the right filehandle before setting $^, $~, or $|. These variables depend on the currently selected filehandle, as determined by select(FILEHANDLE). The initial filehandle so selected is STDOUT. You should really be using the filehandle methods from the FileHandle module instead. See Chapter 28, "Special Names".

24.1.2. Frequently Ignored Advice

Practicing Perl Programmers should take note of the following:

  • Remember that many operations behave differently in a list context than they do in a scalar one. For instance:

    ($x) = (4, 5, 6);        # List context; $x is set to 4
 $x  = (4, 5, 6);        # Scalar context; $x is set to 6

 @a  = (4, 5, 6);
 $x  = @a;               # Scalar context; $x is set to 3 (the array list)

  • Avoid barewords if you can, especially all lowercase ones. You can't tell just by looking at it whether a word is a function or a bareword string. By using quotes on strings and parentheses around function call arguments, you won't ever get them confused. In fact, the pragma use strict at the beginning of your program makes barewords a compile-time error--probably a good thing.

  • You can't tell just by looking which built-in functions are unary operators (like chop and chdir), which are list operators (like print and unlink), and which are argumentless (like time). You'll want to learn them by reading Chapter 29, "Functions". As always, use parentheses if you aren't sure--or even if you aren't sure you're sure. Note also that user-defined subroutines are by default list operators, but they can be declared as unary operators with a prototype of ($) or argumentless with a prototype of ().

  • People have a hard time remembering that some functions default to $_, or @ARGV, or whatever, while others do not. Take the time to learn which are which, or avoid default arguments.

  • <FH> is not the name of a filehandle, but an angle operator that does a line-input operation on the handle. This confusion usually manifests itself when people try to print to the angle operator:

    print <FH> "hi";    # WRONG, omit angles

  • Remember also that data read by the angle operator is assigned to $_ only when the file read is the sole condition in a while loop:

    while (<FH>) { }   # Data assigned to $_.
<FH>;              # Data read and discarded!

  • Don't use = when you need =~; the two constructs are quite different:

    $x =  /foo/;  # Searches $_ for "foo", puts result in $x
$x =~ /foo/;  # Searches $x for "foo", discards result

  • Use my for local variables whenever you can get away with it. Using local merely gives a temporary value to a global variable, which leaves you open to unforeseen side effects of dynamic scoping.

  • Don't use local on a module's exported variables. If you localize an exported variable, its exported value will not change. The local name becomes an alias to a new value but the external name is still an alias for the original.

24.1.3. C Traps

Cerebral C programmers should take note of the following:

  • Curlies are required for if and while blocks.

  • You must use elsif rather than "else if" or "elif". Syntax like this:

    if (expression) {
    block;
}
else if (another_expression) {      # WRONG
    another_block;
}
    is illegal. The else part is always a block, and a naked if is not a block. You mustn't expect Perl to be exactly the same as C. What you want instead is:
    if (expression) {
    block;
}
elsif (another_expression) {
    another_block;
}
    Note also that "elif" is "file" spelled backward. Only Algol-ers would want a keyword that was the same as another word spelled backward.

  • The break and continue keywords from C become in Perl last and next, respectively. Unlike in C, these do not work within a do {} while construct.

  • There's no switch statement. (But it's easy to build one on the fly; see "Bare Blocks" and "Case Structures" in Chapter 4, "Statements and Declarations".)

  • Variables begin with $, @, or % in Perl.

  • Comments begin with #, not /*.

  • You can't take the address of anything, although a similar operator in Perl is the backslash, which creates a reference.

  • ARGV must be capitalized. $ARGV[0] is C's argv[1], and C's argv[0] ends up in $0.

  • Syscalls such as link, unlink, and rename return true for success, not 0.

  • The signal handlers in %SIG deal with signal names, not numbers.

24.1.4. Shell Traps

Sharp shell programmers should take note of the following:

  • Variables are prefixed with $, @, or % on the left side of the assignment as well as the right. A shellish assignment like:

    camel='dromedary';      # WRONG
    won't be parsed the way you expect. You need:
    $camel='dromedary';     # ok

  • The loop variable of a foreach also requires a $. Although csh likes:

    foreach hump (one two)
    stuff_it $hump
end
    in Perl, this is written as:
    foreach $hump ("one", "two") {
    stuff_it($hump);
}

  • The backtick operator does variable interpolation without regard to the presence of single quotes in the command.

  • The backtick operator does no translation of the return value. In Perl, you have to trim the newline explicitly, like this:

    chomp($thishost = `hostname`);

  • Shells (especially csh) do several levels of substitution on each command line. Perl does interpolation only within certain constructs such as double quotes, backticks, angle brackets, and search patterns.

  • Shells tend to interpret scripts a little bit at a time. Perl compiles the entire program before executing it (except for BEGIN blocks, which execute before the compilation is done).

  • Program arguments are available via @ARGV, not $1, $2, and so on.

  • The environment is not automatically made available as individual scalar variables. Use the standard Env module if you want that to happen.

24.1.5. Previous Perl Traps

Penitent Perl 4 (and Prior) Programmers should take note of the following changes between release 4 and release 5 that might affect old scripts:

  • @ now always interpolates an array in double-quotish strings. Some programs may now need to use backslashes to protect any @ that shouldn't interpolate.

  • Barewords that used to look like strings to Perl will now look like subroutine calls if a subroutine by that name is defined before the compiler sees them. For example:

    sub SeeYa { die "Hasta la vista, baby!" }
$SIG{'QUIT'} = SeeYa;
    In prior versions of Perl, that code would set the signal handler. Now, it actually calls the function! You may use the -w switch to find such risky usage or use strict to outlaw it.

  • Identifiers starting with "_" are no longer forced into package main, except for the bare underscore itself (as in $_, @_, and so on).

  • A double colon is now a valid package separator in an identifier. Thus, the statement:

    print "$a::$b::$c\n";
    now parses $a:: as the variable reference, where in prior versions only the $a was considered to be the variable reference. Similarly:
    print "$var::abc::xyz\n";
    is now interpreted as a single variable $var::abc::xyz, whereas in prior versions, the variable $var would have been followed by the constant text ::abc::xyz.

  • s'$pattern'replacement' now performs no interpolation on $pattern. (The $ would be interpreted as an end-of-line assertion.) This behavior occurs only when using single quotes as the substitution delimiter; in other substitutions, $pattern is always interpolated.

  • The second and third arguments of splice are now evaluated in scalar context rather than in list context.

  • These are now semantic errors because of precedence:

    shift @list + 20;    # Now parses like shift(@list + 20), illegal!
$n = keys %map + 20; # Now parses like keys(%map + 20), illegal!
    Because if those were to work, then this couldn't:
    sleep $dormancy + 20;

  • The precedence of assignment operators is now the same as the precedence of assignment. Previous versions of Perl mistakenly gave them the precedence of the associated operator. So you now must parenthesize them in expressions like:

    /foo/ ? ($a += 2) : ($a -= 2);
    Otherwise:
    /foo/ ? $a += 2 : $a -= 2;
    would be erroneously parsed as:
    (/foo/ ? $a += 2 : $a) -= 2;
    On the other hand:
    $a += /foo/ ? 1 : 2;
    now works as a C programmer would expect.

  • open FOO || die is incorrect. You need parentheses around the filehandle, because open has the precedence of a list operator.

  • The elements of argument lists for formats are now evaluated in list context. This means you can interpolate list values now.

  • You can't do a goto into a block that is optimized away. Darn.

  • It is no longer legal to use whitespace as the name of a variable or as a delimiter for any kind of quote construct. Double darn.

  • The caller function now returns a false value in scalar context if there is no caller. This lets modules determine whether they're being required or run directly.

  • m//g now attaches its state to the searched string rather than the regular expression. See Chapter 5, "Pattern Matching", for further details.

  • reverse is no longer allowed as the name of a sort subroutine.

  • taintperl is no longer a separate executable. There is now a -T switch to turn on tainting when it isn't turned on automatically.

  • Double-quoted strings may no longer end with an unescaped $ or @.

  • The archaic if BLOCK BLOCK syntax is no longer supported.

  • Negative array subscripts now count from the end of the array.

  • The comma operator in a scalar context is now guaranteed to give a scalar context to its arguments.

  • The ** operator now binds more tightly than unary minus.

  • Setting $#array lower now discards array elements immediately.

  • delete is not guaranteed to return the deleted value for tied arrays, since this capability may be onerous for some modules to implement.

  • The construct "this is $$x", which used to interpolate the process ID at that point, now tries to dereference $x. $$ by itself still works fine, however.

  • The behavior of foreach when it iterates over a list that is not an array has changed slightly. It used to assign the list to a temporary array but now, for efficiency, no longer does so. This means that you'll now be iterating over the actual values, not copies of the values. Modifications to the loop variable can change the original values, even after the grep! For instance:

    % perl4 -e '@a = (1,2,3); for (grep(/./, @a)) { $_++ }; print "@a\n"'
1 2 3
% perl5 -e '@a = (1,2,3); for (grep(/./, @a)) { $_++ }; print "@a\n"'
2 3 4
    To retain prior Perl semantics, you'd need to explicitly assign your list to a temporary array and then iterate over that. For example, you might need to change:
    foreach $var (grep /x/, @list) { ... }
    to:
    foreach $var (my @tmp = grep /x/, @list) { ... }
    Otherwise changing $var will clobber the values of @list. (This most often happens when you use $_ for the loop variable and call subroutines in the loop that don't properly localize $_.)

  • Some error messages and warnings will be different.

  • Some bugs may have been inadvertently removed.

Previous | Home | Next
23.3. Handling Insecure Code | Book Index | 24.2. Efficiency
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


24.2. Efficiency

While most of the work of programming may be simply getting your program working properly, you may find yourself wanting more bang for the buck out of your Perl program. Perl's rich set of operators, data types, and control constructs are not necessarily intuitive when it comes to speed and space optimization. Many trade-offs were made during Perl's design, and such decisions are buried in the guts of the code. In general, the shorter and simpler your code is, the faster it runs, but there are exceptions. This section attempts to help you make it work just a wee bit better.

If you want it to work a lot better, you can play with the Perl compiler backend described in Chapter 18, "Compiling", or rewrite your inner loop as a C extension as illustrated in Chapter 21, "Internals and Externals".

Note that optimizing for time may sometimes cost you in space or programmer efficiency (indicated by conflicting hints below). Them's the breaks. If programming was easy, they wouldn't need something as complicated as a human being to do it, now would they?

24.2.1. Time Efficiency

  • Use hashes instead of linear searches. For example, instead of searching through @keywords to see if $_ is a keyword, construct a hash with:

    my %keywords;
for (@keywords) {
    $keywords{$_}++;
}
    Then you can quickly tell if $_ contains a keyword by testing $keyword{$_} for a nonzero value.

  • Avoid subscripting when a foreach or list operator will do. Not only is subscripting an extra operation, but if your subscript variable happens to be in floating point because you did arithmetic, an extra conversion from floating point back to integer is necessary. There's often a better way to do it. Consider using foreach, shift, and splice operations. Consider saying use integer.

  • Avoid goto. It scans outward from your current location for the indicated label.

  • Avoid printf when print will do.

  • Avoid $& and its two buddies, $` and $'. Any occurrence in your program causes all matches to save the searched string for possible future reference. (However, once you've blown it, it doesn't hurt to have more of them.)

  • Avoid using eval on a string. An eval of a string (although not of a BLOCK) forces recompilation every time through. The Perl parser is pretty fast for a parser, but that's not saying much. Nowadays there's almost always a better way to do what you want anyway. In particular, any code that uses eval merely to construct variable names is obsolete since you can now do the same directly using symbolic references:

    no strict 'refs';
$name = "variable";
$$name = 7;           # Sets $variable to 7

  • Avoid eval STRING inside a loop. Put the loop into the eval instead, to avoid redundant recompilations of the code. See the study operator in Chapter 29, "Functions" for an example of this.

  • Avoid run-time-compiled patterns. Use the /pattern/o (once only) pattern modifier to avoid pattern recompilation when the pattern doesn't change over the life of the process. For patterns that change occasionally, you can use the fact that a null pattern refers back to the previous pattern, like this:

    "foundstring" =~ /$currentpattern/;        # Dummy match (must succeed).
while (<>) {
    print if //;
}
    Alternatively, you can precompile your regular expression using the qr quote construct. You can also use eval to recompile a subroutine that does the match (if you only recompile occasionally). That works even better if you compile a bunch of matches into a single subroutine, thus amortizing the subroutine call overhead.

  • Short-circuit alternation is often faster than the corresponding regex. So:

    print if /one-hump/ || /two/;
    is likely to be faster than:
    print if /one-hump|two/;
    at least for certain values of one-hump and two. This is because the optimizer likes to hoist certain simple matching operations up into higher parts of the syntax tree and do very fast matching with a Boyer-Moore algorithm. A complicated pattern tends to defeat this.

  • Reject common cases early with next if. As with simple regular expressions, the optimizer likes this. And it just makes sense to avoid unnecessary work. You can typically discard comment lines and blank lines even before you do a split or chop:

    while (<>) {
    next if /^#/;
    next if /^$/;
    chop;
    @piggies = split(/,/);
    ...
}

  • Avoid regular expressions with many quantifiers or with big {MIN,MAX} numbers on parenthesized expressions. Such patterns can result in exponentially slow backtracking behavior unless the quantified subpatterns match on their first "pass". You can also use the (?>...) construct to force a subpattern to either match completely or fail without backtracking.

  • Try to maximize the length of any nonoptional literal strings in regular expressions. This is counterintuitive, but longer patterns often match faster than shorter patterns. That's because the optimizer looks for constant strings and hands them off to a Boyer-Moore search, which benefits from longer strings. Compile your pattern with Perl's -Dr debugging switch to see what Dr. Perl thinks the longest literal string is.

  • Avoid expensive subroutine calls in tight loops. There is overhead associated with calling subroutines, especially when you pass lengthy parameter lists or return lengthy values. In order of increasing desperation, try passing values by reference, passing values as dynamically scoped globals, inlining the subroutine, or rewriting the whole loop in C. (Better than all of those solutions is if you can define the subroutine out of existence by using a smarter algorithm.)

  • Avoid getc for anything but single-character terminal I/O. In fact, don't use it for that either. Use sysread.

  • Avoid frequent substrs on long strings, especially if the string contains UTF-8. It's okay to use substr at the front of a string, and for some tasks you can keep the substr at the front by "chewing up" the string as you go with a four-argument substr, replacing the part you grabbed with "":

    while ($buffer) {
    process(substr($buffer, 0, 10, ""));
}

  • Use pack and unpack instead of multiple substr invocations.

  • Use substr as an lvalue rather than concatenating substrings. For example, to replace the fourth through seventh characters of $foo with the contents of the variable $bar, don't do this:

    $foo = substr($foo,0,3) . $bar . substr($foo,7);
    Instead, simply identify the part of the string to be replaced and assign into it, as in:
    substr($foo, 3, 4) = $bar;
    But be aware that if $foo is a huge string and $bar isn't exactly the length of the "hole", this can do a lot of copying too. Perl tries to minimize that by copying from either the front or the back, but there's only so much it can do if the substr is in the middle.

  • Use s/// rather than concatenating substrings. This is especially true if you can replace one constant with another of the same size. This results in an in-place substitution.

  • Use statement modifiers and equivalent and and or operators instead of full-blown conditionals. Statement modifiers (like $ring = 0 unless $engaged) and logical operators avoid the overhead of entering and leaving a block. They can often be more readable too.

  • Use $foo = $a || $b || $c. This is much faster (and shorter to say) than:

    if ($a) {
    $foo = $a;
}
elsif ($b) {
    $foo = $b;
}
elsif ($c) {
    $foo = $c;
}
    Similarly, set default values with:
    $pi ||= 3;

  • Group together any tests that want the same initial string. When testing a string for various prefixes in anything resembling a switch structure, put together all the /^a/ patterns, all the /^b/ patterns, and so on.

  • Don't test things you know won't match. Use last or elsif to avoid falling through to the next case in your switch statement.

  • Use special operators like study, logical string operations, pack 'u', and unpack '%' formats.

  • Beware of the tail wagging the dog. Misstatements resembling (<STDIN>)[0] can cause Perl much unnecessary work. In accordance with Unix philosophy, Perl gives you enough rope to hang yourself.

  • Factor operations out of loops. The Perl optimizer does not attempt to remove invariant code from loops. It expects you to exercise some sense.

  • Strings can be faster than arrays.

  • Arrays can be faster than strings. It all depends on whether you're going to reuse the strings or arrays and which operations you're going to perform. Heavy modification of each element implies that arrays will be better, and occasional modification of some elements implies that strings will be better. But you just have to try it and see.

  • my variables are faster than local variables.

  • Sorting on a manufactured key array may be faster than using a fancy sort subroutine. A given array value will usually be compared multiple times, so if the sort subroutine has to do much recalculation, it's better to factor out that calculation to a separate pass before the actual sort.

  • If you're deleting characters, tr/abc//d is faster than s/[abc]//g.

  • print with a comma separator may be faster than concatenating strings. For example:

    print $fullname{$name} . " has a new home directory " .
    $home{$name} . "\n";
    has to glue together the two hashes and the two fixed strings before passing them to the low-level print routines, whereas:
    print $fullname{$name}, " has a new home directory ",
    $home{$name}, "\n";
    doesn't. On the other hand, depending on the values and the architecture, the concatenation may be faster. Try it.

  • Prefer join("", ...) to a series of concatenated strings. Multiple concatenations may cause strings to be copied back and forth multiple times. The join operator avoids this.

  • split on a fixed string is generally faster than split on a pattern. That is, use split(/ /, ...) rather than split(/ +/, ...) if you know there will only be one space. However, the patterns /\s+/, /^/, and / / are specially optimized, as is the special split on whitespace.

  • Pre-extending an array or string can save some time. As strings and arrays grow, Perl extends them by allocating a new copy with some room for growth and copying in the old value. Pre-extending a string with the x operator or an array by setting $#array can prevent this occasional overhead and reduce memory fragmentation.

  • Don't undef long strings and arrays if they'll be reused for the same purpose. This helps prevent reallocation when the string or array must be re-extended.

  • Prefer "\0" x 8192 over unpack("x8192",()).

  • system("mkdir ...") may be faster on multiple directories if the mkdir syscall isn't available.

  • Avoid using eof if return values will already indicate it.

  • Cache entries from files (like passwd and group files) that are apt to be reused. It's particularly important to cache entries from the network. For example, to cache the return value from gethostbyaddr when you are converting numeric addresses (like 204.148.40.9) to names (like "www.oreilly.com"), you can use something like:

    sub numtoname {
    local ($_) = @_;
    unless (defined $numtoname{$_}) {
        my (@a) = gethostbyaddr(pack('C4', split(/\./)),2);
        $numtoname{$_} = @a > 0 ? $a[0] : $_;
    }
    return $numtoname{$_};
}

  • Avoid unnecessary syscalls. Operating system calls tend to be rather expensive. So for example, don't call the time operator when a cached value of $now would do. Use the special _ filehandle to avoid unnecessary stat(2) calls. On some systems, even a minimal syscall may execute a thousand instructions.

  • Avoid unnecessary system calls. The system function has to fork a subprocess in order to execute the program you specify--or worse, execute a shell to execute the program. This can easily execute a million instructions.

  • Worry about starting subprocesses, but only if they're frequent. Starting a single pwd, hostname, or find process isn't going to hurt you much--after all, a shell starts subprocesses all day long. We do occasionally encourage the toolbox approach, believe it or not.

  • Keep track of your working directory yourself rather than calling pwd repeatedly. (A standard module is provided for this. See Cwd in Chapter 30, "The Standard Perl Library".)

  • Avoid shell metacharacters in commands--pass lists to system and exec where appropriate.

  • Set the sticky bit on the Perl interpreter on machines without demand paging:

    chmod +t /usr/bin/perl

  • Allowing built-in functions' arguments to default to $_ doesn't make your program faster.

24.2.2. Space Efficiency

  • You can use vec for compact integer array storage if the integers are of fixed width. (Integers of variable width can be stored in a UTF-8 string.)

  • Prefer numeric values over equivalent string values--they require less memory.

  • Use substr to store constant-length strings in a longer string.

  • Use the Tie::SubstrHash module for very compact storage of a hash array, if the key and value lengths are fixed.

  • Use __END__ and the DATA filehandle to avoid storing program data as both a string and an array.

  • Prefer each to keys where order doesn't matter.

  • Delete or undef globals that are no longer in use.

  • Use some kind of DBM to store hashes.

  • Use temp files to store arrays.

  • Use pipes to offload processing to other tools.

  • Avoid list operations and entire file slurps.

  • Avoid using tr///. Each tr/// expression must store a sizable translation table.

  • Don't unroll your loops or inline your subroutines.

24.2.3. Programmer Efficiency

  • Use defaults.

  • Use funky shortcut command-line switches like -a, -n, -p, -s, and -i.

  • Use for to mean foreach.

  • Run system commands with backticks.

  • Use <*> and such.

  • Use patterns created at run time.

  • Use *, +, and {} liberally in your patterns.

  • Process whole arrays and slurp entire files.

  • Use getc.

  • Use $`, $&, and $'.

  • Don't check error values on open, since <HANDLE> and print HANDLE will simply behave as no-ops when given an invalid handle.

  • Don't close your files--they'll be closed on the next open.

  • Don't pass subroutine arguments. Use globals.

  • Don't name your subroutine parameters. You can access them directly as $_[EXPR].

  • Use whatever you think of first.

24.2.4. Maintainer Efficiency

  • Don't use defaults.

  • Use foreach to mean foreach.

  • Use meaningful loop labels with next and last.

  • Use meaningful variable names.

  • Use meaningful subroutine names.

  • Put the important thing first on the line using and, or, and statement modifiers (like exit if $done).

  • Close your files as soon as you're done with them.

  • Use packages, modules, and classes to hide your implementation details.

  • Pass arguments as subroutine parameters.

  • Name your subroutine parameters using my.

  • Parenthesize for clarity.

  • Put in lots of (useful) comments.

  • Include embedded pod documentation.

  • use warnings.

  • use strict.

24.2.5. Porter Efficiency

  • Wave a handsome tip under his nose.

  • Avoid functions that aren't implemented everywhere. You can use eval tests to see what's available.

  • Use the Config module or the $^O variable to find out what kind of machine you're running on.

  • Don't expect native float and double to pack and unpack on foreign machines.

  • Use network byte order (the "n" and "N" formats for pack) when sending binary data over the network.

  • Don't send binary data over the network. Send ASCII. Better, send UTF-8. Better yet, send money.

  • Check $] or $^V to see if the current version supports all the features you use.

  • Don't use $] or $^V. Use require or use with a version number.

  • Put in the eval exec hack even if you don't use it, so your program will run on those few systems that have Unix-like shells but don't recognize the #! notation.

  • Put the #!/usr/bin/perl line in even if you don't use it.

  • Test for variants of Unix commands. Some find programs can't handle the -xdev switch, for example.

  • Avoid variant Unix commands if you can do it internally. Unix commands don't work too well on MS-DOS or VMS.

  • Put all your scripts and manpages into a single network filesystem that's mounted on all your machines.

  • Publish your module on CPAN. You'll get lots of feedback if it's not portable.

24.2.6. User Efficiency

  • Instead of making users enter data line by line, pop users into their favorite editor.

  • Better yet, use a GUI like the Perl/Tk extension, where users can control the order of events. (Perl/Tk is available on CPAN.)

  • Put up something for users to read while you continue doing work.

  • Use autoloading so that the program appears to run faster.

  • Give the option of helpful messages at every prompt.

  • Give a helpful usage message if users don't give correct input.

  • Display the default action at every prompt, and maybe a few alternatives.

  • Choose defaults for beginners. Allow experts to change the defaults.

  • Use single character input where it makes sense.

  • Pattern the interaction after other things the user is familiar with.

  • Make error messages clear about what needs fixing. Include all pertinent information such as filename and error code, like this:

    open(FILE, $file) or die "$0: Can't open $file for reading: $!\n";

  • Use fork && exit to detach from the terminal when the rest of the script is just batch processing.

  • Allow arguments to come from either the command line or standard input.

  • Don't put arbitrary limitations into your program.

  • Prefer variable-length fields over fixed-length fields.

  • Use text-oriented network protocols.

  • Tell everyone else to use text-oriented network protocols!

  • Tell everyone else to tell everyone else to use text-oriented network protocols!!!

  • Be vicariously lazy.

  • Be nice.

Previous | Home | Next
24.1. Common Goofs for Novices | Book Index | 24.3. Programming with Style
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


24.3. Programming with Style

You'll certainly have your own preferences in regard to formatting, but there are some general guidelines that will make your programs easier to read, understand, and maintain.

The most important thing is to run your programs under the use warnings pragma. (You can turn off unwanted warnings with no warnings.) You should also always run under use strict or have a good reason not to. The use sigtrap and even the use diagnostics pragmas may also prove of benefit.

Regarding aesthetics of code layout, about the only thing Larry cares strongly about is that the closing brace of a multiline BLOCK should be "outdented" to line up with the keyword that started the construct. Beyond that, he has other preferences that aren't so strong. Examples in this book (should) all follow these coding conventions:

  • Use four-column indents.

  • An opening brace should be put on the same line as its preceding keyword, if possible; otherwise, line them up vertically.

    while ($condition) {        # for short ones, align with keywords
    # do something
}

# if the condition wraps, line up the braces with each other
while ($this_condition and $that_condition
       and $this_other_long_condition)
{
    # do something
}

  • Put space before the opening brace of a multiline BLOCK.

  • A short BLOCK may be put on one line, including braces.

  • Omit the semicolon in a short, one-line BLOCK.

  • Surround most operators with space.

  • Surround a "complex" subscript (inside brackets) with space.

  • Put blank lines between chunks of code that do different things.

  • Put a newline between a closing brace and else.

  • Do not put space between a function name and its opening parenthesis.

  • Do not put space before a semicolon.

  • Put space after each comma.

  • Break long lines after an operator (but before and and or, even when spelled && and ||).

  • Line up corresponding items vertically.

  • Omit redundant punctuation as long as clarity doesn't suffer.

Larry has his reasons for each of these things, but he doesn't claim that everyone else's mind works the same as his does (or doesn't).

Here are some other, more substantive style issues to think about:

  • Just because you can do something a particular way doesn't mean you should do it that way. Perl is designed to give you several ways to do anything, so consider picking the most readable one. For instance:

    open(FOO,$foo)  or die "Can't open $foo: $!";
    is better than:
    die "Can't open $foo: $!"   unless open(FOO,$foo);
    because the second way hides the main point of the statement in a modifier. On the other hand:
    print "Starting analysis\n" if $verbose;
    is better than:
    $verbose and print "Starting analysis\n";
    since the main point isn't whether the user typed -v or not.

  • Similarly, just because an operator lets you assume default arguments doesn't mean that you have to make use of the defaults. The defaults are there for lazy programmers writing one-shot programs. If you want your program to be readable, consider supplying the argument.

  • Along the same lines, just because you can omit parentheses in many places doesn't mean that you ought to:

    return print reverse sort num values %array;
return print(reverse(sort num (values(%array))));
    When in doubt, parenthesize. At the very least it will let some poor schmuck bounce on the % key in vi.

    Even if you aren't in doubt, consider the mental welfare of the person who has to maintain the code after you, and who will probably put parentheses in the wrong place.

  • Don't go through silly contortions to exit a loop at the top or the bottom. Perl provides the last operator so you can exit in the middle. You can optionally "outdent" it to make it more visible:

    LINE:
    for (;;) {
        statements;
      last LINE if $foo;
        next LINE if /^#/;
        statements;
    }

  • Don't be afraid to use loop labels--they're there to enhance readability as well as to allow multilevel loop breaks. See the example just given.

  • Avoid using grep, map, or backticks in a void context, that is, when you just throw away their return values. Those functions all have return values, so use them. Otherwise, use a foreach loop or the system function.

  • For portability, when using features that may not be implemented on every machine, test the construct in an eval to see whether it fails. If you know the version or patch level of a particular feature, you can test $] ($PERL_VERSION in the English module) to see whether the feature is there. The Config module will also let you interrogate values determined by the Configure program when Perl was installed.

  • Choose mnemonic identifiers. If you can't remember what mnemonic means, you've got a problem.

  • Although short identifiers like $gotit are probably okay, use underscores to separate words. It is generally much easier to read $var_names_like_this than $VarNamesLikeThis, especially for non-native speakers of English. Besides, the same rule works for $VAR_NAMES_LIKE_THIS.

    Package names are sometimes an exception to this rule. Perl informally reserves lowercase module names for pragmatic modules like integer and strict. Other modules should begin with a capital letter and use mixed case, but should probably omit underscores due to name-length limitations on certain primitive filesystems.

  • You may find it helpful to use letter case to indicate the scope or nature of a variable. For example:

    $ALL_CAPS_HERE   # constants only (beware clashes with Perl vars!)
$Some_Caps_Here  # package-wide global/static
$no_caps_here    # function scope my() or local() variables

    For various vague reasons, function and method names seem to work best as all lowercase. For example, $obj->as_string().

    You can use a leading underscore to indicate that a variable or function should not be used outside the package that defined it. (Perl does not enforce this; it's just a form of documentation.)

  • If you have a really hairy regular expression, use the /x modifier and put in some whitespace to make it look a little less like line noise.

  • Don't use slash as a delimiter when your regular expression already has too many slashes or backslashes.

  • Don't use quotes as delimiters when your string contains the same kind of quote. Use the q//, qq//, or qx// pseudofunctions instead.

  • Use the and and or operators to avoid having to parenthesize list operators so much and to reduce the incidence of punctuational operators like && and ||. Call your subroutines as if they were functions or list operators to avoid excessive ampersands and parentheses.

  • Use here documents instead of repeated print statements.

  • Line up corresponding things vertically, especially if they're too long to fit on one line anyway:

    $IDX = $ST_MTIME;
$IDX = $ST_ATIME       if $opt_u;
$IDX = $ST_CTIME       if $opt_c;
$IDX = $ST_SIZE        if $opt_s;

mkdir $tmpdir, 0700 or die "can't mkdir $tmpdir: $!";
chdir($tmpdir)      or die "can't chdir $tmpdir: $!";
mkdir 'tmp',   0777 or die "can't mkdir $tmpdir/tmp: $!";

  • That which we tell you three times is true:

    Always check the return codes of system calls.
Always check the return codes of system calls.
ALWAYS CHECK THE RETURN CODES OF SYSTEM CALLS!

    Error messages should go to STDERR and should say which program caused the problem and what the failed call and its arguments were. Most importantly, for failed syscalls, messages should contain the standard system error message for what went wrong. Here's a simple but sufficient example:

    opendir(D, $dir)  or die "Can't opendir $dir: $!";

  • Line up your transliterations when it makes sense:

    tr [abc]
   [xyz];

  • Think about reusability. Why waste brainpower on a one-shot script when you might want to do something like it again? Consider generalizing your code. Consider writing a module or object class. Consider making your code run cleanly with use strict and -w in effect. Consider giving away your code. Consider changing your whole world view. Consider ... oh, never mind.

  • Be consistent.

  • Be nice.

Previous | Home | Next
24.2. Efficiency | Book Index | 24.4. Fluent Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


24.4. Fluent Perl

We've touched on a few idioms in the preceding sections (not to mention the preceding chapters), but there are many other idioms you'll commonly see if you read programs by accomplished Perl programmers. When we speak of idiomatic Perl in this context, we don't just mean a set of arbitrary Perl expressions with fossilized meanings. Rather, we mean Perl code that shows an understanding of the flow of the language, what you can get away with when, and what that buys you. And when to buy it.

We can't hope to list all the idioms you might see--that would take a book as big as this one. Maybe two. (See the Perl Cookbook, for instance.) But here are some of the important idioms, where "important" might be defined as "that which induces hissy fits in people who think they already know just how computer languages ought to work".

  • Use => in place of a comma anywhere you think it improves readability:

    return bless $mess => $class;
    This reads, "Bless this mess into the specified class." Just be careful not to use it after a word that you don't want autoquoted:
    sub foo () { "FOO" }
sub bar () { "BAR" }
print foo => bar;   # prints fooBAR, not FOOBAR;
    Another good place to use => is near a literal comma that might get confused visually:
    join(", " => @array);
    Perl provides you with more than one way to do things so that you can exercise your ability to be creative. Exercise it!

  • Use the singular pronoun to increase readability:

    for (@lines) {
    $_ .= "\n";
}
    The $_ variable is Perl's version of a pronoun, and it essentially means "it". So the code above means "for each line, append a newline to it." Nowadays you might even spell that:
    $_ .= "\n" for @lines;
    The $_ pronoun is so important to Perl that its use is mandatory in grep and map. Here is one way to set up a cache of common results of an expensive function:
    %cache = map { $_ => expensive($_) } @common_args;
$xval = $cache{$x} || expensive($x);

  • Omit the pronoun to increase readability even further.[1]

    [1]In this section, multiple bullet items in a row all refer to the subsequent example, since some of our examples illustrate more than one idiom.

  • Use loop controls with statement modifiers.

    while (<>) {
    next if /^=for\s+(index|later)/;
    $chars += length;
    $words += split;
    $lines += y/\n//;
}
    This is a fragment of code we used to do page counts for this book. When you're going to be doing a lot of work with the same variable, it's often more readable to leave out the pronouns entirely, contrary to common belief.

    The fragment also demonstrates the idiomatic use of next with a statement modifier to short-circuit a loop.

    The $_ variable is always the loop control variable in grep and map, but the program's reference to it is often implicit:

    @haslen = grep { length } @random;
    Here we take a list of random scalars and only pick the ones that have a length greater than 0.

  • Use for to set the antecedent for a pronoun:

    for ($episode) {
    s/fred/barney/g;
    s/wilma/betty/g;
    s/pebbles/bambam/g;
}
    So what if there's only one element in the loop? It's a convenient way to set up "it", that is, $_. Linguistically, this is known as topicalization. It's not cheating, it's communicating.

  • Implicitly reference the plural pronoun, @_.

  • Use control flow operators to set defaults:

    sub bark {
    my Dog $spot = shift;
    my $quality  = shift || "yapping";
    my $quantity = shift || "nonstop";
    ...
}
    Here we're implicitly using the other Perl pronoun, @_, which means "them". The arguments to a function always come in as "them". The shift operator knows to operate on @_ if you omit it, just as the ride operator at Disneyland might call out "Next!" without specifying which queue is supposed to shift. (There's no point in specifying, because there's only one queue that matters.)

    The || can be used to set defaults despite its origins as a Boolean operator, since Perl returns the first true value. Perl programmers often manifest a cavalier attitude toward the truth; the line above would break if, for instance, you tried to specify a quantity of 0. But as long as you never want to set either $quality or $quantity to a false value, the idiom works great. There's no point in getting all superstitious and throwing in calls to defined and exists all over the place. You just have to understand what it's doing. As long as it won't accidentally be false, you're fine.

  • Use assignment forms of operators, including control flow operators:

    $xval = $cache{$x} ||= expensive($x);
    Here we don't initialize our cache at all. We just rely on the ||= operator to call expensive($x) and assign it to $cache{$x} only if $cache{$x} is false. The result of that is whatever the new value of $cache{$x} is. Again, we take the cavalier approach towards truth, in that if we cache a false value, expensive($x) will get called again. Maybe the programmer knows that's okay, because expensive($x) isn't expensive when it returns false. Or maybe the programmer knows that expensive($x) never returns a false value at all. Or maybe the programmer is just being sloppy. Sloppiness can be construed as a form of creativity.

  • Use loop controls as operators, not just as statements. And...

  • Use commas like small semicolons:

    while (<>) {
    $comments++, next if /^#/;
    $blank++, next    if /^\s*$/;
    last              if /^__END__/;
    $code++;
}
print "comment = $comments\nblank = $blank\ncode = $code\n";
    This shows an understanding that statement modifiers modify statements, while next is a mere operator. It also shows the comma being idiomatically used to separate expressions much like you'd ordinarily use a semicolon. (The difference being that the comma keeps the two expressions as part of the same statement, under the control of the single statement modifier.)

  • Use flow control to your advantage:

    while (<>) {
    /^#/       and $comments++, next;
    /^\s*$/    and $blank++, next;
    /^__END__/ and last;
    $code++;
}
print "comment = $comments\nblank = $blank\ncode = $code\n";
    Here's the exact same loop again, only this time with the patterns out in front. The perspicacious Perl programmer understands that it compiles down to exactly the same internal codes as the previous example. The if modifier is just a backward and (or &&) conjunction, and the unless modifier is just a backward or (or ||) conjunction.

  • Use the implicit loops provided by the -n and -p switches.

  • Don't put semicolon at the end of a one-line block:

    #!/usr/bin/perl -n
$comments++, next LINE if /#/;
$blank++, next LINE    if /^\s*$/;
last LINE              if /^__END__/;
$code++;

END { print "comment = $comments\nblank = $blank\ncode = $code\n" }
    This is essentially the same program as before. We put an explicit LINE label on the loop control operators because we felt like it, but we didn't really need to, since the implicit LINE loop supplied by -n is the innermost enclosing loop. We used an END to get the final print statement outside the implicit main loop, just as in awk.

  • Use here docs when the printing gets ferocious.

  • Use a meaningful delimiter on the here doc:

    END { print <<"COUNTS" }
comment = $comments
blank = $blank
code = $code
COUNTS
    Rather than using multiple prints, the fluent Perl programmer uses a multiline string with interpolation. And despite our calling it a Common Goof earlier, we've brazenly left off the trailing semicolon because it's not necessary at the end of the END block. (If we ever turn it into a multiline block, we'll put the semicolon back in.)

  • Do substitutions and translations en passant on a scalar:

    ($new = $old) =~ s/bad/good/g;
    Since lvalues are lvaluable, so to speak, you'll often see people changing a value "in passing" while it's being assigned. This could actually save a string copy internally (if we ever get around to implementing the optimization):
    chomp($answer = <STDIN>);
    Any function that modifies an argument in place can do the en passant trick. But wait, there's more!

  • Don't limit yourself to changing scalars en passant:

    for (@new = @old) { s/bad/good/g }
    Here we copy @old into @new, changing everything in passing (not all at once, of course--the block is executed repeatedly, one "it" at a time).

  • Pass named parameters using the fancy => comma operator.

  • Rely on assignment to a hash to do even/odd argument processing:

    sub bark {
    my DOG $spot = shift;
    my %parm = @_;
    my $quality  = $parm{QUALITY}  || "yapping";
    my $quantity = $parm{QUANTITY} || "nonstop";
    ...
}

$fido->bark( QUANTITY => "once",
              QUALITY => "woof" );
    Named parameters are often an affordable luxury. And with Perl, you get them for free, if you don't count the cost of the hash assignment.

  • Repeat Boolean expressions until false.

  • Use minimal matching when appropriate.

  • Use the /e modifier to evaluate a replacement expression:

    #!/usr/bin/perl -p
1 while s/^(.*?)(\t+)/$1 . ' ' x (length($2) * 4 - length($1) % 4)/e;
    This program fixes any file you receive from someone who mistakenly thinks they can redefine hardware tabs to occupy 4 spaces instead of 8. It makes use of several important idioms. First, the 1 while idiom is handy when all the work you want to do in the loop is actually done by the conditional. (Perl is smart enough not to warn you that you're using 1 in a void context.) We have to repeat this substitution because each time we substitute some number of spaces in for tabs, we have to recalculate the column position of the next tab from the beginning.

    The (.*?) matches the smallest string it can up until the first tab, using the minimal matching modifier (the question mark). In this case, we could have used an ordinary greedy * like this: ([^\t]*). But that only works because a tab is a single character, so we can use a negated character class to avoid running past the first tab. In general, the minimal matcher is much more elegant, and doesn't break if the next thing that must match happens to be longer than one character.

    The /e modifier does a substitution using an expression rather than a mere string. This lets us do the calculations we need right when we need them.

  • Use creative formatting and comments on complex substitutions:

    #!/usr/bin/perl -p
1 while s{
    ^               # anchor to beginning
    (               # start first subgroup
        .*?         # match minimal number of characters
    )               # end first subgroup
    (               # start second subgroup
        \t+         # match one or more tabs
    )               # end second subgroup
}
{
    my $spacelen = length($2) * 4;  # account for full tabs
    $spacelen -= length($1) % 4;    # account for the uneven tab
    $1 . ' ' x $spacelen;           # make correct number of spaces
}ex;
    This is probably overkill, but some people find it more impressive than the previous one-liner. Go figure.

  • Go ahead and use $` if you feel like it:

    1 while s/(\t+)/' ' x (length($1) * 4 - length($`) % 4)/e;
    Here's the shorter version, which uses $`, which is known to impact performance. Except that we're only using the length of it, so it doesn't really count as bad.

  • Use the offsets directly from the @- (@LAST_MATCH_START) and @+ (@LAST_MATCH_END) arrays:

    1 while s/\t+/' ' x (($+[0] - $-[0]) * 4 - $-[0] % 4)/e;
    This one's even shorter. (If you don't see any arrays there, try looking for array elements instead.) See @- and @+ in Chapter 28, "Special Names".

  • Use eval with a constant return value:

    sub is_valid_pattern {
    my $pat = shift;
    return eval { "" =~ /$pat/; 1 } || 0;
}
    You don't have to use the eval {} operator to return a real value. Here we always return 1 if it gets to the end. However, if the pattern contained in $pat blows up, the eval catches it and returns undef to the Boolean conditional of the || operator, which turns it into a defined 0 (just to be polite, since undef is also false but might lead someone to believe that the is_valid_pattern subroutine is misbehaving, and we wouldn't want that, now would we?).

  • Use modules to do all the dirty work.

  • Use object factories.

  • Use callbacks.

  • Use stacks to keep track of context.

  • Use negative subscripts to access the end of an array or string:

    use XML::Parser;

$p = new XML::Parser Style => 'subs';
setHandlers $p Char => sub { $out[-1] .= $_[1] };

push @out, "";

sub literal {
    $out[-1] .= "C<";
    push @out, "";
}

sub literal_ {
    my $text = pop @out;
    $out[-1] .= $text . ">";
}
...
    This is a snippet from the 250-line program we used to translate the XML version of the old Camel book back into pod format so we could edit it for this edition with a Real Text Editor.

    The first thing you'll notice is that we rely on the XML::Parser module (from CPAN) to parse our XML correctly, so we don't have to figure out how. That cuts a few thousand lines out of our program right there (presuming we're reimplementing in Perl everything XML::Parser does for us,[2] including translation from almost any character set into UTF-8).

    [2]Actually, XML::Parser is just a fancy wrapper around James Clark's expat XML parser.

    XML::Parser uses a high-level idiom called an object factory. In this case, it's a parser factory. When we create an XML::Parser object, we tell it which style of parser interface we want, and it creates one for us. This is an excellent way to build a testbed application when you're not sure which kind of interface will turn out to be the best in the long run. The subs style is just one of XML::Parser's interfaces. In fact, it's one of the oldest interfaces, and probably not even the most popular one these days.

    The setHandlers line shows a method call on the parser, not in arrow notation, but in "indirect object" notation, which lets you omit the parens on the arguments, among other things. The line also uses the named parameter idiom we saw earlier.

    The line also shows another powerful concept, the notion of a callback. Instead of us calling the parser to get the next item, we tell it to call us. For named XML tags like <literal>, this interface style will automatically call a subroutine of that name (or the name with an underline on the end for the corresponding end tag). But the data between tags doesn't have a name, so we set up a Char callback with the setHandlers method.

    Next we initialize the @out array, which is a stack of outputs. We put a null string into it to represent that we haven't collected any text at the current tag embedding level (0 initially).

    Now is when that callback comes back in. Whenever we see text, it automatically gets appended to the final element of the array, via the $out[-1] idiom in the callback. At the outer tag level, $out[-1] is the same as $out[0], so $out[0] ends up with our whole output. (Eventually. But first we have to deal with tags.)

    Suppose we see a <literal> tag. Then the literal subroutine gets called, appends some text to the current output, then pushes a new context onto the @out stack. Now any text up until the closing tag gets appended to that new end of the stack. When we hit the closing tag, we pop the $text we've collected back off the @out stack, and append the rest of the transmogrified data to the new (that is, the old) end of stack, the result of which is to translate the XML string, <literal>text</literal>, into the corresponding pod string, C<text>.

    The subroutines for the other tags are just the same, only different.

  • Use my without assignment to create an empty array or hash.

  • Split the default string on whitespace.

  • Assign to lists of variables to collect however many you want.

  • Use autovivification of undefined references to create them.

  • Autoincrement undefined array and hash elements to create them.

  • Use autoincrement of a %seen array to determine uniqueness.

  • Assign to a handy my temporary in the conditional.

  • Use the autoquoting behavior of braces.

  • Use an alternate quoting mechanism to interpolate double quotes.

  • Use the ?: operator to switch between two arguments to a printf.

  • Line up printf args with their % field:

    my %seen;
while (<>) {
    my ($a, $b, $c, $d) = split;
    print unless $seen{$a}{$b}{$c}{$d}++;
}
if (my $tmp = $seen{fee}{fie}{foe}{foo}) {
    printf qq(Saw "fee fie foe foo" [sic] %d time%s.\n"),
                                          $tmp,  $tmp == 1 ? "" : "s";
}
    These nine lines are just chock full of idioms. The first line makes an empty hash because we don't assign anything to it. We iterate over input lines setting "it", that is, $_, implicitly, then using an argumentless split which splits "it" on whitespace. Then we pick off the four first words with a list assignment, throwing any subsequent words away. Then we remember the first four words in a four-dimensional hash, which automatically creates (if necessary) the first three reference elements and final count element for the autoincrement to increment. (Under use warnings, the autoincrement will never warn that you're using undefined values, because autoincrement is an accepted way to define undefined values.) We then print out the line if we've never seen a line starting with these four words before, because the autoincrement is a postincrement, which, in addition to incrementing the hash value, will return the old true value if there was one.

    After the loop, we test %seen again to see if a particular combination of four words was seen. We make use of the fact that we can put a literal identifier into braces and it will be autoquoted. Otherwise, we'd have to say $seen{"fee"}{"fie"}{"foe"}{"foo"}, which is a drag even when you're not running from a giant.

    We assign the result of $seen{fee}{fie}{foe}{foo} to a temporary variable even before testing it in the Boolean context provided by the if. Because assignment returns its left value, we can still test the value to see if it was true. The my tells your eye that it's a new variable, and we're not testing for equality but doing an assignment. It would also work fine without the my, and an expert Perl programmer would still immediately notice that we used one = instead of two ==. (A semiskilled Perl programmer might be fooled, however. Pascal programmers of any skill level will foam at the mouth.)

    Moving on to the printf statement, you can see the qq() form of double quotes we used so that we could interpolate ordinary double quotes as well as a newline. We could've directly interpolated $tmp there as well, since it's effectively a double-quoted string, but we chose to do further interpolation via printf. Our temporary $tmp variable is now quite handy, particularly since we don't just want to interpolate it, but also test it in the conditional of a ?: operator to see whether we should pluralize the word "time". Finally, note that we lined up the two fields with their corresponding % markers in the printf format. If an argument is too long to fit, you can always go to the next line for the next argument, though we didn't have to in this case.

Whew! Had enough? There are many more idioms we could discuss, but this book is already sufficiently heavy. But we'd like to talk about one more idiomatic use of Perl, the writing of program generators.

Previous | Home | Next
24.3. Programming with Style | Book Index | 24.5. Program Generation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


24.5. Program Generation

Almost from the time people first figured out that they could write programs, they started writing programs that write other programs. We often call these program generators. (If you're a history buff, you might know that RPG stood for Report Program Generator long before it stood for Role Playing Game.) Nowadays they'd probably be called "program factories", but the generator people got there first, so they got to name it.

Now, anyone who has written a program generator knows that it can make your eyes go crossed even when you're wide awake. The problem is simply that much of your program's data looks like real code, but isn't (at least not yet). The same text file contains both stuff that does something and similar looking stuff that doesn't. Perl has various features that make it easy to mix Perl together with other languages, textually speaking.

(Of course, these features also make it easier to write Perl in Perl, but that's rather to be expected by now, we should think.)

24.5.1. Generating Other Languages in Perl

Perl is (among other things) a text-processing language, and most computer languages are textual. Beyond that, Perl's lack of arbitrary limits together with the various quoting and interpolation mechanisms make it easy to visually isolate the code of the other language you're spitting out. For example, here is a small chunk of s2p, the sed-to-perl translator:

print &q(<<"EOT");
:       #!$bin/perl
:       eval 'exec $bin/perl -S \$0 \${1+"\$@"}'
:               if \$running_under_some_shell;
:
EOT
Here the enclosed text happens to be legal in two languages, both Perl and sh. We've used an idiom right off the bat that will preserve your sanity in the writing of a program generator: the trick of putting a "noise" character and a tab on the front of every quoted line, which visually isolates the enclosed code, so you can tell at a glance that it's not the code that is actually being executed. One variable, $bin, is interpolated in the multiline quote in two places, and then the string is passed through a function to strip the colon and tab.

Of course, you aren't required to use multiline quotes. One often sees CGI scripts containing millions of print statements, one per line. It seems a bit like driving to church in an F-16, but hey, if it gets you there... (We will admit that a column of print statements has its own form of visual distinctiveness.)

When you are embedding a large, multiline quote containing some other language (such as HTML), it's often helpful to pretend you're programming inside-out, enclosing Perl into the other language instead, much as you might do with overtly everted languages such as PHP:

print <<"XML";
    <stuff>
    <nonsense>
    blah blah blah @{[ scalar EXPR ]} blah blah blah
    blah blah blah @{[ LIST ]} blah blah blah
    </nonsense>
    </stuff>
XML
You can use either of those two tricks to interpolate the values of arbitrarily complicated expressions into the long string.

Some program generators don't look much like program generators, depending on how much of their work they hide from you. In Chapter 22, "CPAN", we saw how a small Makefile.PL program could be used to write a Makefile. The Makefile can easily be 100 times bigger than the Makefile.PL that produced it. Think how much wear and tear that saves your fingers. Or don't think about it--that's the point, after all.

24.5.2. Generating Perl in Other Languages

It's easy to generate other languages in Perl, but the converse is also true. Perl can easily be generated in other languages because it's both concise and malleable. You can pick your quotes not to interfere with the other language's quoting mechanisms. You don't have to worry about indentation, or where you put your line breaks, or whether to backslash your backslashes Yet Again. You aren't forced to define a package as a single string in advance, since you can slide into your package's namespace repeatedly, whenever you want to evaluate more code in that package.

Another thing that makes it easy to write Perl in other languages (including Perl) is the #line directive. Perl knows how to process these as special directives that reconfigure its idea of the current filename and line number. This can be useful in error or warning messages, especially for strings processed with eval (which, when you think about it, is just Perl writing Perl). The syntax for this mechanism is the one used by the C preprocessor: when Perl encounters a # symbol and the word line, followed by a number and a filename, it sets __LINE__ to the number and __FILE__ to the filename.[3]

[3]Technically, it matches the pattern /^#\s*line\s+(\d+)\s*(?:\s"([^"]+)")?\s*$/, with $1 providing the line number for the next line, and $2 providing the optional filename specified within quotes. (A null filename leaves __FILE__ unchanged.)

Here are some examples that you can test by typing into perl directly. We've used a Control-D to indicate end-of-file, which is typical on Unix. DOS/Windows and VMS users can type Control-Z. If your shell uses something else, you'll have to use that to tell perl you're done. Alternatively, you can always type in __END__ to tell the compiler there's nothing left to parse.

Here, Perl's built-in warn function prints out the new filename and line number:

% perl
# line 2000 "Odyssey"
# the "#" on the previous line must be the first char on line
warn "pod bay doors";  # or die
^D
pod bay doors at Odyssey line 2001.
And here, the exception raised by die within the eval found its way into the $@ ($EVAL_ERROR) variable, along with the temporary new filename and line:
# line 1996 "Odyssey"
eval qq{
#line 2025 "Hal"
    die "pod bay doors";
};
print "Problem with $@";
warn "I'm afraid I can't do that";
^D
Problem with pod bay doors at Hal line 2025.
I'm afraid I can't do that at Odyssey line 2001.
This shows how a #line directive affects only the current compilation unit (file or eval STRING), and that when that unit is done being compiled, the previous settings are automatically restored. This way you can set up your own messages inside an eval STRING or do FILE without affecting the rest of your program.

Perl has a -P switch that invokes the C preprocessor, which emits #line directives. The C preprocessor was the original impetus for implementing #line, but it is seldom used these days, since there are usually better ways to do what we used to rely on it for. Perl has a number of other preprocessors, however, including the AutoSplit module. The JPL (Java Perl Lingo) preprocessor turns .jpl files into .java, .pl, .h, and .c files. It makes use of #line to keep the error messages accurate.

One of the very first Perl preprocessors was the sed-to-perl translator, s2p. In fact, Larry delayed the initial release of Perl in order to complete s2p and awk-to-perl (a2p), because he thought they'd improve the acceptance of Perl. Hmm, maybe they did.

See the online docs for more on these, as well as the find2perl translator.

24.5.3. Source Filters

If you can write a program to translate random stuff into Perl, then why not have a way of invoking that translator from within Perl?

The notion of a source filter started with the idea that a script or module should be able to decrypt itself on the fly, like this:

#!/usr/bin/perl
use MyDecryptFilter;
@*x$]`0uN&k^Zx02jZ^X{.?s!(f;9Q/^A^@~~8H]|,%@^P:q-=
...
But the idea grew from there, and now a source filter can be defined to do any transformation on the input text you like. Put that together with the notion of the -x switch mentioned in Chapter 19, "The Command-Line Interface", and you have a general mechanism for pulling any chunk of program out of a message and executing it, regardless of whether it's written in Perl or not.

Using the Filter module from CPAN, one can now even do things like programming Perl in awk:

#!/usr/bin/perl
use Filter::exec "a2p";         # the awk-to-perl translator
1,30 { print $1 }
Now that's definitely what you might call idiomatic. But we won't pretend for a moment that it's common practice.

Previous | Home | Next
24.4. Fluent Perl | Book Index | 25. Portable Perl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 25. Portable Perl

Contents:

Newlines
Endianness and Number Width
Files and Filesystems
System Interaction
Interprocess Communication (IPC)
External Subroutines (XS)
Standard Modules
Dates and Times
Internationalization
Style

A world with only one operating system makes portability easy, and life boring. We prefer a larger genetic pool of operating systems, as long as the ecosystem doesn't divide too cleanly into predators and prey. Perl runs on dozens of operating systems, and because Perl programs aren't platform dependent, the same program can run on all of those systems without modification.

Well, almost. Perl tries to give the programmer as many features as possible, but if you make use of features particular to a certain operating system, you'll necessarily reduce the portability of your program to other systems. In this section, we'll provide some guidelines for writing portable Perl code. Once you make a decision about how portable you want to be, you'll know where the lines are drawn, and you can stay within them.

Looking at it another way, writing portable code is usually about willfully limiting your available choices. Naturally, it takes discipline and sacrifice to do that, two traits that Perl programmers might be unaccustomed to.

Be aware that not all Perl programs have to be portable. There is no reason not to use Perl to glue Unix tools together, or to prototype a Macintosh application, or to manage the Windows registry. If it makes sense to sacrifice portability, go ahead.[1]

[1] Not every conversation has to be cross-culturally correct. Perl tries to give you at least one way to do the Right Thing but doesn't try to force it on you rigidly. In this respect, Perl more closely resembles your mother tongue than a nanny's tongue.

In general, note that the notions of a user ID, a "home" directory, and even the state of being logged in will exist only on multi-user platforms.

The special $^O variable tells you what operating system your Perl was built on. This is provided to speed up code that would otherwise have to use Config to get the same information via $Config{osname}. (Even if you've pulled in Config for other reasons, it still saves you the price of a tied-hash lookup.)

To get more detailed information about the platform, you can look at the rest of the information in the %Config hash, which is made available by the standard Config module. For example, to check whether the platform has the lstat call, you can check $Config{d_lstat}. See Config's online documentation for a full description of available variables, and the perlport manpage for a listing of the behavior of Perl built-in functions on different platforms. Here are the Perl functions whose behavior varies the most across platforms:

-X (file tests), accept, alarm, bind, binmode, chmod, chown, chroot, connect, crypt, dbmclose, dbmopen, dump, endgrent, endhostent, endnetent, endprotoent, endpwent, endservent, exec, fcntl, fileno, flock, fork, getgrent, getgrgid, getgrnam, gethostbyaddr, gethostbyname, gethostent, getlogin, getnetbyaddr, getnetbyname, getnetent, getpeername, getpgrp, getppid, getpriority, getprotobyname, getprotobynumber, getprotoent, getpwent, getpwnam, getpwuid, getservbyport, getservent, getservbyname, getsockname, getsockopt, glob, ioctl, kill, link, listen, lstat, msgctl, msgget, msgrcv, msgsnd, open, pipe, qx, readlink, readpipe, recv, select, semctl, semget, semop, send, sethostent, setgrent, setnetent, setpgrp, setpriority, setprotoent, setpwent, setservent, setsockopt, shmctl, shmget, shmread, shmwrite, shutdown, socket, socketpair, stat, symlink, syscall, sysopen, system, times, truncate, umask, utime, wait, waitpid

25.1. Newlines

On most operating systems, lines in files are terminated by one or two characters that signal the end of the line. The characters vary from system to system. Unix traditionally uses \012 (that is, the octal 12 character in ASCII), one type of DOSish I/O uses \015\012, and Macs uses \015. Perl uses \n to represent a "logical" newline, regardless of platform. In MacPerl, \n always means \015. In DOSish Perls, \n usually means \012, but when accessing a file in "text mode", it is translated to (or from) \015\012, depending on whether you're reading or writing. Unix does the same thing on terminals in canonical mode. \015\012 is commonly referred to as CRLF.

Because DOS distinguishes between text files and binary files, DOSish Perls have limitations when using seek and tell on a file in "text mode". For best results, only seek to locations obtained from tell. If you use Perl's built-in binmode function on the filehandle, however, you can usually seek and tell with impunity.

A common misconception in socket programming is that \n will be \012 everywhere. In many common Internet protocols, \012 and \015 are specified, and the values of Perl's \n and \r are not reliable since they vary from system to system:

print SOCKET "Hi there, client!\015\012";  # right
print SOCKET "Hi there, client!\r\n";      # wrong
However, using \015\012 (or \cM\cJ, or \x0D\x0A, or even v13.10) can be tedious and unsightly, as well as confusing to those maintaining the code. The Socket module supplies some Right Things for those who want them:
use Socket qw(:DEFAULT :crlf);
print SOCKET "Hi there, client!$CRLF"      # right
When reading from a socket, remember that the default input record separator $/ is \n, which means you have to do some extra work if you're not sure what you'll be seeing across the socket. Robust socket code should recognize either \012 or \015\012 as end of line:
use Socket qw(:DEFAULT :crlf);
local ($/) = LF;     # not needed if $/ is already \012

while (<SOCKET>) {
    s/$CR?$LF/\n/;   # replace LF or CRLF with logical newline
}
Similarly, code that returns text data--such as a subroutine that fetches a web page--should often translate newlines. A single line of code will often suffice:
$data =~ s/\015?\012/\n/g;
return $data;

Previous | Home | Next
24.5. Program Generation | Book Index | 25.2. Endianness and Number Width
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.2. Endianness and Number Width

Computers store integers and floating-point numbers in different orders (big-endian or little-endian) and different widths (32-bit and 64-bit being the most common today). Normally, you won't have to think about this. But if your program sends binary data across a network connection, or onto disk to be read by a different computer, you may need to take precautions.

Conflicting orders can make an utter mess out of numbers. If a little-endian host (such as an Intel CPU) stores 0x12345678 (305,419,896 in decimal), a big-endian host (such as a Motorola CPU) will read it as 0x78563412 (2,018,915,346 in decimal). To avoid this problem in network (socket) connections, use the pack and unpack formats n and N, which write unsigned short and long numbers in big-endian order (also called "network" order) regardless of the platform.

You can explore the endianness of your platform by unpacking a data structure packed in native format such as:

print unpack("h*", pack("s2", 1, 2)), "\n";
# '10002000' on e.g. Intel x86 or Alpha 21064 in little-endian mode
# '00100020' on e.g. Motorola 68040
To determine your endianness, you could use either of these statements:
$is_big_endian    = unpack("h*", pack("s", 1)) =~ /01/;
$is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;
Even if two systems have the same endianness, there can still be problems when transferring data between 32-bit and 64-bit platforms. There is no good solution other than to avoid transferring or storing raw binary numbers. Either transfer and store numbers as text instead of binary, or use modules like Data::Dumper or Storable to do this for you. You really want to be using text-oriented protocols in any event--they're more robust, more maintainable, and more extensible than binary protocols.

Of course, with the advent of XML and Unicode, our definition of text is getting more flexible. For instance, between two systems running Perl 5.6.0 (or newer), you can transport a sequence of integers encoded as characters in utf8 (Perl's version of UTF-8). If both ends are running on an architecture with 64-bit integers, you can exchange 64-bit integers. Otherwise, you're limited to 32-bit integers. Use pack with a U* template to send, and unpack with a U* template to receive.

Previous | Home | Next
25.1. Newlines | Book Index | 25.3. Files and Filesystems
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.3. Files and Filesystems

File path components are separated with / on Unix, with \ on Windows, and with : on Macs. Some systems support neither hard links (link) nor symbolic links (symlink, readlink, lstat). Some systems pay attention to capitalization of filenames, some don't, and some pay attention when creating files but not when reading them.

There are modules that can help. The standard File::Spec modules provide some functions of the Right Thing persuasion:

use File::Spec::Functions;
chdir( updir() );        # go up one directory
$file = catfile( curdir(), 'temp', 'file.txt' );
That last line reads in ./temp/file.txt on Unix and Windows, or :temp:file.txt on Macs, or [.temp]file.txt on VMS, and stores the file's contents in $file.

The File::Basename module, another platform-tolerant module bundled with Perl, splits a pathname into its components: the base filename, the full path to the directory, and the file suffix.

Here are some tips for writing portable file-manipulating Perl programs:

  • Don't use two files of the same name with different case, like test.pl and Test.pl, since some platforms ignore capitalization.

  • Constrain filenames to the 8.3 convention (eight-letter names and three-letter extensions) where possible. You can often get away with longer filenames as long as you make sure the filenames will remain unique when shoved through an 8.3-sized hole in the wall. (Hey, it's gotta be easier than shoving a camel through the eye of a needle.)

  • Minimize nonalphanumeric characters in filenames. Using underscores is often okay, but it wastes a character that could better be used for uniqueness on 8.3 systems. (Remember, that's why we don't usually put underscores into module names.)

  • Likewise, when using the AutoSplit module, try to constrain your subroutine names to eight characters or less, and don't give two subroutines the same name with different case. If you need longer subroutine names, make the first eight characters of each unique.

  • Always use < explicitly to open a file for reading; otherwise, on systems that allow punctuation in filenames, a file prefixed with a > character could result in a file being wiped out, and a file prefixed with a | character could result in a pipe open. That's because the two-argument form of open is magical and will interpret characters like >, <, and |, which may be the wrong thing to do. (Except when it's right.)

    open(FILE,      $existing_file)  or die $!;  # wrongish
open(FILE,    "<$existing_file") or die $!;  # righter
open(FILE, "<", $existing_file)  or die $!;  # righterer

  • Don't assume text files will end with a newline. They should, but sometimes people forget, especially when their text editor helps them forget.

Previous | Home | Next
25.2. Endianness and Number Width | Book Index | 25.4. System Interaction
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.4. System Interaction

Platforms that rely on a graphical user interface sometimes lack command lines, so programs requiring a command-line interface might not work everywhere. You can't do much about this, except upgrade.

Some other tips:

  • Some platforms can't delete or rename files that are in use, so remember to close files when you are done with them. Don't unlink or rename an open file. Don't tie or open a file already tied or opened; untie or close it first.

  • Don't open the same file more than once at a time for writing, since some operating systems put mandatory locks on such files.

  • Don't depend on a specific environment variable existing in %ENV, and don't assume that anything in %ENV will be case sensitive or case preserving. Don't assume Unix inheritance semantics for environment variables; on some systems, they may be visible to all other processes.

  • Don't use signals or %SIG.

  • Try to avoid filename globbing. Use opendir, readdir, and closedir instead. (As of release 5.6.0 of Perl, basic filename globbing is much more portable than it was, but some systems may still chafe under the Unixisms of the default interface if you try to get fancy.)

  • Don't assume specific values of the error numbers or strings stored in $!.

Previous | Home | Next
25.3. Files and Filesystems | Book Index | 25.5. Interprocess Communication (IPC)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.5. Interprocess Communication (IPC)

To maximize portability, don't try to launch new processes. That means you should avoid system, exec, fork, pipe, ``, qx//, or open with a |.

The main problem is not the operators themselves; commands that launch external processes are generally supported on most platforms (though some do not support any type of forking). Problems are more likely to arise when you invoke external programs that have names, locations, output, or argument semantics that vary across platforms.

One especially popular bit of Perl code is opening a pipe to sendmail so that your programs can send mail:

open(MAIL, '|/usr/lib/sendmail -t') or die "cannot fork sendmail: $!";
This won't work on platforms without sendmail. For a portable solution, use one of the CPAN modules to send your mail, such as Mail::Mailer and Mail::Send in the MailTools distribution, or Mail::Sendmail.

The Unix System V IPC functions (msg*(), sem*(), shm*()) are not always available, even on some Unix platforms.

Previous | Home | Next
25.4. System Interaction | Book Index | 25.6. External Subroutines (XS)
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.6. External Subroutines (XS)

XS code can usually be made to work with any platform, but libraries and header files might not be readily available, or the XS code itself might be platform specific. If the libraries and headers are portable, then it's a reasonable guess that the XS code can be made portable as well.

A different type of portability issue arises when writing XS code: the availability of a C compiler on the end user's platform. C brings with it its own portability issues, and writing XS code will expose you to some of those. Writing in pure Perl is an easier way to achieve portability because Perl's configuration process goes through extreme agonies to hide C's portability blemishes from you.[2]

[2] Some people on the margins of society run Perl's Configure script as a cheap form of entertainment. People have even been known to stage "Configure races", between competing systems and wager large sums on them. This practice is now outlawed in most of the civilized world.

Previous | Home | Next
25.5. Interprocess Communication (IPC) | Book Index | 25.7. Standard Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.7. Standard Modules

In general, the standard modules (modules bundled with Perl) work on all platforms. Notable exceptions are the CPAN.pm module (which currently makes connections to external programs that may not be available), platform-specific modules (such as ExtUtils::MM_VMS), and DBM modules.

There is no single DBM module available on all platforms. SDBM_File and the others are generally available on all Unix and DOSish ports, but not in MacPerl, where only NBDM_File and DB_File are available.

The good news is that at least one DBM module should be available, and AnyDBM_File will use whichever module it can find. With such uncertainty, you should use only the features common to all DBM implementations. For instance, keep your records to no more than 1K bytes. See the AnyDBM_File module documentation for more details.

Previous | Home | Next
25.6. External Subroutines (XS) | Book Index | 25.8. Dates and Times
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.8. Dates and Times

Where possible, use the ISO-8601 standard ("YYYY-MM-DD") to represent dates. Strings like "1987-12-18" can be easily converted into a system-specific value with a module like Date::Parse. A list of time and date values (such as that returned by the built-in localtime function) can be converted to a system-specific representation using Time::Local.

The built-in time function will always return the number of seconds since the beginning of the "epoch", but operating systems differ in their opinions of when that was. On many systems, the epoch began on January 1, 1970, at 00:00:00 UTC, but it began 66 years earlier on Macs, and on VMS it began on November 17, 1858, at 00:00:00. So for portable times you may want to calculate an offset for the epoch:

require Time::Local;
$offset = Time::Local::timegm(0, 0, 0, 1, 0, 70);
The value for $offset in Unix and Windows will always be 0, but on Macs and VMS it may be some large number. $offset can then be added to a Unix time value to get what should be the same value on any system.

A system's representation of the time of day and the calendar date can be controlled in widely different ways. Don't assume the time zone is stored in $ENV{TZ}. Even if it is, don't assume that you can control the time zone through that variable.

Previous | Home | Next
25.7. Standard Modules | Book Index | 25.9. Internationalization
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.9. Internationalization

Use Unicode inside your program. Do any translation to and from other character sets at your interfaces to the outside world. See Chapter 15, "Unicode".

Outside the world of Unicode, you should assume little about character sets and nothing about the ord values of characters. Do not assume that the alphabetic characters have sequential ord values. The lowercase letters may come before or after the uppercase letters; the lowercase and uppercase may be interlaced so that both a and A come before b; the accented and other international characters may be interlaced so that ä comes before b.

If your program is to operate on a POSIX system (a rather large assumption), consult the perllocale manpage for more information about POSIX locales. Locales affect character sets and encodings, and date and time formatting, among other things. Proper use of locales will make your program a little bit more portable, or at least more convenient and native-friendly for non-English users. But be aware that locales and Unicode don't mix well yet.

Previous | Home | Next
25.8. Dates and Times | Book Index | 25.10. Style
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


25.10. Style

When it is necessary to have platform-specific code, consider keeping it in one place to ease porting to other platforms. Use the Config module and the special variable $^O to differentiate between platforms.

Be careful in the tests you supply with your module or programs. A module's code may be fully portable, but its tests may well not be. This often happens when tests spawn other processes or call external programs to aid in the testing, or when (as noted above) the tests assume certain things about the filesystem and paths. Be careful not to depend on a specific output style for errors, even when checking $! for "standard" errors after a syscall. Use the Errno module instead.

Remember that good style transcends both time and culture, so for maximum portability, you must seek to understand the universal amidst the exigencies of your existence. The coolest people are not prisoners of the latest cool fad; they don't have to be, because they are not worried about being "in" with respect to their own culture, programmatically or otherwise. Fashion is a variable, but style is a constant.

Previous | Home | Next
25.9. Internationalization | Book Index | 26. Plain Old Documentation
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 26. Plain Old Documentation

Contents:

Pod in a Nutshell
Pod Translators and Modules
Writing Your Own Pod Tools
Pod Pitfalls
Documenting Your Perl Programs

One of the principles underlying Perl's design is that simple things should be simple, and hard things should be possible. Documentation should be simple.

Perl supports a simple text markup format called pod that can stand on its own or be freely intermixed with your source code to create embedded documentation. Pod can be converted to many other formats for printing or viewing, or you can just read it directly, because it's plain.

Pod is not as expressive as languages like XML, [LaTeX], troff(1), or even HTML. This is intentional: we sacrificed that expressiveness for simplicity and convenience. Some text markup languages make authors write more markup than text, which makes writing harder than it has to be, and reading next to impossible. A good format, like a good movie score, stays in the background without causing distraction.

Getting programmers to write documentation is almost as hard as getting them to wear ties. Pod was designed to be so easy to write that even a programmer could do it--and would. We don't claim that pod is sufficient for writing a book, although it was sufficient for writing this one.

26.1. Pod in a Nutshell

Most document formats require the entire document to be in that format. Pod is more forgiving: you can embed pod in any sort of file, relying on pod translators to extract the pod. Some files consist entirely of 100% pure pod. But other files, notably Perl programs and modules, may contain dollops of pod sprinkled about wherever the author feels like it. Perl simply skips over the pod text when parsing the file for execution.

The Perl lexer knows to begin skipping when, at a spot where it would ordinarily find a statement, it instead encounters a line beginning with an equal sign and an identifier, like this:

=head1 Here There Be Pods!
That text, along with all remaining text up through and including a line beginning with =cut, will be ignored. This allows you to intermix your source code and your documentation freely, as in:
=item snazzle

The snazzle() function will behave in the most spectacular
form that you can possibly imagine, not even excepting
cybernetic pyrotechnics.

=cut

sub snazzle {
    my $arg = shift;
    ....
}

=item razzle

The razzle() function enables autodidactic epistemology generation.

=cut

sub razzle {
    print "Epistemology generation unimplemented on this platform.\n";
}
For more examples, look at any standard or CPAN Perl module. They're all supposed to come with pod, and nearly all do, except for the ones that don't.

Since pod is recognized by the Perl lexer and thrown out, you may also use an appropriate pod directive to quickly comment out an arbitrarily large section of code. Use a =for pod block to comment out one paragraph, or a =begin/=end pair for a larger section. We'll cover the syntax of those pod directives later. Remember, though, that in both cases, you're still in pod mode afterwards, so you need to =cut back to the compiler.

print "got 1\n";

=for commentary
This paragraph alone is ignored by anyone except the
mythical "commentary" translator.  When it's over, you're
still in pod mode, not program mode.
print "got 2\n";

=cut

# ok, real program again
print "got 3\n";

=begin comment

print "got 4\n";

all of this stuff
here will be ignored
by everyone

print "got 5\n";

=end comment

=cut

print "got 6\n";
This will print out that it got 1, 3, and 6. Remember that these pod directives can't go just anywhere. You have to put them only where the parser is expecting to see a new statement, not just in the middle of an expression or at other arbitrary locations.

From the viewpoint of Perl, all pod markup is thrown out, but from the viewpoint of pod translators, it's the code that is thrown out. Pod translators view the remaining text as a sequence of paragraphs separated by blank lines. All modern pod translators parse pod the same way, using the standard Pod::Parser module. They differ only in their output, since each translator specializes in one output format.

There are three kinds of paragraphs: verbatim paragraphs, command paragraphs, and prose paragraphs.

26.1.1. Verbatim Paragraphs

Verbatim paragraphs are used for literal text that you want to appear as is, such as snippets of code. A verbatim paragraph must be indented; that is, it must begin with a space or tab character. The translator should reproduce it exactly, typically in a constant width font, with tabs assumed to be on eight-column boundaries. There are no special formatting escapes, so you can't play font games to italicize or embolden. A < character means a literal <, and nothing else.

26.1.2. Pod Directives

All pod directives start with = followed by an identifier. This may be followed by any amount of arbitrary text that the directive can use however it pleases. The only syntactic requirement is that the text must all be one paragraph. Currently recognized directives (sometimes called pod commands) are:

=head1
=head2
...

The =head1, =head2,... directives produce headings at the level specified. The rest of the text in the paragraph is treated as the heading description. These are similar to the .SH and .SS section and subsection headers in man(7), or to <H1>...</H1> and <H2>...</H2> tags in HTML. In fact, that's exactly what those translators convert these directives into.

=cut

The =cut directive indicates the end of a stretch of pod. (There might be more pod later in the document, but if so it will be introduced with another pod directive.)

=pod

The =pod directive does nothing beyond telling the compiler to lay off parsing code through the next =cut. It's useful for adding another paragraph to the document if you're mixing up code and pod a lot.

=over NUMBER
=item SYMBOL
=back

The =over directive starts a section specifically for the generation of a list using the =item directive. At the end of your list, use =back to end it. The NUMBER, if provided, hints to the formatter how many spaces to indent. Some formatters aren't rich enough to respect the hint, while others are too rich to respect it, insofar as it's difficult when working with proportional fonts to make anything line up merely by counting spaces. (However, four spaces is generally construed as enough room for bullets or numbers.)

The actual type of the list is indicated by the SYMBOL on the individual items. Here is a bulleted list:

=over 4

=item *

Mithril armor

=item *

Elven cloak

=back
And a numbered list:
=over 4

=item 1.

First, speak "friend".

=item 2.

Second, enter Moria.

=back
And a named list:
=over 4

=item armor()

Description of the armor() function

=item chant()

Description of the chant() function

=back
You may nest lists of the same or different types, but some basic rules apply: don't use =item outside an =over/=back block; use at least one =item inside an =over/=back block; and perhaps most importantly, keep the type of the items consistent within a given list. Either use =item * for each item to produce a bulleted list, or =item 1., =item 2., and so on to produce numbered list, or use =item foo, =item bar, and so on to produce a named list. If you start with bullets or numbers, stick with them, since formatters are allowed to use the first =item type to decide how to format the list.

As with everything in pod, the result is only as good as the translator. Some translators pay attention to the particular numbers (or letters, or Roman numerals) following the =item, and others don't. The current pod2html translator, for instance, is quite cavalier: it strips out the sequence indicators entirely without looking at them to infer what sequence you're using, then wraps the entire list inside <OL> and </OL> tags so that the browser can display it as an ordered list in HTML. This is not to be construed a feature; it may eventually be fixed.

=for TRANSLATOR
=begin TRANSLATOR
=end TRANSLATOR

=for, =begin, and =end let you include special sections to be passed through unaltered, but only to particular formatters. Formatters that recognize their own names, or aliases for their names, in TRANSLATOR pay attention to that directive; any others completely ignore them. The directive =for specifies that just the rest of this paragraph is destined for a particular translator.

=for html
<p> This is a <flash>raw</flash> <small>HTML</small> paragraph </p>
The paired =begin and =end directives work similarly to =for, but instead of accepting a single paragraph only, they treat all text between matched =begin and =end as destined for a particular translator. Some examples:
=begin html

<br>Figure 1.<IMG SRC="figure1.png"><br>

=end html

=begin text

  ---------------
  |  foo        |
  |        bar  |
  ---------------

^^^^ Figure 1. ^^^^

=end text
Values of TRANSLATOR commonly accepted by formatters include roff, man, troff, nroff, tbl, eqn, latex, tex, html, and text. Some formatters will accept some of these as synonyms. No translator accepts comment--that's just the customary word for something to be ignored by everybody. Any unrecognized word would serve the same purpose. While writing this book, we often left notes for ourselves under the directive =for later.

Note that =begin and =end do nest, but only in the sense that the outermost matched set causes everything in the middle to be treated as nonpod, even if it happens to contain other =word directives. That is, as soon as any translator sees =begin foo, it will either ignore or process everything down to the corresponding =end foo.

26.1.3. Pod Sequences

The third type of paragraph is simply "flowed" text. That is, if a paragraph doesn't start with either whitespace or an equals sign, it's taken as a plain paragraph: regular text that's typed in with as few frills as possible. Newlines are treated as equivalent to spaces. It's largely up to the translator to make it look nice, because programmers have more important things to do. It is assumed that translators will apply certain common heuristics--see the section "Pod Translators and Modules" later in this chapter.

You can do some things explicitly, however. Inside either ordinary paragraphs or heading/item directives (but not in verbatim paragraphs), you may use special sequences to adjust the formatting. These sequences always start with a single capital letter followed by a left angle bracket, and extend through the matching (not necessarily the next) right angle bracket. Sequences may contain other sequences.

Here are the sequences defined by pod:

I<text>

Italicized text, used for emphasis, book titles, names of ships, and manpage references such as "perlpod(1)".

B<text>

Emboldened text, used almost exclusively for command-line switches and sometimes for names of programs.

C<text>

Literal code, probably in a fixed-width font like Courier. Not needed on simple items that the translator should be able to infer as code, but you should put it anyway.

S<text>

Text with nonbreaking spaces. Often surrounds other sequences.

L<name>

A cross reference (link) to a name:

L<name>

Manual page

L<name/ident>

Item in manual page

L<name/"sec">

Section in other manual page

L<"sec">

Section in this manual page (the quotes are optional)

L</"sec">

Ditto

The next five sequences are the same as those above, but the output will be only text, with the link information hidden as in HTML:

L<text|name>
L<text|name/ident>
L<text|name/"sec">
L<text|"sec">
L<text|/"sec">

The text cannot contain the characters / and |, and should contain < or > only in matched pairs.

F<pathname>

Used for filenames. This is traditionally rendered the same as I.

X<entry>

An index entry of some sort. As always, it's up to the translator to decide what to do. The pod specification doesn't dictate that.

E<escape>

A named character, similar to HTML escapes:

Z<>

A zero-width character. This is nice for putting in front of sequences that might confuse something. For example, if you had a line in regular prose that had to start with an equals sign, you could write that as:

Z<>=can you see
or for something with a "From" in it, so the mailer doesn't put a > in front:
Z<>From here on out...

Most of the time, you'll need only a single set of angle brackets to delimit one of these pod sequences. Sometimes, however, you will want to put a < or > inside a sequence. (This is particularly common when using a C<> sequence to provide a constant-width font for a snippet of code.) As with all things in Perl, there is more than one way to do it. One way is to simply represent the closing bracket with an E sequence:

C<$a E<lt>=E<gt> $b>
This produces "$a <=> $b".

A more readable, and perhaps more "plain" way, is to use an alternate set of delimiters that doesn't require the angle brackets to be escaped. Doubled angle brackets (C<<stuff>>) may be used, provided there is whitespace immediately following the opening delimiter and immediately preceding the closing one. For example, the following will work:

C<< $a <=> $b >>
You may use as many repeated angle-brackets as you like so long as you have the same number of them on both sides, and you make sure that whitespace immediately follows the last < of the left side and immediately precedes the first > of the right side. So the following will also work:
C<<< $a <=> $b >>>
C<<<< $a <=> $b >>>>
All these end up spitting out $a <=> $b in a constant-width font.

The extra whitespace inside on either end goes away, so you should leave whitespace on the outside if you want it. Also, the two inside chunks of extra whitespace don't overlap, so if the first thing being quoted is >>, it isn't taken as the closing delimiter:

The C<< >> >> right shift operator.
This produces "The >> right shift operator."

Note that pod sequences do nest. That means you can write "The I<Santa MarE<iacute>a> left port already" to produce "The Santa María left port already", or "B<touch> S<B<-t> I<time>> I<file>" to produce "touch -t timefile", and expect this to work properly.

Previous | Home | Next
25.10. Style | Book Index | 26.2. Pod Translators and Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


26.2. Pod Translators and Modules

Perl is bundled with several pod translators that convert pod documents (or the embedded pod in other types of documents) into various formats. All should be 8-bit clean.

pod2text

Converts pod into text. Normally, this text will be 7-bit ASCII, but it will be 8-bit if it had 8-bit input, or specifically ISO-8859-1 (or Unicode) if you use sequences like LE<uacute>thien for Lúthien or EE<auml>rendil for Eärendil.

If you have a file with pod in it, the easiest (although perhaps not the prettiest) way to view just the formatted pod would be:

% pod2text File.pm | more
Then again, pod is supposed to be human readable without formatting.

pod2man

Converts pod into Unix manpage format suitable for viewing through nroff(1) or creating typeset copies via troff(1). For example:

% pod2man File.pm | nroff -man | more
or
% pod2man File.pm | troff -man -Tps -t > tmppage.ps
% ghostview tmppage.ps
and to print:
% lpr -Ppostscript tmppage.ps

pod2html

Converts pod into HTML for use with your favorite viewer:

% pod2html File.pm > tmppage.html
% lynx tmppage.html
% netscape -remote "openURL(file:`pwd`/tmppage.html)"
That last one is a netscape hack that works if you already have netscape running somewhere to tell that incarnation to load the page. Otherwise, just call it as you did lynx.

pod2latex

Converts pod into [LaTeX].

Additional translators are available on CPAN for other formats.

Translators exhibit different default behaviors depending on the output format. For instance, if your pod has a prose paragraph saying:

This is a $variable right here
then pod2html will turn that into:
This is a <STRONG>$variable</STRONG> right here
but pod2text will leave it unadorned, since the dollar should be enough to let it be read.

You should write your pod as close to plain text as you possibly can, with as few explicit markups as you can get away with. It is up to the individual translator to decide how things in your text should be represented. That means letting the translator figure out how to create paired quotes, how to fill and adjust text, how to find a smaller font for words in all capitals, etc. Since these were written to process Perl documentation, most translators[1] should also recognize unadorned items like these and render them appropriately:

[1]If you're designing a general-purpose pod translator, not one for Perl code, your criteria may vary.

  • FILEHANDLE

  • $scalar

  • @array

  • function()

  • manpage(3r)

  • somebody@someplace.com

  • http://foo.com/

Perl also comes with several standard modules for parsing and converting pod, including Pod::Checker (and the associated podchecker utility) for checking the syntax of pod documents, Pod::Find for finding pod documents in directory trees, and Pod::Parser for creating your own pod utilities.

Note that pod translators should only look at paragraphs beginning with a pod directive (this makes parsing easier), whereas the compiler actually knows to look for pod escapes even in the middle of a paragraph. This means that the following secret stuff will be ignored by both the compiler and the translators.

$a=3;
=secret stuff
warn "Neither POD nor CODE!?"
=cut back
print "got $a\n";
You probably shouldn't rely upon the warn being podded out forever. Not all pod translators are well-behaved in this regard, and the compiler may someday become pickier.

Previous | Home | Next
26.1. Pod in a Nutshell | Book Index | 26.3. Writing Your Own Pod Tools
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


26.3. Writing Your Own Pod Tools

Pod was designed first and foremost to be easy to write. As an added benefit, pod's simplicity also lends itself to writing simple tools for processing pod. If you're looking for pod directives, just set your input record separator to paragraph mode (perhaps with the -00 switch), and only pay attention to paragraphs that look poddish.

For example, here's a simple olpod program to produce a pod outline:

#!/usr/bin/perl -l00n
# olpod - outline pod
next unless /^=head/;
s/^=head(\d)\s+/ ' ' x ($1 * 4 - 4)/e;
print $_, "\n";

If you run that on the current chapter of this book, you'll get something like this:

Plain Old Documentation
    Pod in a Nutshell
        Verbatim Paragraphs
        Pod Directives
        Pod Sequences
    Pod Translators and Modules
    Writing Your Own Pod Tools
    Pod Pitfalls
    Documenting Your Perl Programs

That pod outliner didn't really pay attention to whether it was in a valid pod block or not. Since pod and nonpod can intermingle in the same file, running general-purpose tools to search or analyze the whole file doesn't always make sense. But that's no problem, given how easy it is to write tools for pod. Here's a tool that is aware of the difference between pod and nonpod, and produces only the pod:

#!/usr/bin/perl -00
# catpod - cat out just the pods
while (<>) {
    if (! $inpod) { $inpod = /^=/;            }
    if ($inpod)   { $inpod = !/^=cut/; print; }
} continue {
    if (eof)      {  close ARGV; $inpod = ''; }
}

You could use that program on another Perl program or module, then pipe the output along to another tool. For example, if you have the wc(1) program[2] to count lines, words, and characters, you could feed it catpod output to consider only pod in its counting:

[2]And if you don't, get the Perl Power Tools version from the CPAN scripts directory.

% catpod MyModule.pm | wc

There are plenty of places where pod allows you to write primitive tools trivially using plain, straightforward Perl. Now that you have catpod to use as a component, here's another tool to show just the indented code:

#!/usr/bin/perl -n00
# podlit - print the indented literal blocks from pod input
print if /^\s/;

What would you do with that? Well, you might want to do perl -wc checks on the code in the document, for one thing. Or maybe you want a flavor of grep(1)[3] that only looks at the code examples:

[3]And if you don't have grep, see previous footnote.

% catpod MyModule.pm | podlit | grep funcname

This tool-and-filter philosophy of interchangeable (and separately testable) parts is a sublimely simple and powerful approach to designing reusable software components. It's a form of laziness to just put together a minimal solution that gets the job done today--for certain kinds of jobs, at least.

For other tasks, though, this can even be counterproductive. Sometimes it's more work to write a tool from scratch, sometimes less. For those we showed you earlier, Perl's native text-processing prowess makes it expedient to use brute force. But not everything works that way. As you play with pod, you might notice that although its directives are simple to parse, its sequences can get a little dicey. Although some, um, subcorrect translators don't accommodate this, sequences can nest within other sequences and can have variable-length delimiters.

Instead of coding up all that parsing code on your own, laziness looks for another solution. The standard Pod::Parser module fits that bill. It's especially useful for complicated tasks, like those that require real parsing of the internal bits of the paragraphs, conversion into alternative output formats, and so on. It's easier to use the module for complicated cases, because the amount of code you end up writing is smaller. It's also better because the tricky parsing is already worked out for you. It's really the same principle as using catpod in a pipeline.

The Pod::Parser module takes an interesting approach to its job. It's an object-oriented module of a different flavor than most you've seen in this book. Its primary goal isn't so much to provide objects for direct manipulation as it is to provide a base class upon which other classes can be built.

You create your own class and inherit from Pod::Parser. Then you declare subroutines to serve as callback methods for your parent class's parser to invoke. It's a very different way of programming than the procedural programs given earlier. In a sense, it's more of a declarative programming style, because to get the job done, you simply register functions and let other entities invoke them for you. The program's tiresome logic is handled elsewhere. You just give some plug-and-play pieces.

Here's a rewrite of the original catpod program given earlier, but this time it uses the Pod::Parser module to create our own subclass:

#!/usr/bin/perl
# catpod2, class and program

package catpod_parser;
use Pod::Parser;
@ISA = qw(Pod::Parser);
sub command {
    my ($parser, $command, $paragraph, $line_num) = @_;
    my $out_fh = $parser->output_handle();
    $paragraph .= "\n" unless substr($paragraph, -1) eq "\n";
    $paragraph .= "\n" unless substr($paragraph, -2) eq "\n\n";
    print $out_fh "=$command $paragraph";
}

sub verbatim {
    my ($parser, $paragraph, $line_num) = @_;
    my $out_fh = $parser->output_handle();
    print $out_fh $paragraph;
}

sub textblock {
    my ($parser, $paragraph, $line_num) = @_;
    my $out_fh = $parser->output_handle();
    print $out_fh $paragraph;
}
sub interior_sequence {
    my ($parser, $seq_command, $seq_argument) = @_;
    return "$seq_command<$seq_argument>";
}

if (!caller) {
    package main;
    my $parser = catpod_parser::->new();
    unshift @ARGV, '-' unless @ARGV;
    for (@ARGV) { $parser->parse_from_file($_); }
}
1;
__END__

=head1 NAME
docs describing the new catpod program here
As you see, it's a good bit longer and more complicated. It's also more extensible because all you have to do is plug in your own methods when you want your subclass to act differently than its base class.

The last bit at the end there, where it says !caller, checks whether the file is being used as a module or as a program. If it's being used as a program, then there is no caller. So it fires up its own parser (using the new method it inherited) and runs that parser on the command-line arguments. If no filenames were supplied, it assumes standard input, just as the previous version did.

Following the module code is an __END__ marker, a blank line without whitespace on it, and then the program/module's own pod documentation. This is an example of one file that's a program and a module and its own documentation. It's probably several other things as well.

Previous | Home | Next
26.2. Pod Translators and Modules | Book Index | 26.4. Pod Pitfalls
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


26.4. Pod Pitfalls

Pod is fairly straightforward, but it's still possible to flub a few things:

  • It's really easy to leave out the trailing angle bracket.

  • It's really easy to leave out the trailing =back directive.

  • It's easy to accidentally put a blank line into the middle of a long =for comment directive. Consider using =begin/=end instead.

  • If you mistype one of the tags on a =begin/=end pair, it'll eat the rest of your file (podwise). Consider using =for instead.

  • Pod translators require paragraphs to be separated by completely empty lines; that is, by two or more consecutive newline (\n) characters. If you have a line with spaces or tabs on it, it will not be treated as a blank line. This can cause two or more paragraphs to be treated as one.

  • The meaning of a "link" is not defined by pod, and it's up to each translator to decide what to do with it. (If you're starting to get the idea that most decisions have been deferred to the translators, not pod, you're right.) Translators will often add wording around a L<> link, so that "L<foo(1)>" becomes "the foo(1) manpage", for example. So you shouldn't write things like "the L<foo> manpage" if you want the translated document to read sensibly: that would end up saying "the the foo(1) manpage manpage".

    If you need total control of the text used for a link, use the form L<show this text|foo> instead.

The standard podchecker program checks pod syntax for errors and warnings. For example, it checks for unknown pod sequences and for seemingly blank lines containing whitespace. It is still advisable to pass your document through two or more different pod translators and proofread the results. Some of the problems you find may be idiosyncrasies of the particular translators, which you may or may not wish to work around.

And, as always, Everything is Subject To Change at the Whim of the Random Hacker.

Previous | Home | Next
26.3. Writing Your Own Pod Tools | Book Index | 26.5. Documenting Your Perl Programs
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


26.5. Documenting Your Perl Programs

We hope you document your code, whether or not you're a Random Hacker. If you do, you may wish to include the following sections in your pod:

=head1 NAME

The name of your program or module.

=head1 SYNOPSIS

A one-line description of what your program or module does (purportedly).

=head1 DESCRIPTION

The bulk of your documentation. (Bulk is good in this context.)

=head1 AUTHOR

Who you are. (Or an alias, if you are ashamed of your program.)

=head1 BUGS

What you did wrong (and why it wasn't really your fault).

=head1 SEE ALSO

Where people can find related information (so they can work around your bugs).

=head1 COPYRIGHT

The copyright statement. If you wish to assert an explicit copyright, you should say something like:

Copyright 2013, Randy Waterhouse.  All Rights Reserved.
Many modules also add:
This program is free software.  You may copy or
redistribute it under the same terms as Perl itself.

One caveat: if you're going to put your pod at the end of the file, and you're using an __END__ or __DATA__ token, make sure to put an empty line before the first pod directive:

__END__

=head1 NAME

Modern - I am the very model of a modern major module
Without the empty line before the =head1, the pod translators will ignore the start of your (extensive, accurate, cultured) documentation.

Previous | Home | Next
26.4. Pod Pitfalls | Book Index | 27. Perl Culture
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 27. Perl Culture

Contents:

History Made Practical
Perl Poetry

This book is a part of Perl culture, so we can't hope to put everything we know about Perl culture in here. We can only whet your appetite with a little history, and a little art--some would say "very little art". For a much larger dose of Perl culture, see www.perl.org and www.perl.com. (Larry keeps copies of all his (official) ravings at www.wall.org/~larry.) Or just get acquainted with some other Perl programmers. We can't tell you what sort of people they'll be--about the only personality trait Perl programmers have in common is that they're all pathologically helpful.

27.1. History Made Practical

In order to understand why Perl is defined the way it is (or isn't), one must first understand why Perl even exists. So, let's drag out the old dusty history book....

Way back in 1986, Larry was a systems programmer on a project developing multi-level-secure wide-area networks. He was in charge of an installation consisting of three VAXen and three Suns on the West Coast, connected over an encrypted, 1200-baud serial line to a similar configuration on the East Coast. Since Larry's primary job was support (he wasn't a programmer on the project, just the system guru), he was able to exploit his three virtues (laziness, impatience, and hubris) to develop and enhance all sorts of useful tools--such as rn, patch, and warp.[1]

[1] It was at about this time that Larry latched onto the phrase "feeping creaturism" in a desperate attempt to justify on the basis of biological necessity his overwhelming urge to add "just one more feature". After all, if Life Is Simply Too Complicated, why not programs too? Especially programs like rn that really ought to be treated as advanced Artificial Intelligence projects so that they can read your news for you. Of course, some people say that the patch program is already too smart.

One day, after Larry had just finished ripping rn to shreds, leaving it in pieces on the floor of his directory, the great Manager came to him and said, "Larry, we need a configuration management and control system for all six VAXen and all six Suns. We need it in a month. Go to it!"

So, Larry, never being one to shirk work, asked himself what was the best way to have a bicoastal CM system, without writing it from scratch, that would allow viewing of problem reports on both coasts, with approvals and control. The answer came to him in one word: B-news.[2]

[2]That is, the second implementation of Usenet transport software.

Larry went off and installed news on these machines and added two control commands: an "append" command to append to an existing article, and a "synchronize" command to keep the article numbers the same on both coasts. CM would be done using RCS (Revision Control System), and approvals and submissions would be done using news and rn. Fine so far.

Then the great Manager asked him to produce reports. News was maintained in separate files on a master machine, with lots of cross-references between files. Larry's first thought was "Let's use awk." Unfortunately, the awk of that day couldn't handle opening and closing of multiple files based on information in the files. Larry didn't want to have to code a special-purpose tool. As a result, a new language was born.

This new tool wasn't originally called Perl. Larry bandied about a number of names with his officemates and cohorts (Dan Faigin, who wrote this history, and Mark Biggar, his brother-in-law, who also helped greatly with the initial design). Larry actually considered and rejected every three- or four-letter word in the dictionary. One of the earliest names was "Gloria", after his sweetheart (and wife). He soon decided that this would cause too much domestic confusion.

The name then became "Pearl", which mutated into our present-day "Perl", partly because Larry saw a reference to another language called PEARL, but mostly because he's too lazy to type five letters all the time. And, of course, so that Perl could be used as a four-letter word. (You'll note, however, the vestiges of the former spelling in the acronym's gloss: "Practical Extraction And Report Language".)

This early Perl lacked many of the features of today's Perl. Pattern matching and filehandles were there, scalars were there, and formats were there, but there were very few functions, no associative arrays, and only a crippled implementation of regular expressions, borrowed from rn. The manpage was only 15 pages long. But Perl was faster than sed and awk and began to be used on other applications on the project.

But Larry was needed elsewhere. Another great Manager came over one day and said, "Larry, support R&D." And Larry said, okay. He took Perl with him and discovered that it was turning into a good tool for system administration. He borrowed Henry Spencer's beautiful regular expression package and butchered it into something Henry would prefer not to think about during dinner. Then Larry added most of the goodies he wanted, and a few goodies other people wanted. He released it on the network.[3] The rest, as they say, is history.[4]

[3] More astonishingly, he kept on releasing it as he went to work at Jet Propulsion Lab, then at NetLabs and Seagate. Nowadays, other people do most of the real work, and Larry pretends to work for O'Reilly & Associates (a small company that publishes pamphlets about computers and stuff).

[4] And this, so to speak, is a footnote to history. When Perl was started, rn had just been ripped to pieces in anticipation of a major rewrite. Since he started work on Perl, Larry hasn't touched rn. It is still in pieces. Occasionally, Larry threatens to rewrite rn in Perl, but never seriously.

Which goes something like this: Perl 1.0 was released on December 18, 1987; some people still take Perl's Birthday seriously. Perl 2.0 follows in June 1988, and Randal Schwartz creates the legendary "Just Another Perl Hacker" signature. In 1989, Tom Christiansen presents the first public Perl tutorial at the Baltimore Usenix. With Perl 3.0 in October 1989, the language is released and distributed for the first time under the terms of the GNU Public License.

In March of 1990, Larry writes the first Perl Poem (see the following section). Then he and Randal write the first edition of this book, The Pink Camel; it is published in early 1991. Perl 4.0 is released simultaneously; it includes an Artistic License as well as the GPL.

The unveiling of the much anticipated Perl 5 occurs in October 1994. A complete rewrite of Perl, it includes objects and modules. The advent of Perl 5 even merits coverage by The Economist. In 1995, CPAN is officially introduced to the Perl community. Jon Orwant begins publishing The Perl Journal in 1996. After a long gestation, the second edition of this book, The Blue Camel, appears that fall. The first O'Reilly Perl Conference (TPC) is held in San Jose, California, in the summer of 1997. Notable events are now occurring almost daily, so for the rest of history, check out the Perl Timeline on CPAST, the Comprehensive Perl Arcana Society Tapestry (history.perl.org).

Previous | Home | Next
26.5. Documenting Your Perl Programs | Book Index | 27.2. Perl Poetry
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


27.2. Perl Poetry

The forgery in the attendant sidebar appeared on Usenet on April Fool's Day, 1990. It is presented here without comment, merely to show how disgusting the metaphors of a typical programming language really are. So much for anything resembling literary value. Larry is particularly relieved that "Black Perl", originally written for Perl 3, no longer parses under Perl 5.

Larry's, er, corpus has fortunately been overshadowed by that of the reigning Perl Poet, Sharon Hopkins. She has written quite a few Perl poems, as well as a paper on Perl poetry that she presented at the Usenix Winter 1992 Technical Conference, entitled "Camels and Needles: Computer Poetry Meets the Perl Programming Language". (The paper is available as misc/poetry.ps on CPAN.) Besides being the most prolific Perl poet, Sharon is also the most widely published, having had the following poem published in both the Economist and the Guardian:

#!/usr/bin/perl

APPEAL:

listen (please, please);

open yourself, wide;
    join (you, me),
connect (us,together),

tell me.

do something if distressed;

    @dawn, dance;
    @evening, sing;
    read (books,$poems,stories) until peaceful;
    study if able;

    write me if-you-please;

sort your feelings, reset goals, seek (friends, family, anyone);

        do*not*die (like this)
        if sin abounds;

keys (hidden), open (locks, doors), tell secrets;
do not, I-beg-you, close them, yet.

                            accept (yourself, changes),
                            bind (grief, despair);

require truth, goodness if-you-will, each moment;

select (always), length(of-days)

# listen (a perl poem)
# Sharon Hopkins
# rev. June 19, 1995

Perl Poetry

Article 970 of comp.lang.perl:
Path: jpl-devvax!pl-dexxav!lwall
From: lwall@jpl-dexxav.JPL.NASA.GOV (Larry Wall)
Newsgroups: news.groups,rec.arts.poems,comp.lang.perl
Subject: CALL FOR DISCUSSION: comp.lang.perl.poems
Message-ID: <0401@jpl-devvax.JPL.NASA.GOV>
Date: 1 Apr 90 00:00:00 GMT
Reply-To: lwall@jpl-devvax.JPL.NSAS.GOV (Larry Wall)
Organization: Jet Prepulsion Laboratory, Pasadena, CA
Lines: 61

It has come to my attention that there is a crying need for a place for people to express both their emotional
and technical natures simultaneously. Several people have sent me some items which don't fit into any
newsgroup. Perhaps it's because I recently posted to both comp.lang.perl and to rec.arts.poems, but people
seem to be writing poems in Perl, and they're asking me where they should post them. Here is a sampling:

From a graduate student (in finals week), the following haiku:
study, write, study,
do review (each word) if time.
close book. sleep? what's that?
And someone writing from Fort Lauderdale writes:
sleep, close together,
sort of sin each spring & wait;
50% die
A person who wishes to remain anonymous wrote the following example of "Black Perl".  (The Pearl poet
would have been shocked, no doubt.)
BEFOREHAND: close door, each window & exit;  wait until time.
    open spellbook, study, read (scan, select, tell us);
write it, print the hex while each watches,
    reverse its length, write again;
    kill spiders, pop them, chop, split, kill them.
       unlink arms, shift, wait & listen (listening, wait),
sort the flock (then, warn the "goats" & kill the "sheep");
    kill them, dump qualms, shift moralities,
    values aside, each one;
        die sheep! die to reverse the system
        you accept (reject, respect);
next step,
    kill the next sacrifice, each sacrifice,
    wait, redo ritual until "all the spirits are pleased";
    do it ("as they say").
do it(*everyone***must***participate***in***forbidden**s*e*x*).
return last victim; package body;
    exit crypt (time, times & "half a time") & close it,
    select (quickly) & warn your next victim;
AFTERWORDS: tell nobody.
    wait, wait until time;
    wait until next year, next decade;
        sleep, sleep, die yourself,
        die at last
I tried that, and it actually parses in Perl.  It doesn't appear to do anything useful, however.  I think I'm glad,
actually... I hereby propose the creation of comp.lang.perl.poems as a place for such items, so we don't clutter
the perl or poems newsgroups with things that may be of interest to neither.  Or, alternately, we should
create rec.arts.poems.perl for items such as those above which merely parse, and don't do anything useful.
(There is precedent in rec.arts.poems, after all.)  Then also create comp.lang.perl.poems for poems that
actually do something, such as this haiku of my own:
print STDOUT q
Just another Perl hacker,
unless $spring
Larry Wall            lwall@jpl-devvax.jpl.nasa.gov
Previous | Home | Next
27.1. History Made Practical | Book Index | Part 5. Reference Material
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Part V. Reference Material

Chapter 28: Special Names
Chapter 29: Functions
Chapter 30: The Standard Perl Library
Chapter 31: Pragmatic Modules
Chapter 32: Standard Modules
Chapter 33: Diagnostic Messages

Previous | Home | Next
27.2. Perl Poetry | Book Index | 28. Special Names
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 28. Special Names

Contents:

Special Names Grouped by Type
Special Variables in Alphabetical Order

This chapter is about variables that have special meanings to Perl. Most of the punctuational names have reasonable mnemonics, or analogs in one of the shells (or both). But if you want to use long variable names as synonyms, just say:

use English;
at the top of your program. This aliases all the short names to long names in the current package. Some of these variables even have medium names, generally borrowed from awk. Most people eventually settle on using the short names, at least for the more commonly used variables. Throughout this book, we consistently refer to the short names, but also often mention the long names (in parentheses) so that you can look them up easily in this chapter.

The semantics of these variables can be quite magical. (To create your own magic, see Chapter 14, "Tied Variables".) A few of these variables are read-only. If you try to assign values to them, an exception will be raised.

In what follows, we'll first provide a concise listing of the variables and functions for which Perl assigns a special meaning, grouped by type, so you can look up variables that you're not sure of the proper name. Then we'll explain all of the variables alphabetically under their proper name (or their least improper name).

28.1. Special Names Grouped by Type

We used the word "type" loosely--the sections here actually group variables more by their scope, that is, where they're visible from.

28.1.1. Regular Expression Special Variables

The following special variables related to pattern matching are visible throughout the dynamic scope in which the pattern match occurred (except for $*, which is deprecated). In other words, they behave as though they were declared with local, so you needn't declare them that way yourself. See Chapter 5, "Pattern Matching".

$*
$digits
@+ (@LAST_MATCH_END)
@- (@LAST_MATCH_START)
$+ ($LAST_PAREN_MATCH)
$^R ($LAST_REGEXP_CODE_RESULT)
$& ($MATCH)
$' ($POSTMATCH)
$` ($PREMATCH)

28.1.2. Per-Filehandle Variables

These special variables never need to be mentioned in a local because they always refer to some value pertaining to the currently selected output filehandle--each filehandle keeps its own set of values. When you select another filehandle, the old filehandle remembers the values it had for these variables, and the variables now reflect the values of the new filehandle. See also the FileHandle module in Chapter 32, "Standard Modules".

$| ($AUTOFLUSH, $OUTPUT_AUTOFLUSH)
$- ($FORMAT_LINES_LEFT)
$= ($FORMAT_LINES_PER_PAGE)
$~ ($FORMAT_NAME)
$% ($FORMAT_PAGE_NUMBER)
$^ ($FORMAT_TOP_NAME)

28.1.3. Per-Package Special Variables

These special variables exist separately in each package. There should be no need to localize them, since sort automatically does so on $a and $b, and the rest are probably best left alone (though you will need to declare them with our if you use strict).

$a
$b
@EXPORT
@EXPORT_OK
%EXPORT_TAGS
%FIELDS
@ISA

%OVERLOAD
$VERSION

28.1.4. Program-wide Special Variables

These variables are truly global in the fullest sense--they mean the same thing in every package, because they're all forced into package main when unqualified (except for @F, which is special in main, but not forced). If you want a temporary copy of one of these, you must localize it in the current dynamic scope.

%ENV
%INC
%SIG
%!
%^H

@_
@ARGV
@F
@INC

$_ ($ARG)
$0 ($PROGRAM_NAME)
$ARGV

$! ($ERRNO, $OS_ERROR)
$" ($LIST_SEPARATOR)
$#
$$ ($PID, $PROCESS_ID)
$( ($GID, $REAL_GROUP_ID)
$) ($EGID, $EFFECTIVE_GROUP_ID)
$, ($OFS, $OUTPUT_FIELD_SEPARATOR)
$. ($NR, $INPUT_LINE_NUMBER)
$/ ($RS, $INPUT_RECORD_SEPARATOR)
$: ($FORMAT_LINE_BREAK_CHARACTERS)
$; ($SUBSEP, $SUBSCRIPT_SEPARATOR)

$< ($UID, $REAL_USER_ID)
$> ($EUID, $EFFECTIVE_USER_ID)
$? ($CHILD_ERROR)
$@ ($EVAL_ERROR)
$[
$\ ($ORS, $OUTPUT_RECORD_SEPARATOR)
$]  ($OLD_PERL_VERSION)
$^A ($ACCUMULATOR)
$^C ($COMPILING)
$^D ($DEBUGGING)
$^E ($EXTENDED_OS_ERROR)
$^F ($SYSTEM_FD_MAX)
$^H
$^I ($INPLACE_EDIT)
$^L ($FORMAT_FORMFEED)
$^M
$^O ($OSNAME)
$^P ($PERLDB)
$^R ($LAST_REGEXP_CODE_RESULT)
$^S (EXCEPTIONS_BEING_CAUGHT)
$^T ($BASETIME)
$^V ($PERL_VERSION)
$^W ($WARNING)
${^WARNING_BITS}
${^WIDE_SYSTEM_CALLS}
$^X ($EXECUTABLE_NAME)

28.1.5. Per-Package Special Filehandles

Except for DATA, which is always per-package, the following filehandles are always assumed to be in main when not fully qualified with another package name:

_ (underline)
ARGV
ARGVOUT
DATA
STDIN
STDOUT
STDERR

28.1.6. Per-Package Special Functions

The following subroutine names have a special meaning to Perl. They're always called implicitly because of some event, such as accessing a tied variable or trying to call an undefined function. We don't describe them in this chapter since they all receive heavy-duty coverage elsewhere in the book.

Undefined function call interceptor (see Chapter 10, "Packages"):

AUTOLOAD

Moribund objects' finalization (see Chapter 12, "Objects"):

DESTROY

Exception objects (see die in the next chapter):

PROPAGATE

Auto-init and auto-cleanup functions (see Chapter 18, "Compiling"):

BEGIN, CHECK, INIT, END

Tie methods (see Chapter 14, "Tied Variables"):

BINMODE, CLEAR, CLOSE, DELETE, EOF, EXISTS, EXTEND, FETCH, FETCHSIZE,
FILENO, FIRSTKEY, GETC, NEXTKEY, OPEN, POP, PRINT, PRINTF, PUSH, READ,
READLINE, SEEK, SHIFT, SPLICE, STORE, STORESIZE, TELL, TIEARRAY,
TIEHANDLE, TIEHASH, TIESCALAR, UNSHIFT, WRITE
Previous | Home | Next
 | 28.2. Special Variables in Alphabetical Order
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


28.2. Special Variables in Alphabetical Order

We've alphabetized these entries according to the long variable name. If you don't know the long name of a variable, you can find it in the previous section. (Variables without alphabetical names are sorted to the front.)

So that we don't have to keep repeating ourselves, each variable description starts with one or more of these annotations:

Annotation | Meaning
XXX | Deprecated, do not use in anything new.
NOT | Not Officially There (internal use only).
ALL | Truly global, shared by all packages.
PKG | Package global; each package can have its own.
FHA | Filehandle attribute; one per I/O object.
DYN | Dynamically scoped automatically (implies ALL).
LEX | Lexically scoped at compile time.
RO | Read only; raises an exception if you modify.

When more than one variable name or symbol is listed, only the short one is available by default. Using the English module makes the longer synonyms available to the current package, and only to the current package, even if the variable is marked [ALL].

Entries of the form method HANDLE EXPR show object-oriented interfaces to the per-filehandle variables provided by the FileHandle and various IO:: modules. (You may also use the HANDLE->method(EXPR) notation if you prefer.) These let you avoid having to call select to change the default output handle before examining or changing that variable. Each such method returns the old value of the FileHandle attribute; a new value is set if the EXPR argument is supplied. If not supplied, most of the methods do nothing to the current value, except for autoflush, which assumes an argument of 1, just to be different.

_ (underline)

[ALL] This is the special filehandle used to cache the information from the last successful stat, lstat, or file test operator (like -w $file or -d $file).

$digits

[DYN,RO] The numbered variables $1, $2, and so on (up just as high as you want)[1] contain the text that is matched by the corresponding set of parentheses in the last matched pattern within the currently active dynamic scope. (Mnemonic: like \digits.)

[1] Although many regular expression engines only support up to nine backreferences, Perl has no such limit, so if you go around writing $768, Perl won't mind, although maintainers of your code might if you actually use that many parentheses in your regular expressions.

$[

[XXX,LEX] The index of the first element in an array and of the first character in a substring. Default is 0, but we used to set it to 1 to make Perl behave more like awk (or FORTRAN) when subscripting and when evaluating the index and substr functions. Because it was found to be so dangerous, assignment to $[ is now treated as a lexically scoped compiler directive and cannot influence the behavior of any other file. (Mnemonic: [ begins subscripts.)

$#

[XXX,ALL] Don't use this; use printf instead. $# contains the output format for printed numbers, in a half-hearted attempt to emulate awk's OFMT variable. (Mnemonic: # is the number sign, but if you're sharp, you'll just forget it so you don't make a hash of your program and get pounded for it.)

$*

[XXX,ALL] Wow, three deprecated variables in a row! This one can (but shouldn't) be set to true to get Perl to assume /m on every pattern match that doesn't have an explicit /s. (Mnemonic: * matches multiple things.)

$a

[PKG] This variable is used by the sort function to hold the first of each pair of values to be compared ($b is the second of each pair). The package for $a is the same one that the sort operator was compiled in, which is not necessarily the same as the one its comparison function was compiled into. This variable is implicitly localized within the sort comparison block. Because it is a global, it is exempt from use strict complaints. Because it is an alias for the actual array value, you might think you can modify it, but you shouldn't. See the sort function.

$ACCUMULATOR
$^A

[ALL] The current value of the write accumulator for format lines. A format contains formline commands that put their result into $^A. After calling its format, write prints out the contents of $^A and empties it. So you never actually see the contents of $^A unless you call formline yourself and then look at it. See the formline function.

$ARG
$_

[ALL] The default input and pattern-search space. These pairs are equivalent:

while (<>) {...}    # equivalent only in unadorned while test
while (defined($_ = <>)) {...}

chomp
chomp($_)

/^Subject:/
$_ =~ /^Subject:/

tr/a-z/A-Z/
$_ =~ tr/a-z/A-Z/
Here are the places where Perl will assume $_ if you don't specify something to operate on:

@ARG
@_

[ALL] Within a subroutine, this array holds the argument list passed to that subroutine. See Chapter 6, "Subroutines". A split in scalar context splits to this array, but this usage is deprecated.

ARGV

[ALL] The special filehandle that iterates over command-line filenames in @ARGV. Usually written as the null filehandle in the angle operator: <>.

$ARGV

[ALL] Contains the name of the current file when reading from the ARGV handle using the <> or readline operators.

@ARGV

[ALL] The array containing the command-line arguments intended for the script. Note that $#ARGV is generally the number of arguments minus one, since $ARGV[0] is the first argument, not the command name; use scalar @ARGV for the number of program arguments. See $0 for the program name.

ARGVOUT

[ALL] The special filehandle is used while processing the ARGV handle under the -i switch or the $^I variable. See the -i switch in Chapter 19, "The Command-Line Interface".

$b

[PKG] The variable, companion to $a, used in sort comparisons. See $a and the sort function for details.

$BASETIME
$^T

[ALL] The time at which the script began running, in seconds since the epoch (the beginning of 1970, for Unix systems). The values returned by the -M, -A, and -C file tests are relative to this moment.

$CHILD_ERROR
$?

[ALL] The status returned by the last pipe close, backtick (``) command, or wait, waitpid, or system functions. Note that this is not just the simple exit code, but the entire 16-bit status word returned by the underlying wait(2) or waitpid(2) syscall (or equivalent). Thus, the exit value of the subprocess is in the high byte, that is, $? >> 8; in the low byte, $? & 127 says which signal (if any) the process died from, while $? & 128 reports whether its demise produced a core dump. (Mnemonic: similar to $? in the sh and its offspring.)

Inside an END block, $? contains the value that is going to be given to exit. You can modify $? in an END to change the exit status of the script.

Under VMS, the pragma use vmsish 'status' makes $? reflect the true VMS exit status, instead of the default emulation of POSIX status.

If the h_errno variable is supported in C, its numeric value is returned via $? if any of the gethost*() functions fail.

$COMPILING
$^C

[ALL] The current value of the internal flag associated with the -c switch, mainly of use with -MO and the perlcc(1) tool to let code alter its behavior when being compiled for code generation. For example, you might want to AUTOLOAD at compile time instead of using the normal, deferred loading so that code can be generated right away. See Chapter 18, "Compiling".

DATA

[PKG] This special filehandle refers to anything following either the __END__ token or the __DATA__ token in the current file. The __END__ token always opens the main::DATA filehandle, and so is used in the main program. The __DATA__ token opens the DATA handle in whichever package is in effect at the time, so different modules can each have their own DATA filehandle, since they (presumably) have different package names.

$DEBUGGING
$^D

[ALL] The current value of the internal debugging flags, set from the -D switch on the command line; see Chapter 19, "The Command-Line Interface" for the bit values. (Mnemonic: value of the -D switch.)

$EFFECTIVE_GROUP_ID
$EGID
$)

[ALL] The effective GID (group ID) of this process. If you are on a machine that supports membership in multiple groups simultaneously, $) gives a space-separated list of groups you are in. The first number is the one returned by getegid(2), and the subsequent ones by getgroups(2), one of which may be the same as the first number.

Similarly, a value assigned to $) must also be a space-separated list of numbers. The first number is used to set the effective GID, and the rest (if any) are passed to the setgroups(2) syscall. To get the effect of an empty list for setgroups, just repeat the new effective GID; for example, to force an effective GID of 5 and an effectively empty setgroups list, say:

$) = "5 5";

(Mnemonic: parentheses are used to group things. The effective GID is the group that's right for you, if you're running setgid.) Note: $<, $>, $(, and $) can only be set on machines that support the corresponding system set-id routine. $( and $) can be swapped only on machines supporting setregid(2).

$EFFECTIVE_USER_ID
$EUID
$>

[ALL] The effective UID of this process as returned by the geteuid(2) syscall. Example:

$< = $>;            # set real to effective uid
($<,$>) = ($>,$<);  # swap real and effective uid
(Mnemonic: it's the UID you went to, if you're running setuid.) Note: $< and $> can only be swapped on machines supporting setreuid(2). And sometimes not even then.

%ENV

[ALL] The hash containing your current environment variables. Setting a value in %ENV changes the environment for both your process and child processes launched after the assignment. (It cannot change a parent process's environment on any system resembling Unix.)

$ENV{PATH}  = "/bin:/usr/bin";
$ENV{PAGER} = "less";
$ENV{LESS}  = "MQeicsnf";  # our favorite switches to less(1)
system "man perl";         # picks up new settings
To remove something from your environment, make sure to use the delete function instead of undef on the hash value.

Note that processes running as crontab(5) entries inherit a particularly impoverished set of environment variables. (If your program runs fine from the command line but not under cron, this is probably why.) Also note that you should set $ENV{PATH}, $ENV{SHELL}, $ENV{BASH_ENV}, and $ENV{IFS} if you are running as a setuid script. See Chapter 23, "Security".

$EVAL_ERROR
$@

[ALL] The currently raised exception or the Perl syntax error message from the last eval operation. (Mnemonic: where was the syntax error "at"?) Unlike $! ($OS_ERROR), which is set on failure but not cleared on success, $@ is guaranteed to be set (to a true value) if the last eval had a compilation error or run-time exception, and guaranteed to be cleared (to a false value) if no such problem occurred.

Warning messages are not collected in this variable. You can, however, set up a routine to process warnings by setting $SIG{__WARN__} as described later in this section.

Note that the value of $@ may be an exception object rather than a string. If so, you can still probably treat it as a string if the exception object has stringification overloading defined for its class. If you propagate an exception by saying:

die if $@;
then an exception object will call $@->PROPAGATE to see what to do. (A string exception merely adds a "propagated at" line to the string.)

$EXCEPTIONS_BEING_CAUGHT
$^S

[ALL] This variable reflects the current state of the interpreter, returning true if inside an eval, false otherwise. It's undefined if parsing of the current compilation unit hasn't finished yet, which may be the case in $SIG{__DIE__} and $SIG{__WARN__} handlers. (Mnemonic: state of eval.)

$EXECUTABLE_NAME
$^X

[ALL] The name that the perl binary itself was executed as, from C's argv[0].

@EXPORT

[PKG] This array variable is consulted by the Exporter module's import method to find the list of other package variables and subroutines to be exported by default when the module is used, or when the :DEFAULT import tag is used. It is not exempt from use strict complaints, so it must be declared with our or fully qualified by package name if you've enabled that pragma. However, all variables whose names begin with the string "EXPORT" are exempt from warnings about being used only once. See Chapter 11, "Modules".

@EXPORT_OK

[PKG] This array variable is consulted by the Exporter module's import method to determine whether a requested import is legal. It is not exempt from use strict. See Chapter 11, "Modules".

%EXPORT_TAGS

[PKG] This hash variable is consulted by the Exporter module's import method when an import symbol with a leading colon is requested, as in use POSIX ":sys_wait_h". The keys are the colon tags, but without the loading colon. The values should be references to arrays containing symbols to import when the colon tag is requested, all of which must also appear in either @EXPORT or @EXPORT_OK. It is not exempt from use strict. See Chapter 11, "Modules".

$EXTENDED_OS_ERROR
$^E

[ALL] Error information specific to the current operating system. Under Unix, $^E is identical to $! ($OS_ERROR), but it differs under OS/2, VMS, and Microsoft systems, and on MacPerl. See your port's information for specifics. Caveats mentioned in the description of $! generally apply to $^E as well. (Mnemonic: extra error explanation.)

@F

[PKG] The array into which the input line's fields are split when the -a command-line switch is given. If the -a option is not used, this array has no special meaning. (This array is actually only @main::F, and not in all packages at once.)

%FIELDS

[NOT,PKG] This hash is for internal use by the use fields pragma to determine the current legal fields in an object hash. See use fields, use base, and "Field Declarations with use fields" in Chapter 12, "Objects".

format_formfeed HANDLE EXPR
$FORMAT_FORMFEED
$^L

[ALL] What a write function implicitly outputs to perform a form feed before it emits a top of form header. Default is "\f".

format_lines_left HANDLE EXPR
$FORMAT_LINES_LEFT
$-

[FHA] The number of lines left on the page of the currently selected output handle, for use with the format declaration and the write function. (Mnemonic: lines_on_page - lines_printed.)

format_lines_per_page HANDLE EXPR
$FORMAT_LINES_PER_PAGE
$=

[FHA] The current page length (printable lines) of the currently selected output handle, for use with format and write. Default is 60. (Mnemonic: = has horizontal lines.)

format_line_break_characters HANDLE EXPR
$FORMAT_LINE_BREAK_CHARACTERS
$:

[ALL] The current set of characters after which a string may be broken to fill continuation fields (starting with ^) in a format. Default is " \n-", to break on whitespace or hyphens. (Mnemonic: a colon is a technical word meaning part of a line in poetry. Now you just have to remember the mnemonic...)

format_name HANDLE EXPR
$FORMAT_NAME
$~

[FHA] The name of the current report format for the currently selected output handle. Default is the filehandle's name. (Mnemonic: takes a turn after $^.)

format_page_number HANDLE EXPR
$FORMAT_PAGE_NUMBER
$%

[FHA] The current page number of the currently selected output handle, for use with format and write. (Mnemonic: % is the page number register in troff(1). What, you don't know what troff is?)

format_top_name HANDLE EXPR
$FORMAT_TOP_NAME
$^

[FHA] The name of the current top-of-page format for the currently selected output handle. Default is name of the filehandle with _TOP appended. (Mnemonic: points to top of page.)

$^H

[NOT,LEX] This variable contains lexically scoped status bits (a.k.a. hints) for the Perl parser. This variable is strictly for internal use only. Its availability, behavior, and contents are subject to change without notice. If you touch it, you will undoubtedly die a horrible death of some loathsome tropical disease unknown to science. (Mnemonic: we won't give you a hint.)

%^H

[NOT,LEX] The %^H hash provides the same lexical scoping semantics as $^H, making it useful for implementation of lexically scoped pragmas. Read the dire warnings listed under $^H, and then add to them the fact that this variable is still experimental.

%INC

[ALL] The hash containing entries for the filename of each Perl file loaded via do FILE, require, or use. The key is the filename you specified, and the value is the location of the file actually found. The require operator uses this array to determine whether a given file has already been loaded. For example:

% perl -MLWP::Simple -le 'print $INC{"LWP/Simple.pm"}'
/opt/perl/5.6.0/lib/site_perl/LWP/Simple.pm

@INC

[ALL] The array containing the list of directories where Perl modules may be found by do FILE, require, or use. It initially consists of the arguments to any -I command-line switches and directories in the PERL5LIB environment variable, followed by the default Perl libraries, such as:

/usr/local/lib/perl5/5.6.0/sun4-solaris
/usr/local/lib/perl5/5.6.0
/usr/local/lib/perl5/site_perl/5.6.0/sun4-solaris
/usr/local/lib/perl5/site_perl/5.6.0
/usr/local/lib/perl5/site_perl/5.00552/sun4-solaris
/usr/local/lib/perl5/site_perl/5.00552
/usr/local/lib/perl5/site_perl/5.005/sun4-solaris
/usr/local/lib/perl5/site_perl/5.005
/usr/local/lib/perl5/site_perl
followed by ".", to represent the current directory. If you need to modify this list from within your program, try the use lib pragma, which not only modifies the variable at compile time, but also adds in any related architecture-dependent directories (such as those that contain the shared libraries used by XS modules):
use lib "/mypath/libdir/";
use SomeMod;

$INPLACE_EDIT
$^I

[ALL] The current value of the inplace-edit extension. Use undef to disable inplace editing. You can use this from within your program to get the same behavior as the -i switch provides. For example, to do the equivalent of this command:

% perl -i.orig -pe 's/foo/bar/g' *.c
you can use the following equivalent code in your program:
local $^I   = '.orig';
local @ARGV = glob("*.c");
while (<>) {
    s/foo/bar/g;
    print;
}
(Mnemonic: value of the -i switch.)

$INPUT_LINE_NUMBER
$NR
$.

[ALL] The current record number (usually line number) for the last filehandle you read from (or called seek or tell on). The value may be different from the actual physical line number in the file, depending on what notion of "line" is in effect--see $/ ($INPUT_RECORD_SEPARATOR) on how to affect that. An explicit close on a filehandle resets the line number. Because <> never does an explicit close, line numbers increase across ARGV files (but see examples under eof). Localizing $. also localizes Perl's notion of "the last read filehandle". (Mnemonic: many programs use "." to mean the current line number.)

$INPUT_RECORD_SEPARATOR
$RS
$/

[ALL] The input record separator, newline by default, which is consulted by the readline function, the <FH> operator, and the chomp function. It works like awk's RS variable, and, if set to the null string, treats one or more blank lines as a record terminator. (But a blank line must contain no hidden spaces or tabs.) You may set it to a multicharacter string to match a multicharacter terminator, but you may not set it to a pattern--awk has to be better at something.

Note that setting $/ to "\n\n" means something slightly different than setting it to "", if the file contains consecutive blank lines. Setting it to "" will treat two or more consecutive blank lines as a single blank line. Setting it to "\n\n" means Perl will blindly assume that a third newline belongs to the next paragraph.

Entirely undefining $/ makes the next line input operation slurp in the remainder of the file as one scalar value:

undef $/;           # enable whole-file mode
$_ = <FH>;          # whole file now here
s/\n[ \t]+/ /g;     # fold indented lines
If you're using the while (<>) construct to access ARGV handle while $/ is undefined, each read gets the next file:
undef $/;
while (<>) {        # $_ has the whole next file in it
    ...
}

Although we used undef above, it's safer to undefine $/ using local:

{
    local $/;
    $_ = <FH>;
}

Setting $/ to a reference to either an integer, a scalar containing an integer, or a scalar that's convertible to an integer will make readline and <FH> operations read in fixed-length records (with the maximum record size being the referenced integer) instead of variable-length record terminated by a particular string. So this:

$/ = \32768; # or \"32768" or \$scalar_var_containing_32768
open(FILE, $myfile);
$record = <FILE>;
will read a record of no more than 32,768 bytes from the FILE handle. If you're not reading from a record-oriented file (or your operating system doesn't have record-oriented files), then you'll likely get a full chunk of data with every read. If a record is larger than the record size you've set, you'll get the record back in pieces. Record mode mixes well with line mode only on systems where standard I/O supplies a read(3) function; VMS is a notable exception.

Calling chomp when $/ is set to enable record mode--or when it is undefined--has no effect. See also the -0 (the digit) and the -l (the letter) command-line switches in Chapter 19, "The Command-Line Interface". (Mnemonic: / is used to separate lines when quoting poetry.)

@ISA

[PKG] This array contains names of other packages to look through when a method call cannot be found in the current package. That is, it contains the base classes of the package. The use base pragma sets this implicitly. It is not exempt from use strict. See Chapter 12, "Objects".

@LAST_MATCH_END
@+

This array holds the offsets of the ends of the last successful submatches in the currently active dynamic scope. $+[0] is the offset of the end of the entire match. This is the same value the pos function returns when called on the variable that was matched against. (When we say "offset of the end", we really mean the offset to the first character following the end of whatever matched, so that we can subtract beginning offsets from end offsets and arrive at the length.) The nth element of this array holds the offset of the nth submatch, so $+[1] is the offset where $1 ends, $+[2] the offset where $2 ends, and so on. You can use $#+ to determine how many subgroups were in the last successful match. See also @_ (@LAST_MATCH_START).

After a successful match against some variable $var:

  • $` is the same as substr($var, 0, $-[0])
  • $& is the same as substr($var, $-[0], $+[0] - $-[0])
  • $' is the same as substr($var, $+[0])
  • $1 is the same as substr($var, $-[1], $+[1] - $-[1])
  • $2 is the same as substr($var, $-[2], $+[2] - $-[2])
  • $3 is the same as substr($var, $-[3], $+[3] - $-[2]), and so on.
@LAST_MATCH_START
@-

[DYN,RO] This array holds the offsets of the beginnings of the last successful submatches in the currently active dynamic scope. $-[0] is the offset of the beginning of the entire match. The nth element of this array holds the offset of the nth submatch, so $-[1] is the offset where $1 begins, $-[2] the offset where $2 begins, and so on. You can use $#- to determine how many subgroups were in the last successful match. See also @+ (@LAST_MATCH_END).

$LAST_PAREN_MATCH
$+

[DYN,RO] This returns the last parenthesized submatch from the last successful pattern in the currently active dynamic scope. This is useful when you don't know (or care) which of a set of alternative patterns matched. (Mnemonic: be positive and forward looking.) Example:

$rev = $+   if /Version: (.*)|Revision: (.*)/;

$LAST_REGEXP_CODE_RESULT
$^R

[DYN] This contains the result of the last snippet of code executed inside a successful pattern with the (?{ CODE }) construct. $^R gives you a way to execute code and remember the result for use later in the pattern, or even afterward.

As the Perl regular expression engine moves through the pattern, it may encounter multiple (?{ CODE }) expressions. As it does, it remembers each value of $^R so that if it later has to backtrack past an expression, it restores the previous value of $^R. In other words, $^R has a dynamic scope within the pattern, much like $1 and friends.

So $^R is not simply the result of the last snippet of code executed inside a pattern. It's the result of the last snippet of code leading to a successful match. A corollary is that if the match was not successful, $^R will be restored to whatever value it had before the match occurred.

If the (?{ CODE }) pattern is functioning directly as the conditional of a (?(COND)IFTRUE|IFFALSE) subpattern, $^R is not set.

$LIST_SEPARATOR
$"

[ALL] When an array or slice is interpolated into a double-quoted string (or the like), this variable specifies the string to put between individual elements. Default is a space. (Mnemonic: obvious, one hopes.)

$^M

[ALL] By default, running out of memory is not trappable. However, if your perl was compiled to take advantage of $^M, you may use it as an emergency memory pool. If your Perl is compiled with -DPERL_EMERGENCY_SBRK and uses Perl's malloc, then:

$^M = 'a' x (1 << 16);
would allocate a 64K buffer for emergency use. See the INSTALL file in the Perl source distribution directory for information on how to enable this option. As a disincentive to casual use of this advanced feature, there is no use English long name for this variable (and we won't tell you what the mnemonic is).

$MATCH
$&

[DYN,RO] The string matched by the last successful pattern match in the currently active dynamic scope. (Mnemonic: like & in some editors.)

$OLD_PERL_VERSION
$]

[ALL] Returns the version + patchlevel/1000. It can be used to determine at the beginning of a script whether the Perl interpreter executing the script is in the right range of versions. (Mnemonic: is this version of Perl in the right bracket?) Example:

warn "No checksumming!\n" if $] < 3.019;
die "Must have prototyping available\n" if $] < 5.003;
See also the documentation of use VERSION and require VERSION for a convenient way to fail if the Perl interpreter is too old. See $^V for a more flexible UTF-8 representation of the Perl version.

$OSNAME
$^O

[ALL] This variable contains the name of the platform (usually the operating system) the current perl binary was compiled for. It's a cheap alternative to pulling it out of the Config module.

$OS_ERROR
$ERRNO
$!

[ALL] If used in a numeric context, yields the current value of the last syscall error, with all the usual caveats. (This means that you shouldn't depend on the value of $! to be anything in particular unless you've gotten a specific error return indicating a system error.) If used in a string context, $! yields the corresponding system error string. You can assign an error number to $! if, for instance, you want $! to return the string for that particular error, or you want to set the exit value for die. See also the Errno module in Chapter 32, "Standard Modules". (Mnemonic: what just went bang?)

%OS_ERROR
%ERRNO
%!

[ALL] This hash is defined only if you've loaded the standard Errno module described in Chapter 32, "Standard Modules". Once you've done this, you can subscript into %! using a particular error string, and its value is true only if that's the current error. For example, $!{ENOENT} is true only if the C errno variable is currently set to the C #define value, ENOENT. This is convenient for accessing vendor-specific symbols.

autoflush HANDLE EXPR
$OUTPUT_AUTOFLUSH
$AUTOFLUSH
$|

[FHA] If set to true, forces a buffer flush after every print, printf, and write on the currently selected output handle. (We call this command buffering. Contrary to popular belief, setting this variable does not turn off buffering.) The default is false, which on many systems means that STDOUT will be line buffered if output is to the terminal, and block buffered otherwise, even on pipes and sockets. Setting this variable is useful when you are outputting to a pipe, such as when you are running a Perl script under rsh(1) and want to see the output as it's happening. If you have pending, unflushed data in the currently selected filehandle's output buffer when this variable is set to true, that buffer will be immediately flushed as a side-effect of assignment. See the one-argument form of select for examples of controlling buffering on filehandles other than STDOUT. (Mnemonic: when you want your pipes to be piping hot.)

This variable has no effect on input buffering; for that, see getc in Chapter 29, "Functions" or the example in the POSIX module in Chapter 32, "Standard Modules".

$OUTPUT_FIELD_SEPARATOR
$OFS
$,

[ALL] The output field separator (terminator, actually) for print. Ordinarily, print simply prints out the list elements you specify without anything between them. Set this variable as you would set awk's OFS variable to specify what is printed between fields. (Mnemonic: what is printed when there is a "," in your print statement.)

$OUTPUT_RECORD_SEPARATOR
$ORS
$\

[ALL] The output record separator (terminator, actually) for print. Ordinarily, print simply prints out the comma-separated fields you specify, with no trailing newline or record separator assumed. Set this variable as you would set awk's ORS variable to specify what is printed at the end of the print. (Mnemonic: you set $\ instead of adding "\n" at the end of the print. Also, it's just like /, but it's what you get "back" from Perl.) See also the -l (for "line") command-line switch in Chapter 19, "The Command-Line Interface".

%OVERLOAD

[NOT,PKG] This hash's entries are set internally by the use overload pragma to implement operator overloading for objects of the current package's class. See Chapter 13, "Overloading".

$PERLDB
$^P

[NOT,ALL] The internal variable for enabling the Perl debugger (perl -d).

$PERL_VERSION
$^V

[ALL] The revision, version, and subversion of the Perl interpreter, represented as a binary "version string". V-strings don't generally have a a numeric value, but this variable is dual-valued, and has a numeric value equivalent to the old $] variable; that is, a floating-point number that amounts to revision + version/1000 + subversion/1,000,000. The string value is made of UTF-8 characters: chr($revision) . chr($version) . chr($subversion). This means that $^V is not printable. To print it, you have to say:

printf "%vd", $^V;
On the plus side, it also means that ordinary string comparison can be used to determine whether the Perl interpreter executing your script is in the right range of versions. (This applies to any version numbers represented with v-strings, not just Perl's.) Example:
warn "No 'our' declarations!\n" if $^V lt v5.6;
See the documentation of use VERSION and require VERSION for a convenient way to fail if the running Perl interpreter is older than you were hoping. See also $] for the original representation of the Perl version.

$POSTMATCH
$'

[DYN,RO] The string following whatever was matched by the last successful pattern in the currently active dynamic scope. (Mnemonic: ' often follows a quoted string.) Example:

$_ = 'abcdefghi';
/def/;
print "$`:$&:$'\n";         # prints abc:def:ghi
Thanks to dynamic scope, Perl can't know which patterns will need their results saved away into these variables, so mentioning $` or $' anywhere in a program incurs a performance penalty on all pattern matches throughout the program. This isn't much of an issue in small programs, but you probably should avoid this pair when you're writing reusable module code. The example above can be equivalently recoded like this, but without the global performance hit:
$_ = 'abcdefghi';
/(.*?)(def)(.*)/s;          # /s in case $1 contains newlines
print "$1:$2:$3\n";         # prints abc:def:ghi

$PREMATCH
$`

[DYN,RO] The string preceding whatever was matched by the last successful pattern in the currently active dynamic scope. (Mnemonic: ` often precedes a quoted string.) See the performance note under $' previously.

$PROCESS_ID
$PID
$$

[ALL] The process number (PID) of the Perl running this script. This variable is automatically updated upon a fork. In fact, you can even set $$ yourself; this will not, however, change your PID. That would be a neat trick. (Mnemonic: same as in the various shells.)

You need to be careful not to use $$ anywhere it might be misinterpreted as a dereference: $$alphanum. In this situation, write ${$}alphanum to distinguish it from ${$alphanum}.

$PROGRAM_NAME
$0

[ALL] Contains the name of the file containing the Perl script being executed. Assignment to $0 is magical: it attempts to modify the argument area that the ps(1) program normally reports on. This is more useful as a way of indicating the current program state than it is for hiding the program you're running. But it doesn't work on all systems. (Mnemonic: same as sh, ksh, bash, etc.)

$REAL_GROUP_ID
$GID
$(

[ALL] The real group ID (GID) of this process. If you are on a platform that supports simultaneous membership in multiple groups, $( gives a space-separated list of groups you are in. The first number is the one returned by getgid(2), and the subsequent ones by getgroups(2), one of which may be the same as the first number.

However, a value assigned to $( must be a single number used to set the real GID. So the value given by $( should not be assigned back to $( without being forced to be numeric, such as by adding zero. This is because you can have only one real group. See $) ($EFFECTIVE_GROUP_ID) instead, which allows you to set multiple effective groups.

(Mnemonic: parentheses are used to group things. The real GID is the group you left, if you're running setgid.)

$REAL_USER_ID
$UID
$<

[ALL] The real user ID (UID) of this process as returned by the getuid(2) syscall. Whether and how you can modify this is subject to the vagaries of your system's implementation--see examples under $> ($EFFECTIVE_USER_ID). (Mnemonic: it's the UID you came from, if you're running setuid.)

%SIG

[ALL] The hash used to set signal handlers for various signals. (See the section "Signals" in Chapter 16, "Interprocess Communication".) For example:

sub handler {
    my $sig = shift;   # 1st argument is signal name
    syswrite STDERR, "Caught a SIG$sig--shutting down\n";
                       # Avoid standard I/O in async handlers to suppress
                       # core dumpage.  (Even that string concat is risky.)
    close LOG;         # This calls standard I/O, so may dump core anyway!
    exit 1;            # But since we're exiting, no harm in trying.
}

$SIG{INT}  = \&handler;
$SIG{QUIT} = \&handler;
...
$SIG{INT}  = 'DEFAULT';    # restore default action
$SIG{QUIT} = 'IGNORE';     # ignore SIGQUIT
The %SIG hash contains undefined values corresponding to those signals for which no handler has been set. A handler may be specified as a subroutine reference or as a string. A string value that is not one of the two special actions "DEFAULT" or "IGNORE" is the name of a function, which, if unqualified by package, is interpreted to be the main package. Here are some other examples:
$SIG{PIPE} = "Plumber";   # okay, assumes main::Plumber
$SIG{PIPE} = \&Plumber;   # fine, use Plumber from current package

Certain internal hooks can also be set using the %SIG hash. The routine indicated by $SIG{__WARN__} is called when a warning message is about to be printed. The warning message is passed as the first argument. The presence of a __WARN__ hook causes the ordinary printing of warnings to STDERR to be suppressed. You can use this to save warnings in a variable or to turn warnings into fatal errors, like this:

local $SIG{__WARN__} = sub { die $_[0] };
eval $proggie;
This is similar to saying:
use warnings qw/FATAL all/;
eval $proggie;
except that the first has dynamic scope, whereas the second has lexical scope.

The routine indicated by $SIG{__DIE__} provides a way to turn a frog exception into a prince exception with a magical kiss, which often doesn't work. The best use is for a moribund program that's about to die of an untrapped exception to do some last-moment processing on its way out. You can't save yourself this way, but you can give one last hurrah.

The exception message is passed as the first argument. When a __DIE__ hook routine returns, exception processing continues as it would have in the absence of the hook, unless the hook routine itself exits via a goto, a loop exit, or a die. The __DIE__ handler is explicitly disabled during the call, so that you yourself can then call the real die from a __DIE__ handler. (If it weren't disabled, the handler would call itself recursively forever.) The handler for $SIG{__WARN__} works similarly.

Only the main program should set $SIG{__DIE__}, not modules. That's because currently, even exceptions that are being trapped still trigger a $SIG{__DIE__} handler. This is strongly discouraged because of its potential for breaking innocent modules who aren't expecting their predicted exceptions to be mysteriously altered. Use this feature only as a last resort, and if you must, always put a local on the front to limit the period of danger.

Do not attempt to build an exception-handling mechanism on this feature. Use eval {} to trap exceptions instead.

STDERR

[ALL] The special filehandle for standard error in any package.

STDIN

[ALL] The special filehandle for standard input in any package.

STDOUT

[ALL] The special filehandle for standard output in any package.

$SUBSCRIPT_SEPARATOR
$SUBSEP
$;

[ALL] The subscript separator for multidimensional hash emulation. If you refer to a hash element as:

$foo{$a,$b,$c}
it really means:
$foo{join($;, $a, $b, $c)}
But don't put:
@foo{$a,$b,$c}      # a slice--note the @
which means:
($foo{$a},$foo{$b},$foo{$c})
The default is "\034", the same as SUBSEP in awk. Note that if your keys contain binary data, there might not be any safe value for $;. (Mnemonic: comma--the syntactic subscript separator--is a semi-semicolon. Yeah, we know, it's pretty lame, but $, is already taken for something more important.)

Although we haven't deprecated this feature, you should instead consider using "real" multidimensional hashes now, such as $foo{$a}{$b}{$c} instead of $foo{$a,$b,$c}. The fake ones may be easier to sort, however, and are much more amenable to use as DBM files.

$SYSTEM_FD_MAX
$^F

[ALL] The maximum "system" file descriptor, ordinarily 2. System file descriptors are passed to new programs during an exec, while higher file descriptors are not. Also, during an open, system file descriptors are preserved even if the open fails. (Ordinary file descriptors are closed before the open is attempted and stay closed if the open fails.) Note that the close-on-exec status of a file descriptor will be decided according to the value of $^F at the time of the open, not the time of the exec. Avoid this by temporarily jacking $^F through the roof first:

{
    local $^F = 10_000;
    pipe(HITHER,THITHER) or die "can't pipe: $!";
}

$VERSION

[PKG] This variable is accessed whenever a minimum acceptable version of a module is specified, as in use SomeMod 2.5. If $SomeMod::VERSION is less than that, an exception is raised. Technically, it's the UNIVERSAL->VERSION method that looks at this variable, so you could define your own VERSION function in the current package if you want something other than the default behavior. See Chapter 12, "Objects".

$WARNING
$^W

[ALL] The current Boolean value of the global warning switch (not to be confused with the global warming switch, about which we hear many global warnings). See also the use warnings pragma in Chapter 31, "Pragmatic Modules", and the -W and -X command-line switches for lexically scoped warnings, which are unaffected by this variable. (Mnemonic: the value is related to the -w switch.)

${^WARNING_BITS}

[NOT,ALL] The current set of warning checks enabled by the use warnings pragma. See usewarnings in Chapter 31, "Pragmatic Modules" for more details.

${^WIDE_SYSTEM_CALLS}

[ALL] Global flag that enables all syscalls made by Perl to use wide-character APIs native to the system, if available. This can also be enabled from the command line using the -C command-line switch. The initial value is typically 0 for compatibility with Perl versions earlier than 5.6, but may be automatically set to 1 by Perl if the system provides a user-settable default (such as via $ENV{LC_CTYPE}). The use bytes pragma always overrides the effect of this flag in the current lexical scope.

Now brace yourself for a big chapter...

Previous | Home | Next
28.1. Special Names Grouped by Type | Book Index | 29. Functions
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 29. Functions

Contents:

Perl Functions by Category
Perl Functions in Alphabetical Order

This chapter describes the built-in Perl functions in alphabetical order[1] for convenient reference. Each function description begins with a brief summary of the syntax for that function. Parameter names like THIS represent placeholders for actual expressions, and the text following the syntax summary will describe the semantics of supplying (or omitting) the actual arguments.

[1] Sometimes tightly related functions are grouped together in the system manpages, so we respect that grouping here. To find the description of endpwent, for instance, you'll have to look under getpwent.

You can think of functions as terms in an expression, along with literals and variables. Or you can think of them as prefix operators that process the arguments after them. We call them operators half the time anyway.

Some of these operators, er, functions take a LIST as an argument. Elements of the LIST should be separated by commas (or by =>, which is just a funny kind of comma). The elements of the LIST are evaluated in a list context, so each element will return either a scalar or a list value, depending on its sensitivity to list context. Each returned value, whether scalar or list, will be interpolated as part of the overall sequence of scalar values. That is, all the lists get flattened into one list. From the viewpoint of the function receiving the arguments, the overall argument LIST is always a single-dimensional list value. (To interpolate an array as a single element, you must explicitly create and interpolate a reference to the array instead.)

Predefined Perl functions may be used either with or without parentheses around their arguments; the syntax summaries in this chapter omit the parentheses. If you do use parentheses, the simple but occasionally surprising rule is this: if it looks like a function, then it is a function, so precedence doesn't matter. Otherwise, it's a list operator or unary operator, and precedence does matter. Be careful, because even if you put whitespace between the keyword and its left parenthesis, that doesn't keep it from being a function:

print 1+2*4;       # Prints 9.
print(1+2) * 4;    # Prints 3!
print (1+2)*4;     # Also prints 3!
print +(1+2)*4;    # Prints 12.
print ((1+2)*4);   # Prints 12.
If you run Perl with the -w switch, it will warn you about this. For example, the second and third lines above produce messages like this:
print (...) interpreted as function at - line 2.
Useless use of integer multiplication in void context at - line 2.
Given the simple definition of some functions, you have considerable latitude in how you pass arguments. For instance, the most common way to use chmod is to pass the file permissions (the mode) as an initial argument:
chmod 0644, @array;
but the definition of chmod just says:
chmod LIST
so you could just as well say:
unshift @array, 0644;
chmod @array;
If the first argument of the list is not a valid mode, chmod will fail, but that's a run-time semantic problem unrelated to the syntax of the call. If the semantics require any special arguments to be passed first, the text will describe these restrictions.

In contrast to the simple LIST functions, other functions impose additional syntactic constraints. For instance, push has a syntax summary that looks like this:

push ARRAY, LIST
This means that push requires a proper array as its first argument, but doesn't care about its subsequent arguments. That's what the LIST at the end means. (LISTs always come at the end, since they gobble up all remaining values.) Whenever a syntax summary contains any arguments before the LIST, those arguments are syntactically distinguished by the compiler, not just semantically distinguished by the interpreter when it runs later. Such arguments are never evaluated in list context. They may be evaluated in scalar context, or they may be special referential arguments such as the array in push. (The description will tell you which is which.)

For those operations that are based directly on the C library's functions, we do not attempt to duplicate your system's documentation. When a function description says to see function(2), that means that you should look up the corresponding C version of that function to learn more about its semantics. The number in parentheses indicates the section of the system programmer's manual in which you will find the manpage, if you have the manpages installed. (And in which you won't, if you don't.)

These manpages may document system-dependent behavior like shadow password files, access control lists, and so forth. Many Perl functions that derive from C library functions in Unix are emulated even on non-Unix platforms. For example, although your operating system might not support the flock(2) or fork(2) syscalls, Perl will do its best to emulate them anyway by using whatever native facilities your platform provides.

Occasionally, you'll find that the documented C function has more arguments than the corresponding Perl function. Generally, the missing arguments are things that Perl knows already, such as the length of the previous argument, so you needn't supply them in Perl. Any remaining disparities are caused by the different ways Perl and C specify filehandles and success/failure values.

In general, functions in Perl that serve as wrappers for syscalls of the same name (like chown(2), fork(2), closedir(2), etc.) all return true when they succeed and undef otherwise, as mentioned in the descriptions that follow. This is different from the C library's interfaces to these operations, which all return -1 on failure. Exceptions to this rule are wait, waitpid, and syscall. Syscalls also set the special $! ($OS_ERROR) variable on failure. Other functions do not, except accidentally.

For functions that can be used in either scalar or list context, failure is generally indicated in scalar context by returning a false value (usually undef) and in list context by returning the null list. Successful execution is generally indicated by returning a value that will evaluate to true (in context).

Remember the following rule: there is no rule that relates the behavior of a function in list context to its behavior in scalar context, or vice versa. It might do two totally different things.

Each function knows the context in which it was called. The same function that returns a list when called in list context will, when called in scalar context, return whichever kind of value would be most appropriate. Some functions return the length of the list that would have been returned in list context. Some operators return the first value in the list. Some functions return the last value in the list. Some functions return the "other" value, when something can be looked up either by number or by name. Some functions return a count of successful operations. In general, Perl functions do exactly what you want, unless you want consistency.

One final note: we've tried to be very consistent in our use of the terms "byte" and "character". Historically, these terms have been confused with each other (and with themselves). But when we say "byte" we always mean an octet, 8 bits. When we say "character", we mean an abstract character, usually a Unicode character, which may be represented by one or more bytes within your strings.

But notice that we said "usually". Perl purposefully confuses bytes with characters in the scope of a use bytes declaration, so whenever we say "character", you should take it to mean a byte in a use bytes context, and a Unicode character otherwise. In other words, use bytes just warps the definition of character back to what it was in older versions of Perl. So, for instance, when we say that a scalar reverse reverses a string character by character, don't ask us whether that really means characters or bytes, because the answer is, "Yes, it does."

29.1. Perl Functions by Category

Here are Perl's functions and function-like keywords, arranged by category. Some functions appear under more than one heading.

Scalar manipulation

chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q//, qq//, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///

Regular expressions and pattern matching

m//, pos, qr//, quotemeta, s///, split, study

Numeric functions

abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand

Array processing

pop, push, shift, splice, unshift

List processing

grep, join, map, qw//, reverse, sort, unpack

Hash processing

delete, each, exists, keys, values

Input and output

binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir, readpipe, rewinddir, seek, seekdir, select (ready file descriptors), syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write

Fixed-length data and records

pack, read, syscall, sysread, sysseek, syswrite, unpack, vec

Filehandles, files, and directories

chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, select (ready file descriptors), select (output filehandle), stat, symlink, sysopen, umask, unlink, utime

Flow of program control

caller, continue, die, do, dump, eval, exit, goto, last, next, redo, return, sub, wantarray

Scoping

caller, import, local, my, no, our, package, use

Miscellaneous

defined, dump, eval, formline, lock, prototype, reset, scalar, undef, wantarray

Processes and process groups

alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe, qx//, setpgrp, setpriority, sleep, system, times, wait, waitpid

Library modules

do, import, no, package, require, use

Classes and objects

bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use

Low-level socket access

accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket, socketpair

System V interprocess communication

msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop, shmctl, shmget, shmread, shmwrite

Fetching user and group information

endgrent, endhostent, endnetent, endpwent, getgrent, getgrgid, getgrnam, getlogin, getpwent, getpwnam, getpwuid, setgrent, setpwent

Fetching network information

endprotoent, endservent, gethostbyaddr, gethostbyname, gethostent, getnetbyaddr, getnetbyname, getnetent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, sethostent, setnetent, setprotoent, setservent

Time

gmtime, localtime, time, times

Previous | Home | Next
28.2. Special Variables in Alphabetical Order | Book Index | 29.2. Perl Functions in Alphabetical Order
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


29.2. Perl Functions in Alphabetical Order

Many of the following function names are annotated with, um, annotations. Here are their meanings:

Uses $_ ($ARG) as a default variable.

Sets $! ($OS_ERROR) on syscall errors.

Raises exceptions; use eval to trap $@ ($EVAL_ERROR).

Sets $? ($CHILD_ERROR) when child process exits.

Taints returned data.

Taints returned data under some system, locale, or handle settings.

Raises an exception if given an argument of inappropriate type.

Raises an exception if modifying a read-only target.

Raises an exception if fed tainted data.

Raises an exception if unimplemented on current platform.

Functions that return tainted data when fed tainted data are not marked, since that's most of them. In particular, if you use any function on %ENV or @ARGV, you'll get tainted data.

Functions marked with raise an exception when they require, but do not receive, an argument of a particular type (such as filehandles for I/O operations, references for blessing, etc.).

Functions marked with sometimes need to alter their arguments. If they can't modify the argument because it's marked read-only, they'll raise an exception. Examples of read-only variables are the special variables containing data captured during a pattern match and variables that are really aliases to constants.

Functions marked with may not be implemented on all platforms. Although many of these are named after functions in the Unix C library, don't assume that just because you aren't running Unix, you can't call any of them. Many are emulated, even those you might never expect to see--such as fork on Win32 systems, which works as of the 5.6 release of Perl. For more information about the portability and behavior of system-specific functions, see the perlport manpage, plus any platform-specific documentation that came with your Perl port.

Functions that raise other miscellaneous exceptions are marked with , including math functions that throw range errors, such as sqrt(-1).

29.2.1. abs

abs VALUE
abs
This function returns the absolute value of its argument.
$diff = abs($first - $second);
Note: here and in subsequent examples, good style (and the use strict pragma) would dictate that you add a my modifier to declare a new lexically scoped variable, like this:
my $diff = abs($first - $second);
However, we've omitted my from most of our examples for clarity. Just assume that any such variable was declared earlier, if that cranks your rotor.

29.2.2. accept

accept SOCKET, PROTOSOCKET
This function is used by server processes that wish to listen for socket connections from clients. PROTOSOCKET must be a filehandle already opened via the socket operator and bound to one of the server's network addresses or to INADDR_ANY. Execution is suspended until a connection is made, at which point the SOCKET filehandle is opened and attached to the newly made connection. The original PROTOSOCKET remains unchanged; its only purpose is to be cloned into a real socket. The function returns the connected address if the call succeeds, false otherwise. For example:
unless ($peer = accept(SOCK, PROTOSOCK)) {
    die "Can't accept a connection: $!\n";
}
On systems that support it, the close-on-exec flag will be set for the newly opened file descriptor, as determined by the value of $^F ($SYSTEM_FD_MAX).

See accept(2). See also the example in the section "Sockets" in Chapter 16, "Interprocess Communication".

29.2.3. alarm

alarm EXPR
alarm
This function sends a SIGALRM signal to the current process after EXPR seconds.

Only one timer may be active at once. Each call disables the previous timer, and an EXPR of 0 may be supplied to cancel the previous timer without starting a new one. The return value is the amount of time remaining on the previous timer.

print "Answer me within one minute, or die: ";
alarm(60);             # kill program in one minute
$answer = <STDIN>;
$timeleft = alarm(0);  # clear alarm
print "You had $timeleft seconds remaining\n";
It is usually a mistake to intermix alarm and sleep calls, because many systems use the alarm(2) syscall mechanism to implement sleep(3). On older machines, the elapsed time may be up to one second less than you specified because of how seconds are counted. Additionally, a busy system may not get around to running your process immediately. See Chapter 16, "Interprocess Communication" for information on signal handling.

For alarms of finer granularity than one second, you might be able to use the syscall function to access setitimer(2) if your system supports it. The CPAN module, Timer::HiRes, also provides functions for this purpose.

29.2.4. atan2

atan2 Y, X
This function returns the principal value of the arc tangent of Y/X in the range - [image] to [image]. A quick way to get an approximate value of [image] is to say:
$pi = atan2(1,1) * 4;
For the tangent operation, you may use the tan function from either the Math::Trig or the POSIX modules, or just use the familiar relation:
sub tan { sin($_[0]) / cos($_[0]) }

29.2.5. bind

bind SOCKET, NAME
This function attaches an address (a name) to an already opened socket specified by the SOCKET filehandle. The function returns true if it succeeded, false otherwise. NAME should be a packed address of the proper type for the socket.
use Socket;
$port_number = 80;      # pretend we want to be a web server
$sockaddr = sockaddr_in($port_number, INADDR_ANY);
bind SOCK, $sockaddr or die "Can't bind $port_number: $!\n";
See bind(2). See also the examples in the section "Sockets" in Chapter 16, "Interprocess Communication".

29.2.6. binmode

binmode FILEHANDLE, DISCIPLINES
binmode FILEHANDLE
This function arranges for the FILEHANDLE to have the semantics specified by the DISCIPLINES argument. If DISCIPLINES is omitted, binary (or "raw") semantics are applied to the filehandle. If FILEHANDLE is an expression, the value is taken as the name of the filehandle or a reference to a filehandle, as appropriate.

The binmode function should be called after the open but before any I/O is done on the filehandle. The only way to reset the mode on a filehandle is to reopen the file, since the various disciplines may have treasured up various bits and pieces of data in various buffers. This restriction may be relaxed in the future.

In the olden days, binmode was used primarily on operating systems whose run-time libraries distinguished text from binary files. On those systems, the purpose of binmode was to turn off the default text semantics. However, with the advent of Unicode, all programs on all systems must take some cognizance of the distinction, even on Unix and Mac systems. These days there is only one kind of binary file (as far as Perl is concerned), but there are many kinds of text files, which Perl would also like to treat in a single way. So Perl has a single internal format for Unicode text, UTF-8. Since there are many kinds of text files, text files often need to be translated upon input into UTF-8, and upon output back into some legacy character set, or some other representation of Unicode. You can use disciplines to tell Perl how exactly (or inexactly) to do these translations.[2]

[2]More precisely, you will be able to use disciplines for this, but we're still implementing them as of this writing.

For example, a discipline of ":text" will tell Perl to do generic text processing without telling Perl which kind of text processing to do. But disciplines like ":utf8" and ":latin1" tell Perl which text format to read and write. On the other hand, the ":raw" discipline tells Perl to keep its cotton-pickin' hands off the data. For more on how disciplines work (or will work), see the open function. The rest of this discussion describes what binmode does without the DISCIPLINES argument, that is, the historical meaning of binmode, which is equivalent to:

binmode FILEHANDLE, ":raw";
Unless instructed otherwise, Perl will assume your freshly opened file should be read or written in text mode. Text mode means that \n (newline) will be your internal line terminator. All systems use \n as the internal line terminator, but what that really represents varies from system to system, device to device, and even file to file, depending on how you access the file. In such legacy systems (including MS-DOS and VMS), what your program sees as a \n may not be what's physically stored on disk. The operating system might, for example, store text files with \cM\cJ sequences that are translated on input to appear as \n to your program, and have \n from your program translated back to \cM\cJ on output to a file. The binmode function disables this automatic translation on such systems.

In the absence of a DISCIPLINES argument, binmode has no effect under Unix or Mac OS, both of which use \n to end each line and represent that as a single character. (It may, however, be a different character: Unix uses \cJ and older Macs use \cM. Doesn't matter.)

The following example shows how a Perl script might read a GIF image from a file and print it to the standard output. On systems that would otherwise alter the literal data into something other than its exact physical representation, you must prepare both handles. While you could use a ":raw" discipline directly in the GIF open, you can't do that so easily with pre-opened filehandles like STDOUT:

binmode STDOUT;
open(GIF, "vim-power.gif") or die "Can't open vim-power.gif: $!\n";
binmode GIF;
while (read(GIF, $buf, 1024)) {
    print STDOUT $buf;
}

29.2.7. bless

bless REF, CLASSNAME
bless REF
This function tells the referent pointed to by reference REF that it is now an object in the CLASSNAME package--or the current package if no CLASSNAME is specified. If REF is not a valid reference, an exception is raised. For convenience, bless returns the reference, since it's often the last function in a constructor subroutine. For example:
$pet = Beast->new(TYPE => "cougar", NAME => "Clyde");

# then in Beast.pm:
sub new {
    my $class  = shift;
    my %attrs = @_;
    my $self   = { %attrs };
    return bless($self, $class);
}
You should generally bless objects into CLASSNAMEs that are mixed case. Namespaces with all lowercase names are reserved for internal use as Perl pragmata (compiler directives). Built-in types (such as "SCALAR", "ARRAY", "HASH", etc., not to mention the base class of all classes, "UNIVERSAL") all have uppercase names, so you may wish to avoid such package names as well.

Make sure that CLASSNAME is not false; blessing into false packages is not supported and may result in unpredictable behavior.

It is not a bug that there is no corresponding curse operator. (But there is a sin operator.) See also Chapter 12, "Objects", for more about the blessing (and blessings) of objects.

29.2.8. caller

caller EXPR
caller
This function returns information about the stack of current subroutine calls and such. Without an argument, it returns the package name, filename, and line number that the currently executing subroutine was called from:
($package, $filename, $line) = caller;
Here's an example of an exceedingly picky function, making use of the special tokens __PACKAGE__ and __FILE__ described in Chapter 2, "Bits and Pieces":
sub careful {
    my ($package, $filename) = caller;
    unless ($package  eq __PACKAGE__ && $filename eq __FILE__) {
        die "You weren't supposed to call me, $package!\n";
    }
    print "called me safely\n";
}

sub safecall {
    careful();
}
When called with an argument, caller evaluates EXPR as the number of stack frames to go back before the current one. For example, an argument of 0 means the current stack frame, 1 means the caller, 2 means the caller's caller, and so on. The function also reports additional information as shown here:
$i = 0;
while (($package, $filename, $line, $subroutine,
        $hasargs, $wantarray, $evaltext, $is_require,
        $hints, $bitmask) = caller($i++) )
{
    ...
}
If the frame is a subroutine call, $hasargs is true if it has its own @_ array (not one borrowed from its caller). Otherwise, $subroutine may be "(eval)" if the frame is not a subroutine call, but an eval. If so, additional elements $evaltext and $is_require are set: $is_require is true if the frame is created by a require or use statement, and $evaltext contains the text of the eval EXPR statement. In particular, for a eval BLOCK statement, $filename is "(eval)", but $evaltext is undefined. (Note also that each use statement creates a require frame inside an eval EXPR frame.) The $hints and $bitmask are internal values; please ignore them unless you're a member of the thaumatocracy.

In a fit of even deeper magic, caller also sets the array @DB::args to the arguments passed in the given stack frame--but only when called from within the DB package. See Chapter 20, "The Perl Debugger".

29.2.9. chdir

chdir EXPR
chdir
This function changes the current process's working directory to EXPR, if possible. If EXPR is omitted, the caller's home directory is used. The function returns true upon success, false otherwise.
chdir "$prefix/lib" or die "Can't cd to $prefix/lib: $!\n";
See also the Cwd module, described in Chapter 32, "Standard Modules", which lets you keep track of your current directory automatically.

29.2.10. chmod

chmod LIST
This function changes the permissions of a list of files. The first element of the list must be the numerical mode, as in the chmod(2) syscall. The function returns the number of files successfully changed. For example:
$cnt = chmod 0755, 'file1', 'file2';
will set $cnt to 0, 1, or 2, depending on how many files were changed. Success is measured by lack of error, not by an actual change, because a file may have had the same mode before the operation. An error probably means you lacked sufficient privileges to change its mode because you were neither the file's owner nor the superuser. Check $! to find the actual reason for failure.

Here's a more typical usage:

chmod(0755, @executables) == @executables
        or die "couldn't chmod some of @executables: $!";
If you need to know which files didn't allow the change, use something like this:
@cannot = grep {not chmod 0755, $_} 'file1', 'file2', 'file3';
die "$0: could not chmod @cannot\n" if @cannot;
This idiom makes use of the grep function to select only those elements of the list for which the chmod function failed.

When using nonliteral mode data, you may need to convert an octal string to a number using the oct function. That's because Perl doesn't automatically assume a string contains an octal number just because it happens to have a leading "0".

$DEF_MODE = 0644;   # Can't use quotes here!
PROMPT: {
    print "New mode? ";
    $strmode = <STDIN>;
        exit unless defined $strmode;   # test for eof
    if ($strmode =~ /^\s*$/) {          # test for blank line
        $mode = $DEF_MODE;
    }
    elsif ($strmode !~ /^\d+$/) {
        print "Want numeric mode, not $strmode\n";
        redo PROMPT;
    }
    else {
        $mode = oct($strmode);          # converts "755" to 0755
    }
    chmod $mode, @files;
}
This function works with numeric modes much like the Unix chmod(2) syscall. If you want a symbolic interface like the one the chmod(1) command provides, see the File::chmod module on CPAN.

You can also import the symbolic S_I* constants from the Fcntl module:

use Fcntl ':mode';
chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;
Some people consider that more readable than 0755. Go figure.

29.2.11. chomp

chomp VARIABLE
chomp LIST
chomp
This function (normally) deletes a trailing newline from the end of a string contained in a variable. This is a slightly safer version of chop (described next) in that it has no effect upon a string that doesn't end in a newline. More specifically, it deletes the terminating string corresponding to the current value of $/, and not just any last character.

Unlike chop, chomp returns the number of characters deleted. If $/ is "" (in paragraph mode), chomp removes all trailing newlines from the selected string (or strings, if chomping a LIST). You cannot chomp a literal, only a variable.

For example:

while (<PASSWD>) {
    chomp;   # avoid \n on last field
    @array = split /:/;
    ...
}
With version 5.6, the meaning of chomp changes slightly in that input disciplines are allowed to override the value of the $/ variable and mark strings as to how they should be chomped. This has the advantage that an input discipline can recognize more than one variety of line terminator (such as Unicode paragraph and line separators), but still safely chomp whatever terminates the current line.

29.2.12. chop

chop VARIABLE
chop LIST
chop
This function chops off the last character of a string variable and returns the character chopped. The chop operator is used primarily to remove the newline from the end of an input record, and is more efficient than using a substitution. If that's all you're doing, then it would be safer to use chomp, since chop always shortens the string no matter what's there, and chomp is more selective.

You cannot chop a literal, only a variable.

If you chop a LIST of variables, each string in the list is chopped:

@lines = `cat myfile`;
chop @lines;
You can chop anything that is an lvalue, including an assignment:
chop($cwd = `pwd`);
chop($answer = <STDIN>);
This is different from:
$answer = chop($tmp = <STDIN>);  # WRONG
which puts a newline into $answer because chop returns the character chopped, not the remaining string (which is in $tmp). One way to get the result intended here is with substr:
$answer = substr <STDIN>, 0, -1;
But this is more commonly written as:
chop($answer = <STDIN>);
In the most general case, chop can be expressed in terms of substr:
$last_char = chop($var);
$last_char = substr($var, -1, 1, "");   # same thing
Once you understand this equivalence, you can use it to do bigger chops. To chop more than one character, use substr as an lvalue, assigning a null string. The following removes the last five characters of $caravan:
substr($caravan, -5) = "";
The negative subscript causes substr to count from the end of the string instead of the beginning. If you wanted to save the characters so removed, you could use the four-argument form of substr, creating something of a quintuple chop:
$tail = substr($caravan, -5, 5, "");

29.2.13. chown

chown LIST
This function changes the owner and group of a list of files. The first two elements of the list must be the numeric UID and GID, in that order. A value of -1 in either position is interpreted by most systems to leave that value unchanged. The function returns the number of files successfully changed. For example:
chown($uidnum, $gidnum, 'file1', 'file2') == 2
        or die "can't chown file1 or file2: $!";
will set $cnt to 0, 1, or 2, depending on how many files got changed (in the sense that the operation succeeded, not in the sense that the owner was different afterward). Here's a more typical usage:
chown($uidnum, $gidnum, @filenames) == @filenames
        or die "can't chown @filenames: $!";
Here's a subroutine that accepts a username, looks up the user and group IDs for you, and does the chown:
sub chown_by_name {
    my($user, @files) = @_;
    chown((getpwnam($user))[2,3], @files) == @files
            or die "can't chown @files: $!";
}

chown_by_name("fred", glob("*.c"));
However, you may not want the group changed as the previous function does, because the /etc/passwd file associates each user with a single group even though that user may be a member of many secondary groups according to /etc/group. An alternative is to pass a -1 for the GID, which leaves the group of the file unchanged. If you pass a -1 as the UID and a valid GID, you can set the group without altering the owner.

On most systems, you are not allowed to change the ownership of the file unless you're the superuser, although you should be able to change the group to any of your secondary groups. On insecure systems, these restrictions may be relaxed, but this is not a portable assumption. On POSIX systems, you can detect which rule applies like this:

use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
# only try if we're the superuser or on a permissive system
if ($> == 0 || !sysconf(_PC_CHOWN_RESTRICTED) ) {
    chown($uidnum, -1, $filename)
        or die "can't chown $filename to $uidnum: $!";
}

29.2.14. chr

chr NUMBER
chr

This function returns the character represented by that NUMBER in the character set. For example, chr(65) is "A" in either ASCII or Unicode, and chr(0x263a) is a Unicode smiley face. For the reverse of chr, use ord.

If you'd rather specify your characters by name than by number (for example, "\N{WHITE SMILING FACE}" for a Unicode smiley), see charnames in Chapter 31, "Pragmatic Modules".

29.2.15. chroot

chroot FILENAME
chroot
If successful, FILENAME becomes the new root directory for the current process--the starting point for pathnames beginning with "/". This directory is inherited across exec calls and by all subprocesses forked after the chroot call. There is no way to undo a chroot. For security reasons, only the superuser can use this function. Here's some code that approximates what many FTP servers do:
chroot((getpwnam('ftp'))[7])
    or die "Can't do anonymous ftp: $!\n";
This function is unlikely to work on non-Unix systems. See chroot(2).

29.2.16. close

close FILEHANDLE
close
This function closes the file, socket, or pipe associated with FILEHANDLE. (It closes the currently selected filehandle if the argument is omitted.) It returns true if the close is successful, false otherwise. You don't have to close FILEHANDLE if you are immediately going to do another open on it, since the next open will close it for you. (See open.) However, an explicit close on an input file resets the line counter ($.), while the implicit close done by open does not.

FILEHANDLE may be an expression whose value can be used as an indirect filehandle (either the real filehandle name or a reference to anything that can be interpreted as a filehandle object).

If the filehandle came from a piped open, close will return false if any underlying syscall fails or if the program at the other end of the pipe exited with nonzero status. In the latter case, the close forces $! ($OS_ERROR) to zero. So if a close on a pipe returns a nonzero status, check $! to determine whether the problem was with the pipe itself (nonzero value) or with the program at the other end (zero value). In either event, $? ($CHILD_ERROR) contains the wait status value (see its interpretation under system) of the command associated with the other end of the pipe. For example:

open(OUTPUT, '| sort -rn | lpr -p') # pipe to sort and lpr
    or die "Can't start sortlpr pipe: $!";
print OUTPUT @lines;                # print stuff to output
close OUTPUT                        # wait for sort to finish
    or warn $! ? "Syserr closing sortlpr pipe: $!"
               : "Wait status $? from sortlpr pipe";
A filehandle produced by dup(2)ing a pipe is treated as an ordinary filehandle, so close will not wait for the child on that filehandle. You have to wait for the child by closing the original filehandle. For example:
open(NETSTAT, "netstat -rn |")
    or die "can't run netstat: $!";
open(STDIN, "<&NETSTAT")
    or die "can't dup to stdin: $!";
If you close STDIN above, there is no wait, but if you close NETSTAT, there is.

If you somehow manage to reap an exited pipe child on your own, the close will fail. This could happen if you had a $SIG{CHLD} handler of your own that got triggered when the pipe child exited, or if you intentionally called waitpid on the process ID returned from the open call.

29.2.17. closedir

closedir DIRHANDLE
This function closes a directory opened by opendir and returns the success of that operation. See the examples under readdir. DIRHANDLE may be an expression whose value can be used as an indirect dirhandle, usually the real dirhandle name.

29.2.18. connect

connect SOCKET, NAME
This function initiates a connection with another process that is waiting at an accept. The function returns true if it succeeded, false otherwise. NAME should be a packed network address of the proper type for the socket. For example, assuming SOCK is a previously created socket:
use Socket;

my ($remote, $port) = ("www.perl.com", 80);
my $destaddr = sockaddr_in($port, inet_aton($remote));
connect SOCK, $destaddr
    or die "Can't connect to $remote at port $port: $!";
To disconnect a socket, use either close or shutdown. See also the examples in the section "Sockets" in Chapter 16, "Interprocess Communication". See connect(2).

29.2.19. cos

cos EXPR
cos
This function returns the cosine of EXPR (expressed in radians). For example, the following script will print a cosine table of angles measured in degrees:
# Here's the lazy way of getting degrees-to-radians.

$pi = atan2(1,1) * 4;
$piover180 = $pi/180;

# Print table.
for ($deg = 0; $deg <= 90; $deg++) {
    printf "%3d %7.5f\n", $deg, cos($deg * $piover180);
}
For the inverse cosine operation, you may use the acos() function from the Math::Trig or POSIX modules, or use this relation:
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }

29.2.20. crypt

crypt PLAINTEXT, SALT
This function computes a one-way hash of a string exactly in the manner of crypt(3). This is somewhat useful for checking the password file for lousy passwords,[3] although what you really want to do is prevent people from adding the bad passwords in the first place.

[3] Only people with honorable intentions are allowed to do this.

crypt is intended to be a one-way function, much like breaking eggs to make an omelette. There is no (known) way to decrypt an encrypted password apart from exhaustive, brute-force guessing.

When verifying an existing encrypted string, you should use the encrypted text as the SALT (like crypt($plain, $crypted) eq $crypted). This allows your code to work with the standard crypt, and with more exotic implementations, too.

When choosing a new SALT, you minimally need to create a random two character string whose characters come from the set [./0-9A-Za-z] (like join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]). Older implementations of crypt only needed the first two characters of the SALT, but code that only gives the first two characters is now considered nonportable. See your local crypt(3) manpage for interesting details.

Here's an example that makes sure that whoever runs this program knows their own password:

$pwd = (getpwuid ($<))[1];    # Assumes we're on Unix.

system "stty -echo";   # or look into Term::ReadKey on CPAN
print "Password: ";
chomp($word = <STDIN>);
print "\n";
system "stty echo";

if (crypt($word, $pwd) ne $pwd) {
    die "Sorry...\n";
} else {
    print "ok\n";
}
Of course, typing in your own password to whoever asks for it is unwise.

Shadow password files are slightly more secure than traditional password files, and you might have to be a superuser to access them. Because few programs should run under such powerful privileges, you might have the program maintain its own independent authentication system by storing the crypt strings in a different file than /etc/passwd or /etc/shadow.

The crypt function is unsuitable for encrypting large quantities of data, not least of all because you can't get the information back. Look at the by-module/Crypt and by-module/PGP directories on your favorite CPAN mirror for a slew of potentially useful modules.

29.2.21. dbmclose

dbmclose HASH
This function breaks the binding between a DBM (database management) file and a hash. dbmclose is really just a call to untie with the proper arguments, but is provided for backward compatibility with ancient versions of Perl.

29.2.22. dbmopen

dbmopen HASH, DBNAME, MODE
This binds a DBM file to a hash (that is, an associative array). (DBM stands for database management, and consists of a set of C library routines that allow random access to records via a hashing algorithm.) HASH is the name of the hash (including the %). DBNAME is the name of the database (without any .dir or .pag extension). If the database does not exist and a valid MODE is specified, the database is created with the protection specified by MODE, as modified by the umask. To prevent creation of the database if it doesn't exist, you may specify a MODE of undef, and the function will return false if it can't find an existing database. Values assigned to the hash prior to the dbmopen are not accessible.

The dbmopen function is really just a call to tie with the proper arguments, but is provided for backward compatibility with ancient versions of Perl. You can control which DBM library you use by using the tie interface directly or by loading the appropriate module before you call dbmopen. Here's an example that works on some systems for versions of DB_File similar to the version in your Netscape browser:

use DB_File;
dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.dat", undef)
    or die "Can't open netscape history file: $!";

while (($url, $when) = each %NS_Hist) {
    next unless defined($when);
    chop ($url, $when);        # kill trailing null bytes
    printf "Visited %s at %s.\n", $url,
        scalar(localtime(unpack("V",$when)));
}
If you don't have write access to the DBM file, you can only read the hash variables, not set them. If you want to test whether you can write, either use a file test like -w $file, or try setting a dummy hash entry inside an eval {}, which will trap the exception.

Functions such as keys and values may return huge list values when used on large DBM files. You may prefer to use the each function to iterate over large DBM files so that you don't load the whole thing in memory at once.

Hashes bound to DBM files have the same limitations as the type of DBM package you're using, including restrictions on how much data you can put into a bucket. If you stick to short keys and values, it's rarely a problem. See also the DB_File module in Chapter 32, "Standard Modules".

Another thing you should bear in mind is that many existing DBM databases contain null-terminated keys and values because they were set up with C programs in mind. The Netscape history file and the old sendmail aliases file are examples. Just use "$key\0" when pulling out a value, and remove the null from the value.

$alias = $aliases{"postmaster\0"};
chop $alias;   # kill the null
There is currently no built-in way to lock a generic DBM file. Some would consider this a bug. The GDBM_File module does attempt to provide locking at the granularity of the entire file. When in doubt, your best bet is to use a separate lock file.

29.2.23. defined

defined EXPR
defined
This function returns a Boolean value saying whether EXPR has a defined value or not. Most of the data you deal with is defined, but a scalar that contains no valid string, numeric, or reference value is said to contain the undefined value, or undef for short. Initializing a scalar variable to a particular value will define it, and it will stay defined until you assign an undefined value to it or explicitly call the undef function on that variable.

Many operations return undef under exceptional conditions, such as at end-of-file, when using an uninitialized variable's value, an operating system error, etc. Since undef is just one kind of false value, a simple Boolean test does not distinguish between undef, numeric zero, the null string, and the one-character string, "0"--all of which are equally false. The defined function allows you to distinguish between an undefined null string and a defined null string when you're using operators that might return a real null string.

Here is a fragment that tests a scalar value from a hash:

print if defined $switch{D};
When used on a hash element like this, defined only tells you whether the value is defined, not whether the key has an entry in the hash. It's possible to have a key whose value is undefined; the key itself however still exists. Use exists to determine whether the hash key exists.

In the next example we exploit the convention that some operations return the undefined value when you run out of data:

print "$val\n" while defined($val = pop(@ary));
And in this one, we do the same thing with the getpwent function for retrieving information about the system's users.
setpwent();
while (defined($name = getpwent())) {
    print "<<$name>>\n";
}
endpwent();
The same thing goes for error returns from syscalls that could validly return a false value:
die "Can't readlink $sym: $!"
    unless defined($value = readlink $sym);
You may also use defined to see whether a subroutine has been defined yet. This makes it possible to avoid blowing up on nonexistent subroutines (or subroutines that have been declared but never given a definition):
indir("funcname", @arglist);
sub indir {
    my $subname = shift;
    no strict 'refs';  # so we can use subname indirectly
    if (defined &$subname) {
        &$subname(@_);    # or $subname->(@_);
    }
    else {
        warn "Ignoring call to invalid function $subname";
    }
}
Use of defined on aggregates (hashes and arrays) is deprecated. (It used to report whether memory for that aggregate had ever been allocated.) Instead, use a simple Boolean test to see whether the array or hash has any elements:
if (@an_array) { print "has array elements\n" }
if (%a_hash)   { print "has hash members\n"   }
See also undef and exists.

29.2.24. delete

delete EXPR
This function deletes an element (or a slice of elements) from the specified hash or array. (See unlink if you want to delete a file.) The deleted elements are returned in the order specified, though this behavior is not guaranteed for tied variables such as DBM files. After the delete operation, the exists function will return false on any deleted key or index. (In contrast, after the undef function, the exists function continues to return true, because the undef function only undefines the value of the element, but doesn't delete the element itself.)

Deleting from the %ENV hash modifies the environment. Deleting from a hash that is bound to a (writable) DBM file deletes the entry from that DBM file.

Historically, you could only delete from a hash, but with Perl version 5.6 you may also delete from an array. Deleting from an array causes the element at the specified position to revert to a completely uninitialized state, but it doesn't close up the gap, since that would change the positions of all the subsequent entries. Use a splice for that. (However, if you delete the final element in an array, the array size will shrink by one (or more, depending on the position of the next largest existing element (if any))).

EXPR can be arbitrarily complicated, provided that the final operation is a hash or array lookup:

# set up array of array of hash
$dungeon[$x][$y] = \%properties;

# delete one property from hash
delete $dungeon[$x][$y]{"OCCUPIED"};

# delete three properties all at once from hash
delete @{ $dungeon[$x][$y] }{ "OCCUPIED", "DAMP", "LIGHTED" };

# delete reference to %properties from array
delete $dungeon[$x][$y];
The following naïve example inefficiently deletes all the values of a %hash:
foreach $key (keys %hash) {
    delete $hash{$key};
}
And so does this:
delete @hash{keys %hash};
But both of these are slower than just assigning the empty list or undefining it:
%hash = ();         # completely empty %hash
undef %hash;        # forget %hash ever existed
Likewise for arrays:
foreach $index (0 .. $#array) {
    delete $array[$index];
}
and:
delete @array[0 .. $#array];
are less efficient than either of:
@array = ();         # completely empty @array
undef @array;        # forget @array ever existed

29.2.25. die

die LIST
die
Outside an eval, this function prints the concatenated value of LIST to STDERR and exits with the current value of $! (the C-library errno variable). If $! is 0, it exits with the value of $? >> 8 (which is the status of the last reaped child from a system, wait, close on a pipe, or `command`). If $? >> 8 is 0, it exits with 255.

Within an eval, the function sets the $@ variable to the error message that would have otherwise been produced, then aborts the eval, which returns undef. The die function can thus be used to raise named exceptions that can be caught at a higher level in the program. See eval later in this chapter.

If LIST is a single object reference, that object is assumed to be an exception object and is returned unmodified as the exception in $@.

If LIST is empty and $@ already contains a string value (typically from a previous eval) that value is reused after appending "\t...propagated". This is useful for propagating (reraising) exceptions:

eval { ... };
die unless $@ =~ /Expected exception/;
If LIST is empty and $@ already contains an exception object, the $@->PROPAGATE method is called to determine how the exception should be propagated.

If LIST is empty and $@ is empty, then the string "Died" is used.

If the final value of LIST does not end in a newline (and you're not passing an exception object), the current script filename, line number, and input line number (if any) are appended to the message, as well as a newline. Hint: sometimes appending ", stopped" to your message will cause it to make better sense when the string "at scriptname line 123" is appended. Suppose you are running script canasta; consider the difference between the following two ways of dying:

die "/usr/games is no good";
die "/usr/games is no good, stopped";
which produce, respectively:
/usr/games is no good at canasta line 123.
/usr/games is no good, stopped at canasta line 123.
If you want your own error messages reporting the filename and line number, use the __FILE__ and __LINE__ special tokens:
die '"', __FILE__, '", line ', __LINE__, ", phooey on you!\n";
This produces output like:
"canasta", line 38, phooey on you!
One other style issue--consider the following equivalent examples:
die "Can't cd to spool: $!\n"   unless chdir '/usr/spool/news';

chdir '/usr/spool/news'         or die "Can't cd to spool: $!\n"
Because the important part is the chdir, the second form is generally preferred.

See also exit, warn, %SIG, and the Carp module.

29.2.26. do (block)

do BLOCK
The do BLOCK form executes the sequence of statements in the BLOCK and returns the value of the last expression evaluated in the block. When modified by a while or until statement modifier, Perl executes the BLOCK once before testing the loop condition. (On other statements the loop modifiers test the conditional first.) The do BLOCK itself does not count as a loop, so the loop control statements next, last, or redo cannot be used to leave or restart the block. See the section "Bare Blocks" in Chapter 4, "Statements and Declarations", for workarounds.

29.2.27. do (file)

do FILE
The do FILE form uses the value of FILE as a filename and executes the contents of the file as a Perl script. Its primary use is (or rather was) to include subroutines from a Perl subroutine library, so that:
do 'stat.pl';
is rather like:
scalar eval `cat stat.pl`;   # `type stat.pl` on Windows
except that do is more efficient, more concise, keeps track of the current filename for error messages, searches all the directories listed in the @INC array, and updates %INC if the file is found. (See Chapter 28, "Special Names".) It also differs in that code evaluated with do FILE cannot see lexicals in the enclosing scope, whereas code in eval FILE does. It's the same, however, in that it reparses the file every time you call it--so you might not want to do this inside a loop unless the filename itself changes at each loop iteration.

If do can't read the file, it returns undef and sets $! to the error. If do can read the file but can't compile it, it returns undef and sets an error message in $@. If the file is successfully compiled, do returns the value of the last expression evaluated.

Inclusion of library modules (which have a mandatory .pm suffix) is better done with the use and require operators, which also do error checking and raise an exception if there's a problem. They also offer other benefits: they avoid duplicate loading, help with object-oriented programming, and provide hints to the compiler on function prototypes.

But do FILE is still useful for such things as reading program configuration files. Manual error checking can be done this way:

# read in config files: system first, then user
for $file ("/usr/share/proggie/defaults.rc",
           "$ENV{HOME}/.someprogrc")
{
    unless ($return = do $file) {
        warn "couldn't parse $file: $@" if $@;
        warn "couldn't do $file: $!"    unless defined $return;
        warn "couldn't run $file"       unless $return;
    }
}
A long-running daemon could periodically examine the timestamp on its configuration file, and if the file has changed since it was last read in, the daemon could use do to reload that file. This is more tidily accomplished with do than with require or use.

29.2.28. do (subroutine)

do SUBROUTINE(LIST)
The do SUBROUTINE(LIST) is a deprecated form of a subroutine call. An exception is raised if the SUBROUTINE is undefined. See Chapter 6, "Subroutines".

29.2.29. dump

dump LABEL
dump
This function causes an immediate core dump. Primarily this is so that you can use the undump program (not supplied) to turn your core dump into an executable binary after having initialized all your variables at the beginning of the program. When the new binary is executed it will begin by executing a goto LABEL (with all the restrictions that goto suffers). Think of it as a goto with an intervening core dump and reincarnation. If LABEL is omitted, the program is restarted from the top. Warning: any files opened at the time of the dump will not be open any more when the program is reincarnated, with possible resulting confusion on the part of Perl. See also the -u command-line option in Chapter 19, "The Command-Line Interface".

This function is now largely obsolete, partly because it's difficult in the extreme to convert a core file into an executable in the general case, and because various compiler backends for generating portable bytecode and compilable C code have superseded it.

If you're looking to use dump to speed up your program, check out the discussion of efficiency matters in Chapter 24, "Common Practices", as well the Perl native-code generator in Chapter 18, "Compiling". You might also consider autoloading or selfloading, which at least make your program appear to run faster.

29.2.30. each

each HASH
This function steps through a hash one key/value pair at a time. When called in list context, each returns a two-element list consisting of the key and value for the next element of a hash, so that you can iterate over it. When called in scalar context, each returns just the key for the next element in the hash. When the hash is entirely read, the empty list is returned, which when assigned produces a false value in scalar context, such as a loop test. The next call to each after that will start iterating again. The typical use is as follows, using predefined %ENV hash:
while (($key,$value) = each %ENV) {
    print "$key=$value\n";
}
Internally, a hash maintains its own entries in an apparently random order. The each function iterates through this sequence because every hash remembers which entry was last returned. The actual ordering of this sequence is subject to change in future versions of Perl, but is guaranteed to be in the same order as the keys (or values) function would produce on the same (unmodified) hash.

There is a single iterator for each hash, shared by all each, keys, and values function calls in the program; it can be reset by reading all the elements from the hash, or by evaluating keys %hash or values %hash. If you add or delete elements of a hash while you're iterating over it, the resulting behavior is not well-defined: entries might get skipped or duplicated.

See also keys, values, and sort.

29.2.31. eof

eof FILEHANDLE
eof()
eof
This function returns true if the next read on FILEHANDLE would return end-of-file, or if FILEHANDLE is not open. FILEHANDLE may be an expression whose value gives the real filehandle, or a reference to a filehandle object of some sort. An eof without an argument returns the end-of-file status for the last file read. An eof() with empty parentheses () tests the ARGV filehandle (most commonly seen as the null filehandle in <>). Therefore, inside a while (<>) loop, an eof() with parentheses will detect the end of only the last of a group of files. Use eof (without the parentheses) to test each file in a while (<>) loop. For example, the following code inserts dashes just before the last line of the last file:
while (<>) {
    if (eof()) {
        print "-" x 30, "\n";
    }
    print;
}
On the other hand, this script resets line numbering on each input file:
# reset line numbering on each input file
while (<>) {
    next if /^\s*#/;        # skip comments
    print "$.\t$_";
} continue {
    close ARGV if eof;      # Not eof()!
}
Like "$" in a sed program, eof tends to show up in line number ranges. Here's a script that prints lines from /pattern/ to end of each input file:
while (<>) {
    print if /pattern/ .. eof;
}
Here, the flip-flop operator (..) evaluates the pattern match for each line. Until the pattern matches, the operator returns false. When it finally matches, the operator starts returning true, causing the lines to be printed. When the eof operator finally returns true (at the end of the file being examined), the flip-flop operator resets, and starts returning false again for the next file in @ARGV.

Warning: The eof function reads a byte and then pushes it back on the input stream with ungetc(3), so it is not useful in an interactive context. In fact, experienced Perl programmers rarely use eof, since the various input operators already behave politely in while-loop conditionals. See the example in the description of foreach in Chapter 4, "Statements and Declarations".

29.2.32. eval

eval BLOCK
eval EXPR
eval
The eval keyword serves two distinct but related purposes in Perl. These purposes are represented by two forms of syntax, eval BLOCK and eval EXPR. The first form traps run-time exceptions (errors) that would otherwise prove fatal, similar to the "try block" construct in C++ or Java. The second form compiles and executes little bits of code on the fly at run time, and also (conveniently) traps any exceptions just like the first form. But the second form runs much slower than the first form, since it must parse the string every time. On the other hand, it is also more general. Whichever form you use, eval is the preferred way to do all exception handling in Perl.

For either form of eval, the value returned from an eval is the value of the last expression evaluated, just as with subroutines. Similarly, you may use the return operator to return a value from the middle of the eval. The expression providing the return value is evaluated in void, scalar, or list context, depending on the context of the eval itself. See wantarray for more on how the evaluation context can be determined.

If there is a trappable error (including any produced by the die operator), eval returns undef and puts the error message (or object) in $@. If there is no error, $@ is guaranteed to be set to the null string, so you can test it reliably afterward for errors. A simple Boolean test suffices:

eval { ... };    # trap run-time errors
if ($@) { ... }    # handle error
The eval BLOCK form is syntax-checked at compile time, so it is quite efficient. (People familiar with the slow eval EXPR form are occasionally confused on this issue.) Since the code in the BLOCK is compiled at the same time as the surrounding code, this form of eval cannot trap syntax errors.

The eval EXPR form can trap syntax errors because it parses the code at run time. (If the parse is unsuccessful, it places the parse error in $@, as usual.) Otherwise, it executes the value of EXPR as though it were a little Perl program. The code is executed in the context of the current Perl program, which means that it can see any enclosing lexicals from a surrounding scope, and that any non-local variable settings remain in effect after the eval is complete, as do any subroutine or format definitions. The code of the eval is treated as a block, so any locally scoped variables declared within the eval last only until the eval is done. (See my and local.) As with any code in a block, a final semicolon is not required.

Here is a simple Perl shell. It prompts the user to enter a string of arbitrary Perl code, compiles and executes that string, and prints whatever error occurred:

print "\nEnter some Perl code: ";

while (<STDIN>) {
    eval;
    print $@;
    print "\nEnter some more Perl code: ";
}
Here is a rename program to do a mass renaming of files using a Perl expression:
#!/usr/bin/perl
# rename - change filenames
$op = shift;
for (@ARGV) {
    $was = $_;
    eval $op;
    die if $@;
    # next line calls the built-in function, not the script by the same name
    rename($was,$_) unless $was eq $_;
}
You'd use that program like this:
$ rename 's/\.orig$//'                *.orig
$ rename 'y/A-Z/a-z/ unless /^Make/'  *
$ rename '$_ .= ".bad"'               *.f
Since eval traps errors that would otherwise prove fatal, it is useful for determining whether particular features (such as fork or symlink) are implemented.

Because eval BLOCK is syntax-checked at compile time, any syntax error is reported earlier. Therefore, if your code is invariant and both eval EXPR and eval BLOCK will suit your purposes equally well, the BLOCK form is preferred. For example:

# make divide-by-zero nonfatal
eval { $answer = $a / $b; };    warn $@ if $@;

# same thing, but less efficient if run multiple times
eval '$answer = $a / $b';       warn $@ if $@;

# a compile-time syntax error (not trapped)
eval { $answer = };             # WRONG

# a run-time syntax error
eval '$answer =';               # sets $@
Here, the code in the BLOCK has to be valid Perl code to make it past the compile phase. The code in the EXPR doesn't get examined until run time, so it doesn't cause an error until run time.

The block of eval BLOCK does not count as a loop, so the loop control statements next, last, or redo cannot be used to leave or restart the block.

29.2.33. exec

exec PATHNAME LIST
exec LIST
The exec function terminates the current program and executes an external command and never returns!!! Use system instead of exec if you want to recover control after the commands exits. The exec function fails and returns false only if the command does not exist and if it is executed directly instead of via your system's command shell (discussed below).

If there is only one scalar argument, the argument is checked for shell metacharacters. If metacharacters are found, the entire argument is passed to the system's standard command interpreter (/bin/sh under Unix). If there are no metacharacters, the argument is split into words and executed directly, since in the interests of efficiency this bypasses all the overhead of shell processing. It also gives you more control of error recovery should the program not exist.

If there is more than one argument in LIST, or if LIST is an array with more than one value, the system shell will never be used. This also bypasses any shell processing of the command. The presence or absence of metacharacters in the arguments doesn't affect this list-triggered behavior, which makes it the preferred form in security-conscious programs that do not wish to expose themselves to potential shell escapes.

This example causes the currently running Perl program to replace itself with the echo program, which then prints out the current argument list:

exec 'echo', 'Your arguments are: ', @ARGV;
This example shows that you can exec a pipeline, not just a single program.
exec "sort $outfile | uniq"
    or die "Can't do sort/uniq: $!\n";
Ordinarily, exec never returns--if it does return, it always returns false, and you should check $! to find out what went wrong. Be aware that in older releases of Perl, exec (and system) did not flush your output buffer, so you needed to enable command buffering by setting $| on one or more filehandles to avoid lost output in the case of exec, or misordered output in the case of system. This situation was largely remedied in the 5.6 release of Perl.

When you ask the operating system to execute a new program within an existing process (as Perl's exec function does), you tell the system the location of the program to execute, but you also tell the new program (through its first argument) the name under which the program was invoked. Customarily, the name you tell it is just a copy of the location of the program, but it doesn't necessarily have to be, since there are two separate arguments at the level of the C language. When it is not a copy, you have the odd result that the new program thinks it's running under a name that may be totally different from the actual pathname where the program resides. Often this doesn't matter to the program in question, but some programs do care and adopt a different persona depending on what they think their name is. For example, the vi editor looks to see whether it was called as "vi" or as "view". If invoked as "view", it automatically enables read-only mode, just as though it was called with the -R command-line option.

This is where exec's optional PATHNAME parameter comes into play. Syntactically, it goes in the indirect-object slot like the filehandle for print or printf. Therefore, it doesn't take a comma after it, because it's not exactly part of the argument list. (In a sense, Perl takes the opposite approach from the operating system in that it assumes the first argument is the important one, and lets you modify the pathname if it differs.) For example:

$editor = "/usr/bin/vi";
exec $editor "view", @files      # trigger read-only mode
    or die "Couldn't execute $editor: $!\n";
As with any other indirect object, you can also replace the simple scalar holding the program name with a block containing arbitrary code, which simplifies the previous example to:
exec { "/usr/bin/vi" } "view" @files      # trigger read-only mode
    or die "Couldn't execute $editor: $!\n";
As we mentioned earlier, exec treats a discrete list of arguments as an indication that it should bypass shell processing. However, there is one place where you might still get tripped up. The exec call (and system, too) will not distinguish between a single scalar argument and an array containing only one element.
@args = ("echo surprise");  # just one element in list
exec @args                  # still subject to shell escapes
     or die "exec: $!";     #   because @args == 1
To avoid this, you can use the PATHNAME syntax, explicitly duplicating the first argument as the pathname, which forces the rest of the arguments to be interpreted as a list, even if there is only one of them:
exec { $args[0] } @args   # safe even with one-argument list
    or die "can't exec @args: $!";
The first version, the one without the curlies, runs the echo program, passing it "surprise" as an argument. The second version doesn't--it tries to run a program literally called echo surprise, doesn't find it (we hope), and sets $! to a nonzero value indicating failure.

Because the exec function is most often used shortly after a fork, it is assumed that anything that normally happens when a Perl process terminates should be skipped. Upon an exec, Perl will not call your END blocks, nor will it call any DESTROY methods associated with any objects. Otherwise, your child process would end up doing the cleanup you expected the parent process to do. (We wish that were the case in real life.)

Because it's such a common mistake to use exec instead of system, Perl warns you if there is a following statement that isn't die, warn, or exit when run with the popular -w command-line option, or if you've used the use warnings qw(exec syntax) pragma. If you really want to follow an exec with some other statement, you can use either of these styles to avoid the warning:

exec ('foo')   or print STDERR "couldn't exec foo: $!";
{ exec ('foo') }; print STDERR "couldn't exec foo: $!";
As the second line above shows, a call to exec that is the last statement in a block is exempt from this warning.

See also system.

29.2.34. exists

exists EXPR
This function returns true if the specified hash key or array index exists in its hash or array. It doesn't matter whether the corresponding value is true or false, or whether the value is even defined.
print "True\n"      if         $hash{$key};
print "Defined\n"   if defined $hash{$key};
print "Exists\n"    if exists  $hash{$key};

print "True\n"      if         $array[$index];
print "Defined\n"   if defined $array[$index];
print "Exists\n"    if exists  $array[$index];
An element can be true only if it's defined, and can be defined only if it exists, but the reverse doesn't necessarily hold.

EXPR can be arbitrarily complicated, provided that the final operation is a hash key or array index lookup:

if (exists $hash{A}{B}{$key}) { ... }
Although the last element will not spring into existence just because its existence was tested, intervening ones will. Thus $$hash{"A"} and $hash{"A"}->{"B"} will both spring into existence. This is not a function of exists, per se; it happens anywhere the arrow operator is used (explicitly or implicitly):
undef $ref;
if (exists $ref->{"Some key"}) { }
print $ref;   # prints HASH(0x80d3d5c)
Even though the "Some key" element didn't spring into existence, the previously undefined $ref variable did suddenly come to hold an anonymous hash. This is a surprising instance of autovivification in what does not at first--or even second--glance appear to be an lvalue context. This behavior is likely to be fixed in a future release. As a workaround, you can nest your calls:
if ($ref                        and
    exists $ref->[$x]           and
    exists $ref->[$x][$y]       and
    exists $ref->[$x][$y]{$key} and
    exists $ref->[$x][$y]{$key}[2] ) { ... }
If EXPR is the name of a subroutine, the exists function will return true if that subroutine has been declared, even if it has not yet been defined. The following will just print "Exists":
sub flub;
print "Exists\n"     if exists  &flub;
print "Defined\n"    if defined &flub;
Using exists on a subroutine name can be useful for an AUTOLOAD subroutine that needs to know whether a particular package wants a particular subroutine to be defined. The package can indicate this by declaring a stub sub like flub.

29.2.35. exit

exit EXPR
exit
This function evaluates EXPR as an integer and exits immediately with that value as the final error status of the program. If EXPR is omitted, the function exits with 0 status (meaning "no error"). Here's a fragment that lets a user exit the program by typing x or X:
$ans = <STDIN>;
exit if $ans =~ /^[Xx]/;
You shouldn't use exit to abort a subroutine if there's any chance that someone might want to trap whatever error happened. Use die instead, which can be trapped by an eval. Or use one of die's wrappers from the Carp module, like croak or confess.

We said that the exit function exits immediately, but that was a bald-faced lie. It exits as soon as possible, but first it calls any defined END routines for at-exit handling. These routines cannot abort the exit, although they can change the eventual exit value by setting the $? variable. Likewise, any class that defines a DESTROY method will invoke that method on behalf of all its objects before the real program exits. If you really need to bypass exit processing, you can call the POSIX module's _exit function to avoid all END and destructor processing. And if POSIX isn't available, you can exec "/bin/false" or some such.

29.2.36. exp

exp EXPR
exp
This function returns e to the power of EXPR. To get the value of e, just use exp(1). For general exponentiation of different bases, use the ** operator we stole from FORTRAN:
use Math::Complex;
print -exp(1) ** (i * pi);   # prints 1

29.2.37. fcntl

fcntl FILEHANDLE, FUNCTION, SCALAR
This function calls your operating system's file control functions, as documented in the fcntl(2) manpage. Before you call fcntl, you'll probably first have to say:
use Fcntl;
to load the correct constant definitions.

SCALAR will be read or written (or both) depending on the FUNCTION. A pointer to the string value of SCALAR will be passed as the third argument of the actual fcntl call. (If SCALAR has no string value but does have a numeric value, that value will be passed directly rather than passing a pointer to the string value.) See the Fcntl module for a description of the more common permissible values for FUNCTION.

The fcntl function will raise an exception if used on a system that doesn't implement fcntl(2). On systems that do implement it, you can do such things as modify the close-on-exec flags (if you don't want to play with the $^F ($SYSTEM_FD_MAX) variable), modify the nonblocking I/O flags, emulate the lockf(3) function, and arrange to receive the SIGIO signal when I/O is pending.

Here's an example of setting a filehandle named REMOTE to be nonblocking at the system level. This makes any input operation return immediately if nothing is available when reading from a pipe, socket, or serial line that would otherwise block. It also works to cause output operations that normally would block to return a failure status instead. (For those, you'll likely have to negotiate $| as well.)

use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);

$flags = fcntl(REMOTE, F_GETFL, 0)
            or die "Can't get flags for the socket: $!\n";

$flags = fcntl(REMOTE, F_SETFL, $flags | O_NONBLOCK)
            or die "Can't set flags for the socket: $!\n";
The return value of fcntl (and ioctl) is as follows:

Syscall Returns | Perl Returns
-1 | undef
0 | String "0 but true"
anything else | That number

Thus Perl returns true on success and false on failure, yet you can still easily determine the actual value returned by the operating system:

$retval = fcntl(...) || -1;
printf "fcntl actually returned %d\n", $retval;
Here, even the string "0 but true" prints as 0, thanks to the %d format. This string is true in Boolean context and 0 in numeric context. (It is also happily exempt from the normal warnings on improper numeric conversions.)

29.2.38. fileno

fileno FILEHANDLE
This function returns the file descriptor underlying a filehandle. If the filehandle is not open, fileno returns undef. A file descriptor is a small, non-negative integer like 0 or 1, in contrast to filehandles like STDIN and STDOUT, which are symbols. Unfortunately, the operating system doesn't know about your cool symbols. It only thinks of open files in terms of these small file numbers, and although Perl will usually do the translations for you automatically, occasionally you have to know the actual file descriptor.

So, for example, the fileno function is useful for constructing bitmaps for select and for passing to certain obscure system calls if syscall(2) is implemented. It's also useful for double-checking that the open function gave you the file descriptor you wanted and for determining whether two filehandles use the same system file descriptor.

if (fileno(THIS) == fileno(THAT)) {
    print "THIS and THAT are dups\n";
}
If FILEHANDLE is an expression, the value is taken as an indirect filehandle, generally its name or a reference to something resembling a filehandle object.

One caution: don't count on the association of a Perl filehandle and a numeric file descriptor throughout the life of the program. If a file has been closed and reopened, the file descriptor may change. Perl takes a bit of trouble to try to ensure that certain file descriptors won't be lost if an open on them fails, but it only does this for file descriptors that don't exceed the current value of the special $^F ($SYSTEM_FD_MAX) variable (by default, 2). Although filehandles STDIN, STDOUT, and STDERR start out with file descriptors of 0, 1, and 2 (the Unix standard convention), even they can change if you start closing and opening them with wild abandon. You can't get into trouble with 0, 1, and 2 as long as you always reopen immediately after closing. The basic rule on Unix systems is to pick the lowest available descriptor, and that'll be the one you just closed.

29.2.39. flock

flock FILEHANDLE, OPERATION
The flock function is Perl's portable file-locking interface, although it locks only entire files, not records. The function manages locks on the file associated with FILEHANDLE, returning true for success and false otherwise. To avoid the possibility of lost data, Perl flushes your FILEHANDLE before locking or unlocking it. Perl might implement its flock in terms of flock(2), fcntl(2), lockf(3), or some other platform-specific lock mechanism, but if none of these is available, calling flock raises an exception. See the section "File Locking" in Chapter 16, "Interprocess Communication".

OPERATION is one of LOCK_SH, LOCK_EX, or LOCK_UN, possibly ORed with LOCK_NB. These constants are traditionally valued 1, 2, 8, and 4, but you can use the symbolic names if you import them from the Fcntl module, either individually or as a group using the :flock tag.

LOCK_SH requests a shared lock, so it's typically used for reading. LOCK_EX requests an exclusive lock, so it's typically used for writing. LOCK_UN releases a previously requested lock; closing the file also releases any locks. If the LOCK_NB bit is used with LOCK_SH or LOCK_EX, flock returns immediately rather than waiting for an unavailable lock. Check the return status to see whether you got the lock you asked for. If you don't use LOCK_NB, you might wait indefinitely for the lock to be granted.

Another nonobvious but traditional aspect of flock is that its locks are merely advisory. Discretionary locks are more flexible but offer fewer guarantees than mandatory ones. This means that files locked with flock may be modified by programs that do not also use flock. Cars that stop for red lights get on well with each other, but not with cars that don't stop for red lights. Drive defensively.

Some implementations of flock cannot lock things over the network. While you could in theory use the more system-specific fcntl for that, the jury (having sequestered itself on the case for a decade or so) is still out on whether this is (or even can be) reliable.

Here's a mailbox appender for Unix systems that use flock(2) to lock mailboxes:

use Fcntl qw/:flock/;       # import LOCK_* constants
sub mylock {
    flock(MBOX, LOCK_EX)
        or die "can't lock mailbox: $!";
    # in case someone appended while we were waiting
    # and our stdio buffer is out of sync
    seek(MBOX, 0, 2)
        or die "can't seek to the end of mailbox: $!";
}

open(MBOX, ">>/usr/spool/mail/$ENV{'USER'}")
    or die "can't open mailbox: $!";

mylock();
print MBOX $msg, "\n\n";
close MBOX
    or die "can't close mailbox: $!";
On systems that support a real flock(2) syscall, locks are inherited across fork calls. Other implementations are not so lucky, and are likely to lose the locks across forks. See also the DB_File module in Chapter 32, "Standard Modules" for other flock examples.

29.2.40. fork

fork
This function creates two processes out of one by invoking the fork(2) syscall. If it succeeds, the function returns the new child process's ID to the parent process and 0 to the child process. If the system doesn't have sufficient resources to allocate a new process, the call fails and returns undef. File descriptors (and sometimes locks on those descriptors) are shared, while everything else is copied--or at least made to look that way.

In versions of Perl prior to 5.6, unflushed buffers remain unflushed in both processes, which means you may need to set $| on one or more filehandles earlier in the program to avoid duplicate output.

A nearly bulletproof way to launch a child process while checking for "cannot fork" errors would be:

use Errno qw(EAGAIN);
FORK: {
    if ($pid = fork) {
        # parent here
        # child process pid is available in $pid
    }
        elsif (defined $pid) { # $pid is zero here if defined
        # child here
        # parent process pid is available with getppid
    }
        elsif ($! == EAGAIN) {
        # EAGAIN is the supposedly recoverable fork error
        sleep 5;
        redo FORK;
    }
        else {
        # weird fork error
        die "Can't fork: $!\n";
    }
}
These precautions are not necessary on operations that do an implicit fork(2), such as system, backticks, or opening a process as a filehandle, because Perl automatically retries a fork on a temporary failure when it's doing the fork for you. Be careful to end the child code with an exit, or else your child will inadvertently leave the conditional block and start executing code intended only for the parent process.

If you fork without ever waiting on your children, you will accumulate zombies (exited processes whose parents haven't waited on them yet). On some systems, you can avoid this by setting $SIG{CHLD} to "IGNORE"; on most, you must wait for your moribund children. See the wait function for examples of doing this, or see the "Signals" section of Chapter 16, "Interprocess Communication" for more on SIGCHLD.

If a forked child inherits system file descriptors like STDIN and STDOUT that are connected to a remote pipe or socket, you may have to reopen these in the child to /dev/null. That's because even when the parent process exits, the child will live on with its copies of those filehandles. The remote server (such as, say, a CGI script or a background job launched from a remote shell) will appear to hang because it's still waiting for all copies to be closed. Reopening the system filehandles to something else fixes this.

On most systems supporting fork(2), great care has gone into making it extremely efficient (for example, using copy-on-write technology on data pages), making it the dominant paradigm for multitasking over the last few decades. The fork function is unlikely to be implemented efficiently, or perhaps at all, on systems that don't resemble Unix. For example, Perl 5.6 emulates a proper fork even on Microsoft systems, but no assurances can be made on performance at this point. You might have more luck there with the Win32::Process module.

29.2.41. format

format NAME =
    picture line
    value list
    ...
.
This function declares a named sequence of picture lines (with associated values) for use by the write function. If NAME is omitted, the name defaults to STDOUT, which happens to be the default format name for the STDOUT filehandle. Since, like a sub declaration, this is a package-global declaration that happens at compile time, any variables used in the value list need to be visible at the point of the format's declaration. That is, lexically scoped variables must be declared earlier in the file, while dynamically scoped variables merely need to be set at the time write is called. Here's an example (which assumes we've already calculated $cost and $quantity):
my $str = "widget";               # Lexically scoped variable.

format Nice_Output =
Test: @<<<<<<<< @||||| @>>>>>
      $str,     $%,    '$' . int($num)
.

local $~ = "Nice_Output";         # Select our format.
local $num = $cost * $quantity;   # Dynamically scoped variable.

write;
Like filehandles, format names are identifiers that exist in a symbol table (package) and may be fully qualified by package name. Within the typeglobs of a symbol table's entries, formats reside in their own namespace, which is distinct from filehandles, directory handles, scalars, arrays, hashes, and subroutines. Like those other six types, however, a format named Whatever would also be affected by a local on the *Whatever typeglob. In other words, a format is just another gadget contained in a typeglob, independent of the other gadgets.

The "Format Variables" section in Chapter 7, "Formats" contains numerous details and examples of their use. Chapter 28, "Special Names" describes the internal format-specific variables, and the English and IO::Handle modules provide easier access to them.

29.2.42. formline

formline PICTURE, LIST
This is an internal function used by formats, although you may also call it yourself. It always returns true. It formats a list of values according to the contents of PICTURE, placing the output into the format output accumulator, $^A (or $ACCUMULATOR if you use the English module). Eventually, when a write is done, the contents of $^A are written to some filehandle, but you could also read $^A yourself and then set $^A back to "". A format typically does one formline per line of form, but the formline function itself doesn't care how many newlines are embedded in the PICTURE. This means that the ~ and ~~ tokens will treat the entire PICTURE as a single line. You may therefore need to use multiple formlines to implement a single record-format, just as the format compiler does internally.

Be careful if you put double quotes around the picture, since an @ character may be taken to mean the beginning of an array name. See "Formats" in Chapter 6, "Subroutines" for example uses.

29.2.43. getc

getc FILEHANDLE
getc
This function returns the next byte from the input file attached to FILEHANDLE. It returns undef at end-of-file, or if an I/O error was encountered. If FILEHANDLE is omitted, the function reads from STDIN.

This function is somewhat slow, but occasionally useful for single-character (byte, really) input from the keyboard--provided you manage to get your keyboard input unbuffered. This function requests unbuffered input from the standard I/O library. Unfortunately, the standard I/O library is not so standard as to provide a portable way to tell the underlying operating system to supply unbuffered keyboard input to the standard I/O system. To do that, you have to be slightly more clever, and in an operating-system-dependent fashion. Under Unix you might say this:

if ($BSD_STYLE) {
  system "stty cbreak </dev/tty >/dev/tty 2>&1";
} else {
  system "stty", "-icanon", "eol", "\001";
}

$key = getc;

if ($BSD_STYLE) {
  system "stty -cbreak </dev/tty >/dev/tty 2>&1";
} else {
  system "stty", "icanon", "eol", "^@"; # ASCII NUL
}
print "\n";
This code puts the next character (byte) typed on the terminal in the string $key. If your stty program has options like cbreak, you'll need to use the code where $BSD_STYLE is true. Otherwise, you'll need to use the code where it is false. Determining the options for stty(1) is left as an exercise to the reader.

The POSIX module provides a more portable version of this using the POSIX::getattr function. See also the Term::ReadKey module from your nearest CPAN site for a more portable and flexible approach.

29.2.44. getgrent

getgrent
setgrent
endgrent
These routines iterate through your /etc/group file (or maybe someone else's /etc/group file, if it's coming from a server somewhere). The return value from getgrent in list context is:
($name, $passwd, $gid, $members)
where $members contains a space-separated list of the login names of the members of the group. To set up a hash for translating group names to GIDs, say this:
while (($name, $passwd, $gid) = getgrent) {
    $gid{$name} = $gid;
}
In scalar context, getgrent returns only the group name. The standard User::grent module supports a by-name interface to this function. See getgrent(3).

29.2.45. getgrgid

getgrgid GID
This function looks up a group file entry by group number. The return value in list context is:
($name, $passwd, $gid, $members)
where $members contains a space-separated list of the login names of the members of the group. If you want to do this repeatedly, consider caching the data in a hash using getgrent.

In scalar context, getgrgid returns only the group name. The User::grent module supports a by-name interface to this function. See getgrgid(3).

29.2.46. getgrnam

getgrnam NAME
This function looks up a group file entry by group name. The return value in list context is:
($name, $passwd, $gid, $members)
where $members contains a space-separated list of the login names of the members of the group. If you want to do this repeatedly, consider caching the data in a hash using getgrent.

In scalar context, getgrnam returns only the numeric group ID. The User::grent module supports a by-name interface to this function. See getgrnam(3).

29.2.47. gethostbyaddr

gethostbyaddr ADDR, ADDRTYPE
This function translates addresses into names (and alternate addresses). ADDR should be a packed binary network address, and ADDRTYPE should in practice usually be AF_INET (from the Socket module). The return value in list context is:
($name, $aliases, $addrtype, $length, @addrs) =
    gethostbyaddr($packed_binary_address, $addrtype);
where @addrs is a list of packed binary addresses. In the Internet domain, each address is (historically) four bytes long, and can be unpacked by saying something like:
($a, $b, $c, $d) = unpack('C4', $addrs[0]);
Alternatively, you can convert directly to dot vector notation with the v modifier to sprintf:
$dots = sprintf "%vd", $addrs[0];
The inet_ntoa function from the Socket module is useful for producing a printable version. This approach will become important if and when we all ever manage to switch over to IPv6.
use Socket;
$printable_address = inet_ntoa($addrs[0]);
In scalar context, gethostbyaddr returns only the host name.

To produce an ADDR from a dot vector, say this:

use Socket;
$ipaddr = inet_aton("127.0.0.1");       # localhost
$claimed_hostname = gethostbyaddr($ipaddr, AF_INET);
Interestingly, with version 5.6 of Perl you can skip the inet_aton() and use the new v-string notation that was invented for version numbers but happens to work for IP addresses as well:
$ipaddr = v127.0.0.1;
See the section "Sockets" in Chapter 16, "Interprocess Communication" for more examples. The Net::hostent module supports a by-name interface to this function. See gethostbyaddr(3).

29.2.48. gethostbyname

gethostbyname NAME
This function translates a network hostname to its corresponding addresses (and other names). The return value in list context is:
($name, $aliases, $addrtype, $length, @addrs) =
    gethostbyname($remote_hostname);
where @addrs is a list of raw addresses. In the Internet domain, each address is (historically) four bytes long, and can be unpacked by saying something like:
($a, $b, $c, $d) = unpack('C4', $addrs[0]);
You can convert directly to vector notation with the v modifier to sprintf:
$dots = sprintf "%vd", $addrs[0];
In scalar context, gethostbyname returns only the host address:
use Socket;
$ipaddr = gethostbyname($remote_host);
printf "%s has address %s\n",
    $remote_host, inet_ntoa($ipaddr);
See "Sockets" in Chapter 16, "Interprocess Communication" for another approach. The Net::hostent module supports a by-name interface to this function. See also gethostbyname(3).

29.2.49. gethostent

gethostent
sethostent STAYOPEN
endhostent
These functions iterate through your /etc/hosts file and return each entry one at a time. The return value from gethostent is:
($name, $aliases, $addrtype, $length, @addrs)
where @addrs is a list of raw addresses. In the Internet domain, each address is four bytes long, and can be unpacked by saying something like:
($a, $b, $c, $d) = unpack('C4', $addrs[0]);
Scripts that use gethostent should not be considered portable. If a machine uses a name server, it would have to interrogate most of the Internet to try to satisfy a request for all the addresses of every machine on the planet. So gethostent is unimplemented on such machines. See gethostent(3) for other details.

The Net::hostent module supports a by-name interface to this function.

29.2.50. getlogin

getlogin
This function returns the current login name if found. On Unix systems, this is read from the utmp(5) file. If it returns false, use getpwuid instead. For example:
$login = getlogin() || (getpwuid($<))[0] || "Intruder!!";

29.2.51. getnetbyaddr

getnetbyaddr ADDR, ADDRTYPE
This function translates a network address to the corresponding network name or names. The return value in list context is:
use Socket;
($name, $aliases, $addrtype, $net) = getnetbyaddr(127, AF_INET);
In scalar context, getnetbyaddr returns only the network name. The Net::netent module supports a by-name interface to this function. See getnetbyaddr(3).

29.2.52. getnetbyname

getnetbyname NAME
This function translates a network name to its corresponding network address. The return value in list context is:
($name, $aliases, $addrtype, $net) = getnetbyname("loopback");
In scalar context, getnetbyname returns only the network address. The Net::netent module supports a by-name interface to this function. See getnetbyname(3).

29.2.53. getnetent

getnetent
setnetent STAYOPEN
endnetent
These functions iterate through your /etc/networks file. The return value in list context is:
($name, $aliases, $addrtype, $net) = getnetent();
In scalar context, getnetent returns only the network name. The Net::netent module supports a by-name interface to this function. See getnetent(3).

The concept of network names seems rather quaint these days; most IP addresses are on unnamed (and unnameable) subnets.

29.2.54. getpeername

getpeername SOCKET
This function returns the packed socket address of the other end of the SOCKET connection. For example:

use Socket;
$hersockaddr      = getpeername SOCK;
($port, $heraddr) = sockaddr_in($hersockaddr);
$herhostname      = gethostbyaddr($heraddr, AF_INET);
$herstraddr       = inet_ntoa($heraddr);

29.2.55. getpgrp

getpgrp PID
This function returns the current process group for the specified PID (use a PID of 0 for the current process). Invoking getpgrp will raise an exception if used on a machine that doesn't implement getpgrp(2). If PID is omitted, the function returns the process group of the current process (the same as using a PID of 0). On systems implementing this operator with the POSIX getpgrp(2) syscall, PID must be omitted or, if supplied, must be 0.

29.2.56. getppid

getppid
This function returns the process ID of the parent process. On the typical Unix system, if your parent process ID changes to 1, it means your parent process has died and you've been adopted by the init(8) program.

29.2.57. getpriority

getpriority WHICH, WHO
This function returns the current priority for a process, a process group, or a user. See getpriority(2). Invoking getpriority will raise an exception if used on a machine that doesn't implement getpriority(2).

The BSD::Resource module from CPAN provides a more convenient interface, including the PRIO_PROCESS, PRIO_PGRP, and PRIO_USER symbolic constants to supply for the WHICH argument. Although these are traditionally set to 0, 1, and 2 respectively, you really never know what may happen within the dark confines of C's #include files.

A value of 0 for WHO means the current process, process group, or user, so to get the priority of the current process, use:

$curprio = getpriority(0, 0);

29.2.58. getprotobyname

getprotobyname NAME
This function translates a protocol name to its corresponding number. The return value in list context is:
($name, $aliases, $protocol_number) = getprotobyname("tcp");
When called in scalar context, getprotobyname returns only the protocol number. The Net::proto module supports a by-name interface to this function. See getprotobyname(3).

29.2.59. getprotobynumber

getprotobynumber NUMBER
This function translates a protocol number to its corresponding name. The return value in list context is:
($name, $aliases, $protocol_number) = getprotobynumber(6);
When called in scalar context, getprotobynumber returns only the protocol name. The Net::proto module supports a by-name interface to this function. See getprotobynumber(3).

29.2.60. getprotoent

getprotoent
setprotoent STAYOPEN
endprotoent
These functions iterate through the /etc/protocols file. In list context, the return value from getprotoent is:
($name, $aliases, $protocol_number) = getprotoent();
When called in scalar context, getprotoent returns only the protocol name. The Net::proto module supports a by-name interface to this function. See getprotent(3).

29.2.61. getpwent

getpwent
setpwent
endpwent
These functions conceptually iterate through your /etc/passwd file, though this may involve the /etc/shadow file if you're the superuser and are using shadow passwords, or NIS (née YP) or NIS+ if you're using either of those. The return value in list context is:
($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwent();
Some machines may use the quota and comment fields for other than their named purposes, but the remaining fields will always be the same. To set up a hash for translating login names to UIDs, say this:
while (($name, $passwd, $uid) = getpwent()) {
    $uid{$name} = $uid;
}
In scalar context, getpwent returns only the username. The User::pwent module supports a by-name interface to this function. See getpwent(3).

29.2.62. getpwnam

getpwnam NAME
This function translates a username to the corresponding /etc/passwd file entry. The return value in list context is:
($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwnam("daemon");
On systems that support shadow passwords, you will have to be the superuser to retrieve the actual password. Your C library should notice that you're suitably empowered and open the /etc/shadow file (or wherever it keeps the shadow file). At least, that's how it's supposed to work. Perl will try to do this if your C library is too stupid to notice.

For repeated lookups, consider caching the data in a hash using getpwent.

In scalar context, getpwnam returns only the numeric user ID. The User::pwent module supports a by-name interface to this function. See getpwnam(3) and passwd(5).

29.2.63. getpwuid

getpwuid UID
This function translates a numeric user ID to the corresponding /etc/passwd file entry. The return value in list context is:
($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwuid(2);
For repeated lookups, consider caching the data in a hash using getpwent.

In scalar context, getpwuid returns the username. The User::pwent module supports a by-name interface to this function. See getpwnam(3) and passwd(5).

29.2.64. getservbyname

getservbyname NAME, PROTO
This function translates a service (port) name to its corresponding port number. PROTO is a protocol name such as "tcp". The return value in list context is:
($name, $aliases, $port_number, $protocol_name) = getservbyname("www", "tcp");
In scalar context, getservbyname returns only the service port number. The Net::servent module supports a by-name interface to this function. See getservbyname(3).

29.2.65. getservbyport

getservbyport PORT, PROTO
This function translates a service (port) number to its corresponding names. PROTO is a protocol name such as "tcp". The return value in list context is:
($name, $aliases, $port_number, $protocol_name) = getservbyport(80, "tcp");
In scalar context, getservbyport returns only the service name. The Net::servent module supports a by-name interface to this function. See getservbyport(3).

29.2.66. getservent

getservent
setservent STAYOPEN
endservent
This function iterates through the /etc/services file or its equivalent. The return value in list context is:
($name, $aliases, $port_number, $protocol_name) = getservent();
In scalar context, getservent returns only the service port name. The Net::servent module supports a by-name interface to this function. See getservent(3).

29.2.67. getsockname

getsockname SOCKET
This function returns the packed socket address of this end of the SOCKET connection. (And why wouldn't you know your own address already? Maybe because you bound an address containing wildcards to the server socket before doing an accept and now you need to know what interface someone used to connect to you. Or you were passed a socket by your parent process--inetd, for example.)
use Socket;
$mysockaddr = getsockname(SOCK);
($port, $myaddr) = sockaddr_in($mysockaddr);
$myname = gethostbyaddr($myaddr,AF_INET);
printf "I am %s [%vd]\n", $myname, $myaddr;

29.2.68. getsockopt

getsockopt SOCKET, LEVEL, OPTNAME
This function returns the socket option requested, or undef if there is an error. See setsockopt for more information.

29.2.69. glob

glob EXPR
glob
This function returns the value of EXPR with filename expansions such as a shell would do. This is the internal function implementing the <*> operator.

For historical reasons, the algorithm matches the csh(1)'s style of expansion, not the Bourne shell's. Versions of Perl before the 5.6 release used an external process, but 5.6 and later perform globs internally. Files whose first character is a dot (".") are ignored unless this character is explicitly matched. An asterisk ("*") matches any sequence of any character (including none). A question mark ("?") matches any one character. A square bracket sequence ("[...]") specifies a simple character class, like "[chy0-9]". Character classes may be negated with a circumflex, as in "*.[^oa]", which matches any non-dot files whose names contain a period followed by one character which is neither an "a" nor an "o" at the end of the name. A tilde ("~") expands to a home directory, as in "~/.*rc" for all the current user's "rc" files, or "~jane/Mail/*" for all of Jane's mail files. Braces may be used for alternation, as in "~/.{mail,ex,csh,twm,}rc" to get those particular rc files.

If you want to glob filenames that might contain whitespace, you'll need to use the File::Glob module directly, since glob grandfathers the use of whitespace to separate multiple patterns such as <*.c *.h>. For details, see File::Glob in Chapter 32, "Standard Modules". Calling glob (or the <*> operator) automatically uses that module, so if the module mysteriously vaporizes from your library, an exception is raised.

When you call open, Perl does not expand wildcards, including tildes. You need to glob the result first.

open(MAILRC, "~/.mailrc")                # WRONG: tilde is a shell thing
    or die "can't open ~/.mailrc: $!";

open(MAILRC, (glob("~/.mailrc"))[0])     # expand tilde first
    or die "can't open ~/.mailrc: $!";
The glob function is not related to the Perl notion of typeglobs, other than that they both use a * to represent multiple items.

See also the "Filename globbing operator" section of Chapter 2, "Bits and Pieces".

29.2.70. gmtime

gmtime EXPR
gmtime
This function converts a time as returned by the time function to a nine-element list with the time correct for the Greenwich time zone (a.k.a. GMT, or UTC, or even Zulu in certain cultures, not including the Zulu culture, oddly enough). It's typically used as follows:
#  0    1    2     3     4    5     6     7     8
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
If, as in this case, the EXPR is omitted, it does gmtime(time()). The Perl library module Time::Local contains a subroutine, timegm, that can convert the list back into a time value.

All list elements are numeric and come straight out of a struct tm (that's a C programming structure--don't sweat it). In particular this means that $mon has the range 0..11 with January as month 0, and $wday has the range 0..6 with Sunday as day 0. You can remember which ones are zero-based because those are the ones you're always using as subscripts into zero-based arrays containing month and day names.

For example, to get the current month in London, you might say:

$london_month = (qw(Jan Feb Mar Apr May Jun
                    Jul Aug Sep Oct Nov Dec))[(gmtime)[4]];
$year is the number of years since 1900; that is, in year 2023, $year is 123, not simply 23. To get the 4-digit year, just say $year + 1900. To get the 2-digit year (for example "01" in 2001), use sprintf("%02d", $year % 100).

In scalar context, gmtime returns a ctime(3)-like string based on the GMT time value. The Time::gmtime module supports a by-name interface to this function. See also POSIX::strftime() for a more fine-grained approach to formatting times.

This scalar value is not locale dependent but is instead a Perl built-in. Also see the Time::Local module and the strftime(3) and mktime(3) functions available via the POSIX module. To get somewhat similar but locale-dependent date strings, set up your locale environment variables appropriately (please see the perllocale manpage), and try:

use POSIX qw(strftime);
$now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
The %a and %b escapes, which represent the short forms of the day of the week and the month of the year, may not necessarily be three characters wide in all locales.

29.2.71. goto

goto LABEL
goto EXPR
goto &NAME
goto LABEL finds the statement labeled with LABEL and resumes execution there. If the LABEL cannot be found, an exception is raised. It cannot be used to go into any construct that requires initialization, such as a subroutine or a foreach loop. It also can't be used to go into a construct that is optimized away. It can be used to go almost anywhere else within the dynamic scope,[4] including out of subroutines, but for that purpose it's usually better to use some other construct such as last or die. The author of Perl has never felt the need to use this form of goto (in Perl, that is--C is another matter).

[4]This means that if it doesn't find the label in the current routine, it looks back through the routines that called the current routine for the label, thus making it nearly impossible to maintain your program.

Going to even greater heights of orthogonality (and depths of idiocy), Perl allows goto EXPR, which expects EXPR to evaluate to a label name, whose location is guaranteed to be unresolvable until run time since the label is unknown when the statement is compiled. This allows for computed gotos per FORTRAN, but isn't necessarily recommended[5] if you're optimizing for maintainability:

goto +("FOO", "BAR", "GLARCH")[$i];
The unrelated goto&NAME is highly magical, substituting a call to the named subroutine for the currently running subroutine. This construct may be used without shame by AUTOLOAD subroutines that wish to load another subroutine and then pretend that this new subroutine--and not the original one--had been called in the first place (except that any modifications to @_ in the original subroutine are propagated to the replacement subroutine). After the goto, not even caller will be able to tell that the original AUTOLOAD routine was called first.

[5] Understatement is reputed to be funny, so we thought we'd try one here.

29.2.72. grep

grep EXPR, LIST
grep BLOCK LIST
This function evaluates EXPR or BLOCK in Boolean context for each element of LIST, temporarily setting $_ to each element in turn, much like the foreach construct. In list context, it returns a list of those elements for which the expression is true. (The operator is named after a beloved Unix program that extracts lines out of a file that match a particular pattern. In Perl, the expression is often a pattern, but doesn't have to be.) In scalar context, grep returns the number of times the expression was true.

If @all_lines contains lines of code, this example weeds out comment lines:

@code_lines = grep !/^\s*#/, @all_lines;
Because $_ is an implicit alias to each list value, altering $_ will modify the elements of the original list. While this is useful and supported, it can occasionally cause bizarre results if you aren't expecting it. For example:
@list = qw(barney fred dino wilma);
@greplist = grep { s/^[bfd]// } @list;
@greplist is now "arney", "red", "ino", but @list is now "arney", "red", "ino", "wilma"! Ergo, Caveat Programmor.

See also map. The following two statements are functionally equivalent:

@out = grep { EXPR } @in;
@out = map { EXPR ? $_ : () } @in

29.2.73. hex

hex EXPR
hex
This function interprets EXPR as a hexadecimal string and returns the equivalent decimal value. A leading "0x" is ignored, if present. To interpret strings that might start with any of 0, 0b, or 0x, see oct. The following code sets $number to 4,294,906,560:
$number = hex("ffff12c0");
To do the inverse function, use sprintf:
sprintf "%lx", $number;         # (That's an ell, not a one.)
Hex strings may only represent integers. Strings that would cause integer overflow trigger a warning.

29.2.74. import

import CLASSNAME LIST
import CLASSNAME
There is no built-in import function. It is merely an ordinary class method defined (or inherited) by modules that wish to export names to another module through the use operator. See use for details.

29.2.75. index

index STR, SUBSTR, OFFSET
index STR, SUBSTR
This function searches for one string within another. It returns the position of the first occurrence of SUBSTR in STR. The OFFSET, if specified, says how many characters from the start to skip before beginning to look. Positions are based at 0 (or whatever you've set the subscript base $[ variable to--but don't do that). If the substring is not found, the function returns one less than the base, ordinarily -1. To work your way through a string, you might say:
$pos = -1;
while (($pos = index($string, $lookfor, $pos)) > -1) {
    print "Found at $pos\n";
    $pos++;
}

29.2.76. int

int EXPR
int
This function returns the integer portion of EXPR. If you're a C programmer, you're apt to forget to use int in conjunction with division, which is a floating-point operation in Perl:
$average_age = 939/16;      # yields 58.6875 (58 in C)
$average_age = int 939/16;  # yields 58
You should not use this function for generic rounding, because it truncates towards 0 and because machine representations of floating-point numbers can sometimes produce counterintuitive results. For example, int(-6.725/0.025) produces -268 rather than the correct -269; that's because the value is really more like -268.99999999999994315658. Usually, the sprintf, printf, or the POSIX::floor and POSIX::ceil functions will serve you better than will int.
$n = sprintf("%.0f", $f);   # round (not trunc) to nearest integer

29.2.77. ioctl

ioctl FILEHANDLE, FUNCTION, SCALAR
This function implements the ioctl(2) syscall which controls I/O. To get the correct function definitions, first you'll probably have to say:
require "sys/ioctl.ph";     # perhaps /usr/local/lib/perl/sys/ioctl.ph
If sys/ioctl.ph doesn't exist or doesn't have the correct definitions, you'll have to roll your own based on your C header files such as sys/ioctl.h. (The Perl distribution includes a script called h2ph to help you do this, but running it is nontrivial.) SCALAR will be read or written (or both) depending on the FUNCTION--a pointer to the string value of SCALAR will be passed as the third argument of the actual ioctl(2) call. (If SCALAR has no string value but does have a numeric value, that value will be passed directly rather than a pointer to the string value.) The pack and unpack functions are useful for manipulating the values of structures used by ioctl. The following example determines how many bytes are available for reading using the FIONREADioctl:
require 'sys/ioctl.ph';

$size = pack("L", 0);
ioctl(FH, FIONREAD(), $size)
    or die "Couldn't call ioctl: $!\n";
$size = unpack("L", $size);
If h2ph wasn't installed or doesn't work for you, you can grep the include files by hand or write a small C program to print out the value.

The return value of ioctl (and fcntl) is as follows:

Syscall Returns | Perl Returns
-1 | undef
0 | String "0 but true"
Anything else | That number

Thus Perl returns true on success and false on failure, yet you can still easily determine the actual value returned by the operating system:

$retval = ioctl(...) || -1;
printf "ioctl actually returned %d\n", $retval;
The special string "0 but true" is exempt from -w complaints about improper numeric conversions.

Calls to ioctl should not be considered portable. If, say, you're merely turning off echo once for the whole script, it's more portable to say:

system "stty -echo";   # Works on most Unix boxen.
Just because you can do something in Perl doesn't mean you ought to. To quote the Apostle Paul, "Everything is permissible--but not everything is beneficial."

For still better portability, you might look at the Term::ReadKey module from CPAN.

29.2.78. join

join EXPR, LIST
This function joins the separate strings of LIST into a single string with fields separated by the value of EXPR, and returns the string. For example:
$rec = join ':', $login,$passwd,$uid,$gid,$gcos,$home,$shell;
To do the opposite, see split. To join things together into fixed-position fields, see pack. The most efficient way to concatenate many strings together is to join them with a null string:
$string = join "", @array;
Unlike split, join doesn't take a pattern as its first argument, and will produce a warning if you try.

29.2.79. keys

keys HASH
This function returns a list consisting of all the keys of the indicated HASH. The keys are returned in an apparently random order, but it is the same order produced by either the values or each function (assuming the hash has not been modified between calls). As a side effect, it resets HASH's iterator. Here is a (rather cork-brained) way to print your environment:
@keys   = keys   %ENV;    # keys are in the same order as
@values = values %ENV;    # values, as this demonstrates
while (@keys) {
    print pop(@keys), '=', pop(@values), "\n";
}
You're more likely to want to see the environment sorted by keys:
foreach $key (sort keys %ENV) {
    print $key, '=', $ENV{$key}, "\n";
}
You can sort the values of a hash directly, but that's somewhat useless in the absence of any way to map the values back to the keys. To sort a hash by value, you generally need to sort the keys by providing a comparison function that accesses the values based on the keys. Here's a descending numeric sort of a hash by its values:
foreach $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) {
    printf "%4d %s\n", $hash{$key}, $key;
}
Using keys on a hash bound to a largish DBM file will produce a largish list, causing you to have a largish process. You might prefer to use the each function here, which will iterate over the hash entries one by one without slurping them all into a single gargantuan list.

In scalar context, keys returns the number of elements of the hash (and resets the each iterator). However, to get this information for tied hashes, including DBM files, Perl must walk the entire hash, so it's not efficient then. Calling keys in a void context helps with that.

Used as an lvalue, keys increases the number of hash buckets allocated for the given hash. (This is similar to pre-extending an array by assigning a larger number to $#array.) Pre-extending your hash can gain a measure of efficiency if you happen to know the hash is going to get big, and how big it's going to get. If you say:

keys %hash = 1000;
then %hash will have at least 1000 buckets allocated for it (you get 1024 buckets, in fact, since it rounds up to the next power of two). You can't shrink the number of buckets allocated for the hash using keys in this way (but you needn't worry about doing this by accident, as trying has no effect). The buckets will be retained even if you do %hash = (). Use undef %hash if you want to free the storage while %hash is still in scope.

See also each, values, and sort.

29.2.80. kill

kill SIGNAL, LIST
This function sends a signal to a list of processes. For SIGNAL, you may use either an integer or a quoted signal name (without a "SIG" on the front). Trying to use an unrecognized SIGNAL name raises an exception. The function returns the number of processes successfully signalled. If SIGNAL is negative, the function kills process groups instead of processes. (On SysV, a negative process number will also kill process groups, but that's not portable.) A PID of zero sends the signal to all processes of the same group ID as the sender. For example:

$cnt = kill 1, $child1, $child2;
kill 9, @goners;
kill 'STOP', getppid       # Can *so* suspend my login shell...
        unless getppid == 1;    # (But don't taunt init(8).)
A SIGNAL of 0 tests whether a process is still alive and that you still have permission to signal it. No signal is sent. This way you can check whether the process is still alive and hasn't changed its UID.
use Errno qw(ESRCH EPERM);
if (kill 0 => $minion) {
    print "$minion is alive!\n";
} elsif ($! == EPERM) {             # changed UID
    print "$minion has escaped my control!\n";
} elsif ($! == ESRCH) {
    print "$minion is deceased.\n";  # or zombied
} else {
    warn "Odd; I couldn't check on the status of $minion: $!\n";
}

See the section "Signals" in Chapter 16, "Interprocess Communication".

29.2.81. last

last LABEL
last
The last operator immediately exits the loop in question, just like the break statement in C or Java (as used in loops). If the LABEL is omitted, the operator refers to the innermost enclosing loop. The continue block, if any, is not executed.
LINE: while (<MAILMSG>) {
    last LINE if /^$/; # exit when done with header
    # rest of loop here
}
last cannot be used to exit a block which returns a value, such as eval {}, sub {}, or do {}, and should not be used to exit a grep or map operation. With warnings enabled, Perl will warn you if you last out of a loop that's not in your current lexical scope, such as a loop in a calling subroutine.

A block by itself is semantically identical to a loop that executes once. Thus last can be used to effect an early exit out of such a block.

See also Chapter 4, "Statements and Declarations" for illustrations of how last, next, redo, and continue work.

29.2.82. lc

lc EXPR
lc
This function returns a lowercased version of EXPR. This is the internal function implementing the \L escape in double-quoted strings. Your current LC_CTYPE locale is respected if use locale is in effect, though how locales interact with Unicode is still a topic of ongoing research, as they say. See the perllocale manpage for the most recent results.

29.2.83. lcfirst

lcfirst EXPR
lcfirst
This function returns a version of EXPR with the first character lowercased. This is the internal function implementing the \l escape in double-quoted strings. Your current LC_CTYPE locale is respected if you use locale and if we figure out how that relates to Unicode.

29.2.84. length

length EXPR
length
This function returns the length in characters of the scalar value EXPR. If EXPR is omitted, it returns the length of $_. (But be careful that the next thing doesn't look like the start of an EXPR, or Perl's lexer will get confused. For example, length < 10 won't compile. When in doubt, use parentheses.)

Do not try to use length to find the size of an array or hash. Use scalar @array for the size of an array, and scalar keys %hash for the number of key/value pairs in a hash. (The scalar is typically omitted when redundant.)

To find the length of a string in bytes rather than characters, say:

$blen = do { use bytes; length $string; };
or:
$blen = bytes::length($string);    # must use bytes first

29.2.85. link

link OLDFILE, NEWFILE
This function creates a new filename linked to the old filename. The function returns true for success, false otherwise. See also symlink later in this chapter. This function is unlikely to be implemented on non-Unix-style filesystems.

29.2.86. listen

listen SOCKET, QUEUESIZE
This function tells the system that you're going to be accepting connections on this SOCKET and that the system can queue the number of waiting connections specified by QUEUESIZE. Imagine having call-waiting on your phone, with up to 17 callers queued. (Gives me the willies!) The function returns true if it succeeded, false otherwise.
use Socket;
listen(PROTOSOCK, SOMAXCONN)
    or die "cannot set listen queue on PROTOSOCK: $!";
See accept. See also the section "Sockets" in Chapter 16, "Interprocess Communication". See listen(2).

29.2.87. local

local EXPR
This operator does not create a local variable; use my for that. Instead, it localizes existing variables; that is, it causes one or more global variables to have locally scoped values within the innermost enclosing block, eval, or file. If more than one variable is listed, the list must be placed in parentheses because the operator binds more tightly than commas. All listed variables must be legal lvalues, that is, something you could assign to; this can include individual elements of arrays or hashes.

This operator works by saving the current values of the specified variables on a hidden stack and restoring them upon exiting the block, subroutine, eval, or file. After the local is executed, but before the scope is exited, any subroutines and executed formats will see the local, inner value, instead of the previous, outer value because the variable is still a global variable, despite having a localized value. The technical term for this is "dynamic scoping". See the section "Scoped Declarations" in Chapter 4, "Statements and Declarations".

The EXPR may be assigned to if desired, which allows you to initialize your variables as you localize them. If no initializer is given, all scalars are initialized to undef, and all arrays and hashes to (). As with ordinary assignment, if you use parentheses around the variables on the left (or if the variable is an array or hash), the expression on the right is evaluated in list context. Otherwise, the expression on the right is evaluated in scalar context.

In any event, the expression on the right is evaluated before the localization, but the initialization happens after localization, so you can initialize a localized variable with its nonlocalized value. For instance, this code demonstrates how to make a temporary modification to a global array:

if ($sw eq '-v') {
    # init local array with global array
    local @ARGV = @ARGV;
    unshift @ARGV, 'echo';
    system @ARGV;
}
# @ARGV restored
You can also temporarily modify global hashes:
# temporarily add a couple of entries to the %digits hash
if ($base12) {
    # (NOTE: We're not claiming this is efficient!)
    local(%digits) = (%digits, T => 10, E => 11);
    parse_num();
}
You can use local to give temporary values to individual elements of arrays and hashes, even lexically scoped ones:
if ($protected) {
    local $SIG{INT} = 'IGNORE';
    precious();     # no interrupts during this function
}                   # previous handler (if any) restored
You can also use local on typeglobs to create local filehandles without loading any bulky object modules:
local *MOTD;                # protect any global MOTD handle
my $fh = do { local *FH };  # create new indirect filehandle
(As of the 5.6 release of Perl, a plain my $fh; is good enough, because if you give an undefined variable where a real filehandle is expected, like the first argument to open or socket, Perl now autovivifies a brand new filehandle for you.)

But in general, you usually want to use my instead of local, because local isn't really what most people think of as "local", or even "lo-cal". See my.

29.2.88. localtime

localtime EXPR
localtime
This function converts the value returned by time to a nine-element list with the time corrected for the local time zone. It's typically used as follows:
#  0    1    2     3     4    5     6     7     8
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
If, as in this case, EXPR is omitted, it does localtime(time()).

All list elements are numeric and come straight out of a struct tm. (That's a bit of C programming lingo--don't worry about it.) In particular, this means that $mon has the range 0..11 with January as month 0, and $wday has the range 0..6 with Sunday as day 0. You can remember which ones are zero-based because those are the ones you're always using as subscripts into zero-based arrays containing month and day names.

For example, to get the name of the current day of the week:

$thisday = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[(localtime)[6]];
$year is the number of years since 1900, that is, in year 2023, $year is 123, not simply 23. To get the 4-digit year, just say $year + 1900. To get the 2-digit year (for example "01" in 2001), use sprintf("%02d", $year % 100).

The Perl library module Time::Local contains a subroutine, timelocal, that can convert in the opposite direction.

In scalar context, localtime returns a ctime(3)-like string. For example, the date(1) command can be (almost)[6] emulated with:

perl -le 'print scalar localtime'
See also the standard POSIX module's strftime function for a more fine-grained approach to formatting times. The Time::localtime module supports a by-name interface to this function.

[6]date(1) prints the timezone, whereas scalar localtime does not.

29.2.89. lock

lock THING
The lock function places a lock on a variable, subroutine, or object referenced by THING until the lock goes out of scope. For backward compatibility, this function is a built-in only if your version of Perl was compiled with threading enabled, and if you've said use Threads. Otherwise, Perl will assume this is a user-defined function. See Chapter 17, "Threads".

29.2.90. log

log EXPR
log
This function returns the natural logarithm (that is, base e) of EXPR. If EXPR is negative, it raises an exception. To get the log of another base, use basic algebra: the base-N log of a number is equal to the natural log of that number divided by the natural log of N. For example:
sub log10 {
    my $n = shift;
    return log($n)/log(10);
}
For the inverse of log, see exp.

29.2.91. lstat

lstat EXPR
lstat
This function does the same thing as Perl's stat function (including setting the special _ filehandle), but if the last component of the filename is a symbolic link, it stats the symbolic link itself instead of the file that the symbolic link points to. (If symbolic links are unimplemented on your system, a normal stat is done instead.)

29.2.92. m//

/PATTERN/
m/PATTERN/
This is the match operator, which interprets PATTERN as a regular expression. The operator is parsed as a double-quoted string rather than as a function. See Chapter 5, "Pattern Matching".

29.2.93. map

map BLOCK LIST
map EXPR, LIST
This function evaluates the BLOCK or EXPR for each element of LIST (locally setting $_ to each element) and returns the list comprising the results of each such evaluation. It evaluates BLOCK or EXPR in list context, so each element of LIST may map to zero, one, or more elements in the returned value. These are all flattened into one list. For instance:
@words = map { split ' ' } @lines;
splits a list of lines into a list of words. But often there is a one-to-one mapping between input values and output values:
@chars = map chr, @nums;
translates a list of numbers to the corresponding characters. And here's an example of a one-to-two mapping:
%hash = map { genkey($_) => $_ } @array;
which is just a funny functional way to write this:
%hash = ();
foreach $_ (@array) {
    $hash{genkey($_)} = $_;
}
Because $_ is an alias (implicit reference) into the list's values, this variable can be used to modify the elements of the array. This is useful and supported, although it can cause bizarre results if the LIST is not a named array. Using a regular foreach loop for this purpose may be clearer. See also grep; map differs from grep in that map returns a list consisting of the results of each successive evaluation of EXPR, whereas grep returns a list consisting of each value of LIST for which EXPR evaluates to true.

29.2.94. mkdir

mkdir FILENAME, MASK
mkdir FILENAME
This function creates the directory specified by FILENAME, giving it permissions specified by the numeric MASK as modified by the current umask. If the operation succeeds, it returns true; otherwise, it returns false.

If MASK is omitted, a mask of 0777 is assumed, which is almost always what you want anyway. In general, creating directories with permissive MASKs (like 0777) and letting the user modify that with their umask is better than supplying a restrictive MASK and giving the user no way to be more permissive. The exception to this rule is when the file or directory should be kept private (mail files, for instance). See umask.

If the mkdir(2) syscall is not built into your C library, Perl emulates it by calling the mkdir(1) program for each directory. If you are creating a long list of directories on such a system, it'll be more efficient to call the mkdir program yourself with the list of directories than it is to start zillions of subprocesses.

29.2.95. msgctl

msgctl ID, CMD, ARG
This function calls the System V IPC msgctl(2) syscall; see msgctl(2) for more details. You may have to useIPC::SysV first to get the correct constant definitions. If CMD is IPC_STAT, then ARG must be a variable that will hold the returned msqid_ds C structure. Return values are like ioctl and fcntl: undef for error, "0 but true" for zero, or the actual return value otherwise.

This function is available only on machines supporting System V IPC, which turns out to be far fewer than those supporting sockets.

29.2.96. msgget

msgget KEY, FLAGS
This function calls the System V IPC msgget(2) syscall. See msgget(2) for details. The function returns the message queue ID, or undef if there is an error. Before calling, you should useIPC::SysV.

This function is available only on machines supporting System V IPC.

29.2.97. msgrcv

msgrcv ID, VAR, SIZE, TYPE, FLAGS
This function calls the msgrcv(2) syscall to receive a message from message queue ID into variable VAR with a maximum message size of SIZE. See msgrcv(2) for details. When a message is received, the message type will be the first thing in VAR, and the maximum length of VAR is SIZE plus the size of the message type. The function returns true if successful, or false if there is an error. Before calling, you should useIPC::SysV.

This function is available only on machines supporting System V IPC.

29.2.98. msgsnd

msgsnd ID, MSG, FLAGS
This function calls the msgsnd(2) syscall to send the message MSG to the message queue ID. See msgsnd(2) for details. MSG must begin with the long integer message type. You can create a message like this:
$msg = pack "L a*", $type, $text_of_message;
The function returns true if successful, or false if there is an error. Before calling, useIPC::SysV.

This function is available only on machines supporting System V IPC.

29.2.99. my

my TYPE EXPR : ATTRIBUTES
my EXPR : ATTRIBUTES
my TYPE EXPR
my EXPR
This operator declares one or more private variables to exist only within the innermost enclosing block, subroutine, eval, or file. If more than one variable is listed, the list must be placed in parentheses because the operator binds more tightly than commas. Only simple scalars or complete arrays and hashes may be declared this way.

The variable name cannot be package qualified, because package variables are all globally accessible through their corresponding symbol table, and lexical variables are unrelated to any symbol table. Unlike local, then, this operator has nothing to do with global variables, other than hiding any other variable of the same name from view within its scope (that is, where the private variable exists). A global variable can always be accessed through its package-qualified form, however, or through a symbolic reference.

A private variable's scope does not start until the statement after its declaration. The variable's scope extends into any enclosed blocks thereafter, up to the end of the scope of the variable itself.

However, this means that any subroutines you call from within the scope of a private variable cannot see the private variable unless the block that defines the subroutine itself is also textually enclosed within the scope of that variable. That sounds complicated, but it's not once you get the hang of it. The technical term for this is lexical scoping, so we often call these lexical variables. In C culture, they're sometimes called "auto" variables, since they're automatically allocated and deallocated at scope entry and exit.

The EXPR may be assigned to if desired, which allows you to initialize your lexical variables. (If no initializer is given, all scalars are initialized to the undefined value and all arrays and hashes to the empty list.) As with ordinary assignment, if you use parentheses around the variables on the left (or if the variable is an array or hash), the expression on the right is evaluated in list context. Otherwise, the expression on the right is evaluated in scalar context. For example, you can name your formal subroutine parameters with a list assignment, like this:

my ($friends, $romans, $countrymen) = @_;
But be careful not to omit the parentheses indicating list assignment, like this:
my $country = @_;  # right or wrong?
This assigns the length of the array (that is, the number of the subroutine's arguments) to the variable, since the array is being evaluated in scalar context. You can profitably use scalar assignment for a formal parameter though, as long as you use the shift operator. In fact, since object methods are passed the object as the first argument, many method subroutines start off by "stealing" the first argument:
sub simple_as {
    my $self = shift;   # scalar assignment
    my ($a,$b,$c) = @_; # list assignment
    ...
}
If you attempt to declare a lexically scoped subroutine with my sub, Perl will die with the message that this feature has not been implemented yet. (Unless, of course, this feature has been implemented yet.)

The TYPE and ATTRIBUTES are optional, which is just as well, since they're both considered experimental. Here's what a declaration that uses them might look like:

my Dog $spot :ears(short) :tail(long);
The TYPE, if specified, indicates what kind of scalar or scalars are declared in EXPR, either directly as one or more scalar variables, or indirectly through an array or hash. If TYPE is the name of the class, the scalars will be assumed to contain references to objects of that type, or to objects compatible with that type. In particular, derived classes are considered compatible. That is, assuming Collie is derived from Dog, you might declare:
my Dog $lassie = new Collie;
Your declaration claims that you will use the $lassie object consistently with its being a Dog object. The fact that it's actually a Collie object shouldn't matter as long as you only try to do Dog things. Through the magic of virtual methods, the implementation of those Dog methods might well be in the Collie class, but the declaration above is only talking about the interface, not the implementation. In theory.

Interestingly, up through version 5.6.0, the only time Perl pays attention to the TYPE declaration is when the corresponding class has declared fields with the use fields pragma. Together, these declarations allow the pseudohash implementation of a class to "show through" to code outside the class, so that hash lookups can be optimized by the compiler into array lookups. In a sense, the pseudohash is the interface to such a class, so our theory remains intact, if a bit battered. For more on pseudohashes, see the section "Pseudohashes" in Chapter 8, "References".

In the future, other types of classes may interpret the TYPE differently. The TYPE declaration should be considered a generic type interface that might someday be instantiated in various ways depending on the class. In fact, the TYPE might not even be an official class name. We're reserving the lowercase type names for Perl, because one of the ways we'd like to extend the type interface is to allow optional low-level type declarations such as int, num, str, and ref. These declarations will not be for the purpose of strong typing; rather, they'll be hints to the compiler telling it to optimize the storage of the variable with the assumption that the variable will be used mostly as declared. The semantics of scalars will stay pretty much the same--you'll still be able to add two str scalars, or print an int scalar, just as though they were the ordinary polymorphic scalars you're familiar with. But with an int declaration Perl might decide to store only the integer value and forget about caching the resulting string as it currently does. Loops with int loop variables might run faster, particularly in code compiled down to C. In particular, arrays of numbers could be stored much more compactly. As a limiting case, the built-in vec function might even become obsolete when we can write declarations such as:

my bit @bitstring;

The ATTRIBUTES declaration is even more experimental. We haven't done much more than reserve the syntax and prototype the internal interface; see the use attributes pragma in Chapter 31, "Pragmatic Modules" for more on that. The first attribute we'll implement is likely to be constant:

my num $PI : constant = atan2(1,1) * 4;
But there are many other possibilities, such as establishing default values for arrays and hashes, or letting variables be shared among cooperating interpreters. Like the type interface, the attribute interface should be considered a generic interface, a kind of workbench for inventing new syntax and semantics. We do not know how Perl will evolve in the next 10 years. We only know that we can make it easier on ourselves by planning for that in advance.

See also local, our, and the section "Scoped Declarations" in Chapter 4, "Statements and Declarations".

29.2.100. new

new CLASSNAME LIST
new CLASSNAME
There is no built-in new function. It is merely an ordinary constructor method (that is, a user-defined subroutine) that is defined or inherited by the CLASSNAME class (that is, package) to let you construct objects of type CLASSNAME. Many constructors are named "new", but only by convention, just to trick C++ programmers into thinking they know what's going on. Always read the documentation of the class in question so you know how to call its constructors; for example, the constructor that creates a list box in the Tk widget set is just called Listbox(). See Chapter 12, "Objects".

29.2.101. next

next LABEL
next
The next operator is like the continue statement in C: it starts the next iteration of the loop designated by LABEL:
LINE: while (<STDIN>) {
    next LINE if /^#/;     # discard comments
    ...
}
If there were a continue block in this example, it would be executed immediately following the invocation of next. When LABEL is omitted, the operator refers to the innermost enclosing loop.

A block by itself is semantically identical to a loop that executes once. Thus, next will exit such a block early (via the continue block, if there is one).

next cannot be used to exit a block that returns a value, such as eval {}, sub {}, or do {}, and should not be used to exit a grep or map operation. With warnings enabled, Perl will warn you if you next out of a loop not in your current lexical scope, such as a loop in a calling subroutine. See the section "Loop Statements" in Chapter 4, "Statements and Declarations".

29.2.102. no

no MODULE LIST
See the use operator, which is the opposite of no, kind of. Most standard modules do not unimport anything, making no a no-op, as it were. The pragmatic modules tend to be more obliging here. If the MODULE cannot be found, an exception is raised.

29.2.103. oct

oct EXPR
oct
This function interprets EXPR as an octal string and returns the equivalent decimal value. If EXPR happens to start with "0x", it is interpreted as a hexadecimal string instead. If EXPR starts off with "0b", it is interpreted as a string of binary digits. The following will properly convert to numbers any input strings in decimal, binary, octal, and hex bases written in standard C or C++ notation:
$val = oct $val if $val =~ /^0/;
To perform the inverse function, use sprintf with an appropriate format:

$perms = (stat("filename"))[2] & 07777;
$oct_perms = sprintf "%lo", $perms;
The oct function is commonly used when a data string such as "644" needs to be converted into a file mode, for example. Although Perl will automatically convert strings into numbers as needed, this automatic conversion assumes base 10.

29.2.104. open

open FILEHANDLE, MODE, LIST
open FILEHANDLE, EXPR
open FILEHANDLE
The open function associates an internal FILEHANDLE with an external file specification given by EXPR or LIST. It may be called with one, two, or three arguments (or more if the third argument is a command, and you're running at least version 5.6.1 of Perl). If three or more arguments are present, the second argument specifies the access MODE in which the file should be opened, and the third argument (LIST) supplies the actual filename or the command to execute, depending on the mode. In the case of a command, additional arguments may be supplied if you wish to invoke the command directly without involving a shell, much like system or exec. Or the command may be supplied as a single argument (the third one), in which case the decision to invoke the shell depends on whether the command contains shell metacharacters. (Don't use more than three arguments if the arguments are ordinary filenames; it won't work.) If the MODE is not recognized, open raises an exception.

If only two arguments are present, the mode and filename/command are assumed to be combined in the second argument. (And if you don't specify a mode in the second argument, just a filename, then the file is opened read-only to be on the safe side.)

With only one argument, the package scalar variable of the same name as the FILEHANDLE must contain the filename and optional mode:

$LOG = ">logfile";        # $LOG must not be declared my!
   open LOG or die "Can't open logfile: $!";
But don't do that. It's not stylin'. Forget we mentioned it.

The open function returns true when it succeeds and undef otherwise. If the open starts up a pipe to a child process, the return value will be the process ID of that new process. As with any syscall, always check the return value of open to make sure it worked. But this isn't C or Java, so don't use an if statement when the or operator will do. You can also use ||, but if you do, use parentheses on the open. If you choose to omit parentheses on the function call to turn it into a list operator, be careful to use "or die" after the list rather than "|| die", because the precedence of || is higher than list operators like open, and the || will bind to your last argument, not the whole open:

open LOG, ">logfile" || die "Can't create logfile: $!";  # WRONG
open LOG, ">logfile" or die "Can't create logfile: $!";  # ok
That looks rather intense, but typically you'd introduce some whitespace to tell your eye where the list operator ends:
open LOG, ">logfile"
        or die "Can't create logfile: $!";
As that example shows, the FILEHANDLE argument is often just a simple identifier (normally uppercase), but it may also be an expression whose value provides a reference to the actual filehandle. (The reference may be either a symbolic reference to the filehandle name or a hard reference to any object that can be interpreted as a filehandle.) This is called an indirect filehandle, and any function that takes a FILEHANDLE as its first argument can handle indirect filehandles as well as direct ones. But open is special in that if you supply it with an undefined variable for the indirect filehandle, Perl will automatically define that variable for you, that is, autovivifying it to contain a proper filehandle reference. One advantage of this is that the filehandle will be closed automatically when there are no further references to it, typically when the variable goes out of scope:
{
        my $fh;                   # (uninitialized)
        open($fh, ">logfile")     # $fh is autovivified
            or die "Can't create logfile: $!";
        ...                       # do stuff with $fh
}                                 # $fh closed here
The my$fh declaration can be readably incorporated into the open:
open my $fh, ">logfile" or die ...
The > symbol you've been seeing in front of the filename is an example of a mode. Historically, the two-argument form of open came first. The recent addition of the three-argument form lets you separate the mode from the filename, which has the advantage of avoiding any possible confusion between the two. In the following example, we know that the user is not trying to open a filename that happens to start with ">". We can be sure that they're specifying a MODE of ">", which opens the file named in EXPR for writing, creating the file if it doesn't exist and truncating the file down to nothing if it already exists:
open(LOG, ">", "logfile")  or die "Can't create logfile: $!";
In the shorter forms, the filename and mode are in the same string. The string is parsed much as the typical shell processes file and pipe redirections. First, any leading and trailing whitespace is removed from the string. Then the string is examined, on either end if need be, for characters specifying how the file is to be opened. Whitespace is allowed between the mode and the filename.

The modes that indicate how to open a file are shell-like redirection symbols. A list of these symbols is provided in Table 29-1. (To access a file with combinations of open modes not covered by this table, see the low-level sysopen function.)

Table 29.1. Modes for open

 | Read | Write | Append | Create | Clobber
Mode | Access | Access | Only | Nonexisting | Existing
< PATH | Y | N | N | N | N
> PATH | N | Y | N | Y | Y
>> PATH | N | Y | Y | Y | N
+< PATH | Y | Y | N | N | N
+> PATH | Y | Y | N | Y | Y
+>> PATH | Y | Y | Y | Y | N
| COMMAND | N | Y | n/a | n/a | n/a
COMMAND | | Y | N | n/a | n/a | n/a

If the mode is "<" or nothing, an existing file is opened for input. If the mode is ">", the file is opened for output, which truncates existing files and creates nonexistent ones. If the mode is ">>", the file is created if needed and opened for appending, and all output is automatically placed at the end of the file. If a new file is created because you used a mode of ">" or ">>" and the file did not previously exist, access permissions will depend on the process's current umask under the rules described for that function.

Here are common examples:

open(INFO,      "datafile")  || die("can't open datafile: $!");
open(INFO,    "< datafile")  || die("can't open datafile: $!");
open(RESULTS, "> runstats")  || die("can't open runstats: $!");
open(LOG,    ">> logfile ")  || die("can't open logfile:  $!");
If you prefer the low-punctuation version, you can write:
open INFO,      "datafile"   or die "can't open datafile: $!";
open INFO,    "< datafile"   or die "can't open datafile: $!";
open RESULTS, "> runstats"   or die "can't open runstats: $!";
open LOG,    ">> logfile "   or die "can't open logfile:  $!";
When opened for reading, the special filename "-" refers to STDIN. When opened for writing, the same special filename refers to STDOUT. Normally, these are specified as "<-" and ">-", respectively.
open(INPUT,  "-" ) or die;     # re-open standard input for reading
open(INPUT,  "<-") or die;     # same thing, but explicit
open(OUTPUT, ">-") or die;     # re-open standard output for writing
This way the user can supply a program with a filename that will use the standard input or the standard output, but the author of the program doesn't have to write special code to know about this.

You may also place a "+" in front of any of these three modes to request simultaneous read and write. However, whether the file is clobbered or created and whether it must already exist is still governed by your choice of less-than or greater-than signs. This means that "+<" is almost always preferred for read/write updates, as the dubious "+>" mode would first clobber the file before you could ever read anything from it. (Use that mode only if you want to reread only what you just wrote.)

open(DBASE, "+< database")
    or die "can't open existing database in update mode: $!";
You can treat a file opened for update as a random-access database and use seek to move to a particular byte number, but the variable-length records of regular text files usually make it impractical to use read-write mode to update such files. See the -i command-line option in Chapter 19, "The Command-Line Interface" for a different approach to updating.

If the leading character in EXPR is a pipe symbol, open fires up a new process and connects a write-only filehandle to the command. This way you can write into that handle and what you write will show up on that command's standard input. For example:

open(PRINTER, "| lpr -Plp1")    or die "can't fork: $!";
print PRINTER "stuff\n";
close(PRINTER)                  or die "lpr/close failed: $?/$!";
If the trailing character in EXPR is a pipe symbol, open again launches a new process, but this time with a read-only filehandle connected to it. This allows whatever the command writes to its standard output to show up on your handle for reading. For example:
open(NET, "netstat -i -n |")    or die "can't fork: $!";
while (<NET>) { ... }
close(NET)                      or die "can't close netstat: $!/$?";
Explicitly closing any piped filehandle causes the parent process to wait for the child to finish and returns the status code in $? ($CHILD_ERROR). It's also possible for close to set $! ($OS_ERROR). See the examples under close and system for how to interpret these error codes.

Any pipe command containing shell metacharacters such as wildcards or I/O redirections is passed to your system's canonical shell (/bin/sh on Unix), so those shell-specific constructs can be processed first. If no metacharacters are found, Perl launches the new process itself without calling the shell.

You may also use the three-argument form to start up pipes. Using that style, the equivalent of the previous pipe opens would be:

open(PRINTER, "|-", "lpr -Plp1")    or die "can't fork: $!";
open(NET, "-|", "netstat -i -n")    or die "can't fork: $!";
Here the minus in the second argument represents the command in the third argument. These commands don't happen to invoke the shell, but if you want to guarantee no shell processing occurs, new versions of Perl let you say:
open(PRINTER, "|-", "lpr", "-Plp1")    or die "can't fork: $!";
open(NET, "-|", "netstat", "-i", "-n") or die "can't fork: $!";
If you use the two-argument form to open a pipe to or from the special command "-",[7] an implicit fork is done first. (On systems that can't fork, this raises an exception. Microsoft systems did not support fork prior to the 5.6 release of Perl.) In this case, the minus represents your new child process, which is a copy of the parent. The return value from this forking open is the process ID of the child when examined from the parent process, 0 when examined from the child process, and the undefined value undef if the fork fails--in which case, there is no child. For example:
defined($pid = open(FROM_CHILD, "-|"))
        or die "can't fork: $!";

if ($pid) {
        @parent_lines = <FROM_CHILD>;  # parent code
}
else {
        print STDOUT @child_lines;     # child code
}
The filehandle behaves normally for the parent, but for the child process, the parent's input (or output) is piped from (or to) the child's STDOUT (or STDIN). The child process does not see the parent's filehandle opened. (This is conveniently indicated by the 0 PID.) Typically you'd use this construct instead of the normal piped open when you want to exercise more control over just how the pipe command gets executed (such as when you are running setuid) and don't want to have to scan shell commands for metacharacters. The following piped opens are roughly equivalent:
open FH,            "| tr   'a-z'  'A-Z'";        # pipe to shell command
open FH, "|-",        'tr', 'a-z', 'A-Z';         # pipe to bare command
open FH, "|-" or exec 'tr', 'a-z', 'A-Z' or die;  # pipe to child
as are these:
open FH,              "cat    -n   'file' |";     # pipe from shell command
open FH, "-|",        'cat', '-n', 'file';        # pipe from bare command
open FH, "-|" or exec 'cat', '-n', 'file' or die; # pipe from child
For more elaborate uses of fork open, see the sections "Talking to Yourself" in Chapter 16, "Interprocess Communication" and "Cleaning Up Your Environment" in Chapter 23, "Security".

[7]Or you can think of it as leaving the command off of the three-argument forms above.

When starting a command with open, you must choose either input or output: "cmd|" for reading or "|cmd" for writing. You may not use open to start a command that pipes both in and out, as the (currently) illegal notation, "|cmd|", might appear to indicate. However, the standard IPC::Open2 and IPC::Open3 library routines give you a close equivalent. For details on double-ended pipes, see the section "Bidirectional Communication" in Chapter 16, "Interprocess Communication".

You may also, in the Bourne shell tradition, specify an EXPR beginning with >&, in which case the rest of the string is interpreted as the name of a filehandle (or file descriptor, if numeric) to be duplicated using the dup2(2) syscall.[8] You may use & after >, >>, <, +>, +>>, and +<. (The specified mode should match the mode of the original filehandle.)

[8]This doesn't (currently) work with I/O objects on typeglob references by filehandle autovivification, but you can always use fileno to fetch the file descriptor and dup that.

One reason you might want to do this would be if you already had a filehandle open and wanted to make another handle that's really a duplicate of the first one.

open(SAVEOUT, ">&SAVEERR") or die "couldn't dup SAVEERR: $!";
open(MHCONTEXT, "<&4")     or die "couldn't dup fd4: $!";
That means that if a function is expecting a filename, but you don't want to give it a filename because you already have the file open, you can just pass the filehandle with a leading ampersand. It's best to use a fully qualified handle though, just in case the function happens to be in a different package:
somefunction("&main::LOGFILE");
Another reason to "dup" filehandles is to temporarily redirect an existing filehandle without losing track of the original destination. Here is a script that saves, redirects, and restores STDOUT and STDERR:
#!/usr/bin/perl
open SAVEOUT, ">&STDOUT";
open SAVEERR, ">&STDERR";

open STDOUT, ">foo.out" or die "Can't redirect stdout";
open STDERR, ">&STDOUT" or die "Can't dup stdout";

select STDERR; $| = 1;         # enable autoflush
select STDOUT; $| = 1;         # enable autoflush

print STDOUT "stdout 1\n";     # these I/O streams propagate to
print STDERR "stderr 1\n";     # subprocesses too

system("some command");        # uses new stdout/stderr

close STDOUT;
close STDERR;

open STDOUT, ">&SAVEOUT";
open STDERR, ">&SAVEERR";

print STDOUT "stdout 2\n";
print STDERR "stderr 2\n";
If the filehandle or descriptor number is preceded by a &= combination instead of a simple &, then instead of creating a completely new file descriptor, Perl makes the FILEHANDLE an alias for the existing descriptor using the fdopen(3) C library call. This is slightly more parsimonious of systems resources, although that's less of a concern these days.
$fd = $ENV{"MHCONTEXTFD"};
open(MHCONTEXT, "<&=$fdnum")
        or die "couldn't fdopen descriptor $fdnum: $!";
Filehandles STDIN, STDOUT, and STDERR always remain open across an exec. Other filehandles, by default, do not. On systems supporting the fcntl function, you may modify the close-on-exec flag for a filehandle.
use Fcntl qw(F_GETFD F_SETFD);
$flags = fcntl(FH, F_SETFD, 0)
        or die "Can't clear close-on-exec flag on FH: $!\n";
See also the special $^F ($SYSTEM_FD_MAX) variable in Chapter 28, "Special Names".

With the one- or two-argument form of open, you have to be careful when you use a string variable as a filename, since the variable may contain arbitrarily weird characters (particularly when the filename has been supplied by arbitrarily weird characters on the Internet). If you're not careful, parts of the filename might get interpreted as a MODE string, ignorable whitespace, a dup specification, or a minus. Here's one historically interesting way to insulate yourself:

$path =~ s#^(\s)#./$1#;
open (FH, "< $path\0") or die "can't open $path: $!";
But that's still broken in several ways. Instead, just use the three-argument form of open to open any arbitrary filename cleanly and without any (extra) security risks:
open(FH, "<", $path) or die "can't open $path: $!";
On the other hand, if what you're looking for is a true, C-style open(2) syscall with all its attendant belfries and whistle-stops, then check out sysopen:
use Fcntl;
sysopen(FH, $path, O_RDONLY) or die "can't open $path: $!";
If you're running on a system that distinguishes between text and binary files, you may need to put your filehandle into binary mode--or forgo doing so, as the case may be--to avoid mutilating your files. On such systems, if you use text mode on a binary file, or binary mode on a text file, you probably won't like the results.

Systems that need the binmode function are distinguished from those that don't by the format used for text files. Those that don't need it terminate each line with a single character that corresponds to what C thinks is a newline, \n. Unix and Mac OS fall into this category. VMS, MVS, MS-whatever, and S&M operating systems of other varieties treat I/O on text files and binary files differently, so they need binmode.

Or its equivalent. As of the 5.6 release of Perl, you can specify binary mode in the open function without a separate call to binmode. As part of the MODE argument (but only in the three-argument form), you may specify various input and output disciplines. To do the equivalent of a binmode, use the three argument form of open and stuff a discipline of :raw in after the other MODE characters:

open(FH, "<:raw", $path) or die "can't open $path: $!";
Since this is a very new feature, there will certainly be more disciplines by the time you read this than there were when we wrote it. However, we can reasonably predict that there will in all likelihood be disciplines resembling some or all of the ones in Table 29-2.

Table 29.2. I/O Disciplines

Discipline | Meaning
:raw | Binary mode; do no processing
:text | Default text processing
:def | Default declared by "use open"
:latin1 | File should be ISO-8859-1
:ctype | File should be LC_CTYPE
:utf8 | File should be UTF-8
:utf16 | File should be UTF-16
:utf32 | File should be UTF-32
:uni | Intuit Unicode (UTF-*)
:any | Intuit Unicode/Latin1/LC_CTYPE
:xml | Use encoding specified in file
:crlf | Intuit newlines
:para | Paragraph mode
:slurp | Slurp mode

You'll be able to stack disciplines that make sense to stack, so, for instance, you could say:

open(FH, "<:para:crlf:uni", $path) or die "can't open $path: $!";
while ($para = <FH>) { ... }
That would set up disciplines to:

  • read in some form of Unicode and translate to Perl's internal UTF-8 format if the file isn't already in UTF-8,

  • look for variants of line-ending sequences, translating them all to \n, and

  • process the file into paragraph-sized chunks, much as $/ = "" does.

If you want to set the default open mode (:def) to something other than :text, you can declare that at the top of your file with the open pragma:

use open IN => ":any", OUT => ":utf8";
In fact, it would be really nice if that were the default :text discipline someday. It perfectly captures the spirit of "Be liberal in what you accept, and strict in what you produce."

29.2.105. opendir

opendir DIRHANDLE, EXPR
This function opens a directory named EXPR for processing by readdir, telldir, seekdir, rewinddir, and closedir. The function returns true if successful. Directory handles have their own namespace separate from filehandles.

29.2.106. ord

ord EXPR
ord
This function returns the numeric value (ASCII, Latin-1, or Unicode) of the first character of EXPR. The return value is always unsigned. If you want a signed value, use unpack('c',EXPR). If you want all the characters of the string converted to a list of numbers, use unpack('U*',EXPR) instead.

29.2.107. our

our TYPE EXPR : ATTRIBUTES
our EXPR : ATTRIBUTES
our TYPE EXPR
our EXPR
An our declares one or more variables to be valid globals within the enclosing block, file, or eval. That is, our has the same rules as a my declaration for determination of visibility, but does not create a new private variable; it merely allows unfettered access to the existing package global. If more than one value is listed, the list must be placed in parentheses.

The primary use of an our declaration is to hide the variable from the effects of a use strict "vars" declaration; since the variable is masquerading as a my variable, you are permitted to use the declared global variable without qualifying it with its package. However, just like the my variable, this only works within the lexical scope of the our declaration. In this respect, it differs from use vars, which affects the entire package and is not lexically scoped.

our is also like my in that you are allowed to declare variables with a TYPE and with ATTRIBUTES. Here is the syntax:

our Dog $spot :ears(short) :tail(long);
As of this writing, it's not entirely clear what that will mean. Attributes could affect either the global or the local interpretation of $spot. On the one hand, it would be most like my variables for attributes to warp the current local view of $spot without interfering with other views of the global in other places. On the other hand, if one module declares $spot to be a Dog, and another declares $spot to be a Cat, you could end up with meowing dogs or barking cats. This is a subject of ongoing research, which is a fancy way to say we don't know what we're talking about yet. (Except that we do know what to do with the TYPE declaration when the variable refers to a pseudohash--see "Managing Instance Data" in Chapter 12, "Objects".)

Another way in which our is like my is in its visibility. An our declaration declares a global variable that will be visible across its entire lexical scope, even across package boundaries. The package in which the variable is located is determined at the point of the declaration, not at the point of use. This means the following behavior holds and is deemed to be a feature:

package Foo;
our $bar;      # $bar is $Foo::bar for rest of lexical scope
$bar = 582;

package Bar;
print $bar;    # prints 582, just as if "our" had been "my"
However, the distinction between my creating a new, private variable and our exposing an existing, global variable is important, especially in assignments. If you combine a run-time assignment with an our declaration, the value of the global variable does not disappear once the our goes out of scope. For that, you need local:
($x, $y) = ("one", "two");
print "before block, x is $x, y is $y\n";
{
    our $x = 10;
    local our $y = 20;
    print "in block, x is $x, y is $y\n";
}
print "past block, x is $x, y is $y\n";
That prints out:
before block, x is one, y is two
in block, x is 10, y is 20
past block, x is 10, y is two
Multiple our declarations in the same lexical scope are allowed if they are in different packages. If they happen to be in the same package, Perl will emit warnings if you ask it to.
use warnings;
package Foo;
our $bar;          # declares $Foo::bar for rest of lexical scope
$bar = 20;

package Bar;
our $bar = 30;     # declares $Bar::bar for rest of lexical scope
print $bar;        # prints 30

our $bar;          # emits warning
See also local, my, and the section "Scoped Declarations" in Chapter 4, "Statements and Declarations".

29.2.108. pack

pack TEMPLATE, LIST
This function takes a LIST of ordinary Perl values and converts them into a string of bytes according to the TEMPLATE and returns this string. The argument list will be padded or truncated as necessary. That is, if you provide fewer arguments than the TEMPLATE requires, pack assumes additional null arguments. If you provide more arguments than the TEMPLATE requires, the extra arguments are ignored. Unrecognized format elements in TEMPLATE will raise an exception.

The template describes the structure of the string as a sequence of fields. Each field is represented by a single character that describes the type of the value and its encoding. For instance, a format character of N specifies an unsigned four-byte integer in big-endian byte order.

Fields are packed in the order given in the template. For example, to pack an unsigned one-byte integer and a single-precision floating-point value into a string, you'd say:

$string = pack("Cf", 244, 3.14);
The first byte of the returned string has the value 244. The remaining bytes are the encoding of 3.14 as a single-precision float. The particular encoding of the floating point number depends on your computer's hardware.

Some important things to consider when packing are:

  • the type of data (such as integer or float or string),

  • the range of values (such as whether your integers will fit into one, two, four, or maybe even eight bytes; or whether you're packing 8-bit or Unicode characters),

  • whether your integers are signed or unsigned, and

  • the encoding to use (such as native, little-endian, or big-endian packing of bits and bytes).

Table 29-3 lists the format characters and their meanings. (Other characters can occur in formats as well; these are described later.)

Table 29.3. Template Characters for pack/unpack

Character | Meaning
a | A null-padded string of bytes
A | A space-padded string of bytes
b | A bit string, in ascending bit order inside each byte (like vec)
B | A bit string, in descending bit order inside each byte
c | A signed char (8-bit integer) value
C | An unsigned char (8-bit integer) value; see U for Unicode
d | A double-precision floating-point number in native format
f | A single-precision floating-point number in native format
h | A hexadecimal string, low nybble first
H | A hexadecimal string, high nybble first
i | A signed integer value, native format
I | An unsigned integer value, native format
l | A signed long value, always 32 bits
L | An unsigned long value, always 32 bits
n | A 16-bit short in "network" (big-endian) order
N | A 32-bit long in "network" (big-endian) order
p | A pointer to a null-terminated string
P | A pointer to a fixed-length string
q | A signed quad (64-bit integer) value
Q | An unsigned quad (64-bit integer) value
s | A signed short value, always 16 bits
S | An unsigned short value, always 16 bits
u | A uuencoded string
U | A Unicode character number
v | A 16-bit short in "VAX" (little-endian) order
V | A 32-bit long in "VAX" (little-endian) order
w | A BER compressed integer
x | A null byte (skip forward a byte)
X | Back up a byte
Z | A null-terminated (and null-padded) string of bytes
@ | Null-fill to absolute position

You may freely place whitespace and comments in your TEMPLATEs. Comments start with the customary # symbol and extend up through the first newline (if any) in the TEMPLATE.

Each letter may be followed by a number indicating the count, interpreted as a repeat count or length of some sort, depending on the format. With all formats except a, A, b, B, h, H, P, and Z, count is a repeat count, so pack gobbles up that many values from the LIST. A * for the count means however many items are left.

The a, A, and Z formats gobble just one value, but pack it as a byte string of length count, padding with nulls or spaces as necessary. When unpacking, A strips trailing spaces and nulls, Z strips everything after the first null, and a returns the literal data unmolested. When packing, a and Z are equivalent.

Similarly, the b and B formats pack a string count bits long. Each byte of the input field generates 1 bit of the result based on the least-significant bit of each input byte (that is, on ord($byte) % 2). Conveniently, that means bytes 0 and 1 generate bits 0 and 1. Starting from the beginning of the input string, each 8-tuple of bytes is converted to a single byte of output. If the length of the input string is not divisible by 8, the remainder is packed as if padded by 0's. Similarly, during unpacking any extra bits are ignored. If the input string is longer than needed, extra bytes are ignored. A * for the count means to use all bytes from the input field. On unpacking, the bits are converted to a string of 0s and 1s.

The h and H formats pack a string of count nybbles (4-bit groups often represented as hexadecimal digits).

The p format packs a pointer to a null-terminated string. You are responsible for ensuring the string is not a temporary value (which can potentially get deallocated before you get around to using the packed result). The P format packs a pointer to a structure of the size indicated by count. A null pointer is created if the corresponding value for p or P is undef.

The / character allows packing and unpacking of strings where the packed structure contains a byte count followed by the string itself. You write length-item/string-item. The length-item can be any pack template letter, and describes how the length value is packed. The ones likely to be of most use are integer-packing ones like n (for Java strings), w (for ASN.1 or SNMP) and N (for Sun XDR). The string-item must, at present, be A*, a*, or Z*. For unpack, the length of the string is obtained from the length-item, but if you put in the *, it will be ignored.

unpack 'C/a', "\04Gurusamy";        # gives 'Guru'
unpack 'a3/A* A*', '007 Bond  J ';  # gives (' Bond','J')
pack 'n/a* w/a*','hello,','world';  # gives "\000\006hello,\005world"
The length-item is not returned explicitly from unpack. Adding a count to the length-item letter is unlikely to do anything useful, unless that letter is A, a, or Z. Packing with a length-item of a or Z may introduce null (\0) characters, which Perl does not regard as legal in numeric strings.

The integer formats s, S, l, and L may be immediately followed by a ! to signify native shorts or longs instead of exactly 16 or 32 bits respectively. Today, this is an issue mainly in 64-bit platforms, where the native shorts and longs as seen by the local C compiler can be different than these values. (i! and I! also work but only because of completeness; they are identical to i and I.)

The actual sizes (in bytes) of native shorts, ints, longs, and long longs on the platform where Perl was built are also available via the Config module:

use Config;
print $Config{shortsize},    "\n";
print $Config{intsize},      "\n";
print $Config{longsize},     "\n";
print $Config{longlongsize}, "\n";
Just because Configure knows the size of a long long, doesn't necessarily imply that you have q or Q formats available to you. (Some systems do, but you're probably not running one. Yet.)

Integer formats of greater than one byte in length (s, S, i, I, l, and L) are inherently nonportable between processors because they obey the native byte order and endianness. If you want portable packed integers, use the formats n, N, v, and V; their byte endianness and size are known.

Floating-point numbers are in the native machine format only. Because of the variety of floating formats and lack of a standard "network" representation, no facility for interchange has been made. This means that packed floating-point data written on one machine may not be readable on another. This is a problem even when both machines use IEEE floating-point arithmetic, because the endian-ness of the memory representation is not part of the IEEE spec.

Perl uses doubles internally for all floating-point calculation, so converting from double into float, then back again to double will lose precision. This means that unpack("f", pack("f", $foo)) will not generally equal $foo.

You are responsible for any alignment or padding considerations expected by other programs, particularly those programs that were created by a C compiler with its own idiosyncratic notions of how to lay out a C struct on the particular architecture in question. You'll have to add enough x's while packing to make up for this. For example, a C declaration of:

struct foo {
        unsigned char c;
        float f;
};
might be written out in a "C x f" format, a "C x3 f" format, or even a "f C" format--just to name a few. The pack and unpack functions handle their input and output as flat sequences of bytes because there is no way for them to know where the bytes are going to or coming from.

Let's look at some examples. This first pair packs numeric values into bytes:

$out = pack "CCCC", 65, 66, 67, 68;      # $out eq "ABCD"
$out = pack "C4", 65, 66, 67, 68;        # same thing
This one does the same thing with Unicode circled letters:
$foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
This does a similar thing, with a couple of nulls thrown in:
$out = pack "CCxxCC", 65, 66, 67, 68;    # $out eq "AB\0\0CD"
Packing your shorts doesn't imply that you're portable:
$out = pack "s2", 1, 2;    # "\1\0\2\0" on little-endian
                           # "\0\1\0\2" on big-endian
On binary and hex packs, the count refers to the number of bits or nybbles, not the number of bytes produced:
$out = pack "B32", "01010000011001010111001001101100";
$out = pack "H8", "5065726c";    # both produce "Perl"
The length on an a field applies only to one string:
$out = pack "a4", "abcd", "x", "y", "z";      # "abcd"
To get around that limitation, use multiple specifiers:
$out = pack "aaaa",  "abcd", "x", "y", "z";   # "axyz"
$out = pack "a" x 4, "abcd", "x", "y", "z";   # "axyz"
The a format does null filling:
$out = pack "a14", "abcdefg";   # "abcdefg\0\0\0\0\0\0\0"
This template packs a C struct tm record (at least on some systems):
$out = pack "i9pl", gmtime(), $tz, $toff;
Generally, the same template may also be used in the unpack function, although some formats act differently, notably a, A, and Z.

If you want to join fixed-width text fields together, use pack with a TEMPLATE of several A or a formats:

$string = pack("A10" x 10, @data);
If you want to join variable-width text fields with a separator, use the join function instead:
$string = join(" and ", @data);
$string = join("", @data);             # null separator
Although all of our examples used literal strings as templates, there is no reason you couldn't pull in your templates from a disk file. You could build an entire relational database system around this function. (What that would prove about you we won't get into.)

29.2.109. package

package NAMESPACE
package
This is not really a function, but a declaration that says that the rest of the innermost enclosing scope belongs to the indicated symbol table or namespace. (The scope of a package declaration is thus the same as the scope of a my or our declaration.) Within its scope, the declaration causes the compiler to resolve all unqualified global identifiers by looking them up in the declared package's symbol table.

A package declaration affects only global variables--including those on which you've used local--not lexical variables created with my. It only affects unqualified global variables; global variables that are qualified with a package name of their own ignore the current declared package. Global variables declared with our are unqualified and therefore respect the current package, but only at the point of declaration, after which they behave like my variables. That is, for the rest of their lexical scope, our variables are "nailed" to the package in use at the point of declaration, even if a subsequent package declaration intervenes.

Typically, you would put a package declaration as the first thing in a file that is to be included by the require or use operator, but you can put one anywhere a statement would be legal. When creating a traditional or objected-oriented module file, it is customary to name the package the same name as the file to avoid confusion. (It's also customary to name such packages beginning with a capital letter because lowercase modules are by convention interpreted as pragmatic modules.)

You can switch into a given package in more than one place; it merely influences which symbol table is used by the compiler for the rest of that block. (If the compiler sees another package declaration at the same level, the new declaration overrides the previous one.) Your main program is assumed to start with an invisible package main declaration.

You can refer to variables, subroutines, handles, and formats in other packages by qualifying the identifier with the package name and a double colon: $Package::Variable. If the package name is null, the main package is assumed. That is, $::sail is equivalent to $main::sail, as well as to $main'sail, which is still occasionally seen in older code.

Here's an example:

package main;       $sail = "hale and hearty";
package Mizzen;     $sail = "tattered";
package Whatever;
print "My main sail is $main::sail.\n";
print "My mizzen sail is $Mizzen::sail.\n";
This prints:
My main sail is hale and hearty.
My mizzen sail is tattered.
The symbol table for a package is stored in a hash with a name ending in a double colon. The main package's symbol table is named %main:: for example. So the existing package symbol *main::sail can also be accessed as $main::{"sail"}.

If NAMESPACE is omitted, then there is no current package, and all identifiers must be fully qualified or declared as lexicals. This is stricter than use strict since it also extends to function names.

See Chapter 10, "Packages", for more information about packages. See my earlier in this chapter for other scoping issues.

29.2.110. pipe

pipe READHANDLE, WRITEHANDLE
Like the corresponding syscall, this function opens a pair of connected pipes--see pipe(2). This call is usually used right before a fork, after which the pipe's reader should close WRITEHANDLE, and the writer close READHANDLE. (Otherwise the pipe won't indicate EOF to the reader when the writer closes it.) If you set up a loop of piped processes, deadlock can occur unless you are remarkably careful. In addition, note that Perl's pipes use standard I/O buffering, so you may need to set $| ($OUTPUT_AUTOFLUSH) on your WRITEHANDLE to flush after each output operation, depending on the application--see select (output filehandle).

(As with open, if either filehandle is undefined, it will be autovivfied.)

Here's a small example:

pipe(README, WRITEME);
unless ($pid = fork) {  #               child
    defined $pid or die "can't fork: $!";
    close(README);
    for $i (1..5) { print WRITEME "line $i\n" }
    exit;
}
$SIG{CHLD} = sub { waitpid($pid, 0) };
close(WRITEME);
@strings = <README>;
close(README);
print "Got:\n", @strings;
Notice how the writer closes the read end and the reader closes the write end. You can't use one pipe for two-way communication. Either use two different pipes or the socketpair syscall for that. See the section "Pipes" in Chapter 16, "Interprocess Communication".

29.2.111. pop

pop ARRAY
pop
This function treats an array like a stack--it pops (removes) and returns the last value of the array, shortening the array by one element. If ARRAY is omitted, the function pops @_ within the lexical scope of subroutines and formats; it pops @ARGV at file scopes (typically the main program) or within the lexical scopes established by the eval STRING, BEGIN {}, CHECK {}, INIT {}, and END {} constructs. It has the same effect as:
$tmp = $ARRAY[$#ARRAY--];
or:
$tmp = splice @ARRAY, -1;
If there are no elements in the array, pop returns undef. (But don't depend on that to tell you when the array is empty if your array contains undef values!) See also push and shift. If you want to pop more than one element, use splice.

The pop requires its first argument to be an array, not a list. If you just want the last element of a list, use this:

( LIST )[-1]

29.2.112. pos

pos SCALAR
pos
This function returns the location in SCALAR where the last m//g search over SCALAR left off. It returns the offset of the character after the last one matched. (That is, it's equivalent to length($`) + length($&).) This is the offset where the next m//g search on that string will start. Remember that the offset of the beginning of the string is 0. For example:
$graffito = "fee fie foe foo";
while ($graffito =~ m/e/g) {
    print pos $graffito, "\n";
}
prints 2, 3, 7, and 11, the offsets of each of the characters following an "e". The pos function may be assigned a value to tell the next m//g where to start:
$graffito = "fee fie foe foo";
pos $graffito = 4;  # Skip the fee, start at fie
while ($graffito =~ m/e/g) {
        print pos $graffito, "\n";
}
This prints only 7 and 11. The regular expression assertion \G matches only at the location currently specified by pos for the string being searched. See the section "Positions" in Chapter 5, "Pattern Matching".

29.2.113. print

print FILEHANDLE LIST
print LIST
print
This function prints a string or a comma-separated list of strings. If set, the contents of the $\ ($OUTPUT_RECORD_SEPARATOR) variable will be implicitly printed at the end of the list. The function returns true if successful, false otherwise. FILEHANDLE may be a scalar variable name (unsubscripted), in which case the variable contains either the name of the actual filehandle or a reference to a filehandle object of some sort. As with any other indirect object, FILEHANDLE may also be a block that returns such a value:
print { $OK ? "STDOUT" : "STDERR" } "stuff\n";
print { $iohandle[$i] } "stuff\n";
If FILEHANDLE is a variable and the next token is a term, it may be misinterpreted as an operator unless you interpose a + or put parentheses around the arguments. For example:
print $a - 2;   # prints $a - 2 to default filehandle (usually STDOUT)
print $a (- 2); # prints -2 to filehandle specified in $a
print $a -2;    # also prints -2 (weird parsing rules :-)
If FILEHANDLE is omitted, the function prints to the currently selected output filehandle, initially STDOUT. To set the default output filehandle to something other than STDOUT, use the select FILEHANDLE operation.[9] If LIST is also omitted, the function prints $_. Because print takes a LIST, anything in the LIST is evaluated in list context. Thus, when you say:
print OUT <STDIN>;
it is not going to print the next line from standard input, but all the rest of the lines from standard input up to end-of-file, since that's what <STDIN> returns in list context. If you want the other thing, say:
print OUT scalar <STDIN>;
Also, remembering the if-it-looks-like-a-function-it-is-a-function rule, be careful not to follow the print keyword with a left parenthesis unless you want the corresponding right parenthesis to terminate the arguments to the print--interpose a + or put parens around all the arguments:
print (1+2)*3, "\n";            # WRONG
print +(1+2)*3, "\n";           # ok
print ((1+2)*3, "\n");          # ok

[9] Thus, STDOUT isn't really the default filehandle for print. It's merely the default default filehandle.

29.2.114. printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
This function prints a formatted string to FILEHANDLE or, if omitted, the currently selected output filehandle, initially STDOUT. The first item in the LIST must be a string that says how to format the rest of the items. This is similar to the C library's printf(3) and fprintf(3) functions. The function is equivalent to:
print FILEHANDLE sprintf FORMAT, LIST
except that $\ ($OUTPUT_RECORD_SEPARATOR) is not appended. If use locale is in effect, the character used for the decimal point in formatted floating-point numbers is affected by the LC_NUMERIC locale.

An exception is raised only if an invalid reference type is used as the FILEHANDLE argument. Unrecognized formats are passed through intact. Both situations trigger warnings if they're enabled.

See the print and sprintf functions elsewhere in this chapter. The description of sprintf includes the list of format specifications. We'd duplicate them here, but this book is already an ecological disaster.

If you omit both the FORMAT and the LIST, $_ is used--but in that case, you should have been using print. Don't fall into the trap of using a printf when a simple print would do. The print function is more efficient and less error prone.

29.2.115. prototype

prototype FUNCTION
Returns the prototype of a function as a string (or undef if the function has no prototype). FUNCTION is a reference to, or the name of, the function whose prototype you want to retrieve.

If FUNCTION is a string starting with CORE::, the rest is taken as a name for Perl built-in, and an exception is raised if there is no such built-in. If the built-in is not overridable (such as qw//) or its arguments cannot be expressed by a prototype (such as system), the function returns undef because the built-in does not really behave like a Perl function. Otherwise, the string describing the equivalent prototype is returned.

29.2.116. push

push ARRAY, LIST
This function treats ARRAY as a stack and pushes the values of LIST onto the end of ARRAY. The length of ARRAY increases by the length of LIST. The function returns this new length. The push function has the same effect as:
foreach $value (listfunc()) {
    $array[++$#array] = $value;
}
or:
splice @array, @array, 0, listfunc();
but it is more efficient (for both you and your computer). You can use push in combination with shift to make a fairly time-efficient shift register or queue:
for (;;) {
    push @array, shift @array;
    ...
}
See also pop and unshift.

29.2.117. q/STRING/

q/STRING/
qq/STRING/
qr/STRING/
qw/STRING/
qx/STRING/
Generalized quotes. See the "Pick your own quotes" section Chapter 2, "Bits and Pieces". For status annotations on qx//, see readpipe. For status annotations on qr//, see m//. See also "Staying in Control" in Chapter 5, "Pattern Matching".

29.2.118. quotemeta

quotemeta EXPR
quotemeta
This function returns the value of EXPR with all nonalphanumeric characters backslashed. (That is, all characters not matching /[A-Za-z_0-9]/ will be preceded by a backslash in the returned string, regardless of locale settings.) This is the internal function implementing the \Q escape in interpolative contexts (including double-quoted strings, backticks, and patterns).

29.2.119. rand

rand EXPR
rand
This function returns a pseudorandom floating-point number greater than or equal to 0 and less than the value of EXPR. (EXPR should be positive.) If EXPR is omitted, the function returns a floating-point number between 0 and 1 (including 0, but excluding 1). rand automatically calls srand unless srand has already been called. See also srand.

To get an integral value, such as for a die roll, combine this with int, as in:

$roll = int(rand 6) + 1;       # $roll now a number between 1 and 6
Because Perl uses your own C library's pseudorandom number function, like random(3) or drand48(3), the quality of the distribution is not guaranteed. If you need stronger randomness, such as for cryptographic purposes, you might consult instead the documentation on random(4) (if your system has a /dev/random or /dev/urandom device), the CPAN module Math::TrulyRandom, or a good textbook on computational generation of pseudorandom numbers, such as the second volume of Knuth.[10]

[10] Knuth, D.E. The Art of Computer Programming, Seminumerical Algorithms, vol. 2, 3d ed. (Reading, Mass.: Addison-Wesley, 1997). ISBN 0-201-89684-2.

29.2.120. read [taintgray]

read FILEHANDLE, SCALAR, LENGTH, OFFSET
read FILEHANDLE, SCALAR, LENGTH
This function attempts to read LENGTH bytes of data into variable SCALAR from the specified FILEHANDLE. The function returns the number of bytes read or 0 at end-of-file. It returns undef on error. SCALAR will grow or shrink to the length actually read. The OFFSET, if specified, determines where in the variable to start putting bytes, so that you can read into the middle of a string.

To copy data from filehandle FROM into filehandle TO, you could say:

while (read(FROM, $buf, 16384)) {
    print TO $buf;
}
The opposite of a read is simply a print, which already knows the length of the string you want to write and can write a string of any length. Don't make the mistake of using write, which is solely used with formats.

Perl's read function is implemented in terms of standard I/O's fread(3) function, so the actual read(2) syscall may read more than LENGTH bytes to fill the input buffer, and fread(3) may do more than one read(2) syscall in order to fill the buffer. To gain greater control, specify the real syscall using sysread. Calls to read and sysread should not be intermixed unless you are into heavy wizardry (or pain). Whichever one you use, be aware that when reading from a file containing Unicode or any other multibyte encoding, the buffer boundary may fall in the middle of a character.

29.2.121. readdir

readdir DIRHANDLE
This function reads directory entries (which are simple filenames) from a directory handle opened by opendir. In scalar context, this function returns the next directory entry, if any; otherwise, it returns undef. In list context, it returns all the rest of the entries in the directory, which will be a null list if there are no entries. For example:
opendir(THISDIR, ".") or die "serious dainbramage: $!";
@allfiles = readdir THISDIR;
closedir THISDIR;
print "@allfiles\n";
That prints all the files in the current directory on one line. If you want to avoid the "." and ".." entries, incant one of these (whichever you think is least unreadable):
@allfiles = grep { $_ ne '.' and $_ ne '..' } readdir THISDIR;
@allfiles = grep { not /^[.][.]?\z/ } readdir THISDIR;
@allfiles = grep { not /^\.{1,2}\z/ } readdir THISDIR;
@allfiles = grep !/^\.\.?\z/, readdir THISDIR;
And to avoid all .* files (like the ls program):
@allfiles = grep !/^\./, readdir THISDIR;
To get just text files, say this:
@textfiles = grep -T, readdir THISDIR;
But watch out on that last one because the result of readdir needs to have the directory part glued back on if it's not the current directory--like this:
opendir(THATDIR, $path) or die "can't opendir $path: $!";
@dotfiles = grep { /^\./ && -f } map { "$path/$_" } readdir(THATDIR);
closedir THATDIR;

29.2.122. readline [taintgray]

readline FILEHANDLE
This is the internal function implementing the <FILEHANDLE> operator, but you can use it directly. The function reads the next record from FILEHANDLE, which may be a filehandle name or an indirect filehandle expression that returns either the name of the actual filehandle or a reference to anything resembling a filehandle object, such as a typeglob. (Versions of Perl prior to 5.6 accept only a typeglob.) In scalar context, each call reads and returns the next record until end-of-file is reached, whereupon the subsequent call returns undef. In list context, readline reads records until end-of-file is reached and then returns a list of records. By "record", we normally mean a line of text, but changing the value of $/ ($INPUT_RECORD_SEPARATOR) from its default value causes this operator to "chunk" the text differently. Likewise, some input disciplines such as :para (paragraph mode) will return records in chunks other than lines. Setting the :slurp discipline (or undefining $/) makes the chunk size entire files.

When slurping files in scalar context, if you happen to slurp an empty file, readline returns "" the first time, and undef each subsequent time. When slurping from magical ARGV filehandle, each file returns one chunk (again, null files return as ""), followed by a single undef when the files are exhausted.

The <FILEHANDLE> operator is discussed in more detail in the section "Input Operators" in Chapter 2, "Bits and Pieces".

$line = <STDIN>;
$line = readline(STDIN);          # same thing
$line = readline(*STDIN);         # same thing
$line = readline(\*STDIN);        # same thing

open my $fh, "<&=STDIN" or die;
bless $fh => 'AnyOldClass';
$line = readline($fh);            # same thing

29.2.123. readlink

readlink EXPR
readlink
This function returns the filename pointed to by a symbolic link. EXPR should evaluate to a filename, the last component of which is a symbolic link. If it is not a symbolic link, or if symbolic links are not implemented on the filesystem, or if some system error occurs, undef is returned, and you should check the error code in $!.

Be aware that the returned symlink may be relative to the location you specified. For instance, you may say:

readlink "/usr/local/src/express/yourself.h"
and readlink might return:
../express.1.23/includes/yourself.h
which is not directly usable as a filename unless your current directory happens to be /usr/local/src/express.

29.2.124. readpipe

readpipe scalar EXPR
readpipe LIST (proposed)
This is the internal function implementing the qx// quote construct (also known as the backticks operator). It is occasionally handy when you need to specify your EXPR in a way that wouldn't be handy using the quoted form. Be aware that we may change this interface in the future to support a LIST argument in order to make it more like the exec function, so don't assume that it will continue to provide scalar context for EXPR. Supply the scalar yourself, or try the LIST form. Who knows, it might work by the time you read this.

29.2.125. recv [taintgray]

recv SOCKET, SCALAR, LEN, FLAGS
This function receives a message on a socket. It attempts to receive LENGTH bytes of data into variable SCALAR from the specified SOCKET filehandle. The function returns the address of the sender, or undef if there's an error. SCALAR will grow or shrink to the length actually read. The function takes the same flags as recv(2). See the section "Sockets" in Chapter 16, "Interprocess Communication".

29.2.126. redo

redo LABEL
redo
The redo operator restarts a loop block without reevaluating the conditional. The continue block, if any, is not executed. If the LABEL is omitted, the operator refers to the innermost enclosing loop. This operator is normally used by programs that wish to deceive themselves about what was just input:
# A loop that joins lines continued with a backslash.
while (<STDIN>) {
    if (s/\\\n$// && defined($nextline = <STDIN>)) {
        $_ .= $nextline;
        redo;
    }
    print;  # or whatever...
}
redo cannot be used to exit a block that returns a value such as eval {}, sub {}, or do {}, and should not be used to exit a grep or map operation. With warnings enabled, Perl will warn you if you redo a loop not in your current lexical scope.

A block by itself is semantically identical to a loop that executes once. Thus redo inside such a block will effectively turn it into a looping construct. See the section "Loop Control" in Chapter 4, "Statements and Declarations".

29.2.127. ref

ref EXPR
ref
The ref operator returns a true value if EXPR is a reference, false otherwise. The value returned depends on the type of thing the reference refers to. Built-in types include:
SCALAR
ARRAY
HASH
CODE
GLOB
REF
LVALUE
IO::Handle
If the referenced object has been blessed into a package, then that package name is returned instead. You can think of ref as a "typeof" operator.
if (ref($r) eq "HASH") {
    print "r is a reference to a hash.\n";
}
elsif (ref($r) eq "Hump") {    # Naughty--see below.
    print "r is a reference to a Hump object.\n";
}
elsif (not ref $r) {
    print "r is not a reference at all.\n";
}
It's considered bad OO style to test your object's class for equality to any particular class name, since a derived class will have a different name, but should be allowed access to the base class's methods. It's better to use the UNIVERSAL method isa as follows:
if ($r->isa("Hump") }
    print "r is a reference to a Hump object, or subclass.\n";
}
It's usually best not to test at all, since the OO mechanism won't send the object to your method unless it thinks it's appropriate in the first place. See Chapter 8, "References" and Chapter 12, "Objects" for more details. See also the reftype function under the use attributes pragma in Chapter 31, "Pragmatic Modules".

29.2.128. rename

rename OLDNAME, NEWNAME
This function changes the name of a file. It returns true for success, false otherwise. It will not (usually) work across filesystem boundaries, although on a Unix system the mv command can sometimes be used to compensate for this. If a file named NEWNAME already exists, it will be destroyed. Non-Unix systems might have additional restrictions.

See the standard File::Copy module for cross-filesystem renames.

29.2.129. require

require VERSION
require EXPR
require
This function asserts a dependency of some kind on its argument.

If the argument is a string, require loads and executes the Perl code found in the separate file whose name is given by the string. This is similar to performing a do on a file, except that require checks to see whether the library file has been loaded already and raises an exception if any difficulties are encountered. (It can thus be used to express file dependencies without worrying about duplicate compilation.) Like its cousins do and use, require knows how to search the include path stored in the @INC array and to update %INC upon success. See Chapter 28, "Special Names".

The file must return true as the last value to indicate successful execution of any initialization code, so it's customary to end such a file with 1; unless you're sure it'll return true otherwise.

If require's argument is a version number of the form 5.6.2, require demands that the currently executing version of Perl be at least that version. (Perl also accepts a floating point number such as 5.005_03 for compatibility with older versions of Perl, but that form is now discouraged because folks from other cultures don't understand it.) Thus, a script that requires Perl version 5.6 can put as its first line:

require 5.6.0;             # or require v5.6.0
and earlier versions of Perl will abort. Like all requires, however, this is done at run-time. You might prefer to say use 5.6.0 for a compile-time check. See also $PERL_VERSION in Chapter 28, "Special Names".

If require's argument is a bare package name (see package), require assumes an automatic .pm suffix, making it easy to load standard modules. This behavior is like use, except that it happens at run time rather than compile time, and the import method is not called. For example, to pull in Socket.pm without introducing any symbols into the current package, say this:

require Socket;            # instead of "use Socket;"
However, you can get the same effect with the following, which has the advantage of giving a compile-time warning if Socket.pm can't be located:
use Socket ();
Using require on a bare name also replaces any :: in the package name with your system's directory separator, traditionally /. In other words, if you try this:
require Foo::Bar;          # a splendid bare name
The require function looks for the Foo/Bar.pm file in the directories specified in the @INC array. But if you try this:
$class = 'Foo::Bar';
require $class;            # $class is not a bare name
or this:
require "Foo::Bar";        # quoted literal not a bare name
the require function will look for the Foo::Bar file in the @INC array and will complain about not finding Foo::Bar there. If so, you can do this:
eval "require $class";
See also do FILE, the use command, the use lib pragma, and the standard FindBin module.

29.2.130. reset

reset EXPR
reset
This function is generally used (or abused) at the top of a loop or in a continue block at the end of a loop, to clear global variables or reset ?? searches so that they work again. The expression is interpreted as a list of single characters (hyphens are allowed for ranges). All scalar variables, arrays, and hashes beginning with one of those letters are reset to their pristine state. If the expression is omitted, one-match searches (?PATTERN?) are reset to match again. The function resets variables or searches for the current package only. It always returns true.

To reset all "X" variables, say this:

reset 'X';
To reset all lowercase variables, say this:
reset 'a-z';
Lastly, to just reset ?? searches, say:
reset;
Resetting "A-Z" in package main is not recommended since you'll wipe out your global ARGV, INC, ENV, and SIG arrays and hashes.

Lexical variables (created by my) are not affected. Use of reset is vaguely deprecated because it easily clears out entire namespaces and because the ?? operator is itself vaguely deprecated.

See also the delete_package() function from the standard Symbol module, and the whole issue of Safe compartments documented in the section "Safe Compartments" in Chapter 23, "Security".

29.2.131. return

return EXPR
return
This operator causes the current subroutine (or eval or do FILE) to return immediately with the specified value. Attempting to use return outside these three places raises an exception. Note also that an eval cannot do a return on behalf of the subroutine that called the eval.

EXPR may be evaluated in list, scalar, or void context, depending on how the return value will be used, which may vary from one execution to the next. That is, the supplied expression will be evaluated in the context of the subroutine invocation. If the subroutine was called in a scalar context, EXPR is also evaluated in scalar context. If the subroutine was invoked in list context, then EXPR is also evaluated in list context and can return a list value. A return with no argument returns the scalar value undef in scalar context, an empty list () in list context, and (naturally) nothing at all in void context. The context of the subroutine call can be determined from within the subroutine by using the (misnamed) wantarray function.

29.2.132. reverse

reverse LIST
In list context, this function returns a list value consisting of the elements of LIST in the opposite order. The function can be used to create descending sequences:
for (reverse 1 .. 10) { ... }
Because of the way hashes flatten into lists when passed as a LIST, reverse can also be used to invert a hash, presuming the values are unique:
%barfoo = reverse %foobar;
In scalar context, the function concatenates all the elements of LIST and then returns the reverse of that resulting string, character by character.

A small hint: reversing a list sorted earlier by a user-defined function can often be achieved more easily by sorting the list in the opposite direction in the first place.

29.2.133. rewinddir

rewinddir DIRHANDLE
This function sets the current position to the beginning of the directory for the readdir routine on DIRHANDLE. The function may not be available on all machines that support readdir--rewinddir dies if unimplemented. It returns true on success, false otherwise.

29.2.134. rindex

rindex STR, SUBSTR, POSITION
rindex STR, SUBSTR
This function works just like index except that it returns the position of the last occurrence of SUBSTR in STR (a reverse index). The function returns $[-1 if not SUBSTR is found. Since $[ is virtually always 0 nowadays, the function virtually always returns -1. POSITION, if specified, is the rightmost position that may be returned. To work your way through a string backward, say:
$pos = length $string;
while (($pos = rindex $string, $lookfor, $pos) >= 0) {
    print "Found at $pos\n";
    $pos--;
}

29.2.135. rmdir

rmdir FILENAME
rmdir
This function deletes the directory specified by FILENAME if the directory is empty. If the function succeeds, it returns true; otherwise, it returns false. See also the File::Path module if you want to remove the contents of the directory first and don't care to shell out to call rm -r for some reason. (Such as not having a shell, or an rm command, because you haven't got PPT yet.)

29.2.136. s/// [taintgray]

s///
The substitution operator. See the section "Pattern-Matching Operators" in Chapter 5, "Pattern Matching".

29.2.137. scalar

scalar EXPR
This pseudofunction may be used within a LIST to force EXPR to be evaluated in scalar context when evaluation in the list context would produce a different result. For example:
my ($nextvar) = scalar <STDIN>;
prevents <STDIN> from reading all the lines from standard input before doing the assignment, since assignment to a list (even a my list) provides a list context. (Without the scalar in this example, the first line from <STDIN> would still be assigned to $nextvar, but the subsequent lines would be read and thrown away, since the list we're assigning to is only able to receive a single scalar value.)

Of course, a simpler, less-cluttered way would be to just leave the parentheses off, thereby changing the list context to a scalar one:

my $nextvar = <STDIN>;
Since a print function is a LIST operator, you have to say:
print "Length is ", scalar(@ARRAY), "\n";
if you want the length of @ARRAY to be printed out.

There's no "list" function corresponding to scalar since, in practice, one never needs to force evaluation in a list context. That's because any operation that wants LIST already provides a list context to its list arguments for free.

Because scalar is a unary operator, if you accidentally use a parenthesized list for the EXPR, this behaves as a scalar comma expression, evaluating all but the last element in void context and returning the final element evaluated in scalar context. This is seldom what you want. The following single statement:

print uc(scalar(&foo,$bar)),$baz;
is the (im)moral equivalent of these two:
&foo;
print(uc($bar),$baz);
See Chapter 2, "Bits and Pieces" for more details on the comma operator. See "Prototypes" in Chapter 6, "Subroutines" for more on unary operators.

29.2.138. seek

seek FILEHANDLE, OFFSET, WHENCE
This function positions the file pointer for FILEHANDLE, just like the fseek(3) call of standard I/O. The first position in a file is at offset 0, not offset 1. Also, offsets refer to byte positions, not line numbers. In general, since line lengths vary, it's not possible to access a particular line number without examining the whole file up to that point, unless all your lines are known to be of a particular length, or you've built an index that translates line numbers into byte offsets. (The same restrictions apply to character positions in files with variable-length character encodings: the operating system doesn't know what characters are, only bytes.)

FILEHANDLE can be an expression whose value gives either the name of the actual filehandle or a reference to anything resembling a filehandle object. The function returns true upon success, false otherwise. For handiness, the function can calculate offsets from various file positions for you. The value of WHENCE specifies which file position your OFFSET uses for its starting point: 0, the beginning of the file; 1, the current position in the file; or 2, the end of the file. The OFFSET can be negative for a WHENCE of 1 or 2. If you'd like to use symbolic values for WHENCE, you may use SEEK_SET, SEEK_CUR, and SEEK_END from either the IO::Seekable or the POSIX module, or as of the 5.6 release of Perl, the Fcntl module.

If you want to position the file for sysread or syswrite, don't use seek; standard I/O buffering makes its effect on the file's system position unpredictable and nonportable. Use sysseek instead.

Due to the rules and rigors of ANSI C, on some systems you have to do a seek whenever you switch between reading and writing. Amongst other things, this may have the effect of calling the standard I/O library's clearerr(3) function. A WHENCE of 1 (SEEK_CUR) with an OFFSET 0 is useful for not moving the file position:

seek(TEST,0,1);
One interesting use for this function is to allow you to follow growing files, like this:
for (;;) {
    while (<LOG>) {
        grok($_);          # Process current line.
    }
    sleep 15;
    seek LOG,0,1;          # Reset end-of-file error.
}
The final seek clears the end-of-file error without moving the pointer. Depending on how standard your C library's standard I/O implementation happens to be, you may need something more like this:
for (;;) {
    for ($curpos = tell FILE; <FILE>; $curpos = tell FILE) {
        grok($_);          # Process current line.
    }
    sleep $for_a_while;
    seek FILE, $curpos, 0; # Reset end-of-file error.
}
Similar strategies can be used to remember the seek addresses of each line in an array.

29.2.139. seekdir

seekdir DIRHANDLE, POS
This function sets the current position for the next call to readdir on DIRHANDLE. POS must be a value returned by telldir. This function has the same caveats about possible directory compaction as the corresponding system library routine. The function may not be implemented everywhere that readdir is. It's certainly not implemented where readdir isn't.

29.2.140. select (output filehandle)

select FILEHANDLE
select
For historical reasons, there are two select operators that are totally unrelated to each other. See the next section for the other one. This version of the select operator returns the currently selected output filehandle and, if FILEHANDLE is supplied, sets the current default filehandle for output. This has two effects: first, a write or a print without a filehandle will default to this FILEHANDLE. Second, special variables related to output will refer to this output filehandle. For example, if you have to set the same top-of-form format for more than one output filehandle, you might do the following:
select REPORT1;
$^ = 'MyTop';
select REPORT2;
$^ = 'MyTop';
But note that this leaves REPORT2 as the currently selected filehandle. This could be construed as antisocial, since it could really foul up some other routine's print or write statements. Properly written library routines leave the currently selected filehandle the same on exit as it was upon entry. To support this, FILEHANDLE may be an expression whose value gives the name of the actual filehandle. Thus, you can save and restore the currently selected filehandle like this:
my $oldfh = select STDERR; $| = 1; select $oldfh;
or idiomatically but somewhat obscurely like this:
select((select(STDERR), $| = 1)[0])
This example works by building a list consisting of the returned value from select(STDERR) (which selects STDERR as a side effect) and $| = 1 (which is always 1), but sets autoflushing on the now-selected STDERR as a side effect. The first element of that list (the previously selected filehandle) is now used as an argument to the outer select. Bizarre, right? That's what you get for knowing just enough Lisp to be dangerous.

You can also use the standard SelectSaver module to automatically restore the previous select upon scope exit.

However, now that we've explained all that, we should point out that you rarely need to use this form of select nowadays, because most of the special variables you would want to set have object-oriented wrapper methods to do it for you. So instead of setting $| directly, you might say:

use IO::Handle;             # Unfortunately, this is *not* a small module.
STDOUT->autoflush(1);
And the earlier format example might be coded as:
use IO::Handle;
REPORT1->format_top_name("MyTop");
REPORT2->format_top_name("MyTop");

29.2.141. select (ready file descriptors)

select RBITS, WBITS, EBITS, TIMEOUT
The four-argument select operator is totally unrelated to the previously described select operator. This operator is used to discover which (if any) of your file descriptors are ready to do input or output, or to report an exceptional condition. (This helps you avoid having to do polling.) It calls the select(2) syscall with the bit masks you've specified, which you can construct using fileno and vec, like this:
$rin = $win = $ein = "";
vec($rin, fileno(STDIN), 1)  = 1;
vec($win, fileno(STDOUT), 1) = 1;
$ein = $rin | $win;
If you want to select on many filehandles, you might wish to write a subroutine:
sub fhbits {
    my @fhlist = @_;
    my $bits;
    for (@fhlist) {
        vec($bits, fileno($_), 1) = 1;
    }
    return $bits;
}
$rin = fhbits(qw(STDIN TTY MYSOCK));
If you wish to use the same bit masks repeatedly (and it's more efficient if you do), the usual idiom is:
($nfound, $timeleft) =
    select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
Or to block until any file descriptor becomes ready:
$nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
As you can see, calling select in scalar context just returns $nfound, the number of ready descriptors found.

The $wout=$win trick works because the value of an assignment is its left side, so $wout gets clobbered first by the assignment and then by the select, while $win remains unchanged.

Any of the arguments can also be undef, in which case they're ignored. The TIMEOUT, if not undef, is in seconds, which may be fractional. (A timeout of 0 effects a poll.) Not many implementations are capable of returning $timeleft. If not, they always return $timeleft equal to the supplied $timeout.

The standard IO::Select module provides a more user-friendly interface to select, mostly because it does all the bit mask work for you.

One use for select is to sleep with a finer resolution than sleep allows. To do this, specify undef for all the bitmasks. So, to sleep for (at least) 4.75 seconds, use:

select undef, undef, undef, 4.75;
(On some non-Unix systems the triple undef may not work, and you may need to fake up at least one bitmask for a valid descriptor that won't ever be ready.)

One should probably not attempt to mix buffered I/O (like read or <HANDLE>) with select, except as permitted by POSIX, and even then only on truly POSIX systems. Use sysread instead.

29.2.142. semctl

semctl ID, SEMNUM, CMD, ARG
This function calls the System V IPC function semctl(2). You'll probably have to say useIPC::SysV first to get the correct constant definitions. If CMD is IPC_STAT or GETALL, then ARG must be a variable that will hold the returned semid_ds structure or semaphore value array. As with ioctl and fcntl, return values are undef for error, "0 but true" for zero, and the actual return value otherwise.

See also the IPC::Semaphore module. This function is available only on machines supporting System V IPC.

29.2.143. semget

semget KEY, NSEMS, SIZE, FLAGS
This function calls the System V IPC syscall semget(2). Before calling, you should useIPC::SysV to get the correct constant definitions. The function returns the semaphore ID, or undef if there is an error.

See also the IPC::Semaphore module. This function is available only on machines supporting System V IPC.

29.2.144. semop

semop KEY, OPSTRING
This function calls the System V IPC syscall semop(2) to perform semaphore operations such as signalling and waiting. Before calling, you should useIPC::SysV to get the correct constant definitions.

OPSTRING must be a packed array of semop structures. You can make each semop structure by saying pack("s*", $semnum, $semop, $semflag). The number of semaphore operations is implied by the length of OPSTRING. The function returns true if successful, or false if there is an error.

The following code waits on semaphore $semnum of semaphore id $semid:

$semop = pack "s*", $semnum, -1, 0;
semop $semid, $semop or die "Semaphore trouble: $!\n";
To signal the semaphore, simply replace -1 with 1.

See the section "System V IPC" in Chapter 16, "Interprocess Communication". See also the IPC::Semaphore module. This function is available only on machines supporting System V IPC.

29.2.145. send

send SOCKET, MSG, FLAGS, TO
send SOCKET, MSG, FLAGS
This function sends a message on a socket. It takes the same flags as the syscall of the same name--see send(2). On unconnected sockets, you must specify a destination to send TO, which then makes Perl's send work like sendto(2). The C syscall sendmsg(2) is currently unimplemented in standard Perl. The send function returns the number of bytes sent, or undef if there is an error.

(Some non-Unix systems improperly treat sockets as different from ordinary file descriptors, with the result that you must always use send and recv on sockets rather than the handier standard I/O operators.)

One error that at least one of us makes frequently is to confuse Perl's send with C's send and write:

send SOCK, $buffer, length $buffer      # WRONG
This will mysteriously fail depending on the relationship of the string length to the FLAGS bits expected by the system. See the section "Message Passing" in Chapter 16, "Interprocess Communication" for examples.

29.2.146. setpgrp

setpgrp PID, PGRP
This function sets the current process group (PGRP) for the specified PID (use a PID of 0 for the current process). Invoking setpgrp will raise an exception if used on a machine that doesn't implement setpgrp(2). Beware: some systems will ignore the arguments you provide and always do setpgrp(0, $$). Fortunately, those are the arguments one usually wants to provide. If the arguments are omitted, they default to 0,0. The BSD 4.2 version of setpgrp did not accept any arguments, but in BSD 4.4, it is a synonym for the setpgid function. For better portability (by some definition), use the setpgid function in the POSIX module directly. If what you're really trying to do is daemonize your script, consider the POSIX::setsid() function as well. Note that the POSIX version of setpgrp does not accept arguments, so only setpgrp(0,0) is truly portable.

29.2.147. setpriority

setpriority WHICH, WHO, PRIORITY
This function sets the current PRIORITY for a process, a process group, or a user, as specified by the WHICH and WHO. See setpriority(2). Invoking setpriority will raise an exception if used on a machine that doesn't implement setpriority(2). To "nice" your process down by four units (the same as executing your program with nice(1)), try:
setpriority 0, 0, getpriority(0, 0) + 4;
The interpretation of a given priority may vary from one operating system to the next. Some priorities may be unavailable to nonprivileged users.

See also the BSD::Resource module from CPAN.

29.2.148. setsockopt

setsockopt SOCKET, LEVEL, OPTNAME, OPTVAL
This function sets the socket option requested. The function returns undef on error. LEVEL specifies which protocol layer you're aiming the call at, or SOL_SOCKET for the socket itself at the top of all the layers. OPTVAL may be specified as undef if you don't want to pass an argument. A common option to set on a socket is SO_REUSEADDR, to get around the problem of not being able to bind to a particular address while the previous TCP connection on that port is still making up its mind to shut down. That would look like this:
use Socket;
socket(SOCK, ...) or die "Can't make socket: $!\n";
setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, 1)
        or warn "Can't do setsockopt: $!\n";

See setsockopt(2) for other possible values.

29.2.149. shift

shift ARRAY
shift
This function shifts the first value of the array off and returns it, shortening the array by one and moving everything down. (Or up, or left, depending on how you visualize the array list. We like left.) If there are no elements in the array, the function returns undef.

If ARRAY is omitted, the function shifts @_ within the lexical scope of subroutines and formats; it shifts @ARGV at file scopes (typically the main program) or within the lexical scopes established by the eval STRING, BEGIN {}, CHECK {}, INIT {}, and END {} constructs.

Subroutines often start by copying their arguments into lexical variables, and shift can be used for this:

sub marine {
        my $fathoms = shift;  # depth
        my $fishies = shift;  # number of fish
        my $o2      = shift;  # oxygen concentration
        # ...
}
shift is also used to process arguments at the front of your program:
while (defined($_ = shift)) {
        /^[^-]/     && do { unshift @ARGV, $_; last };
        /^-w/       && do { $WARN = 1;         next };
        /^-r/       && do { $RECURSE = 1;      next };
        die "Unknown argument $_\n";
}
You might also consider the Getopt::Std and Getopt::Long modules for processing program arguments.

See also unshift, push, pop, and splice. The shift and unshift functions do the same thing to the left end of an array that pop and push do to the right end.

29.2.150. shmctl

shmctl ID, CMD, ARG
This function calls the System V IPC syscall, shmctl(2). Before calling, you should useIPC::SysV to get the correct constant definitions.

If CMD is IPC_STAT, then ARG must be a variable that will hold the returned shmid_ds structure. Like ioctl and fcntl, the function returns undef for error, "0 but true" for zero, and the actual return value otherwise.

This function is available only on machines supporting System V IPC.

29.2.151. shmget

shmget KEY, SIZE, FLAGS
This function calls the System V IPC syscall, shmget(2). The function returns the shared memory segment ID, or undef if there is an error. Before calling, useSysV::IPC.

This function is available only on machines supporting System V IPC.

29.2.152. shmread

shmread ID, VAR, POS, SIZE
This function reads from the shared memory segment ID starting at position POS for size SIZE (by attaching to it, copying out, and detaching from it). VAR must be a variable that will hold the data read. The function returns true if successful, or false if there is an error.

This function is available only on machines supporting System V IPC.

29.2.153. shmwrite

shmwrite ID, STRING, POS, SIZE
This function writes to the shared memory segment ID starting at position POS for size SIZE (by attaching to it, copying in, and detaching from it). If STRING is too long, only SIZE bytes are used; if STRING is too short, nulls are written to fill out SIZE bytes. The function returns true if successful, or false if there is an error.

This function is available only on machines supporting System V IPC. (You're probably tired of reading that--we're getting tired of saying it.)

29.2.154. shutdown

shutdown SOCKET, HOW
This function shuts down a socket connection in the manner indicated by HOW. If HOW is 0, further receives are disallowed. If HOW is 1, further sends are disallowed. If HOW is 2, everything is disallowed.
shutdown(SOCK, 0);    # no more reading
shutdown(SOCK, 1);    # no more writing
shutdown(SOCK, 2);    # no more I/O at all
This is useful with sockets when you want to tell the other side you're done writing but not done reading, or vice versa. It's also a more insistent form of close because it also disables any copies of those file descriptors held in forked processes.

Imagine a server that wants to read its client's request until end of file, then send an answer. If the client calls close, that socket is now invalid for I/O, so no answer would ever come back. Instead, the client should use shutdown to half-close the connection:

print SERVER "my request\n";        # send some data
shutdown(SERVER, 1);                # send eof; no more writing
$answer = <SERVER>;                 # but you can still read
(If you came here trying to figure out how to shut down your system, you'll have to execute an external program to do that. See system.)

29.2.155. sin

sin EXPR
sin
Sorry, there's nothing wicked about this operator. It merely returns the sine of EXPR (expressed in radians).

For the inverse sine operation, you may use Math::Trig or the POSIX module's asin function, or use this relation:

sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }

29.2.156. sleep

sleep EXPR
sleep
This function causes the script to sleep for EXPR seconds, or forever if no EXPR, and returns the number of seconds slept. It may be interrupted by sending the process a SIGALRM. On some older systems, it may sleep up to a full second less than what you requested, depending on how it counts seconds. Most modern systems always sleep the full amount. They may appear to sleep longer than that, however, because your process might not be scheduled right away in a busy multitasking system. If available, the select (ready file descriptors) call can give you better resolution. You may also be able to use syscall to call the getitimer(2) and setitimer(2) routines that some Unix systems support. You probably cannot mix alarm and sleep calls, because sleep is often implemented using alarm.

See also the POSIX module's sigpause function.

29.2.157. socket

socket SOCKET, DOMAIN, TYPE, PROTOCOL
This function opens a socket of the specified kind and attaches it to filehandle SOCKET. DOMAIN, TYPE, and PROTOCOL are specified the same as for socket(2). If undefined, SOCKET will be autovivified. Before using this function, your program should contain the line:
use Socket;
This gives you the proper constants. The function returns true if successful. See the examples in the section "Sockets" in Chapter 16, "Interprocess Communication".

On systems that support a close-on-exec flag on files, the flag will be set for the newly opened file descriptor, as determined by the value of $^F. See the $^F ($SYSTEM_FD_MAX) variable in Chapter 28, "Special Names".

29.2.158. socketpair

socketpair SOCKET1, SOCKET2, DOMAIN, TYPE, PROTOCOL
This function creates an unnamed pair of sockets in the specified domain, of the specified type. DOMAIN, TYPE, and PROTOCOL are specified the same as for socketpair(2). If either socket argument is undefined, it will be autovivified. The function returns true if successful, false otherwise. On a system where socketpair(2) is unimplemented, calling this function raises an exception.

This function is typically used just before a fork. One of the resulting processes should close SOCKET1, and the other should close SOCKET2. You can use these sockets bidirectionally, unlike the filehandles created by the pipe function. Some systems define pipe in terms of socketpair, in which a call to pipe(Rdr, Wtr) is essentially:

use Socket;
socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
shutdown(Rdr, 1);        # no more writing for reader
shutdown(Wtr, 0);        # no more reading for writer
On systems that support a close-on-exec flag on files, the flag will be set for the newly opened file descriptors, as determined by the value of $^F. See the $^F ($SYSTEM_FD_MAX) variable in Chapter 28, "Special Names". See also the example at the end of the section "Bidirectional Communication" in Chapter 16, "Interprocess Communication".

29.2.159. sort

sort USERSUB LIST
sort BLOCK LIST
sort LIST
This function sorts the LIST and returns the sorted list value. By default, it sorts in standard string comparison order (undefined values sort before defined null strings, which sort before everything else). When the use locale pragma is in effect, sort LIST sorts LIST according to the current collation locale.

USERSUB, if given, is the name of a subroutine that returns an integer less than, equal to, or greater than 0, depending on how the elements of the list are to be ordered. (The handy <=> and cmp operators can be used to perform three-way numeric and string comparisons.) If a USERSUB is given but that function is undefined, sort raises an exception.

In the interests of efficiency, the normal calling code for subroutines is bypassed, with the following effects: the subroutine may not be a recursive subroutine (nor may you exit the block or routine with a loop control operator), and the two elements to be compared are not passed into the subroutine via @_, but rather by temporarily setting the global variables $a and $b in the package in which the sort was compiled (see the examples that follow). The variables $a and $b are aliases to the real values, so don't modify them in the subroutine.

The comparison subroutine is required to behave. If it returns inconsistent results (sometimes saying $x[1] is less than $x[2] and sometimes saying the opposite, for example), the results are not well defined. (That's another reason you shouldn't modify $a and $b.)

USERSUB may be a scalar variable name (unsubscripted), in which case the value provides either a symbolic or a hard reference to the actual subroutine to use. (A symbolic name rather than a hard reference is allowed even when the use strict 'refs' pragma is in effect.) In place of a USERSUB, you can provide a BLOCK as an anonymous, inline sort subroutine.

To do an ordinary numeric sort, say this:

sub numerically { $a <=> $b }
@sortedbynumber = sort numerically 53,29,11,32,7;
To sort in descending order, you could simply apply reverse after the sort, or you could reverse the order of $a and $b in the sort routine:
@descending = reverse sort numerically 53,29,11,32,7;

sub reverse_numerically { $b <=> $a }
@descending = sort reverse_numerically 53,29,11,32,7;
To sort strings without regard to case, run $a and $b through lc before comparing:
@unsorted = qw/sparrow Ostrich LARK catbird blueJAY/;
@sorted = sort { lc($a) cmp lc($b) } @unsorted;
(Under Unicode, the use of lc for case canonicalization is vaguely preferred to the use of uc, since some languages differentiate titlecase from uppercase. But that doesn't matter for basic ASCII sorting, and if you're going to do Unicode sorting right, your canonicalization routines are going to be a lot fancier than lc.)

Sorting hashes by value is a common use of the sort function. For example, if a %sales_amount hash records department sales, doing a hash lookup in the sort routine allows the hash keys to be sorted according to their corresponding values:

# sort from highest to lowest department sales
sub bysales { $sales_amount{$b} <=> $sales_amount{$a} }

for $dept (sort bysales keys %sale_amount) {
    print "$dept => $sales_amount{$dept}\n";
}
You can perform additional levels of sorting by cascading multiple comparisons using the || or or operators. This works nicely because the comparison operators conveniently return 0 for equivalence, causing them to fall through to the next comparison. Here, the hash keys are sorted first by their associated sales amounts and then by the keys themselves (in case two or more departments have the same sales amount):
sub by_sales_then_dept {
    $sales_amount{$b} <=> $sales_amount{$a}
       ||
    $a cmp $b
}

for $dept (sort by_sales_then_dept keys %sale_amount) {
    print "$dept => $sales_amount{$dept}\n";
}
Assume that @recs is an array of hash references, where each hash contains fields such as FIRSTNAME, LASTNAME, AGE, HEIGHT, and SALARY. The following routine sorts to the front of the list those records for people who are first richer, then taller, then younger, then less alphabetically challenged:
sub prospects {
    $b->{SALARY}    <=>  $a->{SALARY}
        ||
    $b->{HEIGHT}    <=>  $a->{HEIGHT}
        ||
    $a->{AGE}       <=>  $b->{AGE}
        ||
    $a->{LASTNAME}  cmp  $b->{LASTNAME}
        ||
    $a->{FIRSTNAME} cmp  $b->{FIRSTNAME}
}

@sorted = sort prospects @recs;
Any useful information that can be derived from $a and $b can serve as the basis of a comparison in a sort routine. For example, if lines of text are to be sorted according to specific fields, split could be used within the sort routine to derive the fields.
@sorted_lines = sort {
    @a_fields = split /:/, $a;     # colon-separated fields
    @b_fields = split /:/, $b;

    $a_fields[3] <=> $b_fields[3]  # numeric sort on 4th field, then
        ||
    $a_fields[0] cmp $b_fields[0]  # string sort on 1st field, then
        ||
    $b_fields[2] <=> $a_fields[2]  # reverse numeric sort on 3rd field
        ||
    ...                            # etc.

} @lines;
However, because sort performs the sort routine many times using different pairings of values for $a and $b, the previous example will resplit each line more often than needed.

To avoid the expense of repeated derivations such as the splitting of lines in order to compare their fields, perform the derivation once per value prior to the sort and save the derived information. Here, anonymous arrays are created to encapsulate each line along with the results of splitting the line:

@temp = map { [$_, split /:/] } @lines;
Next, the array references are sorted:
@temp = sort {
    @a_fields = @$a[1..$#$a];
    @b_fields = @$b[1..$#$b];

    $a_fields[3] <=> $b_fields[3]  # numeric sort on 4th field, then
        ||
    $a_fields[0] cmp $b_fields[0]  # string sort on 1st field, then
        ||
    $b_fields[2] <=> $a_fields[2]  # reverse numeric sort on 3rd field
        ||
    ...                            # etc.

} @temp;
Now that the array references are sorted, the original lines can be retrieved from the anonymous arrays:
@sorted_lines = map { $_->[0] } @temp;
Putting it all together, this map-sort-map technique, often referred to as the Schwartzian Transform, can be performed in one statement:
@sorted_lines = map { $_->[0] }
                sort {
                    @a_fields = @$a[1..$#$a];
                    @b_fields = @$b[1..$#$b];

                    $a_fields[3] <=> $b_fields[3]
                        ||
                    $a_fields[0] cmp $b_fields[0]
                        ||
                    $b_fields[2] <=> $a_fields[2]
                        ||
                    ...
                }
                map { [$_, split /:/] } @lines;
Do not declare $a and $b as lexical variables (with my). They are package globals (though they're exempt from the usual restrictions on globals when you're using use strict). You do need to make sure your sort routine is in the same package though, or else qualify $a and $b with the package name of the caller.

That being said, in version 5.6 you can write sort subroutines with the standard argument passing method (and, not coincidentally, use XS subroutines as sort subroutines), provided that you declare the sort subroutine with a prototype of ($$). And if you do that, then you can in fact declare $a and $b as lexicals:

sub numerically ($$) {
        my ($a, $b) = @_;
        $a <=> $b;
}
And someday, when full prototypes are implemented, you'll just say:
sub numerically ($a, $b) { $a <=> $b }
and then we'll be back where we started, more or less.

29.2.160. splice

splice ARRAY, OFFSET, LENGTH, LIST
splice ARRAY, OFFSET, LENGTH
splice ARRAY, OFFSET
splice ARRAY
This function removes the elements designated by OFFSET and LENGTH from an ARRAY, and replaces them with the elements of LIST, if any. If OFFSET is negative, the function counts backward from the end of the array, but if that would land before the beginning of the array, an exception is raised. In list context, splice returns the elements removed from the array. In scalar context, it returns the last element removed, or undef if there was none. If the number of new elements doesn't equal the number of old elements, the array grows or shrinks as necessary, and elements after the splice change their position correspondingly. If LENGTH is omitted, the function removes everything from OFFSET onward. If OFFSET is omitted, the array is cleared as it is read. The following equivalences hold (assuming $[ is 0):

Direct Method | Splice Equivalent
push(@a, $x, $y) | splice(@a, @a, 0, $x, $y)
pop(@a) | splice(@a, -1)
shift(@a) | splice(@a, 0, 1)
unshift(@a, $x, $y) | splice(@a, 0, 0, $x, $y)
$a[$x] = $y | splice(@a, $x, 1, $y)
(@a, @a = ()) | splice(@a)

The splice function is also handy for carving up the argument list passed to a subroutine. For example, assuming list lengths are passed before lists:

sub list_eq {       # compare two list values
    my @a = splice(@_, 0, shift);
    my @b = splice(@_, 0, shift);
    return 0 unless @a == @b;       # same length?
    while (@a) {
        return 0 if pop(@a) ne pop(@b);
    }
    return 1;
}
if (list_eq($len, @foo[1..$len], scalar(@bar), @bar)) { ... }
It would be cleaner to use array references for this, however.

29.2.161. split [taintgray]

split /PATTERN/, EXPR, LIMIT
split /PATTERN/, EXPR
split /PATTERN/
split
This function scans a string given by EXPR for separators, and splits the string into a list of substrings, returning the resulting list value in list context or the count of substrings in scalar context.[11] The separators are determined by repeated pattern matching, using the regular expression given in PATTERN, so the separators may be of any size and need not be the same string on every match. (The separators are not ordinarily returned; exceptions are discussed later in this section.) If the PATTERN doesn't match the string at all, split returns the original string as a single substring. If it matches once, you get two substrings, and so on. You may supply regular expression modifiers to the PATTERN, like /PATTERN/i, /PATTERN/x, etc. The //m modifier is assumed when you split on the pattern /^/.

[11]Scalar context also causes split to write its result to @_, but this usage is deprecated.

If LIMIT is specified and positive, the function splits into no more than that many fields (though it may split into fewer if it runs out of separators). If LIMIT is negative, it is treated as if an arbitrarily large LIMIT has been specified. If LIMIT is omitted or zero, trailing null fields are stripped from the result (which potential users of pop would do well to remember). If EXPR is omitted, the function splits the $_ string. If PATTERN is also omitted or is the literal space, " ", the function splits on whitespace, /\s+/, after skipping any leading whitespace.

Strings of any length can be split:

@chars  = split //,   $word;
@fields = split /:/,  $line;
@words  = split " ",  $paragraph;
@lines  = split /^/,  $buffer;
A pattern capable of matching either the null string or something longer than the null string (for instance, a pattern consisting of any single character modified by a * or ?) will split the value of EXPR into separate characters wherever it matches the null string between characters; non-null matches will skip over the matched separator characters in the usual fashion. (In other words, a pattern won't match in one spot more than once, even if it matched with a zero width.) For example:
print join ':', split / */, 'hi there';
produces the output "h:i:t:h:e:r:e". The space disappears because it matches as part of the separator. As a trivial case, the null pattern // simply splits into separate characters, and spaces do not disappear. (For normal pattern matches, a // pattern would repeat the last successfully matched pattern, but split's pattern is exempt from that wrinkle.)

The LIMIT parameter splits only part of a string:

($login, $passwd, $remainder) = split /:/, $_, 3;
We encourage you to split to lists of names like this in order to make your code self-documenting. (For purposes of error checking, note that $remainder would be undefined if there were fewer than three fields.) When assigning to a list, if LIMIT is omitted, Perl supplies a LIMIT one larger than the number of variables in the list, to avoid unnecessary work. For the split above, LIMIT would have been 4 by default, and $remainder would have received only the third field, not all the rest of the fields. In time-critical applications, it behooves you not to split into more fields than you really need. (The trouble with powerful languages is that they let you be powerfully stupid at times.)

We said earlier that the separators are not returned, but if the PATTERN contains parentheses, then the substring matched by each pair of parentheses is included in the resulting list, interspersed with the fields that are ordinarily returned. Here's a simple example:

split /([-,])/, "1-10,20";
produces the list value:
(1, '-', 10, ',', 20)
With more parentheses, a field is returned for each pair, even if some pairs don't match, in which case undefined values are returned in those positions. So if you say:
split /(-)|(,)/, "1-10,20";
you get the value:
(1, '-', undef, 10, undef, ',', 20)
The /PATTERN/ argument may be replaced with an expression to specify patterns that vary at run time. As with ordinary patterns, to do run-time compilation only once, use /$variable/o.

As a special case, if the expression is a single space (" "), the function splits on whitespace just as split with no arguments does. Thus, split(" ") can be used to emulate awk's default behavior. In contrast, split(/ /) will give you as many null initial fields as there are leading spaces. (Other than this special case, if you supply a string instead of a regular expression, it'll be interpreted as a regular expression anyway.) You can use this property to remove leading and trailing whitespace from a string and to collapse intervening stretches of whitespace into a single space:

$string = join(' ', split(' ', $string));
The following example splits an RFC 822 message header into a hash containing $head{Date}, $head{Subject}, and so on. It uses the trick of assigning a list of pairs to a hash, based on the fact that separators alternate with separated fields. It makes use of parentheses to return part of each separator as part of the returned list value. Since the split pattern is guaranteed to return things in pairs by virtue of containing one set of parentheses, the hash assignment is guaranteed to receive a list consisting of key/value pairs, where each key is the name of a header field. (Unfortunately, this technique loses information for multiple lines with the same key field, such as Received-By lines. Ah, well. . . .)
$header =~ s/\n\s+/ /g;      # Merge continuation lines.
%head = ('FRONTSTUFF', split /^(\S*?):\s*/m, $header);
The following example processes the entries in a Unix passwd(5) file. You could leave out the chomp, in which case $shell would have a newline on the end of it.
open PASSWD, '/etc/passwd';
while (<PASSWD>) {
    chomp;        # remove trailing newline
    ($login, $passwd, $uid, $gid, $gcos, $home, $shell) =
            split /:/;
    ...
}
Here's how to process each word of each line of each file of input to create a word-frequency hash.
while (<>) {
    foreach $word (split) {
        $count{$word}++;
    }
}
The inverse of split is performed by join (except that join can only join with the same separator between all fields). To break apart a string with fixed-position fields, use unpack.

29.2.162. sprintf

sprintf FORMAT, LIST
This function returns a string formatted by the usual printf conventions of the C library function sprintf. See sprintf(3) or printf(3) on your system for an explanation of the general principles. The FORMAT string contains text with embedded field specifiers into which the elements of LIST are substituted, one per field.

Perl does its own sprintf formatting--it emulates the C function sprintf, but it doesn't use it.[12] As a result, any nonstandard extensions in your local sprintf(3) function are not available from Perl.

[12]Except for floating-point numbers, and even then only the standard modifiers are allowed.

Perl's sprintf permits the universally known conversions shown in Table 29-4.

Table 29.4. Formats for sprintf

Field | Meaning
%% | A percent sign
%c | A character with the given number
%s | A string
%d | A signed integer, in decimal
%u | An unsigned integer, in decimal
%o | An unsigned integer, in octal
%x | An unsigned integer, in hexadecimal
%e | A floating-point number, in scientific notation
%f | A floating-point number, in fixed decimal notation
%g | A floating-point number, in %e or %f notation

In addition, Perl permits the following widely supported conversions:

Field | Meaning
%X | Like %x, but using uppercase letters
%E | Like %e, but using an uppercase "E"
%G | Like %g, but with an uppercase "E" (if applicable)
%b | An unsigned integer, in binary
%p | A pointer (outputs the Perl value's address in hexadecimal)
%n | Special: stores the number of characters output so far into the next variable in the argument list

Finally, for backward (and we do mean "backward") compatibility, Perl permits these unnecessary but widely supported conversions:

Field | Meaning
%i | A synonym for %d
%D | A synonym for %ld
%U | A synonym for %lu
%O | A synonym for %lo
%F | A synonym for %f

Perl permits the following universally known flags between the % and the conversion character:

Flag | Meaning
space | Prefix positive number with a space
+ | Prefix positive number with a plus sign
- | Left-justify within the field
0 | Use zeros, not spaces, to right-justify
# | Prefix nonzero octal with "0", nonzero hex with "0x"
number | Minimum field width
.number | "Precision": digits after decimal point for floating-point numbers, maximum length for string, minimum length for integer
l | Interpret integer as C type long or unsigned long
h | Interpret integer as C type short or unsigned short (if no flags are supplied, interpret integer as C type int or unsigned)

There are also two Perl-specific flags:

Flag | Meaning
V | Interpret integer as Perl's standard integer type
v | Interpret string as a vector of integers, output as numbers separated either by dots, or by an arbitrary string received from the argument list when the flag is preceded by *

If your Perl understands "quads" (64-bit integers) either because the platform natively supports them or because Perl has been specifically compiled with that ability, then the characters d u o x X b i D U O print quads, and they may optionally be preceded by ll, L, or q. For example, %lld %16LX %qo.

If Perl understands "long doubles" (this requires that the platform support long doubles), the flags e f g E F G may optionally be preceded by ll or L. For example, %llf %Lg.

Where a number would appear in the flags, an asterisk ("*") may be used instead, in which case Perl uses the next item in the argument list as the given number (that is, as the field width or precision). If a field width obtained through "*" is negative, it has the same effect as the "-" flag: left-justification.

The v flag is useful for displaying ordinal values of characters in arbitrary strings:

sprintf "version is v%vd\n", $^V;           # Perl's version
sprintf "address is %vd\n", $addr;          # IPv4 address
sprintf "address is %*vX\n", ":", $addr;    # IPv6 address
sprintf "bits are %*vb\n", " ", $bits;      # random bit strings

29.2.163. sqrt

sqrt EXPR
sqrt
This function returns the square root of EXPR. For other roots such as cube roots, you can use the ** operator to raise something to a fractional power. Don't try either of these approaches with negative numbers, as that poses a slightly more complex problem (and raises an exception). But there's a standard module to take care of even that:
use Math::Complex;
print sqrt(-2);    # prints 1.4142135623731i

29.2.164. srand

srand EXPR
srand
This function sets the random number seed for the rand operator. If EXPR is omitted, it uses a semirandom value supplied by the kernel (if it supports the /dev/urandom device) or based on the current time and process ID, among other things. It's usually not necessary to call srand at all, because if it is not called explicitly, it is called implicitly at the first use of the rand operator. However, this was not true in versions of Perl prior to 5.004, so if your script needs to run under older Perl versions, it should call srand.

Frequently called programs (like CGI scripts) that simply use time ^ $$ for a seed can fall prey to the mathematical property that a^b == (a+1)^(b+1) one-third of the time. So don't do that. Use this instead:

srand( time() ^ ($$ + ($$ << 15)) );
You'll need something much more random than the default seed for cryptographic purposes. On some systems the /dev/random device is suitable. Otherwise, checksumming the compressed output of one or more rapidly changing operating system status programs is the usual method. For example:
srand (time ^ $$ ^ unpack "%32L*", `ps wwaxl | gzip`);
If you're particularly concerned with this, see the Math::TrulyRandom module in CPAN.

Do not call srand multiple times in your program unless you know exactly what you're doing and why you're doing it. The point of the function is to "seed" the rand function so that rand can produce a different sequence each time you run your program. Just do it once at the top of your program, or you won't get random numbers out of rand!

29.2.165. stat

stat FILEHANDLE
stat EXPR
stat
In scalar context, this function returns a Boolean value that indicates whether the call succeeded. In list context, it returns a 13-element list giving the statistics for a file, either the file opened via FILEHANDLE, or named by EXPR. It's typically used as follows:
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
    $atime,$mtime,$ctime,$blksize,$blocks)
            = stat $filename;
Not all fields are supported on all filesystem types; unsupported fields return 0. Table 29-5 lists the meanings of the fields.

Table 29.5. Fields Returned by stat

Index | Field | Meaning
0 | $dev | Device number of filesystem
1 | $ino | Inode number
2 | $mode | File mode (type and permissions)
3 | $nlink | Number of (hard) links to the file
4 | $uid | Numeric user ID of file's owner
5 | $gid | Numeric group ID of file's designated group
6 | $rdev | The device identifier (special files only)
7 | $size | Total size of file, in bytes
8 | $atime | Last access time in seconds since the epoch
9 | $mtime | Last modify time in seconds since the epoch
10 | $ctime | Inode change time (not creation time!) in seconds since the epoch
11 | $blksize | Preferred blocksize for file system I/O
12 | $blocks | Actual number of blocks allocated

$dev and $ino, taken together, uniquely identify a file on the same system. The $blksize and $blocks are likely defined only on BSD-derived filesystems. The $blocks field (if defined) is reported in 512-byte blocks. The value of $blocks*512 can differ greatly from $size for files containing unallocated blocks, or "holes", which aren't counted in $blocks.

If stat is passed the special filehandle consisting of an underline, no actual stat(2) is done, but the current contents of the stat structure from the last stat, lstat, or stat-based file test operator (such as -r, -w, and -x) are returned.

Because the mode contains both the file type and its permissions, you should mask off the file type portion and printf or sprintf using a "%o" if you want to see the real permissions:

$mode = (stat($filename))[2];
printf "Permissions are %04o\n", $mode & 07777;
The File::stat module provides a convenient, by-name access mechanism:
use File::stat;
$sb = stat($filename);
printf "File is %s, size is %s, perm %04o, mtime %s\n",
   $filename, $sb->size, $sb->mode & 07777,
   scalar localtime $sb->mtime;
You can also import symbolic definitions of the various mode bits from the Fcntl module. See the online documentation for more details.

Hint: if you need only the size of the file, check out the -s file test operator, which returns the size in bytes directly. There are also file tests that return the ages of files in days.

29.2.166. study

study SCALAR
study
This function takes extra time in order to study SCALAR in anticipation of doing many pattern matches on the string before it is next modified. This may or may not save time, depending on the nature and number of patterns you are searching on, and on the distribution of character frequencies in the string to be searched--you probably want to compare run times with and without it to see which runs faster. Those loops that scan for many short constant strings (including the constant parts of more complex patterns) will benefit most from study. If all your pattern matches are constant strings anchored at the front, study won't help at all, because no scanning is done. You may have only one study active at a time--if you study a different scalar the first is "unstudied".

The way study works is this: a linked list of every character in the string to be searched is made, so we know, for example, where all the "k" characters are. From each search string, the rarest character is selected, based on some static frequency tables constructed from some C programs and English text. Only those places that contain this rarest character are examined.

For example, here is a loop that inserts index-producing entries before any line containing a certain pattern:

while (<>) {
    study;
    print ".IX foo\n"      if /\bfoo\b/;
    print ".IX bar\n"      if /\bbar\b/;
    print ".IX blurfl\n"   if /\bblurfl\b/;
    ...
    print;
}
In searching for /\bfoo\b/, only those locations in $_ that contain "f" will be looked at, because "f" is rarer than "o". This is a big win except in pathological cases. The only question is whether it saves you more time than it took to build the linked list in the first place.

If you have to look for strings that you don't know until run time, you can build an entire loop as a string and eval that to avoid recompiling all your patterns all the time. Together with setting $/ to input entire files as one record, this can be very fast, often faster than specialized programs like fgrep(1). The following scans a list of files (@files) for a list of words (@words), and prints out the names of those files that contain a case-insensitive match:

$search = 'while (<>) { study;';
foreach $word (@words) {
    $search .= "++\$seen{\$ARGV} if /\\b$word\\b/i;\n";
}
$search .= "}";
@ARGV = @files;
undef $/;               # slurp each entire file
eval $search;           # this screams
die $@ if $@;           # in case eval failed
$/ = "\n";              # restore normal input terminator
foreach $file (sort keys(%seen)) {
    print "$file\n";
}
Now that we have the qr// operator, complicated run-time evals as seen above are less necessary. This does the same thing:
@pats = ();
foreach $word (@words) {
    push @pats, qr/\b${word}\b/i;
}
@ARGV = @files;
undef $/;               # slurp each entire file
while (<>) {
    for $pat (@pats) {
        $seen{$ARGV}++ if /$pat/;
    }
}
$/ = "\n";              # restore normal input terminator
foreach $file (sort keys(%seen)) {
    print "$file\n";
}

29.2.167. sub

Named declarations:

sub NAME PROTO ATTRS
sub NAME ATTRS
sub NAME PROTO
sub NAME
Named definitions:
sub NAME PROTO ATTRS BLOCK
sub NAME ATTRS BLOCK
sub NAME PROTO BLOCK
sub NAME BLOCK
Unnamed definitions:
sub PROTO ATTRS BLOCK
sub ATTRS BLOCK
sub PROTO BLOCK
sub BLOCK
The syntax of subroutine declarations and definitions looks complicated, but is actually pretty simple in practice. Everything is based on the syntax:
sub NAME PROTO ATTRS BLOCK
All four fields are optional; the only restrictions are that the fields that do occur must occur in that order, and that you must use at least one of NAME or BLOCK. For the moment, we'll ignore the PROTO and ATTRS; they're just modifiers on the basic syntax. The NAME and the BLOCK are the important parts to get straight:

  • If you just have a NAME and no BLOCK, it's a declaration of that name (and if you ever want to call the subroutine, you'll have to supply a definition with both a NAME and a BLOCK later). Named declarations are useful because the parser treats a name specially if it knows it's a user-defined subroutine. You can call such a subroutine either as a function or as an operator, just like built-in functions. These are sometimes called forward declarations.

  • If you have both a NAME and a BLOCK, it's a standard named subroutine definition (and a declaration too, if you didn't declare the name previously). Named definitions are useful because the BLOCK associates an actual meaning (the body of the subroutine) with the declaration. That's all we mean when we say it defines the subroutine rather than just declaring it. The definition is like the declaration, however, in that the surrounding code doesn't see it, and it returns no inline value by which you could reference the subroutine.

  • If you have just have a BLOCK without a NAME, it's a nameless definition, that is, an anonymous subroutine. Since it doesn't have a name, it's not a declaration at all, but a real operator that returns a reference to the anonymous subroutine body at run time. This is extremely useful for treating code as data. It allows you to pass odd chunks of code around to be used as callbacks, and maybe even as closures if the sub definition operator refers to any lexical variables outside of itself. That means that different calls to the same sub operator will do the bookkeeping necessary to keep the correct "version" of each such lexical variable in sight for the life of the closure, even if the original scope of the lexical variable has been destroyed.

In any of these three cases, either one or both of the PROTO and ATTRS may occur after the NAME and/or before the BLOCK. A prototype is a list of characters in parentheses that tell the parser how to treat arguments to the function. Attributes are introduced by a colon and supply additional information to the parser about the function. Here's a typical definition that includes all four fields:

sub numstrcmp ($$) : locked {
    my ($a, $b) = @_;
    return $a <=> $b || $a cmp $b;
}
For details on attribute lists and their manipulation, see the attributes pragma in Chapter 31, "Pragmatic Modules". See also Chapter 6, "Subroutines" and "Anonymous Subroutines" in Chapter 8, "References".

29.2.168. substr

substr EXPR, OFFSET, LENGTH, REPLACEMENT
substr EXPR, OFFSET, LENGTH
substr EXPR, OFFSET
This function extracts a substring out of the string given by EXPR and returns it. The substring is extracted starting at OFFSET characters from the front of the string. (Note: if you've messed with $[, the beginning of the string isn't at 0, but since you haven't messed with it (have you?), it is.) If OFFSET is negative, the substring starts that far from the end of the string instead. If LENGTH is omitted, everything to the end of the string is returned. If LENGTH is negative, the length is calculated to leave that many characters off the end of the string. Otherwise, LENGTH indicates the length of the substring to extract, which is sort of what you'd expect.

You may use substr as an lvalue (something to assign to), in which case EXPR must also be a legal lvalue. If you assign something shorter than the length of your substring, the string will shrink, and if you assign something longer than the length, the string will grow to accommodate it. To keep the string the same length, you may need to pad or chop your value using sprintf or the x operator. If you attempt to assign to an unallocated area past the end of the string, substr raises an exception.

To prepend the string "Larry" to the current value of $_, use:

substr($var, 0, 0) = "Larry";
To instead replace the first character of $_ with "Moe", use:
substr($var, 0, 1) = "Moe";
And finally, to replace the last character of $var with "Curly", use:
substr($var, -1) = "Curly";
An alternative to using substr as an lvalue is to specify the REPLACEMENT string as the fourth argument. This allows you to replace parts of the EXPR and return what was there before in one operation, just as you can with splice. The next example also replaces the last character of $var with "Curly" and puts that replaced character into $oldstr:
$oldstr = substr($var, -1, 1, "Curly");
You don't have to use lvalue substr only with assignment. This replaces any spaces with dots, but only in the last 10 characters in the string:
substr($var, -10) =~ s/ /./g;

29.2.169. symlink

symlink OLDNAME, NEWNAME
This function creates a new filename symbolically linked to the old filename. The function returns true for success, false otherwise. On systems that don't support symbolic links, it raises an exception at run time. To check for that, use eval to trap the potential error:
$can_symlink = eval { symlink("",""); 1 };
Or use the Config module. Be careful if you supply a relative symbolic link, since it'll be interpreted relative to the location of the symbolic link itself, not to your current working directory.

See also link and readlink earlier in this chapter.

29.2.170. syscall

syscall LIST
This function calls the system call (meaning a syscall, not a shell command) specified as the first element of the list passes the remaining elements as arguments to the system call. (Many of these calls are now more readily available through modules like POSIX.) The function raises an exception if syscall(2) is unimplemented.

The arguments are interpreted as follows: if a given argument is numeric, the argument is passed as a C integer. If not, a pointer to the string value is passed. You are responsible for making sure the string is long enough to receive any result that might be written into it; otherwise, you're looking at a core dump. You can't use a string literal (or other read-only string) as an argument to syscall because Perl has to assume that any string pointer might be written through. If your integer arguments are not literals and have never been interpreted in a numeric context, you may need to add 0 to them to force them to look like numbers.

syscall returns whatever value was returned by the system call invoked. By C coding conventions, if that system call fails, syscall returns -1 and sets $! (errno). Some system calls legitimately return -1 if successful. The proper way to handle such calls is to assign $!=0; before the call and check the value of $! if syscall returns -1.

Not all system calls can be accessed this way. For example, Perl supports passing up to 14 arguments to your system call, which in practice should usually suffice. However, there's a problem with syscalls that return multiple values. Consider syscall(&SYS_pipe): it returns the file number of the read end of the pipe it creates. There is no way to retrieve the file number of the other end. You can avoid this instance of the problem by using pipe instead. To solve the generic problem, write XSUBs (external subroutine modules, a dialect of C) to access the system calls directly. Then put your new module onto CPAN, and become wildly popular.

The following subroutine returns the current time as a floating-point number rather than as integer seconds as time returns. (It will only work on machines that support the gettimeofday(2) syscall.)

sub finetime() {
    package main;   # for next require
    require 'syscall.ph';
    # presize buffer to two 32-bit longs...
    my $tv = pack("LL", ());
    syscall(&SYS_gettimeofday, $tv, undef) >= 0
        or die "gettimeofday: $!";
    my($seconds, $microseconds) = unpack("LL", $tv);
    return $seconds + ($microseconds / 1_000_000);
}
Suppose Perl didn't support the setgroups(2) syscall,[13] but your kernel did. You could still get at it this way:
require 'syscall.ph';
syscall(&SYS_setgroups, scalar @newgids, pack("i*", @newgids))
        or die "setgroups: $!";
You may have to run h2ph as indicated in the Perl installation instructions for syscall.ph to exist. Some systems may require a pack template of "II" instead. Even more disturbing, syscall assumes the size equivalence of the C types int, long, and char*. Try not to think of syscall as the epitome of portability.

[13]Although through $(, it does.

See the Time::HiRes module from CPAN for a more rigorous approach to fine-grained timing issues.

29.2.171. sysopen

sysopen FILEHANDLE, FILENAME, MODE, MASK
sysopen FILEHANDLE, FILENAME, MODE
The sysopen function opens the file whose filename is given by FILENAME and associates it with FILEHANDLE. If FILEHANDLE is an expression, its value is used as the name of, or reference to, the filehandle. If FILEHANDLE is a variable whose value is undefined, a value will be created for you. The return value is true if the call succeeds, false otherwise.

This function is a direct interface to your operating system's open(2) syscall followed by an fdopen(3) library call. As such, you'll need to pretend you're a C programmer for a bit here. The possible values and flag bits of the MODE parameter are available through the Fcntl module. Because different systems support different flags, don't count on all of them being available on your system. Consult your open(2) manpage or its local equivalent for details. Nevertheless, the following flags should be present on any system with a reasonably standard C library:

Flag | Meaning
O_RDONLY | Read only.
O_WRONLY | Write only.
O_RDWR | Read and write.
O_CREAT | Create the file if it doesn't exist.
O_EXCL | Fail if the file already exists.
O_APPEND | Append to the file.
O_TRUNC | Truncate the file.
O_NONBLOCK | Nonblocking access.

Many other options are possible, however. Here are some less common flags:

Flag | Meaning
O_NDELAY | Old synonym for O_NONBLOCK.
O_SYNC | Writes block until data is physically written to the underlying hardware. O_ASYNC, O_DSYNC, and O_RSYNC may also be seen.
O_EXLOCK | flock with LOCK_EX (advisory only).
O_SHLOCK | flock with LOCK_SH (advisory only).
O_DIRECTORY | Fail if the file is not a directory.
O_NOFOLLOW | Fail if the last path component is a symbolic link.
O_BINARY | binmode the handle for Microsoft systems. An O_TEXT may also sometimes exist to get the opposite behavior.
O_LARGEFILE | Some systems need this for files over 2 GB.
O_NOCTTY | Opening a terminal file won't make that terminal become the process's controlling terminal if you don't have one yet. Usually no longer needed.

The O_EXCL flag is not for locking: here, exclusiveness means that if the file already exists, sysopen fails.

If the file named by FILENAME does not exist and the MODE includes the O_CREAT flag, then sysopen creates the file with initial permissions determined by the MASK argument (or 0666 if omitted) as modified by your process's current umask. This default is reasonable: see the entry on umask for an explanation.

Filehandles opened with open and sysopen may be used interchangeably. You do not need to use sysread and friends just because you happened to open the file with sysopen, nor are you precluded from doing so if you opened it with open. Both can do things that the other can't. Regular open can open pipes, fork processes, set disciplines, duplicate file handles, and convert a file descriptor number into a filehandle. It also ignores leading and trailing whitespace in filenames and respects "-" as a special filename. But when it comes to opening actual files, sysopen can do anything that open can.

The following examples show equivalent calls to both functions. We omit the or die $! checks for clarity, but make sure to always check return values in your programs. We'll restrict ourselves to using only flags available on virtually all operating systems. It's just a matter of controlling the values that you OR together using the bitwise | operator to pass in MODE argument.

  • Open a file for reading:

    open(FH, "<", $path);
sysopen(FH, $path, O_RDONLY);

  • Open a file for writing, creating a new file if needed, or truncating an old file:

    open(FH, ">", $path);
sysopen(FH, $path, O_WRONLY | O_TRUNC | O_CREAT);

  • Open a file for appending, creating one if necessary:

    open(FH, ">>", $path);
sysopen(FH, $path, O_WRONLY | O_APPEND | O_CREAT);

  • Open a file for update, where the file must already exist:

    open(FH, "+<", $path);
sysopen(FH, $path, O_RDWR);

And here are things you can do with sysopen but not with regular open:

  • Open and create a file for writing, which must not previously exist:

    sysopen(FH, $path, O_WRONLY | O_EXCL | O_CREAT);

  • Open a file for appending, which must already exist:

    sysopen(FH, $path, O_WRONLY | O_APPEND);

  • Open a file for update, creating a new file if necessary:

    sysopen(FH, $path, O_RDWR | O_CREAT);

  • Open a file for update, which must not already exist:

    sysopen(FH, $path, O_RDWR | O_EXCL | O_CREAT);

  • Open a write-only file without blocking, but not creating it if it doesn't exist:

    sysopen(FH, $path, O_WRONLY | O_NONBLOCK);

The FileHandle module described in Chapter 32, "Standard Modules" provides a set of object-oriented synonyms (plus a small bit of new functionality) for opening files. You are welcome to call the appropriate FileHandle methods[14] on any handle created with open, sysopen, pipe, socket, or accept, even if you didn't use the module to initialize those handles.

[14]Really IO::File or IO::Handle methods.

29.2.172. sysread [taintgray]

sysread FILEHANDLE, SCALAR, LENGTH, OFFSET
sysread FILEHANDLE, SCALAR, LENGTH
This function attempts to read LENGTH bytes of data into variable SCALAR from the specified FILEHANDLE using a low-level syscall, read(2). The function returns the number of bytes read, or 0 at EOF.[15] The sysread function returns undef on error. SCALAR will grow or shrink to the length actually read. The OFFSET, if specified, says where in the string to start putting the bytes, so that you can read into the middle of a string that's being used as a buffer. For an example of using OFFSET, see syswrite. An exception is raised if LENGTH is negative or if OFFSET points outside the string.

[15]There is no syseof function, which is okay, since eof doesn't work well on device files (like terminals) anyway. Use sysread and check for a return value for 0 to decide whether you're done.

You should be prepared to handle the problems (like interrupted syscalls) that standard I/O normally handles for you. Because it bypasses standard I/O, do not mix sysread with other kinds of reads, print, printf, write, seek, tell, or eof on the same filehandle unless you are into heavy wizardry (and/or pain). Also, please be aware that, when reading from a file containing Unicode or any other multibyte encoding, the buffer boundary may fall in the middle of a character.

29.2.173. sysseek

sysseek FILEHANDLE, POSITION, WHENCE
This function sets FILEHANDLE's system position using the syscall lseek(2). It bypasses standard I/O, so mixing this with reads (other than sysread), print, write, seek, tell, or eof may cause confusion. FILEHANDLE may be an expression whose value gives the name of the filehandle. The values for WHENCE are 0 to set the new position to POSITION, 1 to set the it to the current position plus POSITION, and 2 to set it to EOF plus POSITION (typically negative). For WHENCE, you may use the constants SEEK_SET, SEEK_CUR, and SEEK_END from the standard IO::Seekable and POSIX modules--or, as of the 5.6 release, from Fcntl, which is more portable and convenient.

Returns the new position, or undef on failure. A position of zero is returned as the special string "0 but true", which can be used numerically without producing warnings.

29.2.174. system

system PATHNAME LIST
system LIST
This function executes any program on the system for you and returns that program's exit status--not its output. To capture the output from a command, use backticks or qx// instead. The system function works exactly like exec, except that system does a fork first and then, after the exec, waits for the executed program to complete. That is, it runs the program for you and returns when it's done, whereas exec replaces your running program with the new one, so it never returns if the replacement succeeds.

Argument processing varies depending on the number of arguments, as described under exec, including determining whether the shell will be called and whether you've lied to the program about its name by specifying a separate PATHNAME.

Because system and backticks block SIGINT and SIGQUIT, sending one of those signals (such as from a Control-C) to the program being run doesn't interrupt your main program. But the other program you're running does get the signal. Check the return value from system to see whether the program you were running exited properly or not.

@args = ("command", "arg1", "arg2");
system(@args) == 0
     or die "system @args failed: $?"
The return value is the exit status of the program as returned through the wait(2) syscall. Under traditional semantics, to get the real exit value, divide by 256 or shift right by 8 bits. That's because the lower byte has something else in it. (Two somethings, really.) The lowest seven bits indicate the signal number that killed the process (if any), and the eighth bit indicates whether the process dumped core. You can check all possible failure possibilities, including signals and core dumps, by inspecting $? ($CHILD_ERROR):
$exit_value  = $? >> 8;
$signal_num  = $? & 127;    # or 0x7f, or 0177, or 0b0111_1111
$dumped_core = $? & 128;    # or 0x80, or 0200, or 0b1000_0000
When the program has been run through the system shell[16] because you had only one argument and that argument had shell metacharacters in it, normal return codes are subject to that shell's additional quirks and capabilities. In other words, under those circumstances, you may be unable to recover the detailed information described earlier.

[16]That's /bin/sh by definition, or whatever makes sense on your platform, but not whatever shell the user just happens to be using at the time.

29.2.175. syswrite

syswrite FILEHANDLE, SCALAR, LENGTH, OFFSET
syswrite FILEHANDLE, SCALAR, LENGTH
syswrite FILEHANDLE, SCALAR
This function attempts to write LENGTH bytes of data from variable SCALAR to the specified FILEHANDLE using the write(2) syscall. The function returns the number of bytes written, or undef on error. The OFFSET, if specified, says where in the string to start writing from. (You might do this if you were using the string as a buffer, for instance, or if you needed to recover from a partial write.) A negative OFFSET specifies that writing should start that many bytes backward from the end of the string. If SCALAR is empty, the only OFFSET permitted is 0. An exception is raised if LENGTH is negative or if OFFSET points outside the string.

To copy data from filehandle FROM into filehandle TO, you can use something like:

use Errno qw/EINTR/;
$blksize = (stat FROM)[11] || 16384;  # preferred block size?
while ($len = sysread FROM, $buf, $blksize) {
    if (!defined $len) {
        next if $! == EINTR;
        die "System read error: $!\n";
    }
    $offset = 0;
    while ($len) {          # Handle partial writes.
        $written = syswrite TO, $buf, $len, $offset;
        die "System write error: $!\n" unless defined $written;
        $offset += $written;
        $len    -= $written;
    }
}
You must be prepared to handle the problems that standard I/O normally handles for you, such as partial writes. Because syswrite bypasses the C standard I/O library, do not mix calls to it with reads (other than sysread), writes (like print, printf, or write), or other stdio functions like seek, tell, or eof unless you are into heavy wizardry.[17]

[17]Or pain.

29.2.176. tell

tell FILEHANDLE
tell
This function returns the current file position (in bytes, zero-based) for FILEHANDLE. This value typically will be fed to the seek function at some future time to get back to the current position. FILEHANDLE may be an expression giving the name of the actual filehandle, or a reference to a filehandle object. If FILEHANDLE is omitted, the function returns the position of the file last read. File positions are only meaningful on regular files. Devices, pipes, and sockets have no file position.

There is no systell function. Use sysseek(FH, 0, 1) for that. Seek seek for an example telling how to use tell.

29.2.177. telldir

telldir DIRHANDLE
This function returns the current position of the readdir routines on DIRHANDLE. This value may be given to seekdir to access a particular location in a directory. The function has the same caveats about possible directory compaction as the corresponding system library routine. This function might not be implemented everywhere that readdir is. Even if it is, no calculation may be done with the return value. It's just an opaque value, meaningful only to seekdir.

29.2.178. tie

tie VARIABLE, CLASSNAME, LIST
This function binds a variable to a package class that will provide the implementation for the variable. VARIABLE is the variable (scalar, array, or hash) or typeglob (representing a filehandle) to be tied. CLASSNAME is the name of a class implementing objects of an appropriate type.

Any additional arguments are passed to the appropriate constructor method of the class, meaning one of TIESCALAR, TIEARRAY, TIEHASH, or TIEHANDLE. (If the appropriate method is not found, an exception is raised.) Typically, these are arguments such as might be passed to the dbm_open(3) function of C, but their meaning is package dependent. The object returned by the constructor is in turn returned by the tie function, which can be useful if you want to access other methods in CLASSNAME. (The object can also be accessed through the tied function.) So, a class for tying a hash to an ISAM implementation might provide an extra method to traverse a set of keys sequentially (the "S" of ISAM), since your typical DBM implementation can't do that.

Functions such as keys and values may return huge list values when used on large objects like DBM files. You may prefer to use the each function to iterate over such. For example:

use NDBM_File;
tie %ALIASES, "NDBM_File", "/etc/aliases", 1, 0
    or die "Can't open aliases: $!\n";
while (($key,$val) = each %ALIASES) {
    print $key, ' = ', $val, "\n";
}
untie %ALIASES;
A class implementing a hash should provide the following methods:
TIEHASH CLASS, LIST
FETCH SELF, KEY
STORE SELF, KEY, VALUE
DELETE SELF, KEY
CLEAR SELF
EXISTS SELF, KEY
FIRSTKEY SELF
NEXTKEY SELF, LASTKEY
DESTROY SELF
A class implementing an ordinary array should provide the following methods:
TIEARRAY CLASS, LIST
FETCH SELF, SUBSCRIPT
STORE SELF, SUBSCRIPT, VALUE
FETCHSIZE SELF
STORESIZE SELF, COUNT
CLEAR SELF
PUSH SELF, LIST
POP SELF
SHIFT SELF
UNSHIFT SELF, LIST
SPLICE SELF, OFFSET, LENGTH, LIST
EXTEND SELF, COUNT
DESTROY SELF
A class implementing a scalar should provide the following methods:
TIESCALAR CLASS, LIST
FETCH SELF,
STORE SELF, VALUE
DESTROY SELF
A class implementing a filehandle should have the following methods:
TIEHANDLE CLASS, LIST
READ SELF, SCALAR, LENGTH, OFFSET
READLINE SELF
GETC SELF
WRITE SELF, SCALAR, LENGTH, OFFSET
PRINT SELF, LIST
PRINTF SELF, FORMAT, LIST
CLOSE SELF
DESTROY SELF
Not all methods indicated above need be implemented: the Tie::Hash, Tie::Array, Tie::Scalar, and Tie::Handle modules provide base classes that have reasonable defaults. See Chapter 14, "Tied Variables", for a detailed discussion of all these methods. Unlike dbmopen, the tie function will not use or require a module for you--you need to do that explicitly yourself. See the DB_File and Config modules for interesting tie implementations.

29.2.179. tied

tied VARIABLE
This function returns a reference to the object underlying the scalar, array, hash, or typeglob contained in VARIABLE (the same value that was originally returned by the tie call that bound the variable to a package). It returns the undefined value if VARIABLE isn't tied to a package. So, for example, you can use:
ref tied %hash
to find out which package your hash is tied to. (Presuming you've forgotten.)

29.2.180. time

time
This function returns the number of nonleap seconds since "the epoch", traditionally 00:00:00 on January 1st, 1970, UTC.[18] The returned value is suitable for feeding to gmtime and localtime, for comparison with file modification and access times returned by stat, and for feeding to utime.
$start = time();
system("some slow command");
$end   = time();
if ($end - $start > 1) {
    print "Program started: ", scalar localtime($start), "\n";
    print "Program ended:   ", scalar localtime($end), "\n";
}

[18]Not to be confused with the "epic", which is about the making of Unix. (Other operating systems may have a different epoch, not to mention a different epic.)

29.2.181. times

times
In list context, this function returns a four-element list giving the user and system CPU times, in seconds (probably fractional), for this process and terminated children of this process.
($user, $system, $cuser, $csystem) = times();
printf "This pid and its kids have consumed %.3f seconds\n",
            $user + $system + $cuser + $csystem;
In scalar context, returns just the user time. For example, to time the execution speed of a section of Perl code:
$start = times();
...
$end = times();
printf "that took %.2f CPU seconds of user time\n",
        $end - $start;

29.2.182. tr///

tr///
y///
This is the transliteration (also called translation) operator, which is like the y/// operator in the Unix sed program, only better, in everybody's humble opinion. See Chapter 5, "Pattern Matching".

29.2.183. truncate

truncate FILEHANDLE, LENGTH
truncate EXPR, LENGTH
This function truncates the file opened on FILEHANDLE, or named by EXPR, to the specified length. The function raises an exception if ftruncate(2) or an equivalent isn't implemented on your system. (You can always truncate a file by copying the front of it, if you have the disk space.) The function returns true on success, undef otherwise.

29.2.184. uc [taintgray]

uc EXPR
uc
This function returns an uppercased version of EXPR. This is the internal function implementing the \U escape in double-quoted strings. Perl will try to do the right thing with respect to your current locale settings, but we're still working out how that interacts with Unicode. See the perllocalle manpage for the latest guess. In any event, when Perl uses the Unicode tables, uc translates to uppercase rather than to titlecase. See ucfirst for titlecase translation.

29.2.185. ucfirst [taintgray]

ucfirst EXPR
ucfirst
This function returns a version of EXPR with the first character capitalized (titlecased in "Unicodese"), and other characters left alone. This is the internal function implementing the \u escape in double-quoted strings. Your current LC_CTYPE locale may be respected if you use locale and your data doesn't look like Unicode, but we make no guarantees at this time.

To force the initial character to titlecase and everything else to lowercase, use:

ucfirst lc $word
which is equivalent to "\u\L$word".

29.2.186. umask

umask EXPR
umask
This function sets the umask for the process and returns the old one using the umask(2) syscall. Your umask tells the operating system which permission bits to disallow when creating a new file, including files that happen to be directories. If EXPR is omitted, the function merely returns the current umask. For example, to ensure that the "user" bits are allowed, and the "other" bits disallowed, try something like:
umask((umask() & 077) | 7);   # don't change the group bits
Remember that a umask is a number, usually given in octal; it is not a string of octal digits. See also oct, if all you have is a string. Remember also that the umask's bits are complemented compared to ordinary permissions.

The Unix permission rwxr-x--- is represented as three sets of three bits, or three octal digits: 0750 (the leading 0 indicates octal and doesn't count as one of the digits). Since the umask's bits are flipped, it represents disabled permissions bits. The permission (or "mode") values you supply to mkdir or sysopen are modified by your umask, so even if you tell sysopen to create a file with permissions 0777, if your umask is 0022, the file is created with permissions 0755. If your umask were 0027 (group can't write; others can't read, write, or execute), then passing sysopen a MASK of 0666 would create a file with mode 0640 (since 0666 & ~0027 is 0640).

Here's some advice: supply a creation mode of 0666 for regular files (in sysopen) and one of 0777 both for directories (in mkdir) and for executable files. This gives users the freedom of choice: if they want protected files, they choose process umasks of 022, 027, or even the particularly antisocial mask of 077. Programs should rarely if ever make policy decisions better left to the user. The exception to this rule is programs that write files that should be kept private: mail files, web browser cookies, .rhosts files, and so on.

If umask(2) is not implemented on your system and you are trying to restrict your own access (that is, if EXPR& 0700) > 0), you'll trigger a run-time exception. If umask(2) is not implemented and you are not trying to restrict your own access, the function simply returns undef.

29.2.187. undef

undef EXPR
undef
undef is the name by which we refer to the abstraction known as "the undefined value". It also conveniently happens to be the name of a function that always returns the undefined value. We happily confuse the two.

Coincidentally, the undef function can also explicitly undefine an entity if you supply its name as an argument. The EXPR argument, if specified, must be an lvalue. Hence you may only use this on a scalar value, an entire array or hash, a subroutine name (using the & prefix), or a typeglob. Any storage associated with the object will be recovered for reuse (though not returned to the system, for most operating systems). The undef function will probably not do what you expect on most special variables. Using it on a read-only variable like $1 raises an exception.

The undef function is a unary operator, not a list operator, so you can only undefine one thing at a time. Here are some uses of undef as a unary operator:

undef $foo;
undef $bar{'blurfl'};   # Different from delete $bar{'blurfl'};
undef @ary;
undef %hash;
undef &mysub;
undef *xyz;             # destroys $xyz, @xyz, %xyz, &xyz, etc.
Without an argument, undef is just used for its value:
select(undef, undef, undef, $naptime);

return (wantarray ? () : undef) if $they_blew_it;
return if $they_blew_it;  # same thing
You may use undef as a placeholder on the left side of a list assignment, in which case the corresponding value from the right side is simply discarded. Apart from that, you may not use undef as an lvalue.
($a, $b, undef, $c) = &foo;       # Ignore third value returned
Also, do not try to compare anything to undef--it doesn't do what you think. All it does is compare against 0 or the null string. Use the defined function to determine if a value is defined.

29.2.188. unlink

unlink LIST
unlink
This function deletes a list of files.[19] The function returns the number of filenames successfully deleted. Some sample examples:
$count = unlink 'a', 'b', 'c';
unlink @goners;
unlink glob("*.orig");
The unlink function will not delete directories unless you are superuser and the supply -U command-line option to Perl. Even if these conditions are met, be warned that unlinking a directory can inflict Serious Damage on your filesystem. Use rmdir instead.

[19] Actually, under a POSIX filesystem, it removes the directory entries (filenames) that refer to the real files. Since a file may be referenced (linked) from more than one directory, the file isn't removed until the last reference to it is removed.

Here's a simple rm command with very simple error checking:

#!/usr/bin/perl
@cannot = grep {not unlink} @ARGV;
die "$0: could not unlink @cannot\n" if @cannot;

29.2.189. unpack

unpack TEMPLATE, EXPR
This function does the reverse of pack: it expands a string (EXPR) representing a data structure into a list of values according to the TEMPLATE and returns those values. In scalar context, it can be used to unpack a single value. The TEMPLATE here has much the same format as it has in the pack function--it specifies the order and type of the values to be unpacked. See pack for a detailed description of TEMPLATE. An invalid element in the TEMPLATE, or an attempt to move outside the string with the x, X, or @ formats, raises an exception.

The string is broken into chunks described by the TEMPLATE. Each chunk is converted separately to a value. Typically, the bytes of the string either are the result of a pack, or represent a C structure of some kind.

If the repeat count of a field is larger than the remainder of the input string allows, the repeat count is silently decreased. (Normally, you'd use a repeat count of * here, anyway.) If the input string is longer than what TEMPLATE describes, the rest of the string is ignored.

The unpack function is also useful for plain text data, too, not just binary data. Imagine that you had a data file that contained records that looked like this:

1986 Ender's Game           Orson Scott Card
1985 Neuromancer            William Gibson
1984 Startide Rising        David Brin
1983 Foundation's Edge      Isaac Asimov
1982 Downbelow Station      C. J. Cherryh
1981 The Snow Queen         Joan D. Vinge
you can't use split to parse out the fields because they have no distinct separator. Instead, fields are determined by their byte-offset into the record. So even though this is a regular text record, because it's in a fixed format, you want to use unpack to pull it apart:
while (<>) {
        ($year, $title, $author) = unpack("A4 x A23 A*", $_);
        print "$author won ${year}'s Hugo for $title.\n";
}
(The reason we wrote ${year}'s there is because Perl would have treated $year's as meaning $year::s.)

Here's a complete uudecode program:

#!/usr/bin/perl
$_ = <> until ($mode,$file) = /^begin\s*(\d*)\s*(\S*)/;
open(OUT,"> $file") if $file ne "";
while (<>) {
    last if /^end/;
    next if /[a-z]/;
    next unless int((((ord() - 32) & 077) + 2) / 3) ==
                int(length() / 4);
    print OUT unpack "u", $_;
}
chmod oct($mode), $file;
In addition to fields allowed in pack, you may prefix a field with %number to produce a simple number-bit additive checksum of the items instead of the items themselves. Default is a 16-bit checksum. The checksum is calculated by summing numeric values of expanded values (for string fields, the sum of ord($char) is taken, and for bit fields, the sum of zeros and ones). For example, the following computes the same number as the SysV sum(1) program:
undef $/;
$checksum = unpack ("%32C*", <>) % 65535;
The following efficiently counts the number of set bits in a bitstring:
$setbits = unpack "%32b*", $selectmask;
Here's a simple BASE64 decoder:
while (<>) {
    tr#A-Za-z0-9+/##cd;                   # remove non-base64 chars
    tr#A-Za-z0-9+/# -_#;                  # convert to uuencoded format
    $len = pack("c", 32 + 0.75*length);   # compute length byte
    print unpack("u", $len . $_);         # uudecode and print
}

29.2.190. unshift

unshift ARRAY, LIST
This function does the opposite of shift. (Or the opposite of push, depending on how you look at it.) It prepends LIST to the front of the array, and returns the new number of elements in the array:
unshift @ARGV, '-e', $cmd unless $ARGV[0] =~ /^-/;
Note the LIST is prepended whole, not one element at a time, so the prepended elements stay in the same order. Use reverse to do the reverse.

29.2.191. untie

untie VARIABLE
Breaks the binding between the variable or typeglob contained in VARIABLE and the package that it's tied to. See tie, and all of Chapter 14, "Tied Variables", but especially the section "A Subtle Untying Trap".

29.2.192. use

use MODULE VERSION LIST
use MODULE VERSION ()
use MODULE VERSION
use MODULE LIST
use MODULE ()
use MODULE
use VERSION
The use declaration loads in a module, if it hasn't been loaded before, and imports subroutines and variables into the current package from the named module. (Technically speaking, it imports some semantics into the current package from the named module, generally by aliasing certain subroutine or variable names into your package.) Most use declarations looks like this:
use MODULE LIST;
That is exactly equivalent to saying:
BEGIN { require MODULE; import MODULE LIST; }
The BEGIN forces the require and import to happen at compile time. The require makes sure the module is loaded into memory if it hasn't been yet. The import is not a built-in--it's just an ordinary class method call into the package named by MODULE to tell that module to pull the list of features back into the current package. The module can implement its import method any way it likes, though most modules just choose to derive their import method via inheritance from the Exporter class that is defined in the Exporter module. See Chapter 11, "Modules", and the Exporter module for more information. If no import method can be found, then the call is skipped without murmur.

If you don't want your namespace altered, explicitly supply an empty list:

use MODULE ();
That is exactly equivalent to the following:
BEGIN { require MODULE; }
If the first argument to use is a version number like 5.6.2, the currently executing version of Perl must be at least as modern as the version specified. If the current version of Perl is less than VERSION, an error message is printed and Perl exits immediately. This is useful for checking the current Perl version before loading library modules that depend on newer versions, since occasionally we have to "break" the misfeatures of older versions of Perl. (We try not to break things any more than we have to. In fact, we often try to break things less than we have to.)

Speaking of not breaking things, Perl still accepts old version numbers of the form:

use 5.005_03;
However, in order to align better with industry standards, Perl 5.6 now accepts, (and we prefer to see) the three-tuple form:
use 5.6.0;   # That's version 5, subversion 6, patchlevel 0.
If the VERSION argument is present after MODULE, then the use will call the VERSION method in class MODULE with the given VERSION as an argument. Note that there is no comma after VERSION! The default VERSION method, which is inherited from the UNIVERSAL class, croaks if the given version is larger than the value of the variable $Module::VERSION.

See Chapter 32, "Standard Modules" for a list of standard modules.

Because use provides a wide-open interface, pragmas (compiler directives) are also implemented via modules. Examples of currently implemented pragmas include:

use autouse 'Carp' => qw(carp croak);
use bytes;
use constant PI => 4 * atan2(1,1);
use diagnostics;
use integer;
use lib '/opt/projects/spectre/lib';
use locale;
use sigtrap qw(die INT QUIT);
use strict  qw(subs vars refs);
use warnings "deprecated";
Many of these pragmatic modules import semantics into the current lexical scope. (This is unlike ordinary modules, which only import symbols into the current package, which has little relation to the current lexical scope other than that the lexical scope is being compiled with that package in mind. That is to say...oh, never mind, see Chapter 11, "Modules".)

There's a corresponding declaration, no, that "unimports" any meanings originally imported by use that have since become, er, unimportant:

no integer;
no strict 'refs';
no utf8;
no warnings "unsafe";
See Chapter 31, "Pragmatic Modules" for a list of standard pragmas.

29.2.193. utime

utime LIST
This function changes the access and modification times on each file of a list of files. The first two elements of the list must be the numerical access and modification times, in that order. The function returns the number of files successfully changed. The inode change time of each file is set to the current time. Here's an example of a touch command that sets the modification date of the file (assuming you're the owner) to about a month in the future:
#!/usr/bin/perl
# montouch - post-date files now + 1 month
$day = 24 * 60 * 60;            # 24 hours of seconds
$later = time() + 30 * $day;    # 30 days is about a month
utime $later, $later, @ARGV;
and here's a more sophisticated touch-like command with a smattering of error checking:
#!/usr/bin/perl
# montouch - post-date files now + 1 month
$later = time() + 30 * 24 * 60 * 60;
@cannot = grep {not utime $later, $later, $_} @ARGV;
die "$0: Could not touch @cannot.\n" if @cannot;
To read the times from existing files, use stat and then pass the appropriate fields through localtime or gmtime for printing.

29.2.194. values

values HASH
This function returns a list consisting of all the values in the indicated HASH. The values are returned in an apparently random order, but it is the same order as either the keys or each function would produce on the same hash. Oddly, to sort a hash by its values, you usually need to use the keys function, so see the example under keys for that.

You can modify the values of a hash using this function because the returned list contains aliases of the values, not just copies. (In earlier versions, you needed to use a hash slice for that.)

for (@hash{keys %hash}) { s/foo/bar/g }   # old way
for (values %hash)      { s/foo/bar/g }   # now changes values
Using values on a hash that is bound to a humongous DBM file is bound to produce a humongous list, causing you to have a humongous process. You might prefer to use the each function, which will iterate over the hash entries one by one without slurping them all into a single gargantuan, er, humongous list.

29.2.195. vec

vec EXPR, OFFSET, BITS
The vec function provides compact storage of lists of unsigned integers. These integers are packed as tightly as possible within an ordinary Perl string. The string in EXPR is treated as a bit string made up of some arbitrary number of elements depending on the length of the string.

OFFSET specifies the index of the particular element you're interested in. The syntaxes for reading and writing the element are the same, since vec stores or returns the value of the element depending on whether you use it in an lvalue or an rvalue context.

BITS specifies how wide each element is in bits, which must be a power of two: 1, 2, 4, 8, 16, or 32 (and also 64 on some platforms). (An exception is raised if any other value is used.) Each element can therefore contain an integer in the range 0..(2**BITS)-1. For the smaller sizes, as many elements as possible are packed into each byte. When BITS is 1, there are eight elements per byte. When BITS is 2, there are four elements per byte. When BITS is 4, there are two elements (traditionally called nybbles) per byte. And so on. Integers larger than a byte are stored in big-endian order.

A list of unsigned integers can be stored in a single scalar variable by assigning them individually to the vec function. (If EXPR is not a valid lvalue, an exception is raised.) In the following example, the elements are each 4 bits wide:

$bitstring = "";
$offset = 0;

foreach $num (0, 5, 5, 6, 2, 7, 12, 6) {
    vec($bitstring, $offset++, 4) = $num;
}
If an element off the end of the string is written to, Perl will first extend the string with sufficiently many zero bytes.

The vectors stored in the scalar variable can be subsequently retrieved by specifying the correct OFFSET.

$num_elements = length($bitstring)*2;  # 2 elements per byte

foreach $offset (0 .. $num_elements-1) {
    print vec($bitstring, $offset, 4), "\n";
}
If the selected element is off the end of the string, a value of 0 is returned.

Strings created with vec can also be manipulated with the logical operators |, &, ^, and ~. These operators will assume that a bit string operation is desired when both operands are strings. See the examples of this in Chapter 3, "Unary and Binary Operators", in the section "Bitwise Operators".

If BITS == 1, a bitstring can be created to store a series of bits all in one scalar. The ordering is such that vec($bitstring,0,1) is guaranteed to go into the lowest bit of the first byte of the string.

@bits = (0,0,1,0, 1,0,1,0, 1,1,0,0, 0,0,1,0);

$bitstring = "";
$offset = 0;

foreach $bit (@bits) {
    vec($bitstring, $offset++, 1) = $bit;
}

print "$bitstring\n";        # "TC", ie. '0x54', '0x43'
A bit string can be translated to or from a string of 1's and 0's by supplying a "b*" template to pack or unpack. Alternatively, pack can be used with a "b*" template to create the bit string from a string of 1's and 0's. The ordering is compatible with that expected by vec.
$bitstring = pack "b*", join('', @bits);
print "$bitstring\n";   # "TC", same as before
unpack can be used to extract the list of 0's and 1's from the bit string.
@bits = split(//, unpack("b*", $bitstring));
print "@bits\n";        # 0 0 1 0 1 0 1 0 1 1 0 0 0 0 1 0
If you know the exact length in bits, it can be used in place of the "*".

See select for additional examples of using bitmaps generated with vec. See pack and unpack for higher-level manipulation of binary data.

29.2.196. wait

wait
This function waits for a child process to terminate and returns the PID of the deceased process, or -1 if there are no child processes (or on some systems, if child processes are being automatically reaped). The status is returned in $? as described under system. If you get zombie child processes, you should be calling this function, or waitpid.

If you expected a child and didn't find it with wait, you probably had a call to system, a close on a pipe, or backticks between the fork and the wait. These constructs also do a wait(2) and may have harvested your child process. Use waitpid to avoid this problem.

29.2.197. waitpid

waitpid PID, FLAGS
This function waits for a particular child process to terminate and returns the PID when the process is dead, -1 if there are no child processes, or 0 if the FLAGS specify nonblocking and the process isn't dead yet. The status of the dead process is returned in $? as described under system. To get valid flag values, you'll need to import the ":sys_wait_h" import tag group from the POSIX module. Here's an example that does a nonblocking wait for all pending zombie processes.
use POSIX ":sys_wait_h";
do {
    $kid = waitpid(-1,&WNOHANG);
} until $kid == -1;
On systems that implement neither the waitpid(2) nor wait4(2) syscall, FLAGS may be specified only as 0. In other words, you can wait for a specific PID there, but you can't do so in nonblocking mode.

On some systems, a return value of -1 could mean that child processes are being automatically reaped because you set $SIG{CHLD} = 'IGNORE'.

29.2.198. wantarray

wantarray
This function returns true if the context of the currently executing subroutine is looking for a list value, and false otherwise. The function returns a defined false value ("") if the calling context is looking for a scalar, and the undefined false value (undef) if the calling context isn't looking for anything; that is, if it's in void context.

Here's are examples of typical usage:

return unless defined wantarray;    # don't bother doing more
my @a = complex_calculation();
return wantarray ? @a : \@a;
See also caller. This function should really have been named "wantlist", but we named it back when list contexts were still called array contexts.

29.2.199. warn

warn LIST
warn
This function produces an error message, printing LIST to STDERR just like die, but doesn't try to exit or throw an exception. For example:
warn "Debug enabled" if $debug;
If LIST is empty and $@ already contains a value (typically from a previous eval), the string "\t...caught" is appended following $@ on STDERR. (This is similar to the way die propagates errors, except that warn doesn't propagate (reraise) the exception.) If the message string supplied is empty, the message "Warning: Something's wrong" is used.

As with die, if the strings supplied don't end in a newline, file and line number information is automatically appended. The warn function is unrelated to Perl's -w command-line option, but can be used in conjunction with it, such as when you wish to emulate built-ins:

warn "Something wicked\n" if $^W;
No message is printed if there is a $SIG{__WARN__} handler installed. It is the handler's responsibility to deal with the message as it sees fit. One thing you might want to do is promote a mere warning into an exception:
local $SIG{__WARN__} = sub {
    my $msg = shift;
    die $msg if $msg =~ /isn't numeric/;
};
Most handlers must therefore make arrangements to display the warnings that they are not prepared to deal with, by calling warn again in the handler. This is perfectly safe; it won't produce an endless loop because __WARN__ hooks are not called from inside __WARN__ hooks. This behavior differs slightly from that of $SIG{__DIE__} handlers (which don't suppress the error text, but can instead call die again to change it).

Using a __WARN__ handler provides a powerful way to silence all warnings, even the so-called mandatory ones. Sometimes you need to wrap this in a BEGIN{} block so that it can happen at compile time:

# wipe out *all* compile-time warnings
BEGIN { $SIG{__WARN__} = sub { warn $_[0] if $DOWARN } }
my $foo = 10;
my $foo = 20;          # no warning about duplicate my $foo,
                       # but hey, you asked for it!

# no compile-time or run-time warnings before here
$DOWARN = 1;           # *not* a built-in variable

# run-time warnings enabled after here
warn "\$foo is alive and $foo!";     # does show up
See the use warnings pragma for lexically scoped control of warnings. See the Carp module's carp and cluck functions for other ways to produce warning messages.

29.2.200. write

write FILEHANDLE
write
This function writes a formatted record (possibly multiline) to the specified filehandle, using the format associated with that filehandle--see the section "Format Variables" in Chapter 7, "Formats". By default the format associated with a filehandle is the one having the same name as the filehandle. However, the format for a filehandle may be changed by altering the $~ variable after you select that handle:
$old_fh = select(HANDLE);
$~ = "NEWNAME";
select($old_fh);
or by saying:
use IO::Handle;
HANDLE->format_name("NEWNAME");
Since formats are put into a package namespace, you may have to fully qualify the format name if the format was declared in a different package:
$~ = "OtherPack::NEWNAME";
Top-of-form processing is handled automatically: if there is insufficient room on the current page for the formatted record, the page is advanced by writing a form feed, a special top-of-page format is used for the new page header, and then the record is written. The number of lines remaining on the current page is in the variable $-, which can be set to 0 to force a new page on the next write. (You may need to select the filehandle first.) By default, the name of the top-of-page format is the name of the filehandle with "_TOP" appended, but the format for a filehandle may be changed altering the $^ variable after selecting that handle, or by saying:
use IO::Handle;
HANDLE->format_top_name("NEWNAME_TOP");
If FILEHANDLE is unspecified, output goes to the current default output filehandle, which starts out as STDOUT, but may be changed by the single-argument form of the select operator. If the FILEHANDLE is an expression, then the expression is evaluated to determine the actual FILEHANDLE at run time.

If a specified format or the current top-of-page format does not exist, an exception is raised.

The write function is not the opposite of read. Unfortunately. Use print for simple string output. If you looked up this entry because you wanted to bypass standard I/O, see syswrite.

29.2.201. y//

y///
The transliteration (historically, also called translation) operator, also known as tr///. See Chapter 5, "Pattern Matching".

Previous | Home | Next
29.1. Perl Functions by Category | Book Index | 30. The Standard Perl Library
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 30. The Standard Perl Library

Contents:

Library Science
A Tour of the Perl Library

The standard Perl distribution contains much more than just the perl executable that executes your scripts. It also includes hundreds of modules filled with reusable code. Because the standard modules are available everywhere, if you use one of them in your program, you can run your program anywhere Perl is installed, without any extra installation steps.

30.1. Library Science

Before we enumerate these modules in the following chapters, let's review a bit of the terminology we've been splattering about.

namespace

A namespace is a place to keep names so they won't be confused with names in other namespaces. This leaves you with the simpler problem of not confusing the namespaces themselves. There are two ways to avoid confusing namespaces with each other: give them unique names, or give them unique locations. Perl lets you do both: named namespaces are called packages and unnamed namespaces are called lexical scopes. Since lexical scopes can be no larger than a file, and since the standard modules are file-sized (at minimum), it follows that all module interfaces must make use of named namespaces (packages) if they're to be used by anyone outside the file.

package

A package is Perl's standard mechanism for declaring a named namespace. It's a simple mechanism for grouping together related functions and variables. Just as two directories can both contain a (different) file named fred, two different parts of a Perl program can each have its own $fred variable or &fred function. Even though these variables or functions seem to have the same name as one another, those names reside in distinct namespaces managed by the package declaration. Package names are used to identify both modules and classes, as described in Chapter 11, "Modules", and in Chapter 12, "Objects".

library

The term library is unfortunately rather overloaded in Perl culture. These days we normally use the term to mean the entire set of Perl modules installed on your system.

Historically, a Perl library was also a single file containing a collection of subroutines sharing some common purpose. Such a file often has the file extension .pl, short for "perl library". We still use that extension for random bits of Perl code that you pull in with do FILE or with require. Although it's not a full-fledged module, a library file typically declares itself to be in a distinct package so related variables and subroutines can be kept together and don't accidentally interfere with other variables in your program. There is no mandatory extension; others besides .pl sometimes occur as explained later in this chapter. These simple, unstructured library files have been largely superseded by the module.

module

A Perl module is a library file that conforms to certain specific conventions that allow one or more files implementing that module to be brought in with a single use declaration at compile time. Module filenames must always end in .pm, because the use declaration assumes it. The use declaration will also translate the package separator :: to whatever your directory separator is, so that the directory structure in your Perl library can match your package structure. Chapter 11, "Modules" describes how to create your own Perl modules.

class

A class is just a module that implements methods for objects associated with the module's package name. If you're interested in object-oriented modules, see Chapter 12, "Objects".

pragma

A pragma is just a special module that twiddles Perl's internal knobs. See Chapter 31, "Pragmatic Modules".

extension

An extension is a Perl module that, in addition to loading a .pm file, also loads a shared library implementing the module's semantics in C or C++.

program

A Perl program is code designed to be run as an independent entity; also known as a script when you don't want anyone to expect much from it, an application when it's big and complicated, an executable when its caller doesn't care what language it was written in, or an enterprise solution when it costs a fortune. Perl programs might exist as source code, bytecode, or native machine code. If it's something you might run from the command line, we'll call it a program.

Previous | Home | Next
29.2. Perl Functions in Alphabetical Order | Book Index | 30.2. A Tour of the Perl Library
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


30.2. A Tour of the Perl Library

You'll save an enormous amount of time if you make the effort to familiarize yourself with the standard Perl library, because there's no reason to reinvent those particular wheels. You should be aware, however, that this collection contains a wide range of material. Although some libraries may be extremely helpful, others might be completely irrelevant to your needs. For example, if you're only writing in 100% pure Perl, those modules that support the dynamic loading of C and C++ extensions aren't going to help you much.

Perl expects to find library modules somewhere in its library "include" path, @INC. This array specifies the ordered list of directories Perl searches when you load in some library code using the keywords do, require, or use. You can easily list out those directories by calling Perl with the -V switch for Very Verbose Version information, or with this simple code:

% perl -le "print foreach @INC"
/usr/libdata/perl5/sparc-openbsd/5.00503
/usr/local/libdata/perl5/sparc-openbsd/5.00503
/usr/libdata/perl5
/usr/local/libdata/perl5
/usr/local/libdata/perl5/site_perl/sparc-openbsd
/usr/libdata/perl5/site_perl/sparc-openbsd
/usr/local/libdata/perl5/site_perl
/usr/libdata/perl5/site_perl
.
That's only one sample of possible output. Every installation of Perl uses its own paths. The important thing is that, although contents will vary depending upon your vendor's and your site's installation policy, you can rely upon all standard libraries being installed with Perl. If you want to find out where a file was actually loaded from, consult the %INC variable. For a module file, you can find exactly where Perl is getting it from with this command:
% perldoc -l MODULE
If you look through the directories in @INC and their subdirectories, you'll find several different kinds of files installed. Most have names ending in .pm, but some end in .pl, .ph, .al, or .so. The ones that most interest you are the first set, because a suffix of .pm indicates that the file is a proper Perl module. More on those in a minute.

The few files you see there ending in .pl are those old Perl libraries we mentioned earlier. They are included for compatibility with ancient releases of Perl from the 80s and early 90s. Because of this, Perl code that worked back in, say, 1990, should continue to behave properly without any fuss even if you have a modern version of Perl installed. When writing new code that makes use of the standard Perl library, you should always elect to use the .pm version over any .pl, where possible. That's because modules don't pollute your namespace the way many of the old .pl files do.

One note on the use of the .pl extension: it means Perl library, not Perl program. Although .pl is sometimes used to identify Perl programs on web servers that need to distinguish executable programs from static content in the same directory, we suggest that you use a suffix of .plx instead to indicate an executable Perl program. (Similar advice holds for operating systems that choose interpreters based on filename extensions.)

Files with extensions of .al are small pieces of larger modules will be automatically loaded when you use their parent .pm file. If you build your module layout using the standard h2xs tool that comes with Perl (and if you haven't used Perl's -A flag), the make install procedure will use the AutoLoader module to create these little .al files for you.

The .ph files were made by the standard h2ph program, a somewhat aging but still occasionally necessary tool that does its best to translate C preprocessor directives into Perl. The resulting .ph files contain constants sometimes needed by low-level functions like ioctl, fcntl, or syscall. (Nowadays most of these values are more conveniently and portably available in standard modules such as the POSIX, Errno, Fcntl, or Socket modules.) See perlinstall for how to install these optional but sometimes important components.

One last file extension you might encounter while poking around is .so (or whatever your system uses for shared libraries). These .so files are platform-dependent portions of extension modules. Originally written in C or C++, these modules have been compiled into dynamically relocatable object code. The end user doesn't need to be aware of their existence, however, because the module interface hides them. When the user code says require Module or use Module, Perl loads Module.pm and executes it, which lets the module pull in any other necessary pieces, such as Module.so or any autoloaded .al components. In fact, the module could load anything it jolly well pleases, including 582 other modules. It could download all of CPAN if it felt like it, and maybe the last two years of freshmeat.net archives.

A module is not just a static chunk of code in Perl. It's an active agent that figures out how to implement an interface on your behalf. It may follow all the standard conventions, or it may not. It's allowed to do anything to warp the meaning of the rest of your program, up to and including translating the rest of your program into SPITBOL. This sort of chicanery is considered perfectly fair as long as it's well documented. When you use such a Perl module, you're agreeing to its contract, not a standard contract written by Perl.

So you'd best read the fine print.

Previous | Home | Next
30.1. Library Science | Book Index | 31. Pragmatic Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 31. Pragmatic Modules

Contents:

use attributes
use autouse
use base
use blib
use bytes
use charnames
use constant
use diagnostics
use fields
use filetest
use integer
use less
use lib
use locale
use open
use overload
use re
use sigtrap
use strict
use subs
use vars
use warnings

A pragma is a special kind of module that affects the compilation phase of your program. Some pragmatic modules (or pragmata, for short (or pragmas, for shorter)) may also affect the execution phase of your program. Think of these as hints to the compiler. Because they need to be seen at compile time, they'll only work when invoked by a use or a no, because by the time a require or a do is run, compilation is long since over.

By convention, pragma names are written in all lowercase because lowercase module names are reserved for the Perl distribution itself. When writing your own modules, use at least one capital letter in the module name to avoid conflict with pragma names.

Unlike regular modules, most pragmas limit their effects to the rest of the innermost enclosing block from which they were invoked. In other words, they're lexically scoped, just like my variables. Ordinarily, the lexical scope of an outer block covers any inner block embedded within it, but an inner block may countermand a lexically scoped pragma from an outer block by using the no statement:

use strict;
use integer;
{
    no strict 'refs';       # allow symbolic references
    no integer;             # resume floating-point arithmetic
    # ....
}
More so than the other modules Perl ships with, the pragmas form an integral and essential part of the Perl compilation environment. It's hard to use the compiler well if you don't know how to pass hints to it, so we'll put some extra effort into describing pragmas.

Another thing to be aware of is that we often use pragmas to prototype features that later get encoded into "real" syntax. So in some programs you'll see deprecated pragmas like use attrs whose functionality is now supported directly by subroutine declaration syntax. Similarly, use vars is in the process of being replaced by our declarations. And use subs may someday be replaced by an override attribute on ordinary subroutine declarations. We're not in a terrible hurry to break the old ways of doing things, but we do think the new ways are prettier.

31.1. use attributes

sub afunc : method;
my $closure = sub : method { ... };

use attributes;
@attrlist = attributes::get(\&afunc);

The attributes pragma has two purposes. The first is to provide an internal mechanism for declaring attribute lists, which are optional properties associated with subroutine declarations and (someday soon) variable declarations. (Since it's an internal mechanism, you don't generally use this pragma directly.) The second purpose is to provide a way to retrieve those attribute lists at run time using the attributes::get function call. In this capacity, attributes is just a standard module, not a pragma.

Only a few built-in attributes are currently handled by Perl. Package-specific attributes are allowed by an experimental extension mechanism described in the section "Package-specific Attribute Handling" of the attributes(3) manpage.

Attribute setting occurs at compile time; attempting to set an unrecognized attribute is a compilation error. (The error is trappable by eval, but it still stops the compilation within that eval block.)

Only three built-in attributes for subroutines are currently implemented: locked, method, and lvalue. See Chapter 6, "Subroutines", and Chapter 17, "Threads", for further discussion of these. There are currently no built-in attributes for variables as there are for subroutines, but we can think of several we might like, such as constant.

The attributes pragma provides two subroutines for general use. They may be imported if you ask for them.

get

This function returns a (possibly empty) list of attributes given a single input parameter that's a reference to a subroutine or variable. The function raises an exception by invoking Carp::croak if passed invalid arguments.

reftype

This function acts somewhat like the built-in ref function, but it always returns the underlying, built-in Perl data type of the referenced value, ignoring any package into which it might have been blessed.

Precise details of attribute handling remain in flux, so you'd best check out the online documentation included with your Perl release to see what state it's all in.

Previous | Home | Next
30.2. A Tour of the Perl Library | Book Index | 31.2. use autouse
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.2. use autouse

use autouse 'Carp' => qw(carp croak);
carp "this carp was predeclared and autoused";

This pragma provides a mechanism for run-time demand loading of a particular module only when a function from that module really gets called. It does this by providing a stub function that replaces itself with the real call once triggered. This is similar in spirit to the way the standard AutoLoader and SelfLoader modules behave. In short, it's a performance hack to help make your Perl program start up faster (on average) by avoiding compilation of modules that might never ever be called during a given execution run.

How autouse behaves depends on whether the module is already loaded. For example, if the module Module is already loaded, then the declaration:

use autouse 'Module' => qw(func1 func2($;$) Module::func3);
is equivalent to the simple import of two functions:
use Module qw(func1 func2);
This assumes that Module defines func2() with prototype ($;$), and that func1() and func3() have no prototypes. (More generally, this also assumes that Module uses Exporter's standard import method; otherwise, a fatal error is raised.) In any event, it completely ignores Module::func3 since that is presumably already declared.

If, on the other hand, Module has not yet been loaded when the autouse pragma is parsed, the pragma declares functions func1 and func2 to be in the current package. It also declares a function Module::func3 (which could be construed as mildly antisocial, were it not for the fact that the nonexistence of the Module module has even more antisocial consequences). When these functions are called, they make sure the Module in question is loaded and then replace themselves with calls to the real functions just loaded.

Because the autouse pragma moves portions of your program's execution from compile time to run time, this can have unpleasant ramifications. For example, if the module you autouse has some initialization that is expected to be done early, this may not happen early enough. Autousing can also hide bugs in your code when important checks are moved from compile time to run time.

In particular, if the prototype you've specified on autouse line is wrong, you will not find out about it until the corresponding function is executed (which may be months or years later, for a rarely called function). To partially alleviate this problem, you could write your code like this during code development:

use Chase;
use autouse Chase => qw(hue($) cry(&$));
cry "this cry was predeclared and autoused";
The first line ensures that errors in your argument specification will be found early. When your program graduates from development into production mode, you can comment out the regular loading of the Chase module and leave just the autousing call in place. That way you get safety during development and performance during production.

Previous | Home | Next
31.1. use attributes | Book Index | 31.3. use base
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.3. use base

use base qw(Mother Father);

This pragma lets a programmer conveniently declare a derived class based upon the listed parent classes. The declaration above is roughly equivalent to:

BEGIN {
    require Mother;
    require Father;
    push @ISA, qw(Mother Father);
}
The use base pragma takes care of any require needed. When the strict 'vars' pragma is in scope, use base lets you (in effect) assign to @ISA without first having to declare our @ISA. (Since the use base pragma happens at compile time, it's best to avoid diddling @ISA on your own at run time.)

But beyond this, use base has another property. If any named base class makes use of the fields facility described under use fields later in this chapter, then the pragma initializes the package's special field attributes from the base class. (Multiple inheritance of field classes is not supported. The use base pragma raises an exception if more than one named base class has fields.)

Any base class not yet loaded will be loaded automatically via require. However, whether to require a base class package is determined not by the customary inspection of %INC, but by the absence of a global $VERSION in the base package. This hack keeps Perl from repeatedly trying (and failing) to load a base class that isn't in its own requirable file (because, for example, it's loaded as part of some other module's file). If $VERSION is not detected after successfully loading a file, use base will define $VERSION in the base package, setting it to the string "-1, defined by base.pm".

Previous | Home | Next
31.2. use autouse | Book Index | 31.4. use blib
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.4. use blib

From the command line:

% perl -Mblib program [args...]
% perl -Mblib=DIR program [args...]
From your Perl program:
use blib;
use blib 'DIR';
This pragma is intended primarily as a way of testing arbitrary Perl programs against an uninstalled version of a package through Perl's -M command-line switch. It assumes your directory structure was produced by the standard ExtUtils::MakeMaker module.

The pragma looks for a blib directory structure starting in the directory named DIR (or current directory if none was specified), and if it doesn't find a blib directory there, works its way back up through your ".." directories, scanning up to five levels of parent directory.

Previous | Home | Next
31.3. use base | Book Index | 31.5. use bytes
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.5. use bytes

use bytes;
no bytes;

The use bytes pragma disables character semantics for the rest of the lexical scope in which it appears. The no bytes pragma can be used to reverse the effect of use bytes within the current lexical scope.

Perl normally assumes character semantics in the presence of character data (that is, data from a source marked as being of a particular character encoding).

To understand the implications and differences between character semantics and byte semantics, see Chapter 15, "Unicode". A visit to Tokyo might also help.

Previous | Home | Next
31.4. use blib | Book Index | 31.6. use charnames
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.6. use charnames

use charnames HOW;
print "\N{CHARSPEC} is a funny character";

This lexically scoped pragma enables named characters to be interpolated into strings using the \N{CHARSPEC} notation:

use charnames ':full';
print "\N{GREEK SMALL LETTER SIGMA} is called sigma.\n";

use charnames ':short';
print "\N{greek:Sigma} is an upper-case sigma.\n";

use charnames qw(cyrillic greek);
print "\N{sigma} is Greek sigma, and \N{be} is Cyrillic b.\n";
The pragma supports HOW arguments :full and :short, as well as specific script names.[1] The HOW argument determines how the character specified by the CHARSPEC in \N{CHARSPEC}} is to be searched for. If :full is present, the CHARSPEC is first looked for in the Unicode character tables as a complete Unicode character name. If :short is present and CHARSPEC has the form SCRIPTNAME:CHARNAME, CHARNAME is looked for as a letter in script SCRIPTNAME. If HOW contains specific script names, CHARSPEC is looked for as an individual CHARNAME in each of the given scripts, in the specified order.

[1] By which we don't mean Perl scripts. We mean "script" as in some particular style of written letters, like Roman or Greek or Cyrillic. Unfortunately, "script" is the technical term for that, and we're not likely to persuade the Unicode Consortium to use a different term.

For lookup of CHARNAME inside a given script SCRIPTNAME, the pragma looks in the table of standard Unicode names for patterns of the form:

SCRIPTNAME CAPITAL LETTER CHARNAME
SCRIPTNAME SMALL LETTER CHARNAME
SCRIPTNAME LETTER CHARNAME
If CHARNAME is entirely lowercase (as in \N{sigma}), the CAPITAL variant is ignored. Otherwise, the SMALL variant is ignored.

You can write your own module that works like the charnames pragma but defines character names differently. However, the interface to that is still experimental, so see the manpage for the latest.

Previous | Home | Next
31.5. use bytes | Book Index | 31.7. use constant
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.7. use constant

use constant BUFFER_SIZE    => 4096;
use constant ONE_YEAR       => 365.2425 * 24 * 60 * 60;
use constant PI             => 4 * atan2 1, 1;
use constant DEBUGGING      => 0;
use constant ORACLE         => 'oracle@cs.indiana.edu';
use constant USERNAME       => scalar getpwuid($<);
use constant USERINFO       => getpwuid($<);

sub deg2rad { PI * $_[0] / 180 }

print "This line does nothing"      unless DEBUGGING;

# references can be declared constant
use constant CHASH          => { foo => 42 };
use constant CARRAY         => [ 1,2,3,4 ];
use constant CPSEUDOHASH    => [ { foo => 1}, 42 ];
use constant CCODE          => sub { "bite $_[0]\n" };

print CHASH->{foo};
print CARRAY->[$i];
print CPSEUDOHASH->{foo};
print CCODE->("me");
print CHASH->[10];                          # compile-time error

This pragma declares the named symbol to be an immutable constant[2] with the given scalar or list value. You must make a separate declaration for each symbol. Values are evaluated in list context. You may override this with scalar as we did above.

[2] Implemented as a subroutine taking no arguments and returning the same constant each time.

Since these constants don't have a $ on the front, you can't interpolate them directly into double-quotish strings, although you may do so indirectly:

print "The value of PI is @{[ PI ]}.\n";
Because list constants are returned as lists, not as arrays, you must subscript a list-valued constant using extra parentheses as you would any other list expression:
$homedir = USERINFO[7];             # WRONG
$homedir = (USERINFO)[7];           # ok
Although using all capital letters for constants is recommended to help them stand out and to help avoid potential collisions with other keywords and subroutine names, this is merely a convention. Constant names must begin with a letter, but it need not be a capital one.

Constants are not private to the lexical scope in which they occur. Instead, they are simply argumentless subroutines in the symbol table of the package issuing the declaration. You may refer to a constant CONST from package Other as Other::CONST. Read more about compile-time inlining of such subroutines in the section "Inlining Constant Functions" in Chapter 6, "Subroutines".

As with all use directives, use constant happens at compile time. It's therefore misleading at best to place a constant declaration inside a conditional statement, such as if ($foo) { use constant ... }.

Omitting the value for a symbol gives it the value of undef in scalar context or the empty list, (), in a list context. But it is probably best to declare these explicitly:

use constant CAMELIDS       => ();
use constant CAMEL_HOME     => undef;

31.7.1. Restrictions on use constant

List constants are not currently inlined the way scalar constants are. And it is not possible to have a subroutine or keyword with the same name as a constant. This is probably a Good Thing.

You cannot declare more than one named constant at a time:

use constant FOO => 4, BAR => 5;    # WRONG
That defines a constant named FOO whose return list is (4, "BAR", 5). You need this instead:
use constant FOO => 4
use constant BAR => 5;
You can get yourself into trouble if you use a constant in a context that automatically quotes bare names. (This is true for any subroutine call, not just constants.) For example, you can't say $hash{CONSTANT} because CONSTANT will be interpreted as a string. Use $hash{CONSTANT()} or $hash{+CONSTANT} to prevent the quoting mechanism from kicking in. Similarly, since the => operator quotes its left operand if that operand is a bare name, you must say CONSTANT() => 'value' instead of CONSTANT => 'value' .

At some point, you'll be able to use a constant attribute on variable declarations:

my $PI : constant = 4 * atan2(1,1);
This has all the advantages of being a variable rather than a subroutine. It has all the disadvantages of not being implemented yet.

Previous | Home | Next
31.6. use charnames | Book Index | 31.8. use diagnostics
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.8. use diagnostics

use diagnostics;            # compile-time enable
use diagnostics -verbose;

enable  diagnostics;        # run-time enable
disable diagnostics;        # run-time disable

This pragma expands the normal, terse diagnostics and suppresses duplicate warnings. It augments the short versions with the more explicative and endearing descriptions found in Chapter 33, "Diagnostic Messages". Like other pragmas, it also affects the compilation phase of your program, not just the run phase.

When you use diagnostics at the start of your program, this automatically enables Perl's -w command-line switch by setting $^W to 1. The remainder of your whole compilation will then be subject to enhanced diagnostics. These still go out on STDERR.

Because of the interaction between run-time and compile-time issues, and because it's probably not a good idea anyway, you may not use no diagnostics to turn them off at compile time. However, you may control their behavior at run time using the disable and enable methods. (Make sure you do the use first, or else you won't be able to get at the methods.)

The -verbose flag first prints out the perldiag manpage's introduction before any other diagnostics are issued. The $diagnostics::PRETTY variable can be set (before the use) to generate nicer escape sequences for pagers like less(1) or more(1):

BEGIN { $diagnostics::PRETTY = 1 }
use diagnostics;
Warnings dispatched from Perl and detected by this pragma are each displayed only once. This is useful when you're caught in a loop that's generating the same warning (like uninitialized value) over and over again. Manually generated warnings, such as those stemming from calls to warn or carp, are unaffected by this duplicate detection mechanism.

Here are some examples of using the diagnostics pragma. The following file is certain to trigger a few errors at both run time and compile time:

use diagnostics;
print NOWHERE "nothing\n";
print STDERR "\n\tThis message should be unadorned.\n";
warn "\tThis is a user warning";
print "\nDIAGNOSTIC TESTER: Please enter a <CR> here: ";
my $a, $b = scalar <STDIN>;
print "\n";
print $x/$y;
Here's the output:
Parentheses missing around "my" list at diagtest line 6 (#1)

    (W parenthesis) You said something like

        my $foo, $bar = @_;

    when you meant

        my ($foo, $bar) = @_;

Remember that "my", "our", and "local" bind tighter than comma.

Name "main::NOWHERE" used only once: possible typo at diagtest line 2 (#2)

(W once) Typographical errors often show up as unique variable
    names.  If you had a good reason for having a unique name,
    then just mention it again somehow to suppress the message.
    The our declaration is provided for this purpose.

Name "main::b" used only once: possible typo at diagtest line 6 (#2)
Name "main::x" used only once: possible typo at diagtest line 8 (#2)
Name "main::y" used only once: possible typo at diagtest line 8 (#2)

Filehandle main::NOWHERE never opened at diagtest line 2 (#3)

(W unopened) An I/O operation was attempted on a filehandle that
    was never initialized.  You need to do an open() or a socket()
    call, or call a constructor from the FileHandle package.

        This message should be unadorned.
        This is a user warning at diagtest line 4.

DIAGNOSTIC TESTER: Please enter a <CR> here:
Use of uninitialized value in division (/) at diagtest line 8 (#4)

(W uninitialized) An undefined value was used as if it were
    already defined.  It was interpreted as a "" or a 0, but maybe
    it was a mistake.  To suppress this warning assign a defined
    value to your variables.

Illegal division by zero at diagtest line 8 (#5)

(F) You tried to divide a number by 0.  Either something was
    wrong in your logic, or you need to put a conditional in to
    guard against meaningless input.

Uncaught exception from user code:
        Illegal division by zero at diagtest line 8.

Diagnostic messages derive from the perldiag.pod file. If an extant $SIG{__WARN__} handler is discovered, this will still be honored, but only after the diagnostics::splainthis function (the pragma's $SIG{__WARN__} interceptor) has had its way with your warnings. Perl does not currently support stacked handlers, so this is the best we can do for now. There is a $diagnostics::DEBUG variable you may set if you're desperately curious about what sorts of things are being intercepted:

BEGIN { $diagnostics::DEBUG = 1 }
use diagnostics;

Previous | Home | Next
31.7. use constant | Book Index | 31.9. use fields
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.9. use fields

In the Pet module:

package Pet;
use strict;
use fields qw(name weight _Pet_pid);
my $PID = 0;
sub new {
    my Pet $self = shift;
    unless (ref $self) {
        $self = fields::new($self);
        $self->{_Pet_pid} = "this is Pet's secret ID";
    }
    $self->{name} = "Hey, you!";
    $self->{weight} = 20;
    return $self;
}
1;
In a separate program, demopet:
use Pet;
my Pet $rock = new Pet;           # typed lexical

$rock->{name}     = "quartz";
$rock->{weight}   = "2kg";
$rock->{_Pet_pid} = 1233;         # private attribute

$rock->{color}    = "blue";       # generates compile-time error
In the Dog module:
package Dog;
use strict;
use base 'Pet';                   # inherit fields and methods from Pet
use fields qw(name pedigree);     # override Pet name attribute,
                                  # add new pedigree attribute
use fields qw(wag _Dog_private);  # not shared with Pet
sub new {
    my $class = shift;
    my $self = fields::new($class);
    $self->SUPER::new();          # init base fields
    $self->{pedigree} = "none";   # init own fields
    return $self;
}
In a separate program, demodog:
use Dog;

my Dog $spot = new Dog;           # typed lexical

$spot->{name}     = "Theloneus";  # not inherited
$spot->{weight}   = "30lbs";      # inherited
$spot->{pedigree} = "mutt";       # not inherited

$spot->{color}    = "brown";      # generates compile-time error
$spot->{_Pet_pid} = 3324;         # generates compile-time error

The fields pragma provides a method of declaring class fields that can be type checked at compile time. This relies on a feature known as pseudohashes: if a typed lexical variable (my Pet $rock) is holding a reference (the Pet object) and is used to access a hash element ($rock->{name}), and if there exists a package with the same name as the declared type that has set up class fields using the fields pragma, then the operation is turned into an array access at compile time, provided the field specified is valid.

The related base pragma will combine fields from base classes and any fields declared using the fields pragma. This enables field inheritance to work properly.

Field names that start with an underscore character are made private to the class and are not visible to subclasses. Inherited fields can be overridden but will generate a warning if warnings are enabled.

The effect of all this is that you can have objects with named fields which are as compact as arrays and as fast to access. This only works as long as the objects are accessed through properly typed lexical variables, though. If the variables are not typed, access is only checked at run time, so your program runs slower because it has to do both a hash access and an array access. In addition to field declarations, the following functions are supported:

new

The fields::new function creates and blesses a pseudohash into the specified class (which may also be specified by passing an object of that class). The object is created with the fields declared earlier for that class using the fields pragma. This makes it possible to write a constructor like this:

package Critter::Sounds;
use fields qw(cat dog bird);

sub new {
    my Critter::Sounds $self = shift;
    $self = fields::new($self) unless ref $self;
    $self->{cat} = 'meow';                          # scalar element
    @$self{'dog','bird'} = ('bark','tweet');        # slice
    return $self;
}

phash

The fields::phash function creates and initializes a plain (unblessed) pseudohash. You should always use this function to create pseudohashes instead of creating them directly, in case we decide to change the implementation.

If the first argument to phash is a reference to an array, the pseudohash will be created with keys from that array. If a second argument is supplied, it must also be a reference to an array whose elements will be used as the values. If the second array contains less elements than the first, the trailing elements of the pseudohash will not be initialized. This makes it particularly useful for creating a pseudohash from subroutine arguments:

sub dogtag {
    my $tag = fields::phash([qw(name rank ser_num)], [@_]);
}
Alternatively, you can pass a list key/value pairs that will be used to construct the pseudohash:
my $tag = fields::phash(name => "Joe",
                        rank => "captain",
                        ser_num => 42);

my $pseudohash = fields::phash(%args);
For more on pseudohashes, see the section "Pseudohashes" in Chapter 8, "References".

The current implementation keeps the declared fields in the %FIELDS hash of the calling package, but this may change in future versions, so it's best to rely on this pragma's interface to manage your fields.

Previous | Home | Next
31.8. use diagnostics | Book Index | 31.10. use filetest
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.10. use filetest

$can_perhaps_read = -r "file";      # use the mode bits
{
    use filetest 'access';          # intuit harder
    $can_really_read = -r "file";
}
$can_perhaps_read = -r "file";      # use the mode bits again

This lexically scoped pragma tells the compiler to change the behavior of the unary file test operators -r, -w, -x, -R, -W, and -X, documented in Chapter 3, "Unary and Binary Operators". The default behavior for these file tests is to use the mode bits returned by the stat family of calls. However, this may not always be the right thing to do, such as when a filesystem understands ACLs (access control lists). In environments such as AFS where this matters, the use filetest pragma may help the permission operators to return results more consistent with other tools.

There may be a slight performance decrease in the affected file test operators under use filetest, since on some systems the extended functionality needs to be emulated.

Warning: any notion of using file tests for security purposes is a lost cause from the start. There is a window open for race conditions, because there's no way to guarantee that the permissions will not change between the test and the real operation. If you are the least bit serious about security, you won't use file test operators to decide whether something will work. Instead, just go ahead try the real operation, then test for whether that operation succeeded. (You should be doing that anyway.) See the section "Handling Timing Glitches" in Chapter 23, "Security".

31.10.1. use filetest 'access'

Currently only one import, access, is implemented. Calling use filetext 'access' enables the use of access(2) or similar syscalls when performing file tests, and no filetest 'access' similarly disables it. This extended file test functionality is used only when the operator's operand (or, if you prefer, the unary function's argument) is a real filename, not when it is a filehandle.

Previous | Home | Next
31.9. use fields | Book Index | 31.11. use integer
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.11. use integer

use integer;
$x = 10/3;
# $x is now 3, not 3.33333333333333333

This lexically scoped pragma tells the compiler to use integer operations from here through the end of the enclosing block. On many machines, this doesn't matter a great deal for most computations, but on those few remaining architectures without floating-point hardware, it can amount to a dramatic performance difference.

Note that this pragma affects certain numeric operations, not the numbers themselves. For example, if you run this code:

use integer;
$x = 1.8;
$y = $x + 1;
$z = -1.8;
you'll be left with $x == 1.8, $y == 2 and $z == -1. The $z case happens because unary - counts as an operation, so the value 1.8 is truncated to 1 before its sign bit is flipped. Likewise, functions that expect floating-point numbers, such as sqrt or the trig functions, still receive and return floats even under use integer. So sqrt(1.44) is 1.2, but 0 + sqrt(1.44) is now just 1.

Native integer arithmetic as provided by your C compiler is used. This means that Perl's own semantics for arithmetic operations might not be preserved. One common source of trouble is the modulus of negative numbers. Perl may do it one way, but your hardware may do it another:

% perl -le 'print (4 % -3)'
-2
% perl -Minteger -le 'print (4 % -3)'
1

Previous | Home | Next
31.10. use filetest | Book Index | 31.12. use less
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.12. use less

use less;               # These are all UNIMPLEMENTED!

use less 'CPU';
use less 'memory';
use less 'time';
use less 'disk';
use less 'fat';         # great with "use locale";

Currently unimplemented, this pragma is intended to someday give hints to the compiler, code-generator, or interpreter to enable certain trade-offs.

It is not an error to ask to use less of something that Perl doesn't know how to make less of right now.

Previous | Home | Next
31.11. use integer | Book Index | 31.13. use lib
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.13. use lib

use lib "$ENV{HOME}/libperl";   # add ~/libperl
no lib ".";                     # remove cwd

This pragma simplifies the manipulation of @INC at compile time. It is typically used to add extra directories to Perl's search path so that later do, require, and use statements will find library files that aren't located in Perl's default search path. It's especially important with use, since that happens at compile time too, and setting @INC normally (that is, at run time) would be too late.

Parameters to use lib are prepended to the beginning of Perl's search path. Saying use lib LIST is almost the same as saying BEGIN { unshift(@INC,LIST) }, but use lib LIST includes support for platform-specific directories. For each given directory $dir in its argument list, the lib pragma also checks to see whether a directory named $dir/$archname/auto exists. If so, the $dir/$archname directory is assumed to be a corresponding platform-specific directory, so is added to @INC (in front of $dir).

To avoid redundant additions that slow access time and waste a small amount of memory, trailing duplicate entries in @INC are removed when entries are added.

Normally, you should only add directories to @INC. If you do need to delete directories from @INC, take care to delete only those that you yourself added, or those that you're somehow certain aren't needed by other modules in your program. Other modules may have added directories to your @INC that they need for correct operation.

The no lib pragma deletes all instances of each named directory from @INC. It also deletes any corresponding platform-specific directory as described earlier.

When the lib pragma is loaded, it saves the current value of @INC to the array @lib::ORIG_INC, so to restore the original, just copy that array to the real @INC.

Even though @INC typically includes dot ("."), the current directory, this really isn't as useful as you'd think. For one thing, the dot entry comes at the end, not the start, so that modules installed in the current directory don't suddenly override system versions. You could say use lib "." if that's what you really want. More annoyingly, it's the current directory of the Perl process, not the directory that the script was installed into, which makes it completely unreliable. If you create a program plus some modules for that program to use, it will work while you're developing, but it won't work when you aren't running in the directory the files live in.

One solution for this is to use the standard FindBin module:

use FindBin;                # where was script installed?
use lib $FindBin::Bin;      # use that dir for libs, too
The FindBin module tries to guess the full path to the directory in which the running process's program was installed. Don't use this for security purposes, because malicious programs can usually deceive it if they try hard enough. But unless you're intentionally trying to break the module, it should work as intended. The module provides a $FindBin::Bin variable (which you may import) that contains the module's guess of where the program was installed. You can then use the lib pragma to add that directory to your @INC, thus producing an executable-relative path.

Some programs expect to be installed in a bin directory and then find their library modules in "cousin" files installed in a lib directory at the same level as bin. For example, programs might go in /usr/local/apache/bin or /opt/perl/bin, and libraries go in /usr/local/apache/lib and /opt/perl/lib. This code takes care of that neatly:

use FindBin qw($Bin);
use lib "$Bin/../lib";
If you find yourself specifying the same use lib in several unrelated programs, you might consider setting the PERL5LIB environment variable instead. See the description of the PERL5LIB environment variable in Chapter 19, "The Command-Line Interface".
# syntax for sh, bash, ksh, or zsh
$ PERL5LIB=$HOME/perllib; export PERL5LIB

# syntax for csh or tcsh
% setenv PERL5LIB ~/perllib
If you want to use optional directories on just this program without changing its source, look into the -I command-line switch:
% perl -I ~/perllib program-path args
See the Chapter 19, "The Command-Line Interface" for more about using -I from the command line.

Previous | Home | Next
31.12. use less | Book Index | 31.14. use locale
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.14. use locale

@x = sort @y;       # ASCII sorting order
{
    use locale;
    @x = sort @y;   # Locale-defined sorting order
}
@x = sort @y;       # ASCII sorting order again

This lexically scoped pragma tells the compiler to enable (or disable, under no locale) the use of POSIX locales for built-in operations. Enabling locales tells Perl's case-conversion functions and pattern-matching engine to be respectful of your language environment, allowing for characters with diacritical markings, etc. If this pragma is in effect and your C library knows about POSIX locales, Perl looks to your LC_CTYPE setting for regular expressions and to your LC_COLLATE setting for string comparisons like those in sort.

Since locales are more a form of nationalization than of internationalization, the use of locales may interact oddly with Unicode. See Chapter 15, "Unicode" for more on internationalization.

Previous | Home | Next
31.13. use lib | Book Index | 31.15. use open
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.15. use open

use open IN => ":crlf", OUT => ":raw";

The open pragma declares one or more default disciplines for I/O operations. Any open and readpipe (that is, qx// or backticks) operators found within the lexical scope of this pragma that do not specify their own disciplines will use the declared defaults. Neither open with an explicit set of disciplines, nor sysopen under any cirumstances, is influenced by this pragma.

Only the two disciplines :raw and :crlf are currently available (though as of this writing we expect a :utf8 discipline to be along shortly). On legacy systems that distinguish between those two translation modes when opening files, the :raw discipline corresponds to "binary mode", and :crlf to "text mode". (These two disciplines are currently no-ops on platforms where binmode is a no-op, but only for now; see the open function in Chapter 29, "Functions", for a longer description of the semantics we expect of various disciplines.)

Full-fledged support for I/O disciplines is currently unimplemented. When they are eventually supported, this pragma will serve as one of the interfaces to declare default disciplines for all I/O. At that time, any default disciplines declared by this pragma will be available by the special discipline name ":DEFAULT" and usable within handle constructors that allow disciplines to be specified. This will make it possible to stack new disciplines over the default ones.

open (FH, "<:para :DEFAULT", $file) or die "can't open $file: $!";
Once complete, full support for I/O disciplines will enable all supported disciplines to work on all platforms.

Previous | Home | Next
31.14. use locale | Book Index | 31.16. use overload
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.16. use overload

In the Number module:

package Number;
use overload "+" => \&myadd,
             "-" => \&mysub,
            "*=" => "multiply_by";
In your program:
use Number;
$a = new Number 57;
$b = $a + 5;
The built-in operators work well on strings and numbers, but make little sense when applied to object references (since, unlike C or C++, Perl doesn't allow pointer arithmetic). The overload pragma lets you redefine the meanings of these built-in operations when applied to objects of your own design. In the previous example, the call to the pragma redefines three operations on Number objects: addition will call the Number::myadd function, subtraction will call the Number::mysub function, and the multiplicative assignment operator will call the multiply_by method in class Number (or one of its base classes). We say of these operators that they are now overloaded because they have additional meanings overlaid on them (and not because they have too many meanings--though that may also be the case).

For much more on overloading, see Chapter 13, "Overloading".

Previous | Home | Next
31.15. use open | Book Index | 31.17. use re
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.17. use re

This pragma controls the use of regular expressions. It has four possible invocations: "taint" and "eval", which are lexically scoped, plus "debug" and "debugcolor", which aren't.

use re 'taint';
# Contents of $match are tainted if $dirty was also tainted.
($match) = ($dirty =~ /^(.*)$/s);

# Allow code interpolation:
use re 'eval';
$pat = '(?{ $var = 1 })';      # embedded code execution
/alpha${pat}omega/;            # won't fail unless under -T
                               # and $pat is tainted

use re 'debug';                # like "perl -Dr"
/^(.*)$/s;                     # output debugging info during
                               #     compile time and run time

use re 'debugcolor';           # same as 'debug',
                               #    but with colored output
When use re 'taint' is in effect and a tainted string is the target of a regex, the numbered regex variables and values returned by the m// operator in list context are all tainted. This is useful when regex operations on tainted data aren't meant to extract safe substrings, but to perform other transformations. See the discussion on tainting in Chapter 23, "Security".

When use re 'eval' is in effect, a regex is allowed to contain assertions that execute Perl code, which are of the form (?{ ... }), even when the regex contains interpolated variables. Execution of code segments resulting from variable interpolation into a regex is normally disallowed for security reasons: you don't want programs that read patterns from config files, command-line arguments, or CGI form fields to suddenly start executing arbitrary code if they weren't designed to expect this possibility. This use of the pragma allows only untainted strings to be interpolated; tainted data will still cause an exception to be raised (if you're running with taint checks enabled). See also Chapter 5, "Pattern Matching", and Chapter 23, "Security".

For the purposes of this pragma, interpolation of precompiled regular expressions (produced by the qr// operator) is not considered variable interpolation. Nevertheless, when you build the qr// pattern it needs to have use re 'eval' in effect if any of its interpolated strings contain code assertions. For example:

$code = '(?{ $n++ })';      # code assertion
$str  = '\b\w+\b' . $code;  # build string to interpolate

$line =~ /$str/;    # this needs use re 'eval'

$pat = qr/$str/;    # this also needs use re 'eval'
$line =~ /$pat/;    # but this doesn't need use re 'eval'
Under use re 'debug', Perl emits debugging messages when compiling and when executing regular expressions. The output is the same as that obtained by running a "debugging Perl" (one compiled with -DDEBUGGING passed to the C compiler) and then executing your Perl program under Perl's -Dr command-line switch. Depending on how complicated your pattern is, the resulting output can be overwhelming. Calling use re 'debugcolor' enables more colorful output that can be useful, provided your terminal understands color sequences. Set your PERL_RE_TC environment variable to a comma-separated list of relevant termcap(5) properties for highlighting. For more details, see Chapter 20, "The Perl Debugger".

Previous | Home | Next
31.16. use overload | Book Index | 31.18. use sigtrap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.18. use sigtrap

use sigtrap;
use sigtrap qw(stack-trace old-interface-signals);  # same thing

use sigtrap qw(BUS SEGV PIPE ABRT);
use sigtrap qw(die INT QUIT);
use sigtrap qw(die normal-signals);
use sigtrap qw(die untrapped normal-signals);
use sigtrap qw(die untrapped normal-signals
                stack-trace any error-signals);

use sigtrap 'handler' => \&my_handler, 'normal-signals';
use sigtrap qw(handler my_handler normal-signals stack-trace error-signals);

The sigtrap pragma installs some simple signal handlers on your behalf so that you don't have to worry about them. This is useful in situations where an untrapped signal would cause your program to misbehave, like when you have END {} blocks, object destructors, or other at-exit processing that needs to be run no matter how your program happens to terminate.

The sigtrap pragma provides two simple signal handlers for your use. One provides a Perl stack trace, and the other throws an ordinary exception via die. Alternately, you can supply your own handler for the pragma to install. You may specify predefined sets of signals to trap; you can also supply your own explicit list of signals. The pragma can optionally install handlers for only those signals that have not otherwise been handled.

Arguments passed to use sigtrap are processed in order. When a user-supplied signal name or the name of one of sigtrap's predefined signal lists is encountered, a handler is immediately installed. When an option is encountered, this affects only those handlers installed later in processing the argument list.

31.18.1. Signal Handlers

These options affect which handler will be used for signals installed later:

stack-trace

This pragma-supplied handler outputs a Perl stack trace to STDERR and then tries to dump core. This is the default signal handler.

die

This pragma-supplied handler calls die via Carp::croak with a message indicating the signal caught.

handler YOURHANDLER

YOURHANDLER will be used as the handler for signals installed later. YOURHANDLER can be any value valid for assignment into %SIG. Remember that the proper functioning of many C library calls (particularly standard I/O calls) cannot be guaranteed within a signal handler. Worse, it's hard to guess which bits of C library code are called from which bits of Perl code. (On the other hand, many of the signals that sigtrap traps are pretty vile--they're gonna take you down anyway, so there's not much harm in trying to do something, now is there?)

31.18.2. Predefined Signal Lists

The sigtrap pragma has a few built-in lists of signals to trap:

normal-signals

These are the signals a program might normally expect to encounter, and which, by default, cause it to terminate. They are the HUP, INT, PIPE, and TERM signals.

error-signals

These are the signals that usually indicate a serious problem with the Perl interpreter or with your program. They are the ABRT, BUS, EMT, FPE, ILL, QUIT, SEGV, SYS, and TRAP signals.

old-interface-signals

These are the signals that were trapped by default under an older version of sigtrap's interface. They are ABRT, BUS, EMT, FPE, ILL, PIPE, QUIT, SEGV, SYS, TERM, and TRAP. If no signals or signals lists are passed to use sigtrap, this list is used.

If your platform does not implement a particular signal named in the predefined lists, that signal name will be silently ignored. (The signal itself can't be ignored, because it doesn't exist.)

31.18.3. Other Arguments to sigtrap

untrapped

This token suppresses the installation of handlers for subsequently listed signals if they're already been trapped or ignored.

any

This token installs handlers for all subsequently listed signals. This is the default behavior.

signal

Any argument that looks like a signal name (that is, one matching the pattern /^[A-Z][A-Z0-9]*$/) requests sigtrap to handle that signal.

number

A numeric argument requires the version number of the sigtrap pragma to be at least number. This works is just like most regular modules that have a $VERSION package variable:

% perl -Msigtrap -le 'print $sigtrap::VERSION'
1.02

31.18.4. Examples of sigtrap

Provide a stack trace for the old interface signals:

use sigtrap;
Same thing, but more explicitly:
use sigtrap qw(stack-trace old-interface-signals);
Provide a stack trace only on the four listed signals:
use sigtrap qw(BUS SEGV PIPE ABRT);
Die on an INT or a QUIT signal:
use sigtrap qw(die INT QUIT);
Die on any of HUP, INT, PIPE, or TERM:
use sigtrap qw(die normal-signals);
Die on HUP, INT, PIPE, or TERM--except don't change the behavior for signals that have already been trapped or ignored elsewhere in the program:
use sigtrap qw(die untrapped normal-signals);
Die on receipt of any currently untrapped normal-signals; additionally, provide a stack backtrace on receipt of any of the error-signals:
use sigtrap qw(die untrapped normal-signals
                stack-trace any error-signals);
Install the routine my_handler as the handler for the normal-signals:
use sigtrap 'handler' => \&my_handler, 'normal-signals';
Install my_handler as the handler for the normal-signals; provide a Perl stack backtrace on receipt of any of the error-signals:
use sigtrap qw(handler my_handler normal-signals
                stack-trace error-signals);

Previous | Home | Next
31.17. use re | Book Index | 31.19. use strict
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.19. use strict

use strict;         # Install all three strictures.

use strict "vars";  # Variables must be predeclared.
use strict "refs";  # Can't use symbolic references.
use strict "subs";  # Bareword strings must be quoted.

use strict;         # Install all...
no strict "vars";   # ...then renege on one.

This lexically scoped pragma changes some basic rules about what Perl considers to be legal code. Sometimes these restrictions seem too strict for casual programming, such as when you're just trying to whip up a five-line filter program. The larger your program, the more you need to be strict about it.

Currently, there are three possible things to be strict about: subs, vars, and refs. If no import list is supplied, all three restrictions are assumed.

31.19.1. strict 'refs'

This generates a run-time error if you use symbolic references, intentionally or otherwise. See Chapter 8, "References" for more about these.

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.
Symbolic references are suspect for various reasons. It's surprisingly easy for even well-meaning programmers to invoke them accidentally; strict 'refs' guards against that. Unlike real references, symbolic references can only refer to global variables. They aren't reference-counted. And there's often a better way to do what you're doing: instead of referencing a symbol in a global symbol table, use a hash as its own little mini-symbol table. It's more efficient, more readable, and less error prone.

Nevertheless, some sorts of valid manipulation really do require direct access to the package's global symbol table of variables and function names. For example, you might want to examine the @EXPORT list or the @ISA superclass of a given package whose name you don't know in advance. Or you might want to install a whole slew of function calls that are all aliases to the same closure. This is just what symbolic references are best at, but to use them while use strict is in effect, you must first undo the "refs" stricture:

# make a bunch of attribute accessors
for my $methname (qw/name rank serno/) {
    no strict 'refs';
    *$methname = sub { $_[0]->{ __PACKAGE__ . $methname };
}

31.19.2. strict 'vars'

Under this stricture, a compile-time error is triggered if you attempt to access a variable that hasn't met at least one of the following criteria:

  • Predefined by Perl itself, such as @ARGV, %ENV, and all the global punctuation variables such as $. or $_.

  • Declared with our (for a global) or my (for a lexical).

  • Imported from another package. (The use vars pragma fakes up an import, but use our instead.)

  • Fully qualified using its package name and the double-colon package separator.

Just using a local operator isn't good enough to keep use strict 'vars' happy because, despite its name, that operator doesn't change whether the named variable is global or not. It just gives the variable a new, temporary value for the duration of block at run time. You still need to use our to declare a global variable, or my to declare a lexical variable. You can, however, localize an our:

local our $law = "martial";
Globals predefined by Perl are exempt from these requirements. This applies to program-wide globals (those forced into package main like @ARGV or $_) and to per-package variables like $a and $b, which are normally used by the sort function. Per-package variables used by modules like Exporter still need to be declared using our:
our @EXPORT_OK = qw(name rank serno);

31.19.3. strict 'subs'

This stricture makes Perl treat all barewords as syntax errors. A bareword ("bearword" in some dialects) is any bare name or identifier that has no other interpretation forced by context. (Context is often forced by a nearby keyword or token, or by predeclaration of the word in question.) Historically, barewords were interpreted as unquoted strings. This stricture outlaws that interpretation. If you mean to use it as a string, quote it. If you mean to use it as a function call, predeclare it or use parentheses.

As a particular case of forced context, remember that a word that appears by itself in curly braces or on the lefthand side of the => operator counts as being quoted, and so is not subject to this restriction.

use strict 'subs';

$x = whatever;      # WRONG: bareword error!
$x = whatever();    # This always works, though.

sub whatever;       # Predeclare function.
$x = whatever;      # Now it's ok.

# These uses are permitted, because the => quotes:
%hash = (red => 1, blue => 2, green => 3);

$rednum =  $hash{red};              # Ok, braces quote here.

# But not this one:
@coolnums = @hash{blue, green};     # WRONG: bareword error.
@coolnums = @hash{"blue", "green"}; # Ok, words now quoted.
@coolnums = @hash{qw/blue green/};  # Likewise.

Previous | Home | Next
31.18. use sigtrap | Book Index | 31.20. use subs
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.20. use subs

use subs qw/winken blinken nod/;
@x = winken 3..10;
@x = nod blinken @x

This pragma predeclares as standard subroutines all the names in the argument list. The advantage here is that you may now use those functions without parentheses as list operators, just as if you'd declared them yourself. This is not necessarily as useful as full declarations, because it doesn't allow prototypes or attributes, such as:

sub winken(@);
sub blinken(\@) : locked;
sub nod($) : lvalue;
Because it is based on the standard import mechanism, the use subs pragma is not lexically scoped but package scoped. That is, the declarations are effective for the entire file in which they appear, but only in the current package. You may not rescind such declarations with no subs.

Previous | Home | Next
31.19. use strict | Book Index | 31.21. use vars
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.21. use vars

use vars qw($frobbed @munge %seen);

This pragma, once used to declare a global variable, is now somewhat deprecated in favor of the our modifier. The previous declaration is better accomplished using:

our($frobbed, @munge, %seen);
or even:
our $frobbed = "F";
our @munge = "A" .. $frobbed;
our %seen = ();
No matter which of these you use, remember that they're talking about package globals, not file-scoped lexicals.

Previous | Home | Next
31.20. use subs | Book Index | 31.22. use warnings
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


31.22. use warnings

use warnings;   # same as importing "all"
no warnings;    # same as unimporting "all"

use warnings::register;
if (warnings::enabled()) {
    warnings::warn("some warning");
}

if (warnings::enabled("void")) {
    warnings::warn("void", "some warning");
}

This lexically scoped pragma permits flexible control over Perl's built-in warnings, both those emitted by the compiler as well as those from the run-time system.

Once upon a time, the only control you had in Perl over the treatment of warnings in your program was through either the -w command-line option or the $^W variable. Although useful, these tend to be all-or-nothing affairs. The -w option ends up enabling warnings in pieces of module code that you may not have written, which is occasionally problematic for you and embarrassing for the original author. Using $^W to either disable or enable blocks of code can be less than optimal because it works only during execution time, not during compile time.[3] Another issue is that this program-wide global variable is scoped dynamically, not lexically. That means that if you enable it in a block and then from there call other code, you again risk enabling warnings in code not developed with such exacting standards in mind.

[3]In the absence of BEGIN blocks, of course.

The warnings pragma circumvents these limitations by being a lexically scoped, compile-time mechanism that permits finer control over where warnings can or can't be triggered. A hierarchy of warning categories (see Figure 31-1) has been defined to allow groups of warnings to be enabled or disabled in isolation from one another. (The exact categorization is experimental and subject to change.) These categories can be combined by passing multiple arguments to use or no:

use warnings qw(void redefine);
no  warnings qw(io syntax untie);

Figure 31.1. Perl's warning categories

If multiple instances of the warnings pragma are active for a given scope, their effects are cumulative:

use warnings "void"; # Only "void" warnings enabled.
...
use warnings "io";   # Both "void" and "io" warnings now enabled.
...
no warnings "void";  # Only "io" warnings now enabled.
To make fatal errors of all warnings enabled by a particular warnings pragma, use the word FATAL at the front of the import list. This is useful when you would prefer a certain condition that normally causes only a warning to abort your program. Suppose, for example, that you considered it so improper to use an invalid string as a number (which normally produces a value of 0) that you want this brazen act to kill your program. While you're at it, you decide that using uninitialized values in places where real string or numeric values are expected should also be cause for immediate suicide:
{
    use warnings FATAL => qw(numeric uninitialized);
    $x = $y + $z;
}
Now if either $y or $z is uninitialized (that is, holds the special scalar value, undef), or if they contain strings that don't cleanly convert into numeric values, instead of going merrily on its way, or at most issuing a small complaint if you had -w enabled, your program will now raise a exception. (Think of this as Perl running in Python mode.) If you aren't trapping exceptions, that makes it a fatal error. The exception text is the same as would normally appear in the warning message.

The warnings pragma ignores the -w command-line switch and the value of the $^W variable; the pragma's settings take precedence. However, the -W command-line flag overrides the pragma, enabling full warnings in all code within your program, even code loaded with do, require, or use. In other words, with -W, Perl pretends that every block in your program has a use warnings 'all' pragma. Think of it as a lint(1) for Perl programs. (But see also the online documentation for the B::Lint module.) The -X command-line flag works the other way around. It pretends that every block has no warnings 'all' in effect.

Several functions are provided to assist module authors who want to make their module's functions behave like built-in functions with respect to the lexical scoping of the caller (that is, so that users of the module can lexically enable or disable warnings the module might issue):

warnings::register

Registers the current module name as a new category of warnings, so that users of your module can turn off warnings from it.

warnings::enabled(CATEGORY)

Returns true if the warnings category CATEGORY is enabled in the lexical scope of the calling module. Otherwise, it returns false. If CATEGORY is not supplied, the current package name is used.

warnings::warn(CATEGORY, MESSAGE)

If the calling module has not set CATEGORY to "FATAL", prints MESSAGE to STDERR. If the calling module has set CATEGORY to "FATAL", prints MESSAGE to STDERR, then dies. If CATEGORY is not supplied, the current package name is used.

Previous | Home | Next
31.21. use vars | Book Index | 32. Standard Modules
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 32. Standard Modules

Contents:

Listings by Type
Benchmark
Carp
CGI
CGI::Carp
Class::Struct
Config
CPAN
Cwd
Data::Dumper
DB_File
Dumpvalue
English
Errno
Exporter
Fatal
Fcntl
File::Basename
File::Compare
File::Copy
File::Find
File::Glob
File::Spec
File::stat
File::Temp
FileHandle
Getopt::Long
Getopt::Std
IO::Socket
IPC::Open2
IPC::Open3
Math::BigInt
Math::Complex
Math::Trig
Net::hostent
POSIX
Safe
Socket
Symbol
Sys::Hostname
Sys::Syslog
Term::Cap
Text::Wrap
Time::Local
Time::localtime
User::grent
User::pwent

The previous edition of this book included comprehensive, definitive coverage for all modules that were part of the standard Perl distribution. But if we did that again now, you'd pay twice what you're paying for this book, not to mention what you'd have to pay the chiropractor after trying to carry the book home. Over the last few years, more and more modules have come bundled standard; we're up to around two hundred of them right now. Some of these, such as CGI, have remarkably extensive documentation in their own right. And if you're using ActiveState's distribution of Perl, your standard library is even more luxed out.

So instead, we provide a complete listing of the standard modules, sorted by type, along with a brief description of what each module does. Then we cherry pick a few of our favorite modules by providing examples of typical uses, followed by a short description of how they work, just to give you a taste of using them. The descriptions are suggestive rather than comprehensive, and virtually all the modules have features beyond those shown. However, complete documentation for all standard modules is included with every Perl distribution, so you can just look up the details on your own system using the perldoc program, your system's man(1) command, or your favorite browser. See the section "Online Documentation" in the Preface. Ask your Local Expert if you can't find the docs, because they're almost certainly installed somewhere on your system. Even if they're not, you can always read the pod docs directly from the modules themselves, because all module docs come embedded in their corresponding module (.pm) files, and pod was designed to be somewhat readable. (Unlike, say, HTML.)

32.1. Listings by Type

Normal module names begin with an uppercase letter. Lowercase names indicate pragmas that you'll find documented in Chapter 31, "Pragmatic Modules", rather than in this chapter.

32.1.1. Data Types

These modules extend Perl's type system (or lack thereof) in various ways.

Module | Description
Class::Struct | Create struct-like Perl object classes
constant | Declare constant scalars and lists
integer | Force Perl to do arithmetic with integers instead of floating point
Math::BigFloat | Calculate with arbitrary length floating-point math
Math::BigInt | Calculate with arbitrary length integer math
Math::Complex | Calculate with complex numbers and associated mathematical functions
Math::Trig | Load many trigonometric and related functions
overload | Overload Perl operators on objects
Symbol | Manipulate Perl symbol tables and generate anonymous typeglobs
Time::Local | Efficiently compute epoch time given localtime or gmtime

32.1.2. String Processing, Language Text Processing, Parsing, and Searching

These modules do things with (or to) text.

Module | Description
Search::Dict | Use a binary search for a string in a sorted text file
Text::Abbrev | Create an abbreviation table from a list
Text::ParseWords | Parse text into a list of tokens or an array of arrays
Text::Soundex | Use Knuth's Soundex algorithm
Text::Tabs | Expand or unexpand tabs like expand (1) and unexpand (1)
Text::Wrap | Wrap lines to form simple paragraphs

32.1.3. Option, Argument, Parameter, and Configuration File Processing

These modules process your command line.

Module | Description
Getopt::Long | Process extended command-line options in long form (--xxx)
Getopt::Std | Process single-character switches with switch clustering (-xyz)

32.1.4. Filenames, Filesystems, and File Locking

These modules provide cross-platform methods of file access.

Module | Description
Cwd | Get the pathname of the current working directory
File::Basename | Portably parse a pathname into directory, basename, and extension components
File::CheckTree | Run many file test checks on a set of directory trees
File::Compare | Portably compare contents of filenames or filehandles
File::Copy | Portably copy filenames or filehandles or move filenames
File::DosGlob | Do Microsoft-style fileglobbing
File::Find | Traverse a file tree like find(1)
File::Glob | Use Unix-style fileglobbing
File::Path | Portably create or remove a series of directories
File::Spec | Use portable filename operations (object-oriented interface)
File::Spec::Functions | Use portable filename operations (functional interface)
File::Spec::Mac | Use filename operations for Mac OS files
File::Spec::OS2 | Use filename operations for OS/2 files
File::Spec::Unix | Use filename operations for Unix files
File::Spec::VMS | Use filename operations for VMS files
File::Spec::Win32 | Use filename operations for Microsoft files
File::stat | Override built-in stat and lstat functions with a method interface

32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities

These modules provide object-oriented file, directory, and IPC access.

Module | Description
DirHandle | Use object methods for directory handles
FileCache | Keep more files concurrently open for output than your system permits
FileHandle | Use object methods for filehandles
IO | Provide a frontend to load all of IO::Dir, IO::File, IO::Handle, IO::Pipe, IO::Seekable, and IO::Socket
IO::Dir | Use object methods for directory handles
IO::File | Use file-related object methods for filehandles
IO::Handle | Use generic object methods for filehandles
IO::Pipe | Use object methods for pipes
IO::Poll | Provide an object interface to poll(2) syscall
IO::Seekable | Use object methods for seekable I/O objects
IO::Select | Use a convenient OO interface to the select(2) syscall
SelectSaver | Save and restore selected filehandle

32.1.6. Internationalization and Locale

These modules help you perform Un-American Activities.

Module | Description
bytes | Enforce old byte-oriented semantics
charnames | Define character names used in \N{name} escapes in string literals
I18N::Collate | Compare 8-bit scalar data according to current locale (deprecated)
locale | Use or avoid POSIX locales for built-in operations
utf8 | Turn on UTF-8 and Unicode support explicitly

32.1.7. Operating System Interfaces

These modules tweak your interface to the operating system.

Module | Description
Fcntl | Load the C library's fcntl.h definitions as Perl constants
filetest | Control the file test operators (-r, -w, etc.) for nontraditional filesystems
open | Set default disciplines for open function calls
POSIX | Use the Perl interface to POSIX 1003.1
Shell | Run shell commands transparently within Perl
sigtrap | Enable simple signal handling
Sys::Hostname | Portably try every conceivable way to determine the current hostname
Sys::Syslog | Use the C library's syslog(3) functions
Time::gmtime | Override the built-in gmtime function with a method interface
Time::localtime | Override the built-in localtime function with a method interface
Time::tm | Provide the internal object used by Time::gmtime and Time::localtime
User::grent | Override built-in getgr* functions with a method interface
User::pwent | Override built-in getpw* functions with a method interface

32.1.8. Networking and Interprocess Communication

These modules provide abstract interfaces around the basic interfaces we wrote about in Chapter 16, "Interprocess Communication".

Module | Description
IO::Socket | Use a generic object interface to socket communications
IO::Socket::INET | Use an object interface for Internet-domain sockets
IO::Socket::UNIX | Use an object interface for Unix-domain (local) sockets
IPC::Msg | Use object methods for working with System V messages (SysV Msg IPC object class)
IPC::Open2 | Open a process for simultaneous reading and writing
IPC::Open3 | Open a process for reading, writing, and error handling
IPC::Semaphore | Use object methods for System V semaphores
IPC::SysV | Define constants for all System V IPC mechanisms
Net::hostent | Override built-in gethost* functions with a method interface
Net::netent | Override built-in getnet* functions with a method interface
Net::Ping | Check a remote host for reachability
Net::protoent | Override built-in getproto* functions with a method interface
Net::servent | Override built-in getserv* functions with a method interface
Socket | Load the C library socket.h definitions and structure manipulators

32.1.9. World Wide Web

These modules interface to the WWW. You may have heard of it.

Module | Description
CGI | Access CGI forms and powerful automated HTML generation
CGI::Apache | Make your CGI script work under the Perl-Apache API
CGI::Carp | Write to the httpd(8) (or other) CGI error log
CGI::Cookie | Set and get HTTP cookies
CGI::Fast | Use the Fast CGI protocol
CGI::Pretty | Produce nicely formatted HTML code
CGI::Push | Do server-push CGI scripting

32.1.10. DBM Interfaces

These modules load various database management libraries.

Module | Description
AnyDBM_File | Provide a framework for multiple DBM libraries
DB_File | Provide tied access to the db(3) library (version 1.x Berkeley DB)
GDBM_File | Provide tied access to the gdbm(3) library
NDBM_File | Provide tied access to the ndbm(3) library
SDBM_File | Provide tied access to SDBM (simple DBM) files

32.1.11. User Interfaces

These modules provide a decent OS CLI I/O API, ASAP.

Module | Description
Term::Cap | Use the termcap(3) library
Term::Complete | Do programmable command completion on word lists
Term::ReadLine | Use any of several readline packages

32.1.12. Authentication, Security, and Encryption

These modules work with sandboxes.

Module | Description
Opcode | Enable or disable named opcodes when compiling Perl code for use with the Safe module
ops | Restrict unsafe operations when compiling
Safe | Compile and execute code in restricted compartments

32.1.13. Perl Language Extensions and Internals

(Not to be confused with Intentions and Externals.)

Module | Description
attributes | Get or set subroutine or variable attributes
attrs | Get or set subroutine or variable attributes (obsolete)
base | Establish inheritance of base class at compile time
Data::Dumper | Serialize Perl data structures
DB | Access the Perl debugger's experimental API
Devel::DProf | Profile a Perl program's execution
Devel::Peek | Load data debugging tools for XS programmers
diagnostics | Force verbose warnings and suppress duplicates
Dumpvalue | Provide screen dump of data
English | Use longer variable names for built-in punctuation variables
Env | Access environment variables in %ENV as regular scalars
Errno | Load the C library's errno.h definitions and tie the %! variable
Fatal | Replace built-ins with versions that raise exceptions on failure
fields | Declare compile-time verified access to a class's data attributes
less | Request less of something from Perl (unimplemented)
re | Alter default regular expression behavior
strict | Restrict sloppy constructs
subs | Predeclare the subroutine names in current the package
vars | Predeclare global variables (obsolete--see our in Chapter 29, "Functions")

32.1.14. Convenient Classes

These modules provide base classes and other conveniences.

Module | Description
Tie::Array | Provide a base class for tied arrays
Tie::Handle | Provide base class definitions for tied handles
Tie::Hash | Provide base class definitions for tied hashes
Tie::RefHash | Provide references as hash keys
Tie::Scalar | Provide base class definitions for tied scalars
Tie::SubstrHash | Hash a fixed-size table with a fixed-length key
UNIVERSAL | Provide a base class for all classes (blessed references)

32.1.15. Warnings and Exceptions

What to do when things go rwong.

Module | Description
Carp | Provide routines that warn and die from the perspective of the caller
warnings | Control warnings within the lexical scope

32.1.16. Documentation Support

And there's an awful lot of documentation to support.

Module | Description
Pod::Checker | Check pod documents for syntax errors (used by podchecker(1))
Pod::Functions | List built-in functions by type
Pod::Html | Convert pod files to HTML (used by pod2html(1))
Pod::InputObjects | Manage documentation support
Pod::Man | Convert pod to troff(1) format for the man(1) system (used by pod2man(1))
Pod::Parser | Provide a base class for creating pod filters and translators
Pod::Select | Extract selected sections of pod from input (used by podselect(1))
Pod::Text | Convert pod data to formatted ASCII text (used by pod2text(1))
Pod::Text::Color | Convert pod data to formatted ASCII text with ANSI color escapes
Pod::Text::Termcap | Convert pod data to ASCII text with terminal-specific escapes
Pod::Usage | Print a usage message derived from embedded pod documentation

32.1.17. Module Installation Support

These modules help other modules jump through various hoops.

Module | Description
AutoLoader | Load subroutines only on demand
AutoSplit | Split a package for autoloading
autouse | Postpone module loading until a function is used from that module
blib | Use the library from MakeMaker's uninstalled version of an extension
Config | Access Perl configuration information
CPAN | Query, download, and build Perl modules from CPAN sites
Devel::SelfStubber | Generate stubs for a module using SelfLoader
DynaLoader | Dynamically load C or C++ libraries as Perl extensions
Exporter | Implement default import method for traditional modules
ExtUtils::Command | Provide utilities to replace common external commands in Makefile
ExtUtils::Embed | Provide utilities for embedding Perl in C or C++ programs
ExtUtils::Install | Install files into the system's Perl library
ExtUtils::Installed | Manage inventory of installed modules
ExtUtils::Liblist | Determine which libraries to use and how to use them
ExtUtils::MakeMaker | Create a Makefile for a Perl extension
ExtUtils::Manifest | Load tools to write and check a MANIFEST file
ExtUtils::Miniperl | Write the C code for perlmain.c
ExtUtils::Mkbootstrap | Create a bootstrap file for use by DynaLoader
ExtUtils::Mksymlists | Write linker options files for dynamic extension
ExtUtils::MM_Cygwin | Override Unix behavior methods in ExtUtils::MakeMaker
ExtUtils::MM_OS2 | Override Unix behavior methods in ExtUtils::MakeMaker
ExtUtils::MM_Unix | Provide methods used by ExtUtils::MakeMaker
ExtUtils::MM_VMS | Override Unix behavior methods in ExtUtils::MakeMaker
ExtUtils::MM_Win32 | Override Unix behavior methods in ExtUtils::MakeMaker
ExtUtils::Packlist | Manage .packlist files
ExtUtils::testlib | Add blib/* directories to @INC
FindBin | Locate installation directory of the Perl program that is running
lib | Manipulate @INC at compile time
SelfLoader | Load functions only on demand
XSLoader | Dynamically load C or C++ libraries as Perl extensions

32.1.18. Development Support

These modules are for timing and testing, to see how much faster and cleaner your code doesn't run anymore.

Module | Description
Benchmark | Compare running times of alternate code versions
Test | Use a simple framework for writing test scripts
Test::Harness | Run standard test scripts with statistics

32.1.19. Perl Compiler and Code Generator

These modules support various backend code generators for Perl.

Module | Description
B | Load Perl code generators (a.k.a. the "Perl compiler")
B::Asmdata | Provide autogenerated data about Perl ops to produce bytecode
B::Assembler | Assemble Perl bytecode
B::Bblock | Walk basic blocks in the syntax tree
B::Bytecode | Use the Perl compiler's bytecode backend
B::C | Use the Perl compiler's C translation backend
B::CC | Use the Perl compiler's optimized C translation backend
B::Debug | Walk the Perl syntax tree, printing debug info about ops
B::Deparse | Use the Perl compiler backend to reproduce Perl code
B::Disassembler | Disassemble Perl bytecode
B::Lint | Catch dubious constructs
B::Showlex | Show lexical variables used in functions or files
B::Stash | Show what stashes are loaded
B::Terse | Walk the Perl syntax tree, printing terse info about ops
B::Xref | Generate cross-reference reports for Perl programs
ByteLoader | Load byte-compiled Perl code
O | Provide a generic interface to Perl compiler backends

32.1.20. Microsoft-Related Modules

If you got the Perl distribution for Microsoft systems from ActiveState, you already have the following Microsoft-only modules included for you. If you just grabbed the standard source distribution (maybe you want to build it under the Cygwin Unix-emulation environment) but you're running on Wintel, you can get all of these modules from CPAN.

Module | Description
Win32::ChangeNotify | Monitor events related to files and directories
Win32::Console | Use Win32 console and character mode functions
Win32::Event | Use Win32 event objects from Perl
Win32::EventLog | Process Win32 event logs from Perl
Win32::File | Manage file attributes in Perl
Win32::FileSecurity | Manage FileSecurity Discretionary Access Control Lists in Perl
Win32::IPC | Load the base class for Win32 synchronization objects
Win32::Internet | Access WININET.DLL functions
Win32::Mutex | Use Win32 mutex objects from Perl
Win32::NetAdmin | Manage network groups and users in Perl
Win32::NetResource | Manage network resources in Perl
Win32::ODBC | Use ODBC Extension for Win32
Win32::OLE | Use OLE automation extensions
Win32::OLE::Const | Extract constant definitions from TypeLib
Win32::OLE::Enum | Use OLE Automation Collection Objects
Win32::OLE::NLS | Use OLE National Language Support
Win32::OLE::Variant | Create and modify OLE VARIANT variables
Win32::PerfLib | Access the Windows NT Performance Counter
Win32::Process | Create and manipulate processes
Win32::Semaphore | Use Win32 semaphore objects
Win32::Service | Manage system services
Win32::Sound | Play with Windows sounds
Win32::TieRegistry | Mung the registry
Win32API::File | Access low-level Win32 system API calls for files and directories
Win32API::Net | Manage Windows NT LanManager accounts
Win32API::Registry | Access low-level Win32 system API calls from WINREG.H
Previous | Home | Next
31.22. use warnings | Book Index | 32.2. Benchmark
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.2. Benchmark

use Benchmark qw(timethese cmpthese timeit countit timestr);

# You can always pass in code as strings:
timethese $count, {
    'Name1' => '...code1...',
    'Name2' => '...code2...',
};

# Or as subroutines references:
timethese $count, {
    'Name1' => sub { ...code1... },
    'Name2' => sub { ...code2... },
};

cmpthese $count, {
    'Name1' => '...code1...',
    'Name2' => '...code2...',
};

$t = timeit $count, '...code...';
print "$count loops of code took:", timestr($t), "\n";

$t = countit $time, '...code...';
$count = $t->iters;
print "$count loops of code took:", timestr($t), "\n";

The Benchmark module can help you determine which of several possible choices executes the fastest. The timethese function runs the specified code segments the number of times requested and reports back how long each segment took. You can get a nicely sorted comparison chart if you call cmpthese the same way.

Code segments may be given as function references instead of strings (in fact, they must be if you use lexical variables from the calling scope), but call overhead can influence the timings. If you don't ask for enough iterations to get a good timing, the function emits a warning.

Lower-level interfaces are available that run just one piece of code either for some number of iterations (timeit) or for some number of seconds (countit). These functions return Benchmark objects (see the online documentation for a description). With countit, you know it will run in enough time to avoid warnings, because you specified a minimum run time.

To get the most out of the Benchmark module, you'll need a good bit of practice. It isn't usually enough to run a couple different algorithms on the same data set, because the timings only reflect how well those algorithms did on that particular data set. To get a better feel for the general case, you'll need to run several sets of benchmarks, varying the data sets used.

For example, suppose you wanted to know the best way to get a copy of a string without the last two characters. You think of four ways to do so (there are, of course, several others): chop twice, copy and substitute, or use substr on either the left- or righthand side of an assignment. You test these algorithms on strings of length 2, 200, and 20_000:

use Benchmark qw/countit cmpthese/;
sub run($) { countit(5, @_) }
for $size (2, 200, 20_000) {
    $s = "." x $len;
    print "\nDATASIZE = $size\n";
    cmpthese {
        chop2   => run q{
            $t = $s; chop $t; chop $t;
        },
        subs    => run q{
            ($t = $s) =~ s/..\Z//s;
        },
        lsubstr => run q{
             $t = $s; substr($t, -2) = '';
        },
        rsubstr => run q{
             $t = substr($s, 0, length($s)-2);
        },

    };
}
which produces the following output:
DATASIZE = 2
            Rate    subs lsubstr   chop2 rsubstr
subs    181399/s      --    -15%    -46%    -53%
lsubstr 214655/s     18%      --    -37%    -44%
chop2   338477/s     87%     58%      --    -12%
rsubstr 384487/s    112%     79%     14%      --

DATASIZE = 200
            Rate    subs lsubstr rsubstr   chop2
subs    200967/s      --    -18%    -24%    -34%
lsubstr 246468/s     23%      --     -7%    -19%
rsubstr 264428/s     32%      7%      --    -13%
chop2   304818/s     52%     24%     15%      --

DATASIZE = 20000
          Rate rsubstr    subs lsubstr   chop2
rsubstr 5271/s      --    -42%    -43%    -45%
subs    9087/s     72%      --     -2%     -6%
lsubstr 9260/s     76%      2%      --     -4%
chop2   9660/s     83%      6%      4%      --
With small data sets, the "rsubstr" algorithm runs 14% faster than the "chop2" algorithm, but in large data sets, it runs 45% slower. On empty data sets (not shown here), the substitution mechanism is the fastest. So there is often no best solution for all possible cases, and even these timings don't tell the whole story, since you're still at the mercy of your operating system and the C library Perl was built with. What's good for you may be bad for someone else. It takes a while to develop decent benchmarking skills. In the meantime, it helps to be a good liar.

Previous | Home | Next
32.1. Listings by Type | Book Index | 32.3. Carp
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.3. Carp

use Carp;
croak "We're outta here!";

use Carp qw(:DEFAULT cluck);
cluck "This is how we got here!";
The Carp module lets you write modules whose functions report errors the way built-in operators report errors--from the perspective of the users of your module. The Carp module supplies routines that you use much like the standard built-in functions warn and die, but that change the filename and line number so it looks like the error originated from the user's code instead of your code. In short, Carp is great way to misdirect blame.

There are actually four functions. The carp function works like the warn operator, but with caller-relative filename and line number information. The croak function works like die does--raising an exception--but again gives caller-relative information. If you prefer a longer lament, use cluck and confess instead of carp and croak respectively, and you'll get a full stack backtrace reporting who called whom and with what arguments (in the library with a lead pipe, no doubt). You have to import cluck explicitly, because it's not normally exported. People don't often want full stack traces on mere warnings, for some reason.

Previous | Home | Next
32.2. Benchmark | Book Index | 32.4. CGI
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.4. CGI

use CGI qw(:standard);
$who   = param("Name");
$phone = param("Number");
@picks = param("Choices");

The CGI module helps manage HTML forms, especially multistage forms where passing state from one stage to another is critical. The extremely simple example above expects to process a form with two parameters that take single values, such as text fields or radio buttons, and one that takes multiple values, like scrolling lists specified as "MULTIPLE". The module is several orders of magnitude fancier than this, supporting such features as convenient cookie processing, persistent values for multiscreen shopping carts, and dynamic generation of HTML lists and tables you might pull from a database--just to name a few. Support for turbo-charged execution of precompiled Perl scripts through Apache's mod_perl facility is also provided. The O'Reilly book Writing Apache Modules with Perl and C, by Lincoln Stein and Doug MacEachern, can tell you all about this.

Previous | Home | Next
32.3. Carp | Book Index | 32.5. CGI::Carp
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.5. CGI::Carp

use CGI::Carp;
warn "This is a complaint";     # Stamp it with progname and date.
die "But this one is serious";  # But don't cause server 500 errors.

use CGI::Carp qw(carpout);      # Import this function.
open(LOG, ">>/var/tmp/mycgi-log")
    or die "Can't append to mycgi-log: $!\n";
carpout(*LOG);                  # Now uses program-specific errlog.

use CGI::Carp qw(fatalsToBrowser);
die "Fatal error messages are now sent to browser, too";

The CGI::Carp module provides versions of the warn and die Perl built-in functions, plus the Carp module's carp, cluck, confess, and croak functions which are more verbose and safer, too. They're more verbose because each message includes the date and time with the name of the program issuing the message, which helps when you're using a log file shared by a hundred different programs scribbling a thousand different messages on it at the same time.

The module is also kinder to web surfers, since premature death in a CGI script tends to cause inscrutable "Server 500" errors when the proper HTTP header doesn't get out to the server before your program pegs out, and this module makes sure that doesn't happen. The carpout function redirects all warnings and errors to the filehandle specified. The fatalsToBrowser directive sends a copy of such messages to the user's browser, too. These facilities ease debugging of problems in CGI scripts.

Previous | Home | Next
32.4. CGI | Book Index | 32.6. Class::Struct
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.6. Class::Struct

use Class::Struct;

struct Manager => {         # Creates a Manager->new() constructor.
    name    => '$',         # Now name() method accesses a scalar value.
    salary  => '$',         # And so does salary().
    started => '$',         # And so does started().
};

struct Shoppe => {          # Creates a Shoppe->new() constructor.
    owner   => '$',         # Now owner() method accesses a scalar.
    addrs   => '@',         # And addrs() method accesses an array.
    stock   => '%',         # And stock() method accesses a hash.
    boss    => 'Manager',   # Initializes with Manager->new().
};

$store = Shoppe->new();
$store->owner('Abdul Alhazred');
$store->addrs(0, 'Miskatonic University');
$store->addrs(1, 'Innsmouth, Mass.');
$store->stock("books", 208);
$store->stock("charms", 3);
$store->stock("potions", "none");
$store->boss->name('Prof L. P. Haitch');
$store->boss->salary('madness');
$store->boss->started(scalar localtime);
The Class::Struct module provides a way to "declare" a class as having objects whose fields are of a specific type. The function that does this is called struct. Because structures or records are not base types in Perl, each time you want to create a class to provide a record-like data object, you have to define a constructor method along with accessor methods for each data field, sometimes called "wrapper" methods. The Class::Struct module's struct function alleviates this tedium by creating a class for you on the fly. You just tell it what data members should exist and their types. The function creates a constructor method named new in the package specified by the first argument, plus an attribute accessor method for each member, as specified by the second argument, which should be a hash reference.

Field types are specified as either a built-in type using the customary "$", "@", "%", and "&" symbols, or as another class using the class name. The type of each field will be enforced when you try to set the value.

Many standard modules use Class::Struct to create their objects and accessors, including Net::hostent and User::pwent, whose source you can look at as a model. See also the CPAN modules Tie::SecureHash and Class::Multimethods for more elaborate approaches to autogeneration of classes and accessor methods. See the section "Managing Instance Data" in Chapter 12, "Objects".

Previous | Home | Next
32.5. CGI::Carp | Book Index | 32.7. Config
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.7. Config

use Config;
if ($Config{cc} =~ /gcc/) {
    print "This perl was built by GNU C.\n";
}
use Config qw(myconfig config_sh config_vars);
print myconfig();    # like perl -V without a pattern
print config_sh();   # gives absolutely everything

config_vars qw/osname osvers archname/;
The configuration mechanism that builds and installs Perl assembles a wealth of information about your system. The Config module exports by default a tied hash variable named %Config, which provides access to over 900 different configuration values. (These values are also available through Perl's -V:PATTERN command-line switch.) Config also provides three functions that give more shell-like access to these values, as shown above. For instance, that last call might print out:
osname='openbsd';
osvers='2.6';
archname='OpenBSD.sparc-openbsd';
The module's online documentation describes the configuration variables and their possible values. Be aware that if you move your perl executable to a system other than the one on which it was built, these values may not reflect the current reality; for instance, if you're running a Linux or a Solaris binary on a BSD system.

Previous | Home | Next
32.6. Class::Struct | Book Index | 32.8. CPAN
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.8. CPAN

# Get interactive CPAN shell.
% perl -MCPAN -e shell

# Just ask for upgrade recommendations.
% perl -MCPAN -e 'CPAN::Shell->r'

# Install the named module in batch mode.
% perl -MCPAN -e "install Class::Multimethods"
The CPAN module is an automated, user-friendly interface to the Comprehensive Perl Archive Network described in Chapter 22, "CPAN". Unlike most modules you encounter, it's intended to be called from the command line, just like a little program. The first time you call it, the module prompts for the default CPAN mirror site and other information it needs. After that, you can fire up its interactive shell to make queries and select modules to install, ask the module for recommendations on which modules need an upgrade, or just have it install one particular module.

Previous | Home | Next
32.7. Config | Book Index | 32.9. Cwd
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.9. Cwd

use Cwd;
$dir = getcwd();    # Where am I?

use Cwd 'chdir';
chdir "/tmp";       # Updates $ENV{PWD}.

use Cwd 'realpath';
print realpath("/usr////spool//mqueue/../");  # prints /var/spool

The Cwd module provides platform-independent functions to determine your process's current working directory. This is better than shelling out to pwd(1) because non-POSIX-conforming systems aren't guaranteed to have such a command, and Perl runs on more than just POSIX platforms. The getcwd function, which is exported by default, returns the current working directory using whatever mechanism is deemed safest on the current platform. If you import the chdir function, it overrides the built-in operator with the module's operator, which maintains the $ENV{PWD} environment variable; commands you might launch later that would care about that variable would then have a consistent view of their world. The realpath function resolves its pathname argument of any symbolic links and relative-path components to return a full path directory in canonical form, just like realpath(3).

Previous | Home | Next
32.8. CPAN | Book Index | 32.10. Data::Dumper
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.10. Data::Dumper

use Data::Dumper;
print Dumper($store);

When used on the example from Class::Struct, this prints:

$VAR1 = bless( {
             'Shoppe::owner' => 'Abdul Alhazred',
             'Shoppe::stock' => {
                                  'charms' => 3,
                                  'books' => 208,
                                  'potions' => 'none'
                                },
             'Shoppe::boss' => bless( {
                                        'Manager::name' =>
                                            'Prof L. P. Haitch',
                                        'Manager::salary' =>
                                            'madness',
                                        'Manager::started' =>
                                            'Sat Apr  1 16:18:13 2000'
                                      }, 'Manager' ),
             'Shoppe::addrs' => [
                                  'Miskatonic University',
                                  'Innsmouth, Mass.'
                                ]
           }, 'Shoppe' );
The Data::Dumper module's Dumper function takes a list of scalars (including references, which can even refer to objects) and returns a printable or evalable string that accurately reproduces an faithful copy of the original. You could use this to write out a saved version of a data structure to a regular disk file or into a DBM file, or to pass it to another process over a pipe or socket connection. This module can be used with MLDBM from CPAN and DB_File to implement a DBM file that can transparently store complex data values, not just flat strings. Other stringification (or serialization, or marshalling) modules include Storable and FreezeThaw, both available from CPAN.

Previous | Home | Next
32.9. Cwd | Book Index | 32.11. DB_File
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.11. DB_File

use DB_File;

Tie a hash to a DBM-style file:

tie(%hash, "DB_File", $filename)     # Open database.
    or die "Can't open $filename: $!";

$v = $hash{"key"};                   # Retrieve from database.
$hash{"key"} = "value";              # Put value into database.
untie %hash;
Tie a hash to a B-tree file, but still access as a regular DBM hash:
tie(%hash, "DB_File", "mytree", O_RDWR|O_CREAT, 0666, $DB_BTREE)
    or die "Cannot open file `mytree': $!";

while (($k, $v) = each %hash) {     # Do in-order traversal.
    print "$k => $v\n";
}
Tie an array to a plain text file:
tie(@lines, "DB_File", $textfile, O_RDWR|O_CREAT, 0666, $DB_RECNO)
    or die "Cannot open textfile $textfile: $!";

# Write a few lines to the file, overwriting any old contents.
$lines[0] = "first line";
$lines[1] = "second line";
$lines[2] = "third line";

push @lines, "penult", "last";  # Append two lines to the file.
$wc = scalar @lines;            # Count lines in file.
$last = pop @lines;             # Delete and retrieve last line.
The DB_File module provides tied access to Berkeley DB.[1] The default tie function gives you a standard DBM-style database with some features that no other DBM library provides: there are no size limits on either keys or values, and your data is stored in a byte-order independent format.

[1]Providing you have that library installed on your system. If not, you can build and install it easily enough.

The second tie mechanism uses B-trees to give you a true ISAM (indexed sequential access method) file, that is, a hash whose keys are automatically ordered--alphabetically by default, but configurable by the user.

The third tie mechanism binds an array to a file of records (text lines by default) so that changes to the array are automatically reflected on disk. This simulates random access by line number on a regular text file. The standard interface conforms to version 1.x of Berkeley DB; if you want to make use of the new features available in Berkeley DB 2.x or 3.x, use the CPAN module BerkeleyDB instead.

Starting with version 2.x, Berkeley DB has internal support for locking; earlier versions did not. See the section "File Locking" in Chapter 16, "Interprocess Communication" for a description of how you can safely lock any kind of database file using flock on a semaphore file.

Previous | Home | Next
32.10. Data::Dumper | Book Index | 32.12. Dumpvalue
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.12. Dumpvalue

use Dumpvalue;

Dumpvalue->new->dumpValue($store);
When used on the example from Class::Struct, this prints:
'Shoppe::addrs' => ARRAY(0x9c1d4)
   0  'Miskatonic University'
   1  'Innsmouth, Mass.'
'Shoppe::boss' => Manager=HASH(0xa5754)
   'Manager::name' => 'Prof L. P. Haitch'
   'Manager::salary' => 'madness'
   'Manager::started' => 'Sat Apr  1 16:18:13 2000'
'Shoppe::owner' => 'Abdul Alhazred'
'Shoppe::stock' => HASH(0xfdbb4)
   'books' => 208
   'charms' => 3
   'potions' => 'none'
This is another module to help display complex data. It's not so much meant for marshalling as it is for pretty printing. It's used by the Perl debugger's x command. As such, it offers a dizzying wealth of options to control the output format. It also provides convenient access to Perl's package symbol tables to dump out the contents of an entire package.

Previous | Home | Next
32.11. DB_File | Book Index | 32.13. English
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.13. English

use English;

# Use awk-style names.
$RS = '';                   # instead of $/
while (<>) {
    next if $NR < 10;       # instead of $.
    ...
}

# Same thing, but even more cobolaciously.
$INPUT_RECORD_SEPARATOR = '';
while (<>) {
    next if $INPUT_LINE_NUMBER < 10;
    ...
}
The English module provides cumbersome aliases for the built-in variables for prodigious typists with a visceral dislike for nonalphabetic identifiers (and a visceral like for the Caps Lock key). As with all imports, these aliases are only available in the current package. The variables are still available under their real names. For example, once you use this module, you can use $PID if $$ bothers you, or $PROGRAM_NAME if $0 makes you queasy. Some variables have more than one alias. See Chapter 28, "Special Names", for a complete description of all built-in variables, along with their English aliases.

Previous | Home | Next
32.12. Dumpvalue | Book Index | 32.14. Errno
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.14. Errno

use Errno;
unless (open(FH, $pathname)) {
    if ($!{ENOENT}) {  # We don't need an import for this!
        warn "$pathname does not exist\n";
    }
    else {
        warn "open failed on `$pathname': $!";
    }
}

use Errno qw(EINTR EIO :POSIX);
if ($! == ENOENT) { .... }
The Errno module makes available the symbolic names for the error status values set when a syscall fails, but does not export them by default. The module has a single export tag, ":POSIX", which exports only those symbols defined by the POSIX 1003.1 standard. The module also makes the global %! variable magical using tie. You can subscript into the %! hash using any valid errno on your system, not just the POSIX ones, and its value is true only if that's the current error.

Previous | Home | Next
32.13. English | Book Index | 32.15. Exporter
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.15. Exporter

Inside your MyModule.pm file:

package MyModule;

use strict;
use Exporter;

our $VERSION = 1.00;           # Or higher...
our @ISA = qw(Exporter);

our @EXPORT      = qw(f1 %h);  # Symbols imported by default.
our @EXPORT_OK   = qw(f2 f3);  # Symbols imported only by request.
our %EXPORT_TAGS = (           # Mappings for :shortcuts.
    a => [qw(f1 f2 f3)],
    b => [qw(f2 %h)],
);

# Your code here.

1;
From a program or another module that makes use of your module:
use MyModule;                  # Import everything in @EXPORT.
use MyModule ();               # Load module, no imports at all.
use MyModule "f1", "f2", "%h"; # Two subs and a variable.
use MyModule qw(:DEFAULT f3);  # All in @EXPORT + one sub.
use MyModule "f4";             # Fatal because f4 not exported.
Whenever anyone invokes a use declaration to load your module, it calls the import method from your module to fetch any symbols it needs into the package of the invoker. Your module (the one doing the exporting) can define the import method any way it pleases, but the standard way is to inherit the method from the Exporter class module. That is what the code above arranges.

The Exporter module serves as a base class for modules that wish to establish their own exports. Oddly, object-oriented modules typically don't use Exporter, since they don't normally export anything (method calls don't need to be exported). However, the Exporter module itself is accessed in an OO fashion because of the @ISA array you installed, as in our example. When another program or module uses your module, the import method is invoked as a class method in your module: MyModule->import(LIST). However, since you didn't define an import method in your module, you'll automatically make use of the Exporter::import method through inheritance.

The module's @EXPORT array contains a list of symbols (functions and even variables) that the calling code automatically imports with an unadorned use statement. The @EXPORT_OK array holds symbols that can be imported if specifically requested by name. The $VERSION number is consulted if the use statement requests that a particular version (or newer) of the module. Many, many other features are available. See Chapter 11, "Modules", as well as the online manpage for the Exporter module.

Previous | Home | Next
32.14. Errno | Book Index | 32.16. Fatal
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.16. Fatal

The Fatal module makes functions fail more spectacularly. It replaces functions that normally return false upon failure with wrappers that raise an exception if the real function returns false. That way you can safely use these functions without testing their return values explicitly on each call.

Both user-defined functions and built-in functions may be wrapped, except for those built-ins that cannot be expressed via prototypes. Attempting to override a nonoverridable built-in raises an exception. These include system, print, printf, exec, split, grep, and map--or more generally, any FUNC for which prototype "CORE::FUNC" returns false, including the prototype function itself.

If the symbol :void appears in the import list, functions named later in the list are limited to raising an exception when the function is called in void context--that is, when the return value is ignored. (Be careful about the last statement in a subroutine.) For example:

use Fatal qw(:void open close);

# open properly checked, so no exception is raised on failure.
if (open(FH, "< /nonesuch") { warn "no /nonesuch: $!"; }

# close not properly checked, so failure raises an exception.
close FH;

Previous | Home | Next
32.15. Exporter | Book Index | 32.17. Fcntl
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.17. Fcntl

use Fcntl;              # Import standard fcntl.h constants.
use Fcntl ":flock";     # Import LOCK_* constants.
use Fcntl ":seek";      # Import SEEK_CUR, SEEK_SET, SEEK_END.
use Fcntl ":mode";      # Import S_* stat checking constants.
use Fcntl ":Fcompat";   # Import F* constants.
The Fcntl module provides constants for use with various Perl built-in functions. The default set of imports includes constants like F_GETFL and F_SETFL for fcntl, SEEK_SET and SEEK_END for seek and sysseek, and O_CREAT and O_EXCL for sysopen. Supported import tags include ":flock" to access the LOCK_EX, LOCK_NB, LOCK_SH, and LOCK_UN constants for flock; ":mode" to get at constants from sys/stat.h like S_IRUSR and S_ISFIFO; ":seek" to get at the three arguments for seek and sysseek; and ":Fcompat" to get the old-style symbols with a leading "F" but not "F_", like FAPPEND, FASYNC, and FNONBLOCK. See the online documentation for the Fcntl module and your operating system's documentation on the relevant syscalls, like fcntl(2), lseek(2), open(2), and stat(2).

Previous | Home | Next
32.16. Fatal | Book Index | 32.18. File::Basename
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.18. File::Basename

use File::Basename;

$fullname = "/usr/local/src/perl-5.6.1.tar.gz";

$file = basename($fullname);
# file="perl-5.6.1.tar.gz"

$dir = dirname($fullname);
# dir="/usr/local/src"

($file,$dir,$ext) = fileparse($fullname, qr/\..*/);
# dir="/usr/local/src/" file="perl-5" ext=".6.1.tar.gz"

($file,$dir,$ext) = fileparse($fullname, qr/\.[^.]*/);
# dir="/usr/local/src/" file="perl-5.6.1.tar" ext=".gz"

($file,$dir,$ext) = fileparse($fullname, qr/\.\D.*/);
# dir="/usr/local/src/" file="perl-5.6.1" ext=".tar.gz"

($file,$dir,$bak) = fileparse("/tmp/file.bak",
                        qr/~+$/, qr/\.(bak|orig|save)/)
# dir="/tmp/" file="file" ext=".bak"

($file,$dir,$bak) = fileparse("/tmp/file~",
                        qr/~+$/, qr/\.(bak|orig|save)/)
# dir="/tmp/" file="file" ext="~"
The File::Basename module provides functions to parse pathnames into their individual components. The dirname function pulls out the directory portion and basename the nondirectory portion. The more elaborate fileparse function picks out the full pathname into the directory name, the filename, and the suffix; you must supply a list of regular expressions describing the suffixes that interest you. The examples above illustrate how choice of suffix patterns affects the result. By default, these functions parse pathnames according to the native conventions of your current platform. The fileparse_set_fstype function selects a different platform's parsing rules, such as fileparse_set_fstype("VMS") to parse names using VMS rules, even when running on non-VMS systems.

Previous | Home | Next
32.17. Fcntl | Book Index | 32.19. File::Compare
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.19. File::Compare

use File::Compare;

printf "fileA and fileB are %s.\n",
    compare("fileA","fileB") ? "different" : "identical";

use File::Compare 'cmp';
sub munge($) {
    my $line = $_[0];
    for ($line) {
        s/^\s+//;   # Trim leading whitespace.
        s/\s+$//;   # Trim trailing whitespace.
    }
    return uc($line);
}

if (not cmp("fileA", "fileB", sub {munge $_[0] eq munge $_[1]} ) {
    print "fileA and fileB are kinda the same.\n";
}
The File::Compare module provides one function, compare, which compares the contents of the two files passed to it. It returns 0 if the files contain the same data, 1 if they contain different data, and -1 if an error was encountered in accessing the named files. If you pass a subroutine reference as the third argument, that function is repeatedly called to determine whether any two lines are equivalent. For compatibility with the cmp(1) program, you may explicitly import the function as cmp. (This does not affect the binary cmp operator.)

Previous | Home | Next
32.18. File::Basename | Book Index | 32.20. File::Copy
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.20. File::Copy

use File::Copy;

copy("/tmp/fileA", "/tmp/fileA.orig") or die "copy failed: $!";
copy("/etc/motd", *STDOUT)            or die "copy failed: $!";
move("/tmp/fileA", "/tmp/fileB")      or die "move failed: $!";

use File::Copy qw/cp mv/;             # Get normal Unix names.
cp "/tmp/fileA", "/tmp/fileA.orig"    or die "copy failed: $!";
mv "/tmp/fileA", "/tmp/fileB"         or die "move failed: $!";
The File::Copy module exports two functions, copy and move, that respectively copy or rename their first argument to their second argument, similar to calling the Unix cp(1) and mv(1) commands (names you may use if you import them explicitly). The copy function also accepts filehandles as arguments. These functions return true when they work and false when they fail, setting $! ($OS_ERROR) as appropriate. (Unfortunately, you can't tell whether something like "Permission denied" applies to the first file or to the second one.) These functions are something of a compromise between convenience and precision. They do not support the numerous options and optimizations found in cp(1) and mv(1), such as recursive copying, automatic backups, retention of original timestamps and ownership information, and interactive confirmation. If you need any of those features, it's probably best to call your platform's versions of those commands.[2] Just realize that not all systems support the same commands or use the same options for them.
system("cp -R -pi /tmp/dir1 /tmp/dir2") == 0
    or die "external cp command status was $?";

[2]Or get the PPT versions if your platform is tool-challenged.

Previous | Home | Next
32.19. File::Compare | Book Index | 32.21. File::Find
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.21. File::Find

use File::Find;

# Print out all directories below current one.
find sub { print "$File::Find::name\n" if -d }, ".";

# Compute total space used by all files in listed directories.
@dirs = @ARGV ? @ARGV : ('.');
my $sum = 0;
find sub { $sum += -s }, @dirs;
print "@dirs contained $sum bytes\n";

# Alter default behavior to go through symlinks
# and visit subdirectories first.
find { wanted => \&myfunc, follow => 1, bydepth => 1 }, ".";
The File::Find module's find function recursively descends directories. Its first argument should be a reference to a function, and all following arguments should be directories. The function is called on each filename from the listed directories. Within that function, the $_ variable is set to the basename of the current filename visited, and the process's current working directory is by default set to that directory. The package variable $File::Find::name is the full pathname of the visited filename. An alternative calling convention takes as its first argument a reference to a hash containing option specifications, including "wanted", "bydepth", "follow", "follow_fast", "follow_skip", "no_chdir", "untaint", "untaint_pattern", and "untaint_skip", as fully explained in the online documentation. This module is also used by the standard find2perl(1) translator program that comes with Perl.

Previous | Home | Next
32.20. File::Copy | Book Index | 32.22. File::Glob
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.22. File::Glob

use File::Glob ':glob';      # Override glob built-in.
@list = <*.[Cchy]>;          # Now uses POSIX glob, not csh glob.

use File::Glob qw(:glob csh_glob);
@sources = bsd_glob("*.{C,c,h,y,pm,xs}", GLOB_CSH);
@sources = csh_glob("*.{C,c,h,y,pm,xs}");  # (same thing)

use File::Glob ':glob';
# call glob with extra arguments
$homedir = bsd_glob('~jrhacker', GLOB_TILDE | GLOB_ERR);
if (GLOB_ERROR) {
    # An error occurred expanding the home directory.
}
The File::Glob module's bsd_glob function implements the glob(3) routine from the C library. An optional second argument contains flags governing additional matching properties. The :glob import tag imports both the function and the necessary flags.

The module also implements a csh_glob function. This is what the built-in Perl glob and GLOBPAT fileglobbing operators really call. Calling csh_glob is (mostly) like calling bsd_glob this way:

bsd_glob(@_ ? $_[0] : $_,
    GLOB_BRACE | GLOB_NOMAGIC | GLOB_QUOTE | GLOB_TILDE);
If you import the :glob tag, then all calls to the built-in fileglobbing operators in the current package will really call the module's bsd_glob function instead of its csh_glob function. One reason you might want to do this is that, although bsd_glob handles patterns with whitespace in them correctly, csh_glob handles them, um, in the historical fashion. Old scripts would write <*.c *.h> to glob both of those. Neither function is bothered by whitespace in the actual filenames, however.

The bsd_glob function takes an argument containing the fileglobbing pattern (not a regular expression pattern) plus an optional flags argument. Filenames with a leading dot are not matched unless specifically requested. The return value is influenced by the flags in the second argument, which should be bitwise ORed together:[3]

[3]Due to restrictions in the syntax of the built-in glob operator, you may need to call the function as bsd_glob if you want to pass it the second argument.

GLOB_BRACE

Preprocess the string to expand {pat,pat,...} strings as csh(1) would. The pattern {} is left unexpanded for historical reasons, mostly to ease typing of find(1) patterns.

GLOB_CSH

Synonym for GLOB_BRACE | GLOB_NOMAGIC | GLOB_QUOTE | GLOB_TILDE.

GLOB_ERR

Return an error when bsd_glob encounters a directory it cannot open or read. Ordinarily, bsd_glob skips over the error, looking for more matches.

GLOB_MARK

Return values that are directories with a slash appended.

GLOB_NOCASE

By default, filenames are case sensitive; this flag makes bsd_glob treat case differences as insignificant. (But see below for exceptions on MS-DOSish systems).

GLOB_NOCHECK

If the pattern does not match any pathname, then makes bsd_glob return a list consisting of only the pattern, as /bin/sh does. If GLOB_QUOTE is set, its effect is present in the pattern returned.

GLOB_NOMAGIC

Same as GLOB_NOCHECK but it only returns the pattern if it does not contain any of the special characters *, ? or [. NOMAGIC is provided to simplify implementing the historic csh(1) globbing behavior and should probably not be used anywhere else.

GLOB_NOSORT

By default, the pathnames are sorted in ascending order (using normal character comparisons irrespective of locale setting). This flag prevents that sorting for a small increase in speed.

GLOB_QUOTE

Use the backslash character \ for quoting: every occurrence of a backslash followed by a character in the pattern is replaced by that character, avoiding any special interpretation of the character. (But see below for exceptions on MS-DOSish systems).

GLOB_TILDE

Allow patterns whose first path component is ~USER. If USER is omitted, the tilde by itself (or followed by a slash) represents the current user's home directory.

The bsd_glob function returns a (possibly empty) list of matching paths, which will be tainted if that matters to your program. On error, GLOB_ERROR will be true and $! ($OS_ERROR) will be set to the standard system error. GLOB_ERROR is guaranteed to be false if no error occurred, and to be either GLOB_ABEND or GLOB_NOSPACE otherwise. (GLOB_ABEND means that the bsd_glob was stopped due to some error, GLOB_NOSPACE because it ran out of memory.) If bsd_glob had already found some matching paths when the error occurred, it returns the list of filenames found so far, and also sets GLOB_ERROR. Note that this implementation of bsd_glob varies from most others by not considering ENOENT and ENOTDIR as terminating error conditions. Instead, it continues processing despite those errors, unless the GLOB_ERR flag is set.

If no flag argument is supplied, your system's defaults are followed, meaning that filenames differing only in case are indistinguishable from one another on VMS, OS/2, old Mac OS (but not Mac OS X), and Microsoft systems (but not when Perl was built with Cygwin). If you supply any flags at all and still want this behavior, then you must include GLOB_NOCASE in the flags. Whatever system you're on, you can change your defaults up front by importing the :case or :nocase flags.

On MS-DOSish systems, the backslash is a valid directory separator character.[4] In this case, use of backslash as a quoting character (via GLOB_QUOTE) interferes with the use of backslash as a directory separator. The best (simplest, most portable) solution is to use slashes for directory separators, backslashes for quoting. However, this does not match some users' expectations, so backslashes (under GLOB_QUOTE) quote only the glob metacharacters [, ], {, }, -, ~, and \ itself. All other backslashes are passed through unchanged, if you can manage to get them by Perl's own backslash quoting in strings. It may take as many as four backslashes to finally match one in the filesystem. This is so completely insane that even MS-DOSish users should strongly consider using slashes. If you really want to use backslashes, look into the standard File::DosGlob module, as it might be more to your liking than Unix-flavored fileglobbing.

[4] Although technically, so is a slash--at least as far as those kernels and syscalls are concerned; command shells are remarkably less enlightened.

Previous | Home | Next
32.21. File::Find | Book Index | 32.23. File::Spec
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.23. File::Spec

use File::Spec;     # OO style

$path = File::Spec->catfile("subdir", "filename");
    # 'subdir/filename' on Unix, OS2, or Mac OS X
    # 'subdir:filename' on (old) Apple Macs
    # 'subdir\filename' on Microsoft

$path = File::Spec->catfile("", "dir1", "dir2", "filename");
    # '/dir1/dir2/filename' on Unix, OS2, or Mac OS X
    # ':dir1:dir2:filename' on (old) Apple Macs
    # '\dir1\dir2\filename' on Microsoft

use File::Spec::Unix;
$path = File::Spec::Unix->catfile("subdir", "filename");
    # 'subdir/filename' (even when executed on non-Unix systems)

use File::Spec::Mac;
$path = File::Spec::Mac->catfile("subdir", "filename");
    # 'subdir:filename'

use File::Spec::Win32;
$path = File::Spec::Win32->catfile("subdir", "filename";)
    # 'subdir\filename'

# Use functional interface instead.
use File::Spec::Functions;
$path = catfile("subdir", "filename");
The File::Spec family of modules lets you construct paths using directories and filenames without hardcoding platform-specific directory separators. Supported systems include Unix, VMS, Mac, and Win32. These modules all offer a catfile class method that catenates together each path component using the specified platform's path separator. The File::Spec module returns different results depending on your current platform. The others return results specific to that platform. The File::Spec::Functions module provides a functional interface.

Previous | Home | Next
32.22. File::Glob | Book Index | 32.24. File::stat
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.24. File::stat

use File::stat;
$st = stat($file)      or die "Can't stat $file: $!";
if ($st->mode & 0111 and $st->nlink > 1)) {
    print "$file is executable with many links\n";
}

use File::stat ":FIELDS";
stat($file)            or die "Can't stat $file: $!";
if ($st_mode & 0111 and $st_nlink > 1) ) {
    print "$file is executable with many links\n";
}

@statinfo = CORE::stat($file);    # Access overridden built-in.
The File::stat module provides a method interface to Perl's built-in stat and lstat functions by replacing them with versions that return a File::stat object (or undef on failure). This object has methods that return the like-named structure field name from the traditional stat(2) syscall; namely, dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize, and blocks. You may also import the structure fields into your own namespace as regular variables using the ":FIELDS" import tag. (This still overrides your stat and lstat built-ins.) These fields show up as scalar variables named with a "st_" in front of the field name. That is, the $st_dev variable corresponds to the $st->dev method.

Previous | Home | Next
32.23. File::Spec | Book Index | 32.25. File::Temp
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.25. File::Temp

use File::Temp qw(tempfile tempdir);

$dir = tempdir(CLEANUP => 1);
($fh, $filename) = tempfile(DIR => $dir);
($fh, $filename) = tempfile($template, DIR => $dir);
($fh, $filename) = tempfile($template, SUFFIX => ".data");
$fh = tempfile();

use File::Temp ':mktemp';

($fh, $filename) = mkstemp("tmpfileXXXXX");
($fh, $filename) = mkstemps("tmpfileXXXXXX", $suffix);
$tmpdir = mkdtemp($template);
$unopened_file = mktemp($template);
New to version 5.6.1 of Perl, the File::Temp module provides convenient functions for creating and opening temporary files securely. It's better to use this module than to try to pick a temporary file on your own. Otherwise, you'll just fall into all the same traps as everyone else before you. This module guards you against various subtle race conditions, as well as the dangers of using directories that others can write to; see Chapter 23, "Security". The tempfile function returns both a filehandle and filename. It's safest to use the filehandle that's already open and ignore the filename entirely (except perhaps for error messages). Once the file is closed, it is automatically deleted. For compatibility with the C library, the :mktemp import tag provides access to functions with names familiar to C programmers, but please remember that filenames are always less secure than filehandles.

Previous | Home | Next
32.24. File::stat | Book Index | 32.26. FileHandle
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.26. FileHandle

use FileHandle;

$fh = new FileHandle;
if ($fh->open("< file")) {
    print $line while defined($line = $fh->getline);
    $fh->close;
}

$pos = $fh->getpos;     # like tell()
$fh->setpos($pos);      # like seek()

($readfh, $writefh) = FileHandle::pipe();

autoflush STDOUT 1;
The FileHandle module mostly serves as a mechanism for cloaking Perl's punctuation variables in longer, more OO-looking calls. It is provided for compatibility with older releases, but is now really only a frontend for several more specific modules, like IO::Handle and IO::File.[5] Its best property is the low-level access it provides to certain rare functions from the C library (clearerr(3), fgetpos(3), fsetpos(3), and setvbuf(3)).

[5]Because it loads so much code, this module costs you a megabyte or so of memory.

Variable | Method
$| | autoflush
$, | output_field_separator
$\ | output_record_separator
$/ | input_record_separator
$. | input_line_number
$% | format_page_number
$= | format_lines_per_page
$- | format_lines_left
$~ | format_name
$^ | format_top_name
$: | format_line_break_characters
$^L | format_formfeed

Instead of saying:

$ofh = select(HANDLE);
$~ = 'SomeFormat';
$| = 1;
select($ofh);
you can just say:
use FileHandle;
HANDLE->format_name('SomeFormat');
HANDLE->autoflush(1);
Currently, three methods (output_field_separator, output_record_separator, and input_record_separator) only pretend to be per-handle methods: setting them on one handle actually affects all filehandles. They are therefore only supported as class methods, not as per-filehandle methods. This restriction may be lifted someday.

To get a lexically scoped filehandle, instead of using filehandle autovivification:

open my $fh, "< somefile"
    or die "can't open somefile: $!";
one could say:
use FileHandle;
my $fh = FileHandle->new("< somefile")
    or die "can't open somefile: $!";
FileHandle inherits from IO::File, which inherits from IO::Handle and IO::Seekable. Virtually all the module's functionality is available more efficiently through basic, unadorned Perl calls, except for the following, not all of which may be implemented on all non-Unix platforms:

HANDLE->blocking(EXPR)

Called with an argument, enables nonblocking I/O if the argument is false, and disables nonblocking (that is, enables blocking) if the argument is true. The method returns the previously set value (which is still the current setting if no argument was given). On error, blocking sets $! and returns undef. This could be done using fcntl directly, but the FileHandle interface is much easier to use.

HANDLE->clearerr

Calls the C library function clearerr(3) to clear the handle's internal end-of-file and error status indicators.

HANDLE->error

Calls the C library function ferror(3) to test the error indicator for the given handle, returning whether that internal indicator is set. The error indicator can be reset reliably only via the clearerr method. (Some systems also reset it on calls to the seek operator.)

HANDLE->formline(PICTURE, LIST)

This is the same as saving the old accumulator variable ($^A), calling the formline function with the given PICTURE and LIST, outputting the resulting contents of the accumulator to the given handle, and finally restoring the original accumulator. For example, here's how to output a long text variable, with automatic word-wrapping at column 72:

use FileHandle;
STDOUT->formline("^" . ("<" x 72) . "~~\n", $long_text);

HANDLE->getpos

Calls the C library function fgetpos(3), providing an alternative interface to tell. On some (non-UNIX) systems the return value may be a complex object, and getpos and setpos may be the only way to portably reposition a text stream.

FileHandle->new_tmpfile

Calls the C library function tmpfile(3) to create a new temporary file opened for read-write mode and returns a handle to this stream. On systems where this is possible, the temporary file is anonymous--that is, it is unlinked after creation, but held open. You should use this function, or POSIX::tmpnam as described under the POSIX module, to safely create a temporary file without exposing yourself to subtle but serious security problems through race conditions. As of the 5.6.1 release of Perl, the File::Temp module is now the preferred interface.

HANDLE->setbuf(BUFFER)

Calls the C library function setbuf(3) with the given BUFFER variable. It passes undef to indicate unbuffered output. A variable used as a buffer by setbuf or setvbuf must not be modified in any way until the handle is closed, or until setbuf or setvbuf is called again. Otherwise, memory corruption may result, and you will be sad.

HANDLE->setpos(EXPR)

Calls the C library function fsetpos(3), providing an alternative interface to seek. The argument should only be the return value from getpos, described earlier.

HANDLE->setvbuf(BUFFER, TYPE, SIZE)

Calls the C library function setvbuf(3) with the given BUFFER. The standard C library constants _IONBF (unbuffered), _IOLBF (line buffered), and _IOFBF (fully buffered) are available for the TYPE field if explicitly imported. See the warning under setbuf.

HANDLE->sync

Calls the C library function fsync(3) to synchronize a file's in-memory state with the physical medium. Note that sync operates not on the handle, but on the file descriptor, so any data held by buffers will not be synchronized unless flushed first.

HANDLE->untaint

Marks the filehandle or directory handle as providing untainted data. When running under taint mode (see Chapter 23, "Security"), data read in from external files is considered untrustworthy. Do not invoke this method blindly: you're circumventing Perl's best attempts to protect you from yourself.

Previous | Home | Next
32.25. File::Temp | Book Index | 32.27. Getopt::Long
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.27. Getopt::Long

If your program says:

use Getopt::Long;
GetOptions("verbose"  => \$verbose,
           "debug"    => \$debug,
           "output=s" => \$output);
it can be called from the command line like this:
% prog --verbose more args here
% prog --debug more args here
% prog -v -d more args here
% prog --output=somefile more args here
% prog -o somefile more args here
The Getopt::Long module provides a GetOptions function to process command-line switches with long names. It includes support for things like abbreviating switches, typed arguments like Boolean or string or integer or float, array variables for repeating options, user-defined validation routines, POSIX-conforming versus FSF-style processing, case-insensitive options, and traditional bundling of short options--just to name a few out of its vast cornucopia of features. If this module is overkill, consider the more traditional Getopt::Std module described next. If this module is underkill, check out the CPAN module Getopt::Declare, which provides a more declarative syntax for option specification.

Previous | Home | Next
32.26. FileHandle | Book Index | 32.28. Getopt::Std
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.28. Getopt::Std

use Getopt::Std;
You can use getopt and getopts with globals:
our ($opt_o, $opt_i, $opt_f);
getopt('oif');            # -o, -i, and -f all take arguments.
                          # Sets global $opt_* variables.
getopts('oif:');          # Now -o & -i are boolean; -f takes an arg.
                          # Still sets global $opt_* as side effect.
Or you can use them with a private options hash:
my %opts;                 # We'll place results here.
getopt('oif', \%opts);    # All three still take arguments.
getopts('oif:', \%opts);  # Now -o and -i are boolean flags
                          # and only -f takes an argument.
The Getopt::Std module provides two functions, getopt and getopts, to help you parse command-line arguments for single-character options. Of the two, getopts is the more useful because it lets you specify that some options take arguments and others don't, whereas getopt assumes all options take arguments. By specifying to getopts a letter with a colon after it, you indicate that that argument takes an argument; otherwise, a Boolean flag is expected. Standard option clustering is supported. Ordering doesn't matter, so options taking no arguments may be grouped together. Options that do take an argument must be the last in a group or by themselves, and their argument may either come immediately after the option in the same string, or else as the next program argument. Given the example getopts use above, these are equivalent calls:
% prog -o -i -f TMPFILE more args here
% prog -o -if TMPFILE more args here
% prog -io -fTMPFILE more args here
% prog -iofTMPFILE more args here
% prog -oifTMPFILE more args here

Previous | Home | Next
32.27. Getopt::Long | Book Index | 32.29. IO::Socket
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.29. IO::Socket

use IO::Socket;

As a client:

$socket = new IO::Socket::INET (PeerAddr => $remote_host,
                                PeerPort => $remote_port,
                                Proto    => "tcp",
                                Type     => SOCK_STREAM)
    or die "Can't connect to $remote_host:$remote_port : $!\n";

# Or use the simpler single-argument interface.
$socket = IO::Socket::INET->new("$remote_host:$remote_port");
                              # "localhost:80", for example.

print $socket "data\n";
$line = <$socket>;
As a server:
$server = IO::Socket::INET->new(LocalPort => $server_port,
                                Type      => SOCK_STREAM,
                                Reuse     => 1,
                                Listen    => 10 )  # or SOMAXCONN
    or die "Can't be a TCP server on port $server_port : $!\n";

while ($client = $server->accept()) {
    # $client is the new connection
    $request = <$client>;
    print $client "answer\n";
    close $client;
}

# Make simple TCP connecting function that returns a filehandle
# for use in simple client programs.
sub tcp_connect {
    my ($host, $service) = @_;
    require IO::Socket;
    return  IO::Socket::INET->new(join ":", $host, $service);
}
my $fh    = tcp_connect("localhost", "smtp");  # with scalar
local *FH = tcp_connect("localhost", "smtp");  # with handle
The IO::Socket module provides a higher-level approach to socket handling than the raw Socket module. You may use it in an object-oriented fashion, although this isn't mandatory, because the return values are proper filehandles and may be used as such, as shown in the tcp_connect function in the example. This module inherits methods from IO::Handle, and itself requires IO::Socket::INET and IO::Socket::UNIX. See the description of the FileHandle module for other interesting features. See Chapter 16, "Interprocess Communication" for a description of using sockets.

Previous | Home | Next
32.28. Getopt::Std | Book Index | 32.30. IPC::Open2
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.30. IPC::Open2

use IPC::Open2;

local(*HIS_OUT, *HIS_IN);  # Create local handles if needed.

$childpid = open2(*HIS_OUT, *HIS_IN, $program, @args)
    or die "can't open pipe to $program: $!";
print HIS_IN "here's your input\n";
$his_output = <HIS_IN>;
close(HIS_OUT);
close(README);
waitpid($childpid, 0);
The IPC::Open2 module's one exported function, open2, starts up another program and provides both read and write access to that command. The first two arguments should be valid filehandles (or else empty variables into which autogenerated filehandles can be placed). The remaining arguments are the program plus its arguments, which if passed in separately will not be subject to shell interpolation. This module does not reap the child process after it exits. Except for short programs where it's acceptable to let the operating system take care of this, you need to do this yourself. This is normally as simple as calling waitpid $pid, 0 when you're done with that child process. Failure to do this can result in an accumulation of defunct ("zombie") processes.

In practice, this module doesn't work well with many programs because of the way buffering works in C's standard I/O library. If you control the source code to both programs, however, you can easily circumvent this restriction by flushing your output buffers more frequently than the default. If you don't, programs can be annoyingly miserly in their hoarding of output. Another potential pitfall is deadlock: if both processes are reading at the same time, and no one is writing, then your program will hang. See Chapter 16, "Interprocess Communication" for more discussion.

Previous | Home | Next
32.29. IO::Socket | Book Index | 32.31. IPC::Open3
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.31. IPC::Open3

use IPC::Open3;

local(*HIS_IN, *HIS_OUT, *HIS_ERR);

$childpid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd, @args);
print HIS_IN "stuff\n";
close(HIS_IN);            # Give end of file to kid.
@outlines = <HIS_OUT>;    # Read till EOF.
@errlines = <HIS_ERR>;    # XXX: block potential if massive
print "STDOUT:\n", @outlines, "\n";
print "STDERR:\n", @errlines, "\n";
close HIS_OUT;
close HIS_ERR;
waitpid($childpid, 0);
if ($?) {
    print "That child exited with wait status of $?\n";
}
The IPC::Open3 module works like IPC::Open2 (the latter is implemented in terms of the former), except that open3 provides access to the standard input, the standard output, and the standard error handles of the program you launch. The same caveats apply as with open2 (see the previous entry), plus a few more. The order of arguments is different in open3 than with open2. Instead of passing the handle to read from first and the handle to write to second, this time it's the other way around. Also, with open3, danger of deadlock is even greater than before. If you try to read through end-of-file on one of the child's two output handles, but meanwhile there's a great deal of output on the other handle, the peer process blocks and appears to hang. Use either the four-argument form of select or the standard IO::Select module to circumvent this. See Chapter 16, "Interprocess Communication" for more details.

Previous | Home | Next
32.30. IPC::Open2 | Book Index | 32.32. Math::BigInt
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.32. Math::BigInt

use Math::BigInt;
$i = Math::BigInt->new($string);

use Math::BigInt ':constant';
print 2**200;
This prints:
+1606938044258990275541962092341162602522202993782792835301376
The Math::BigInt module provides objects that represent integers with arbitrary precision and overloaded arithmetical operators. Create these objects using the new constructor, or, within a lexical scope, by importing the special value ":constant", after which all numeric literals through the end of that lexical scope are treated as Math::BigInt objects. All standard integer operators are implemented, including (as of the 5.6 release of Perl) the bitwise logical operators. Under the current implementation, this module is not what you'd call blazingly fast, but this may be addressed in the future. (We'd like to see you how fast you are at calculating 2**200 in your head.)

Previous | Home | Next
32.31. IPC::Open3 | Book Index | 32.33. Math::Complex
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.33. Math::Complex

use Math::Complex;

$z = Math::Complex->make(5, 6);
$z = cplx(5, 6);         # same thing, but shorter
$t = 4 - 3*i + $z;       # do standard complex math
print "$t\n";            # prints 9+3i

print sqrt(-9), "\n";    # prints 3i
The Math::Complex module provides complex number objects with overloaded operators. These are numbers with both real and imaginary portions, like those satisfying even-numbered integral roots of negative numbers as shown above. Besides arithmetical operators, many built-in math functions are also overridden by versions that understand complex numbers, including abs, log, sqrt, sin, cos, and atan2. Other functions provided are Re and Im to provide the real and imaginary portions of their complex arguments, plus a full battery of extended trigonometric functions, such as tan, asin, acos, sinh, cosh, and tanh. The module also exports the constant i, which, as you might imagine, holds the value of i; that is, the square root of -1.

Previous | Home | Next
32.32. Math::BigInt | Book Index | 32.34. Math::Trig
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.34. Math::Trig

use Math::Trig;

$x = tan(0.9);
$y = acos(3.7);
$z = asin(2.4);

$halfpi = pi/2;

$rad = deg2rad(120);
Perl itself defines only three trigonometric functions: sin, cos, and atan2. The Math::Trig module overrides these with fancier versions and supplies all the rest of the trig functions, including tan, csc, cosec, sec, cot, cotan, asin, acos, atan, sinh, cosh, tanh, and many others. Additionally, the constant pi is defined, as are conversion functions like deg2rad and grad2rad. Support is provided for Cartesian, spherical, and cylindrical coordinates systems. This module makes implicit use of Math::Complex as needed (and vice versa) for computations requiring imaginary numbers.

Previous | Home | Next
32.33. Math::Complex | Book Index | 32.35. Net::hostent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.35. Net::hostent

use Socket;
use Net::hostent;

print inet_ntoa(gethost("www.perl.com")->addr);  # prints 208.201.239.50
printf "%vd", gethost("www.perl.com")->addr;     # same thing

print gethost("127.0.0.1")->name;                # prints localhost

use Net::hostent ':FIELDS';
if (gethost($name_or_number)) {
    print "name is $h_name\n";
    print "aliases are $h_aliases\n";
    print "addrs are ",
        join ", " => map { inet_ntoa($_) } @h_addr_list;
}
This module's default exports override the core gethostbyname and gethostbyaddr functions, replacing them with versions that return a Net::hostent object (or undef on failure). This object has attribute accessor methods that return the like-named structure field name from the C library's struct hostent from netdb.h: name, aliases, addrtype, length, or addr_list. The aliases and addr_list methods return array references; the rest return scalars. The addr method is equivalent to the initial element in the addr_list array reference. The gethost function is a frontend that forwards a numeric argument to gethostbyaddr by way of the Socket::inet_aton function and the rest to gethostbyname. As with the other semipragmatic modules that override list-returning built-ins, if you import the ":FIELDS" tag, you can access scalar or array package variables by the same names as the method calls by using a leading "h_". This still overrides your core functions, though.

Previous | Home | Next
32.34. Math::Trig | Book Index | 32.36. POSIX
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.36. POSIX

use POSIX;

# Round floats up or down to nearest integer.
$n = ceil($n);      # round up
$n = floor($n);     # round down

# Produces "2000-04-01" for today.
$datestr = strftime("%Y-%m-%d", localtime);

# Produces "Saturday 04/01/00" for same date.
$datestr = strftime("%A %D", localtime);

# Try new temporary filenames until we get one
# that didn't already exist; see also File::Temp
# on CPAN, or in v5.6.1.
do {
    $name = tmpnam();
} until sysopen(FH, $name, O_CREAT|O_EXCL|O_RDWR, 0666);

# Check for whether system has insecure chown giveaway.
if (sysconf(_PC_CHOWN_RESTRICTED)) {
    print "Hurray -- only the superuser may call chown\n";
}

# Find current system's uname info.
my($kernel, $hostname, $release, $version, $hardware) = uname();

use POSIX ":sys_wait_h";
while (($dead_pid = waitpid(-1, &WNOHANG)) > 0) {
    # Do something with $dead_pid if you want.
}

# Become new session/process-group leader (needed to create daemons
# unaffected by keyboard signals or exiting login shells).
setsid(0)           or die "setsid failed: $!";
Perl's POSIX module permits you to access all (or nearly all) the standard POSIX 1003.1 identifiers, plus a few more from ANSI C that we didn't know where else to put. This module provides more functions than any other. See its online documentation for the gory details or the POSIX Programmer's Guide, by Donald Lewine (O'Reilly, 1991).

Identifiers that are parameterless #defines in C, such as EINTR or O_NDELAY, are automatically exported into your namespace as constant functions. Functions that aren't normally available in Perl (like floor, ceil, strftime, uname, setsid, setlocale, and sysconf) are exported by default. Functions with the same name as a Perl built-in, like open, are not exported unless specifically requested, but most folks are likely to prefer fully qualified function names to distinguish POSIX::open from CORE::open.

A few functions are not implemented because they are C-specific. If you attempt to call these, they print a message telling you that they aren't implemented, and suggest using the Perl equivalent should one exist. For example, trying to access the setjmp function elicits the message "setjmp() is C-specific: use eval {} instead", and tmpfile tells you to "Use method IO::File::new_tmpfile()". (But as of 5.6.1 you should be using File::Temp instead.)

The POSIX module lets you get as close to the operating system (or those parts of the POSIX standard addresses, at least) as any C programmer could. This lets you do some phenomenally powerful and useful things, like blocking signals and controlling the terminal I/O settings. However, it also means that your code will end up looking quasi-C-like. By way of useful demonstration of how to get around input buffering, here's an example of a complete program for getting unbuffered, single-character input under any POSIX system:

#!/usr/bin/perl -w
use strict;
$| = 1;
for (1..4) {
    my $got;
    print "gimme: ";
    $got = getone();
    print "--> $got\n";
}
exit;

BEGIN {
    use POSIX qw(:termios_h);
    my ($term, $oterm, $echo, $noecho, $fd_stdin);
    $fd_stdin = fileno(STDIN);
    $term     = POSIX::Termios->new();
    $term->getattr($fd_stdin);
    $oterm    = $term->getlflag();
    $echo     = ECHO | ECHOK | ICANON;
    $noecho   = $oterm & ~$echo;
    sub cbreak {
        $term->setlflag($noecho);
        $term->setcc(VTIME, 1);
        $term->setattr($fd_stdin, TCSANOW);
    }

    sub cooked {
        $term->setlflag($oterm);
        $term->setcc(VTIME, 0);
        $term->setattr($fd_stdin, TCSANOW);
    }
    sub getone {
        my $key = "";
        cbreak();
        sysread(STDIN, $key, 1);
        cooked();
        return $key;
    }
}
END { cooked() }
The POSIX module's manpage provides a complete listing of which functions and constants it exports. It has so many that you'll often wind up importing only a subset of them, such as ":sys_wait_h", ":sys_stat_h", or ":termios_h". An example of blocking signals with the POSIX module is given in Chapter 16, "Interprocess Communication".

Previous | Home | Next
32.35. Net::hostent | Book Index | 32.37. Safe
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.37. Safe

use Safe;

$sandbox = Safe->new();             # anonymous sandbox
$sandbox = Safe->new("PackName");   # in that symbol table

# Enable or disable opcodes by group or name.
$sandbox->permit(qw(:base_core));
$sandbox->permit_only(qw(:base_core :base_loop :base_mem));
$sandbox->deny("die");

# like do(), but in the sandbox
$ok = $sandbox->rdo($filename);

# like do(), but in the sandbox
$ok = $sandbox->reval($code);       # without 'use strict'
$ok = $sandbox->reval($code, 1);    # with 'use strict'
The Safe module attempts to provide a restricted environment to protect the rest of the program from dangerous operations. It uses two different strategies to do this. Much as an anonymous FTP daemon's use of chroot(2) alters the view of the root of the filesystem, creating a compartment object with Safe->new("PackName") alters that compartment's view of its own namespace. The compartment now sees as its root symbol table (main::) the symbol table that the rest of the program sees as PackName::. What looks like Frobnitz:: on the inside of the compartment is really PackName::Frobnitz:: on the outside. If you don't give an argument to the constructor, a random new package name is selected for you.

The second and more important facility that a Safe compartment provides is a way to limit code that is deemed legal within an eval. You can tweak the allowable opcode set (legal Perl operations) using method calls on your Safe object. Two methods are available to compile code in a Safe compartment: rdo ("restricted do") for files and reval ("restricted eval") for strings. These are like do on a filename and eval on a string but execute in a restricted namespace with limited opcodes. The first argument is the filename or string to compile, and the optional second argument is whether the code should be compiled under use strict.

This module is scheduled for a rewrite (we intend to isolate the sandbox into a different interpreter thread for additional safety), so be sure to check the Safe manpage for updates. See also Chapter 23, "Security".

Previous | Home | Next
32.36. POSIX | Book Index | 32.38. Socket
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.38. Socket

use Socket;

$proto = getprotobyname('udp');
socket(SOCK, PF_INET, SOCK_DGRAM, $proto)
    or die "socket: $!";
$iaddr = gethostbyname('hishost.com');
$port  = getservbyname('time', 'udp');
$sin   = sockaddr_in($port, $iaddr);
send(SOCK, 0, 0, $sin)
    or die "send: $!";

$proto = getprotobyname('tcp');
socket(SOCK, PF_INET, SOCK_STREAM, $proto)
    or die "socket: $!";
$port = getservbyname('smtp', 'tcp');
$sin  = sockaddr_in($port,inet_aton("127.1"));
$sin  = sockaddr_in(7,inet_aton("localhost"));
$sin  = sockaddr_in(7,INADDR_LOOPBACK);
connect(SOCK,$sin)
    or die "connect: $!";

($port, $iaddr) = sockaddr_in(getpeername(SOCK));
$peer_host = gethostbyaddr($iaddr, AF_INET);
$peer_addr = inet_ntoa($iaddr);

$proto = getprotobyname('tcp');
socket(SOCK, PF_UNIX, SOCK_STREAM, $proto)
    or die "connect: $!";
unlink('/tmp/usock');   # XXX: intentionally ignore failure
$sun = sockaddr_un('/tmp/usock');
connect(SOCK,$sun)     or die "connect: $!";

use Socket qw(:DEFAULT :crlf);
# Now you can use CR(), LF(), and CRLF() or
# $CR, $LF, and $CRLF for line-endings.
The Socket module provides access to constants from the C library's sys/socket.h#include file to use with Perl's low-level socket functions. It also provides two functions, inet_aton and inet_ntoa, to convert between ASCII (like "127.0.0.1") and packed network representations of IP addresses, and two special packer/unpacker functions, sockaddr_in and sockaddr_un, which manipulate the binary socket addresses needed by those low-level calls. The :crlf import tag gives symbolic names for the various end-of-line conventions so you don't have to rely upon native interpretations of \r and \n, which vary. Most Internet protocols prefer CRLF but tolerate LF. The standard IO::Socket module provides a higher-level interface to TCP. See Chapter 16, "Interprocess Communication".

Previous | Home | Next
32.37. Safe | Book Index | 32.39. Symbol
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.39. Symbol

use Symbol "delete_package";
delete_package("Foo::Bar");
print "deleted\n" unless exists $Foo::{"Bar::"};

use Symbol "gensym";
$sym1 = getsym();       # Returns new, anonymous typeglob.
$sym2 = getsym();       # Yet another new, anonymous typeglob.

package Demo;
use Symbol "qualify";
$sym = qualify("x");              # "Demo::x"
$sym = qualify("x", "Foo");       # "Foo::x"
$sym = qualify("Bar::x");         # "Bar::x"
$sym = qualify("Bar::x", "Foo");  # "Bar::x"

use Symbol "qualify_to_ref";
sub pass_handle(*) {
    my $fh = qualify_to_ref(shift, caller);
    ...
}
# Now you can call pass_handle with FH, "FH", *FH, or \*FH.
The Symbol module provides functions to help manipulate global names: typeglobs, format names, filehandles, package symbol tables, and anything else you might want to name via a symbol table. The delete_package function completely clears out a package's namespace (effectively anonymizing any extra references to the symbol table's referents, including references from precompiled code). The gensym function returns an anonymous typeglob each time it is called. (This function isn't used so much these days, now that undefined scalars autovivify into proper filehandles when used as arguments to open, pipe, socket, and the like).

The qualify function takes a name that may or may not be completely package-qualified, and returns a name that is. If it needs to prepend the package name, it will use the name specified via the second argument (or if omitted, your current package name). The qualify_to_ref function works similarly, but produces a reference to the typeglob the symbol would represent. This is important in functions that accept filehandles, directory handles, or format names as arguments but don't require these to be passed by reference. For example, functions prototyped with a typeglob accept any of these forms, but don't automatically convert barewords to symbol table references. By converting that argument with qualify_to_ref, you can now use the supplied handle even with strict refs in effect. You may also bless it into objectdom, since it's a proper reference.

Previous | Home | Next
32.38. Socket | Book Index | 32.40. Sys::Hostname
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.40. Sys::Hostname

use Sys::Hostname;
$hostname = hostname();
The Sys::Hostname module supplies just one function, hostname, which makes up for that fact by busting its behind to try to figure out what your current host calls itself. On those systems that support the standard gethostname(2) syscall, this is used, as it's the most efficient method.[6] On other systems, output from the standard hostname(1) is used. On still others, it calls the uname(3) function in your C library, which is also accessible as POSIX::uname from Perl. If these strategies all fail, more valiant attempts are made. Whatever your native system thinks makes sense, Perl tries its best to go along with it. On some systems, this hostname may not be fully qualified with the domain name; see the Net::Domain module from CPAN if you need that.

[6] Which is available directly as the unexported Sys::Hostname::ghname function, but don't tell anyone we told you.

Another consideration is that hostname returns just one value, but your system could have multiple network interfaces configured, so you might not get back the name associated with the interface you're interested in if you're planning on using this module for certain sorts of socket programming. There are cases where you'll probably have to scrounge around in the output from the ifconfig(8) command, or your system's moral equivalent.

Previous | Home | Next
32.39. Symbol | Book Index | 32.41. Sys::Syslog
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.41. Sys::Syslog

use Sys::Syslog;                          # Misses setlogsock.
use Sys::Syslog qw(:DEFAULT setlogsock);  # Also gets setlogsock.

openlog($program, 'cons,pid', 'user');
syslog('info', 'this is another test');
syslog('mail|warning', 'this is a better test: %d', time());
closelog();

syslog('debug', 'this is the last test');

setlogsock('unix');
openlog("$program $$", 'ndelay', 'user');
syslog('info', 'problem was %m'); # %m == $! in syslogese
syslog('notice', 'fooprogram: this is really done');

setlogsock("unix");             # "inet" or "unix"
openlog("myprogname", $logopt, $facility);
syslog($priority, $format, @args);
$oldmask = setlogmask($mask_priority);
closelog();
The Sys::Syslog module acts like your C library's syslog(3) function, sending messages to your system log daemon, syslogd(8). It is especially useful in daemons and other programs lacking a terminal to receive diagnostic output, or for security-minded programs that want to produce a more lasting record of their actions (or someone else's actions). Supported functions are:

openlog IDENT, OPTLIST, FACILITY

Establishes a connection with your friendly syslog daemon. IDENT is the string to log messages under (like $0, your program name). OPTLIST is a string with comma-separated options such as "cons", "pid", and "ndelay". FACILITY is something like "auth", "daemon", "kern", "lpr", "mail", "news" or "user" for system programs, and one of "local0" .. "local7" for local ones. Further messages are logged using the given facility and identifying string.

syslog PRIORITY, FORMAT, ARGS

Sends a message to the daemon using the given PRIORITY. The FORMAT is just like printf--filling in percent escapes using the following ARGS--except that following the conventions of the standard syslog(3) library function, the special escape "%m" interpolates errno (Perl's $! variable) at that point.

setlogsock TYPE

TYPE must be either "inet" or "unix". Some systems' daemons do not by default pay attention to incoming Internet-domain syslog messages, so you might set this to "unix" instead, since it's not the default.

closelog

Severs the connection with the daemon.

For this module to work prior to the 5.6.0 release of Perl, your sysadmin had to run h2ph(1) on your sys/syslog.h include file to create a sys/syslog.ph library file. However, this wasn't done by default at Perl installation time. Later releases now use an XS interface, so the sys/syslog.ph preparation is no longer needed.

Previous | Home | Next
32.40. Sys::Hostname | Book Index | 32.42. Term::Cap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.42. Term::Cap

use Term::Cap;

$ospeed = eval {
    require POSIX;
    my $termios = POSIX::Termios->new();
    $termios->getattr;
    $termios->getospeed;
} || 9600;

$terminal = Term::Cap->Tgetent({ TERM => undef, OSPEED => $ospeed });
$terminal->Tputs('cl', 1, STDOUT);          # Clear screen.
$terminal->Tgoto('cm', $col, $row, STDOUT); # Position cursor.
The Term::Cap module provides access to your system's termcap(3) library routines. See your system documentation for details. Systems that have only terminfo(5) and not termcap(5) will lose. (Many terminfo systems can emulate termcap.) However, on CPAN you can find a Term::Info module, as well as Term::ReadKey, Term::ANSIColor, and various Curses modules to help you with single-key input, colored output, or managing terminal screens, at a higher level than Term::Cap or Term::Info.

Previous | Home | Next
32.41. Sys::Syslog | Book Index | 32.43. Text::Wrap
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.43. Text::Wrap

use Text::Wrap;  # Imports wrap().

@lines = (<<"EO_G&S" =~ /\S.*\S/g);

    This particularly rapid,
    unintelligible
    patter isn't generally
    heard,
    and if
    it is, it
    doesn't matter.

EO_G&S

$Text::Wrap::columns = 50;
print wrap(" " x 8, " " x 3, @lines), "\n";
This prints:
           This particularly rapid, unintelligible
      patter isn't generally heard, and if it is, it
      doesn't matter.
The Text::Wrap module implements a simple paragraph formatter. Its wrap function formats a single paragraph at a time by breaking lines at word boundaries. The first argument is the prefix prepended to the first line returned. The second argument is the prefix string used for all lines save the first. All remaining arguments are joined together using a newline as the separator and returned as one reformatted paragraph string. You'll have to figure out your terminal's width yourself, or at least specify what you want in $Text::Wrap::columns. Although one could use the TIOCGWINSZioctl call to figure out the number of columns, it would be easier for those not used to C programming to install the CPAN module Term::ReadKey and use that module's GetTerminalSize routine.

Previous | Home | Next
32.42. Term::Cap | Book Index | 32.44. Time::Local
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.44. Time::Local

use Time::Local;
$time = timelocal($sec,$min,$hours,$mday,$mon,$year);
$time = timegm($sec,$min,$hours,$mday,$mon,$year);

$time = timelocal(50, 45, 3, 18, 0, 73);
print "Scalar localtime gives: ", scalar(localtime($time)), "\n";
$time += 28 * 365.2425 * 24 * 60 * 60;
print "Twenty-eight years of seconds later, it's now\n\t",
    scalar(localtime($time)), "\n";
This prints:
Scalar localtime gives: Thu Jan 18 03:45:50 1973
Twenty-eight years of seconds later, it's now
        Wed Jan 17 22:43:26 2001
The Time::Local module provides two functions, timelocal and timegm, that work like inverse functions for the standard localtime and gmtime functions, respectively. That is, they take a list of numeric values for the various components of what localtime returns in list context and figure out what input to localtime would produce those values. You might do this if you wanted to compare or run calculations on two different dates. Although these are not general-purpose functions for parsing dates and times, if you can arrange to have your input in the right format, they often suffice. As you can see from the example above, however, time has its oddities, and even simple calculations often fail to do the job intended due to leap years, leap seconds, and the phase of the moon. Two large but fully featured CPAN modules address these issues and more: Date::Calc and Date::Manip.

Previous | Home | Next
32.43. Text::Wrap | Book Index | 32.45. Time::localtime
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.45. Time::localtime

use Time::localtime;
printf "Year is %d\n", localtime->year() + 1900;

$now = ctime();

use Time::localtime;
use File::stat;
$date_string = ctime(stat($file)->mtime);
This module's overrides the core localtime function, replacing it with a version that returns a Time::tm object (or undef on failure). The Time::gmtime module does the same thing, except it replaces the core gmtime function, instead. The returned object has methods that access the like-named structure field names from the C library's struct tm out of time.h; namely sec, min, hour, mday, mon, year, wday, yday, and isdst. The ctime function provides a way of getting at (the scalar sense of) the original CORE::localtime function. Note that the values returned are straight out of a struct tm, so they have the same ranges found there; see the example above for the correct way to produce a four-digit year. The POSIX::strftime function is even more useful for formatting dates and times in a variety of appealing styles.

Previous | Home | Next
32.44. Time::Local | Book Index | 32.46. User::grent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.46. User::grent

use User::grent;
$gr = getgrgid(0)          or die "No group zero";
if ($gr->name eq "wheel" && @{$gr->members} > 1) {
    print "gid zero name wheel, with other members";
}

$gr = getgr($whoever);  # Accepts both string or number.

use User::grent ':FIELDS';
getgrgid(0)                or die "No group zero";
if ($gr_name eq "wheel" && @gr_members > 1) {
    print "gid zero name wheel, with other members";
}
This module's default exports override the core getgrent, getgruid, and getgrnam functions, replacing them with versions that return a User::grent object (or undef on failure). This object has methods that access the like-named structure fields from the C library's struct group out of grp.h; namely name, passwd, gid, and members (not mem as in C!). The first three return scalars, the last an array reference. You may also import the structure fields into your own namespace as regular variables using the ":FIELDS" import tag, although this still overrides your core functions. The variables (three scalars and an array) are named with a preceding "gr_". The getgr function is a simple frontend switch that forwards any numeric argument to getgrgid and any string argument to getgrnam.

Previous | Home | Next
32.45. Time::localtime | Book Index | 32.47. User::pwent
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


32.47. User::pwent

use User::pwent;                 # Default overrides built-ins only.
$pw = getpwnam("daemon")   or die "No daemon user";
if ($pw->uid == 1 && $pw->dir =~ m#^/(bin|tmp)?$# ) {
    print "gid 1 on root dir";
}

$pw = getpw($whoever);           # Accepts both string or number.
$real_shell = $pw->shell || '/bin/sh';
for (($fullname, $office, $workphone, $homephone) =
       split /\s*,\s*/, $pw->gecos)
{
   s/&/ucfirst(lc($pw->name))/ge;
}

use User::pwent qw(:FIELDS);     # Sets globals in current package.
getpwnam("daemon")         or die "No daemon user";
if ($pw_uid == 1 && $pw_dir =~ m#^/(bin|tmp)?$# ) {
    print "gid 1 on root dir";
}

use User::pwent qw/pw_has/;
if (pw_has(qw[gecos expire quota])) { .... }
if (pw_has("name uid gid passwd"))  { .... }
printf "Your struct pwd supports [%s]\n", scalar pw_has();

By default, this module's exports override the core getpwent, getpwuid, and getpwnam functions, replacing them with versions that return a User::pwent object (or undef on failure). It is often better to use the module than the core functions it replaces, because the built-ins overload or even omit various slots in the return list in the name of backward compatibility.

The returned object has methods that access the similarly named structure field name from the C's passwd structure from pwd.h, stripped of their leading "pw_" parts, namely name, passwd, uid, gid, change, age, quota, comment, class, gecos, dir, shell, and expire. The passwd, gecos, and shell fields are tainted. You may also import the structure fields into your own namespace as regular variables using the ":FIELDS" import tag, although this still overrides your core functions. Access these fields as scalar variables named with a "pw_" prepended to the method name. The getpw function is a simple frontend switch that forwards a numeric argument to getpwuid and a string argument to getpwnam.

Perl believes that no machine ever has more than one of change, age, or quota implemented, nor more than one of either comment or class. Some machines do not support expire, gecos, or allegedly, even passwd. You may call these methods no matter what machine you're on, but they'll return undef if unimplemented. See passwd(5) and getpwent(3) for details.

You can determine whether these fields are implemented by asking the importable pw_has function about them. It returns true if all parameters are supported fields on the build platform or false if one or more were not, and it raises an exception if you ask about a field whose name it doesn't recognize. If you pass no arguments, it returns the list of fields your C library thinks are supported.

Interpretation of the gecos field varies between systems but often holds four comma-separated fields containing the user's full name, office location, work phone number, and home phone number. An & in the gecos field should be replaced by the user's properly capitalized login name. The shell field, if blank, must be assumed to be /bin/sh, although Perl does not do this for you. The passwd is one-way hashed gobbledygook, not clear text, and may not be unhashed save by brute-force guessing. Secure systems often use a more secure hashing than DES. On systems supporting shadow password systems, Perl automatically returns the shadow password entry when called by a suitably empowered user, even if your underlying vendor-provided C library was too short-sighted to realize it should do this.

Previous | Home | Next
32.46. User::grent | Book Index | 33. Diagnostic Messages
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Chapter 33. Diagnostic Messages

These messages are classified as follows (listed in increasing order of desperation):

Class | Meaning
(W) | A warning (optional)
(D) | A deprecation (optional)
(S) | A severe warning (mandatory)
(F) | A fatal error (trappable)
(P) | An internal error (panic) that you should never see (trappable)
(X) | A very fatal error (nontrappable)
(A) | An alien error message (not generated by Perl)

The majority of messages from the first three classifications above (W, D, and S) can be controlled using the warnings pragma or the -w and -W switches. If a message can be controlled by the warnings pragma, its warning category is given after the classification letter; for example, (W misc) indicates a miscellaneous warning. The warnings pragma is described in Chapter 31, "Pragmatic Modules".

Warnings may be captured rather than printed by setting $SIG{__WARN__} to a reference to a routine that will be called on each warning. You can also capture control before a trappable error "dies" by setting $SIG{__DIE__} to a subroutine reference, but if you don't call die within the handler, the exception is still thrown when you return from it. In other words, you're not allowed to "de-fatalize" an exception that way. You must use eval for that.

Default warnings are always enabled unless they are explicitly disabled with the warnings pragma or the -X switch.

In the following messages, %s stands for an interpolated string that is determined only when the message is generated. (Similarly, %d stands for an interpolated number--think printf formats, but we use %d to mean a number in any base here.) Note that some messages begin with %s--which means that listing them alphabetically is problematical. You should search among these messages if the one you are looking for does not appear in the expected place. The symbols "%-?@ sort before alphabetic characters, while [ and \ sort after.

If you decide a bug is a Perl bug and not your bug, you should try to reduce it to a minimal test case and then report it with the perlbug program that comes with Perl.

"%s" variable %s masks earlier declaration in same %s

(W misc) A my or our variable has been redeclared in the current scope or statement, effectively eliminating all access to the previous instance. This is almost always a typographical error. Note that the earlier variable will still exist until the end of the scope or until all closure referents to it are destroyed.

"my sub" not yet implemented

(F) Lexically scoped subroutines are not yet implemented. Don't try that yet.

"my" variable %s can't be in a package

(F) Lexically scoped variables aren't in a package, so it doesn't make sense to try to declare one with a package qualifier in front. Use local if you want to localize a package variable.

"no" not allowed in expression

(F) The no keyword is recognized and executed at compile time and returns no useful value.

"our" variable %s redeclared

(W misc) You seem to have already declared the same global once before in the current lexical scope.

"use" not allowed in expression

(F) The use keyword is recognized and executed at compile time and returns no useful value.

'!' allowed only after types %s

(F) The '!' is allowed in pack and unpack only after certain types.

'|' and '<' may not both be specified on command line

(F) This is an error peculiar to VMS. Perl does its own command-line redirection. It found that STDIN was a pipe and that you also tried to redirect STDIN using <. Only one STDIN stream to a customer, please.

'|' and '>' may not both be specified on command line

(F) This is an error peculiar to VMS. Perl does its own command-line redirection and thinks you tried to redirect STDOUT both to a file and into a pipe to another command. You need to choose one or the other, though nothing's stopping you from piping into a program or Perl script that splits the output into two streams, such as:

open(OUT,">$ARGV[0]") or die "Can't write to $ARGV[0]: $!";
while (<STDIN>) {
    print;
    print OUT;
}
close OUT;

/ cannot take a count

(F) You had an unpack template indicating a counted-length string, but you have also specified an explicit size for the string.

/ must be followed by a, A, or Z

(F) You had an unpack template indicating a counted-length string, which must be followed by one of the letters a, A or Z to indicate what sort of string is to be unpacked.

/ must be followed by a*, A*, or Z*

(F) You had a pack template indicating a counted-length string. Currently, the only things that can have their length counted are a*, A* or Z*.

/ must follow a numeric type

(F) You had an unpack template that contained a #, but this did not follow some numeric unpack specification.

% may only be used in unpack

(F) You can't pack a string by supplying a checksum, because the checksumming process loses information, and you can't go the other way.

Repeat count in pack overflows

(F) You can't specify a repeat count so large that it overflows your signed integers.

Repeat count in unpack overflows

(F) You can't specify a repeat count so large that it overflows your signed integers.

/%s/: Unrecognized escape \\%c passed through

(W regexp) You used a backslash-character combination that is not recognized by Perl. This combination appears in an interpolated variable or a '-delimited regular expression. The character was understood literally.

/%s/: Unrecognized escape \\%c in character class passed through

(W regexp) You used a backslash-character combination that is not recognized by Perl inside character classes. The character was understood literally.

/%s/ should probably be written as "%s"

(W syntax) You have used a pattern where Perl expected to find a string, as in the first argument to join. Perl will treat the true or false result of matching the pattern against $_ as the string, which is probably not what you had in mind.

%s (...) interpreted as function

(W syntax) You've run afoul of the rule that says that any list operator followed by parentheses turns into a function, with all the list operators arguments found inside the parentheses.

%s() called too early to check prototype

(W prototype) You've called a function that has a prototype before the parser saw a definition or declaration for it, and Perl could not check that the call conforms to the prototype. You need to either add an early prototype declaration for the subroutine in question, or move the subroutine definition ahead of the call to get proper prototype checking. Alternatively, if you are certain that you're calling the function correctly, you may put an ampersand before the name to avoid the warning.

%s argument is not a HASH or ARRAY element

(F) The argument to exists must be a hash or array element, such as:

$foo{$bar}
$ref->{"susie"}[12]

%s argument is not a HASH or ARRAY element or slice

(F) The argument to delete must be either a hash or array element, such as:

$foo{$bar}
$ref->{"susie"}[12]
or a hash or array slice, such as:
@foo[$bar, $baz, $xyzzy]
@{$ref->[12]}{"susie", "queue"}

%s argument is not a subroutine name

(F) The argument to exists for exists &sub must be a subroutine name, and not a subroutine call. exists &sub() will generate this error.

%s did not return a true value

(F) A required (or used) file must return a true value to indicate that it compiled correctly and ran its initialization code correctly. It's traditional to end such a file with a 1;, though any true value would do.

%s found where operator expected

(S) The Perl lexer knows whether to expect a term or an operator. If it sees what it knows to be a term when it was expecting to see an operator, it gives you this warning. Usually it indicates that an operator or delimiter was omitted, such as a semicolon.

%s had compilation errors

(F) The final summary message when a perl -c fails.

%s has too many errors

(F) The parser has given up trying to parse the program after 10 errors. Further error messages would likely be uninformative.

%s matches null string many times

(W regexp) The pattern you've specified would be an infinite loop if the regular expression engine didn't specifically check for that.

%s never introduced

(S internal) The symbol in question was declared but somehow went out of scope before it could possibly have been used.

%s package attribute may clash with future reserved word: %s

(W reserved) A lowercase attribute name was used that had a package-specific handler. That name might have a meaning to Perl itself some day, even though it doesn't yet. Perhaps you should use a mixed-case attribute name, instead.

%s syntax OK

(F) The final summary message when a perl -c succeeds.

%s: Command not found

(A) You've accidentally run your script through csh instead of Perl. Check the #! line, or manually feed your script into Perl yourself with perl scriptname.

%s: Expression syntax

(A) You've accidentally run your script through csh instead of Perl. Check the #! line, or manually feed your script into Perl yourself with perl scriptname.

%s: Undefined variable

(A) You've accidentally run your script through csh instead of Perl. Check the #! line, or manually feed your script into Perl yourself with perl scriptname.

%s: not found

(A) You've accidentally run your script through the Bourne shell instead of Perl. Check the #! line, or manually feed your script Perl yourself with perl scriptname.

(in cleanup) %s

(W misc) This prefix usually indicates that a DESTROY method raised the indicated exception. Since destructors are usually called by the system at arbitrary points during execution, and often a vast number of times, the warning is issued only once for any number of failures that would otherwise result in the same message being repeated.

Failure of user callbacks dispatched using the G_KEEPERR flag could also result in this warning. See perlcall(1).

(Missing semicolon on previous line?)

(S) This is an educated guess made in conjunction with the message "%s found where operator expected." Don't automatically put a semicolon on the previous line just because you saw this message.

-P not allowed for setuid/setgid script

(F) The script would have to be opened by the C preprocessor by name, which provides a race condition that breaks security.

-T and -B not implemented on filehandles

(F) Perl can't peek at the standard I/O buffer of filehandles when it doesn't know about your kind of standard I/O. You'll have to use a filename instead.

-p destination: %s

(F) An error occurred during the implicit output invoked by the -p command-line switch. (This output goes to STDOUT unless you've redirected it with select.)

500 Server error

See Server error.

?+* follows nothing in regexp

(F) You started a regular expression with a quantifier. Backslash it if you meant it literally.

@ outside of string

(F) You had a pack template that specified an absolute position outside the string being unpacked.

<> should be quotes

(F) You wrote require <file> when you should have written require 'file'.

\1 better written as $1

(W syntax) Outside of patterns, backreferences live on as variables. The use of backslashes is grandfathered on the righthand side of a substitution, but stylistically it's better to use the variable form because other Perl programmers will expect it, and it works better if there are more than nine backreferences.

accept() on closed socket %s

(W closed) You tried to do an accept on a closed socket. Did you forget to check the return value of your socket call?

Allocation too large: %lx

(X) You can't allocate more than 64K on an MS-DOS machine.

Applying %s to %s will act on scalar(%s)

(W misc) The pattern match (//), substitution (s///), and transliteration (tr///) operators work on scalar values. If you apply one of them to an array or a hash, it will convert the array or hash to a scalar value--the length of an array or the population info of a hash--and then work on that scalar value. This is probably not what you meant to do.

Arg too short for msgsnd

(F) msgsnd requires a string at least as long as sizeof(long).

Ambiguous use of %s resolved as %s

(W ambiguous|S) You said something that may not be interpreted the way you thought. Normally it's pretty easy to disambiguate it by supplying a missing quote, operator, pair of parentheses, or declaration.

Ambiguous call resolved as CORE::%s(), qualify as such or use &

(W ambiguous) A subroutine you have declared has the same name as a Perl keyword, and you have used the name without qualification for calling one or the other. Perl decided to call the built-in because the subroutine is not imported.

To force interpretation as a subroutine call, either put an ampersand before the subroutine name or qualify the name with its package. Alternatively, you can import the subroutine (or pretend that it's imported with the use subs pragma).

To silently interpret it as the Perl operator, use the CORE:: prefix on the operator (e.g., CORE::log($x)) or declare the subroutine to be an object method.

Args must match #! line

(F) The setuid emulator requires that the arguments Perl was invoked with match the arguments specified on the #! line. Since some systems impose a one-argument limit on the #! line, try combining switches; for example, turn -w -U into -wU.

Argument "%s" isn't numeric

(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.

Array @%s missing the @ in argument %d of %s()

(D deprecated) Really old Perls let you omit the @ on array names in some spots. This is now heavily deprecated.

assertion botched: %s

(P) The malloc package that comes with Perl had an internal failure.

Assertion failed: file "%s"

(P) A general assertion failed. The file in question must be examined.

Assignment to both a list and a scalar

(F) If you assign to a conditional operator, the second and third arguments must either both be scalars or both be lists. Otherwise, Perl won't know which context to supply to the right side.

Attempt to free non-arena SV: 0x%lx

(P internal) All SV objects are supposed to be allocated from arenas that will be garbage collected on exit. An SV was discovered to be outside any of those arenas.

Attempt to free nonexistent shared string

(P internal) Perl maintains a reference-counted internal table of strings to optimize the storage and access of hash keys and other strings. This message indicates that someone tried to decrement the reference count of a string that can no longer be found in the table.

Attempt to free temp prematurely

(W debugging) Mortalized values are supposed to be freed by the internal free_tmps routine. This message indicates that something else is freeing the SV before the free_tmps routine gets a chance, which means that the free_tmps routine will be freeing an unreferenced scalar when it does try to free it.

Attempt to free unreferenced glob pointers

(P internal) The reference counts got screwed up on symbol aliases.

Attempt to free unreferenced scalar

(W internal) Perl went to decrement the reference count of a scalar to see if it would go to 0, and discovered that it had already gone to 0 earlier and should have been freed and, in fact, probably was freed. This could indicate that SvREFCNT_dec was called too many times, or that SvREFCNT_inc was called too few times, or that the SV was mortalized when it shouldn't have been, or that memory has been corrupted.

Attempt to join self

(F) You tried to join a thread from within itself, which is an impossible task. You may be joining the wrong thread, or you may need to move the join to some other thread.

Attempt to pack pointer to temporary value

(W pack) You tried to pass a temporary value (like the result of a function, or a computed expression) to the p template of pack template. This means the result contains a pointer to a location that could become invalid anytime, even before the end of the current statement. Use literals or global values as arguments to the p template of pack to avoid this warning.

Attempt to use reference as lvalue in substr

(W substr) You supplied a reference as the first argument to substr used as an lvalue, which is pretty strange. Perhaps you forgot to dereference it first.

Bad arg length for %s, is %d, should be %d

(F) You passed a buffer of the wrong size to one of msgctl, semctl or shmctl. In C parlance, the correct sizes are, respectively, sizeof(struct msqid_ds *), sizeof(struct semid_ds *), and sizeof(struct shmid_ds *).

Bad filehandle: %s

(F) A symbol was passed to something wanting a filehandle, but the symbol has no filehandle associated with it. Perhaps you didn't do an open, or did it in another package.

Bad free() ignored

(S malloc) An internal routine called free on something that had never been malloced in the first place. Mandatory, but can be disabled by setting environment variable PERL_BADFREE to 1.

This message can be seen quite often with DB_File on systems with "hard" dynamic linking, like AIX and OS/2. It's a bug in Berkeley DB.

Bad hash

(P) One of the internal hash routines was passed a null HV pointer.

Bad index while coercing array into hash

(F) The index looked up in the hash found as the 0th element of a pseudohash is not legal. Index values must be 1 or greater.

Bad name after %s::

(F) You started to name a symbol by using a package prefix and then didn't finish the symbol. In particular, you can't interpolate outside of quotes, so:

$var = 'myvar';
$sym = mypack::$var;
is not the same as:
$var = 'myvar';
$sym = "mypack::$var";

Bad realloc() ignored

(S malloc) An internal routine called realloc on something that had never been malloced in the first place. Mandatory, but can be disabled by setting environment variable PERL_BADFREE to 1.

Bad symbol for array

(P) An internal request asked to add an array entry to something that wasn't a symbol table entry.

Bad symbol for filehandle

(P) An internal request asked to add a filehandle entry to something that wasn't a symbol table entry.

Bad symbol for hash

(P) An internal request asked to add a hash entry to something that wasn't a symbol table entry.

Badly placed ()'s

(A) You've accidentally run your script through csh instead of Perl. Check the #! line, or manually feed your script into Perl yourself with perl scriptname.

Bareword "%s" not allowed while "strict subs" in use

(F) With strict subs in use, a bareword is only allowed as a subroutine identifier, in curly brackets or to the left of the => symbol. Perhaps you need to predeclare a subroutine?

Bareword "%s" refers to nonexistent package

(W bareword) You used a qualified bareword of the form Foo::, but the compiler saw no other uses of that namespace before that point. Perhaps you need to predeclare a package?

Bareword found in conditional

(W bareword) The compiler found a bareword where it expected a conditional, which often indicates that an || or && was parsed as part of the last argument of the previous construct, for example:

open FOO || die;
It may also indicate a misspelled constant that has been interpreted as a bareword:
use constant TYPO => 1;
if (TYOP) { print "foo" }
The strict pragma is useful in avoiding such errors.

BEGIN failed--compilation aborted

(F) An untrapped exception was raised while executing a BEGIN subroutine. Compilation stops immediately and the interpreter is exited.

BEGIN not safe after errors--compilation aborted

(F) Perl found a BEGIN subroutine (or a use directive, which implies a BEGIN) after one or more compilation errors had already occurred. Since the intended environment for the BEGIN could not be guaranteed (due to the errors), and since subsequent code likely depends on its correct operation, Perl just gave up.

Binary number > 0b11111111111111111111111111111111 non-portable

(W portable) The binary number you specified is larger than 2**32-1 (4,294,967,295) and therefore nonportable between systems.

bind() on closed socket %s

(W closed) You tried to do a bind on a closed socket. Did you forget to check the return value of your socket call?

Bit vector size > 32 non-portable

(W portable) Using bit vector sizes larger than 32 is nonportable.

Bizarre copy of %s in %s

(P) Perl detected an attempt to copy an internal value that is not copiable.

Buffer overflow in prime_env_iter: %s

(W internal) A warning peculiar to VMS. While Perl was preparing to iterate over %ENV, it encountered a logical name or symbol definition which was too long, so it was truncated to the string shown.

Callback called exit

(F) A subroutine invoked from an external package via call_sv exited by calling exit.

Can't "goto" out of a pseudo block

(F) A goto statement was executed to jump out of what might look like a block, except that it isn't a proper block. This usually occurs if you tried to jump out of a sort block or subroutine, which is a no-no.

Can't "goto" into the middle of a foreach loop

(F) A goto statement was executed to jump into the middle of a foreach loop. You can't get there from here.

Can't "last" outside a loop block

(F) A last statement was executed to break out of the current block, except that there's this itty-bitty problem called there isn't a current block. Note that an if or else block doesn't count as a "loopish" block, nor does a block given to sort, map, or grep. You can usually double the curlies to get the same effect, though, because the inner curlies will be considered a block that loops once.

Can't "next" outside a loop block

(F) A next statement was executed to reiterate the current block, but there isn't a current block. Note that an if or else block doesn't count as a "loopish" block, nor does a block given to sort, map, or grep. You can usually double the curlies to get the same effect though, because the inner curlies will be considered a block that loops once.

Can't read CRTL environ

(S) This is a warning peculiar to VMS. Perl tried to read an element of %ENV from the CRTL's internal environment array and discovered the array was missing. You need to figure out where your CRTL misplaced its environ or define PERL_ENV_TABLES (see perlvms(1)) so that the environ array is not searched.

Can't "redo" outside a loop block

(F) A redo statement was executed to restart the current block, but there isn't a current block. Note that an if or else block doesn't count as a "loopish" block, nor does a block given to sort, map, or grep. You can usually double the curlies to get the same effect though, because the inner curlies will be considered a block that loops once.

Can't bless non-reference value

(F) Only hard references may be blessed. This is how Perl "enforces" encapsulation of objects.

Can't break at that line

(S internal) This warning is intended to be printed only while running within the debugger, indicating the line number specified wasn't the location of a statement that could be stopped at.

Can't call method "%s" in empty package "%s"

(F) You called a method correctly, and it correctly indicated a package functioning as a class, but that package doesn't have anything defined in it, let alone methods.

Can't call method "%s" on unblessed reference

(F) A method call must know in what package it's supposed to run. It ordinarily finds this out from the object reference you supply, but you didn't supply an object reference in this case. A reference isn't an object reference until it has been blessed.

Can't call method "%s" without a package or object reference

(F) You used the syntax of a method call, but the slot filled by the object reference or package name contains an expression that returns a defined value that is neither an object reference nor a package name. Something like this will reproduce the error:

$BADREF = 42;
process $BADREF 1,2,3;
$BADREF->process(1,2,3);

Can't call method "%s" on an undefined value

(F) You used the syntax of a method call, but the slot filled by the object reference or package name contains an undefined value. Something like this will reproduce the error:

$BADREF = undef;
process $BADREF 1,2,3;
$BADREF->process(1,2,3);

Can't chdir to %s

(F) You called perl -x/foo/bar, but /foo/bar is not a directory that you can chdir to, possibly because it doesn't exist.

Can't check filesystem of script "%s" for nosuid

(P) For some reason you can't check the filesystem of the script for nosuid.

Can't coerce %s to integer in %s

(F) Certain types of SVs, in particular symbol table entries (typeglobs), can't be forced to stop being what they are. So you can't say things like:

*foo += 1;
You can say:
$foo = *foo;
$foo += 1;
but then $foo no longer contains a glob.

Can't coerce %s to number in %s

(F) Certain types of SVs, in particular symbol table entries (typeglobs), can't be forced to stop being what they are.

Can't coerce %s to string in %s

(F) Certain types of SVs, in particular symbol table entries (typeglobs), can't be forced to stop being what they are.

Can't coerce array into hash

(F) You used an array where a hash was expected, but the array has no information on how to map from keys to array indices. You can do that only with arrays that have a hash reference at index 0.

Can't create pipe mailbox

(P) This is an error peculiar to VMS. The process is suffering from exhausted quotas or other plumbing problems.

Can't declare class for non-scalar %s in "%s"

(S) Currently, only scalar variables can declared with a specific class qualifier in a my or our declaration. The semantics may be extended for other types of variables in future.

Can't declare %s in "%s"

(F) Only scalar, array, and hash variables may be declared as my or our variables. They must have ordinary identifiers as names.

Can't do inplace edit on %s: %s

(S inplace) The creation of the new file failed for the indicated reason.

Can't do inplace edit without backup

(F) You're on a system such as MS-DOS that gets confused if you try reading from a deleted (but still opened) file. You have to say -i.bak, or some such.

Can't do inplace edit: %s would not be unique

(S inplace) Your filesystem does not support filenames longer than 14 characters and Perl was unable to create a unique filename during inplace editing with the -i switch. The file was ignored.

Can't do inplace edit: %s is not a regular file

(S inplace) You tried to use the -i switch on a special file, such as a file in /dev, or a FIFO. The file was ignored.

Can't do setegid!

(P) The setegid call failed for some reason in the setuid emulator of suidperl.

Can't do seteuid!

(P) The setuid emulator of suidperl failed for some reason.

Can't do setuid

(F) This typically means that ordinary perl tried to exec suidperl to do setuid emulation, but couldn't exec it. It looks for a name of the form sperl5.000 in the same directory that the perl executable resides under the name perl5.000, typically /usr/local/bin on Unix machines. If the file is there, check the execute permissions. If it isn't, ask your sysadmin why not.

Can't do waitpid with flags

(F) This machine doesn't have either waitpid or wait4, so only waitpid without flags is emulated.

Can't do {n,m} with n > m

(F) Minima must be less than or equal to maxima. If you really want your regexp to match something 0 times, just use {0}.

Can't emulate -%s on #! line

(F) The #! line specifies a switch that doesn't make sense at this point. For example, it would be kind of silly to put a -x on the #! line.

Can't exec "%s": %s

(W exec) A system, exec, or piped open call could not execute the named program for the indicated reason. Typical reasons include the permissions were wrong on the file, the file wasn't found in $ENV{PATH}, the executable in question was compiled for another architecture, or the #! line in a script points to an interpreter that can't be run for similar reasons. (Or maybe your system doesn't support #! at all.)

Can't exec %s

(F) Perl was trying to execute the indicated program for you because that's what the #! line said to do. If that's not what you wanted, you may need to mention perl on the #! line somewhere.

Can't execute %s

(F) You used the -S switch, but the copies of the script to execute found in the PATH did not have correct permissions.

Can't find %s on PATH, '.' not in PATH

(F) You used the -S switch, but the script to execute could not be found in the PATH, or at least not with the correct permissions. The script exists in the current directory, but PATH prohibits running it.

Can't find %s on PATH

(F) You used the -S switch, but the script to execute could not be found in the PATH.

Can't find label %s

(F) You said to goto a label that isn't mentioned anywhere that it's possible for us to go to.

Can't find string terminator %s anywhere before EOF

(F) Perl strings can stretch over multiple lines. This message means that the closing delimiter was omitted. Because bracketed quotes count nesting levels, the following is missing its final parenthesis:

print q(The character '(' starts a side comment.);
If you're getting this error from a here document, you may have included unseen whitespace before or after your closing tag. A good programmer's editor will have a way to help you find these characters.

Can't fork

(F) A fatal error occurred trying to fork.

Can't get filespec - stale stat buffer?

(S) This warning is peculiar to VMS. This arises because of the difference between access checks under VMS and under the Unix model Perl assumes. Under VMS, access checks are done by filename, rather than by bits in the stat buffer, so that ACLs and other protections can be taken into account. Unfortunately, Perl assumes that the stat buffer contains all the necessary information and passes it, instead of the filespec, to the access-checking routine. It will try to retrieve the filespec using the device name and FID present in the stat buffer, but if you have made a subsequent call to the CRTL stat routine, this won't work because the device name is overwritten with each call. If this warning appears, the name lookup failed and the access-checking routine gave up and returned false, just to be conservative. (Note: the access-checking routine knows about the Perl stat operator and file tests, so you shouldn't ever see this warning in response to a Perl command; it arises only if some internal code takes stat buffers lightly.)

Can't get pipe mailbox device name

(P) This error is peculiar to VMS. After creating a mailbox to act as a pipe, Perl can't retrieve its name for later use.

Can't get SYSGEN parameter value for MAXBUF

(P) This error is peculiar to VMS. Perl asked $GETSYI how big you want your mailbox buffers to be, and it didn't get an answer.

Can't goto subroutine outside a subroutine

(F) The deeply magical goto SUBROUTINE call can only replace one subroutine call for another. It can't manufacture one out of whole cloth. In general, you should be calling it out of only an AUTOLOAD routine anyway.

Can't goto subroutine from an eval-string

(F) The goto SUBROUTINE call can't be used to jump out of an eval string. (You can use it to jump out of an eval BLOCK, but you probably don't want to.)

Can't ignore signal CHLD, forcing to default

(W signal) Perl has detected that it is being run with the SIGCHLD signal (sometimes known as SIGCLD) disabled. Since disabling this signal will interfere with proper determination of exit status of child processes, Perl has reset the signal to its default value. This situation typically indicates that the parent program under which Perl may be running (e.g., cron) is being very careless.

Can't localize through a reference

(F) You said something like local $$ref, which Perl can't currently handle because when it goes to restore the old value of whatever $ref pointed to after the scope of the local is finished, it can't be sure that $ref will still be a reference.

Can't localize lexical variable %s

(F) You used local on a variable name that was previously declared as a lexical variable using my. This is not allowed. If you want to localize a package variable of the same name, qualify it with the package name.

Can't localize pseudohash element

(F) You said something like local $ar->{'key'}, where $ar is a reference to a pseudohash. That hasn't been implemented yet, but you can get a similar effect by localizing the corresponding array element directly--local $ar->[$ar->[0]{'key'}].

Can't locate auto/%s.al in @INC

(F) A function (or method) was called in a package that allows autoloading, but there is no function to autoload. Most probable causes are a misprint in a function/method name or a failure to AutoSplit the file, say, by doing make install.

Can't locate %s

(F) You said to do (or require, or use) a file that couldn't be found. Perl looks for the file in all the locations mentioned in @INC, unless the filename included the full path to the file. Perhaps you need to set the PERL5LIB or PERL5OPT environment variable to say where the extra library is, or maybe the script needs to add the library name to @INC. Or maybe you just misspelled the name of the file.

Can't locate object method "%s" via package "%s"

(F) You called a method correctly, and it correctly indicated a package functioning as a class, but that package doesn't define that particular method, nor does any of its base classes.

Can't locate package %s for @%s::ISA

(W syntax) The @ISA array contained the name of another package that doesn't seem to exist.

Can't make list assignment to \%ENV on this system

(F) List assignment to %ENV is not supported on some systems, notably VMS.

Can't modify %s in %s

(F) You aren't allowed to assign to the item indicated or otherwise try to change it, such as with an autoincrement.

Can't modify non-lvalue subroutine call

(F) Subroutines meant to be used in lvalue context should be declared as such.

Can't modify nonexistent substring

(P) The internal routine that does assignment to a substr was handed a NULL.

Can't msgrcv to read-only var

(F) The target of a msgrcv must be modifiable to be used as a receive buffer.

Can't open %s: %s

(S inplace) The implicit opening of a file through use of the <> filehandle, either implicitly under the -n or -p command-line switches or explicitly, failed for the indicated reason. Usually this is because you don't have read permission for a file which you named on the command line.

Can't open bidirectional pipe

(W pipe) You tried to say open(CMD, "|cmd|"), which is not supported. You can try any of several modules in the Perl library to do this, such as IPC::Open2. Alternatively, direct the pipe's output to a file using >, and then read it in under a different filehandle.

Can't open error file %s as stderr

(F) This is an error peculiar to VMS. Perl does its own command-line redirection, and it couldn't open the file specified after 2> or 2>> on the command line for writing.

Can't open input file %s as stdin

(F) This is an error peculiar to VMS. Perl does its own command-line redirection, and it couldn't open the file specified after < on the command line for reading.

Can't open output file %s as stdout

(F) This is an error peculiar to VMS. Perl does its own command-line redirection, and it couldn't open the file specified after > or >> on the command line for writing.

Can't open output pipe (name: %s)

(P) This is an error peculiar to VMS. Perl does its own command-line redirection, and it couldn't open the pipe into which to send data destined for STDOUT.

Can't open perl script "%s": %s

(F) The script you specified can't be opened for the indicated reason.

Can't redefine active sort subroutine %s

(F) Perl optimizes the internal handling of sort subroutines and keeps pointers into them. You tried to redefine one such sort subroutine when it was currently active, which is not allowed. If you really want to do this, you should write sort { &func } @x instead of sort func @x.

Can't remove %s: %s, skipping file

(S inplace) You requested an inplace edit without creating a backup file. Perl was unable to remove the original file to replace it with the modified file. The file was left unmodified.

Can't rename %s to %s: %s, skipping file

(S inplace) The rename done by the -i switch failed for some reason, probably because you don't have write permission to the directory.

Can't reopen input pipe (name: %s) in binary mode

(P) An error peculiar to VMS. Perl thought STDIN was a pipe, and tried to reopen it to accept binary data. Alas, it failed.

Can't reswap uid and euid

(P) The setreuid call failed for some reason in the setuid emulator of suidperl.

Can't return outside a subroutine

(F) The return statement was executed in mainline code, that is, where there was no subroutine call to return out of.

Can't return %s from lvalue subroutine

(F) Perl detected an attempt to return illegal lvalues (such as temporary or readonly values) from a subroutine used as an lvalue. This is not allowed.

Can't stat script "%s"

(P) For some reason, you can't fstat the script even though you have it open already. Bizarre.

Can't swap uid and euid

(P) The setreuid call failed for some reason in the setuid emulator of suidperl.

Can't take log of %g

(F) For ordinary real numbers, you can't take the logarithm of a negative number or zero. There's a Math::Complex package that comes standard with Perl, though, if you really want to do that for the negative numbers.

Can't take sqrt of %g

(F) For ordinary real numbers, you can't take the square root of a negative number. There's a Math::Complex package that comes standard with Perl, though, if you really want to do that.

Can't undef active subroutine

(F) You can't undefine a routine that's currently running. You can, however, redefine it while it's running, and you can even undef the redefined subroutine while the old routine is running. Go figure.

Can't unshift

(F) You tried to unshift an "unreal" array that can't be unshifted, such as the main Perl stack.

Can't upgrade that kind of scalar

(P) The internal sv_upgrade routine adds "members" to an SV, making it into a more specialized kind of SV. The top several SV types are so specialized, however, that they cannot be interconverted. This message indicates that such a conversion was attempted.

Can't upgrade to undef

(P) The undefined SV is the bottom of the totem pole, in the scheme of upgradability. Upgrading to undef indicates an error in the code calling sv_upgrade.

Can't use %%! because Errno.pm is not available

(F) The first time the %! hash is used, Perl automatically loads the Errno module. The Errno module is expected to tie the %! hash to provide symbolic names for $! errno values.

Can't use "my %s" in sort comparison

(F) The global variables $a and $b are reserved for sort comparisons. You mentioned $a or $b in the same line as the <=> or cmp operator, and the variable had earlier been declared as a lexical variable. Either qualify the sort variable with the package name, or rename the lexical variable.

Bad evalled substitution pattern

(F) You've used the /e switch to evaluate the replacement for a substitution, but Perl found a syntax error in the code to evaluate, most likely an unexpected right brace }.

Can't use %s for loop variable

(F) Only a simple scalar variable may be used as a loop variable on a foreach.

Can't use %s ref as %s ref

(F) You've mixed up your reference types. You have to dereference a reference of the type needed. You can use the ref function to test the type of the reference, if need be.

Can't use \%c to mean $%c in expression

(W syntax) In an ordinary expression, backslash is a unary operator that creates a reference to its argument. The use of backslash to indicate a backreference to a matched substring is valid only as part of a regular expression pattern. Trying to do this in ordinary Perl code produces a value that prints out looking like SCALAR(0xdecaf). Use the $1 form instead.

Can't use bareword ("%s") as %s ref while "strict refs" in use

(F) Only hard references are allowed by strict refs. Symbolic references are disallowed.

Can't use string ("%s") as %s ref while "strict refs" in use

(F) Only hard references are allowed by strict refs. Symbolic references are disallowed.

Can't use an undefined value as %s reference

(F) A value used as either a hard reference or a symbolic reference must be a defined value. This helps to delurk some insidious errors.

Can't use global %s in "my"

(F) You tried to declare a magical variable as a lexical variable. This is not allowed because the magic can be tied to only one location (namely the global variable) and it would be incredibly confusing to have variables in your program that looked like magical variables but weren't.

Can't use subscript on %s

(F) The compiler tried to interpret a bracketed expression as a subscript. But to the left of the brackets was an expression that didn't look like an array reference, or anything else subscriptable.

Can't weaken a nonreference

(F) You attempted to weaken something that was not a reference. Only references can be weakened.

Can't x= to read-only value

(F) You tried to repeat a constant value (often the undefined value) with an assignment operator, which implies modifying the value itself. Perhaps you need to copy the value to a temporary variable, and repeat that.

Can't find an opnumber for "%s"

(F) A string of a form CORE::word was given to prototype, but there is no built-in with the name word.

Can't resolve method `%s' overloading `%s' in package `%s'

(F|P) An error occurred when resolving overloading specified by a method name (as opposed to a subroutine reference): no such method callable via the package. If the method name is ???, this is an internal error.

Character class [:%s:] unknown

(F) The class in the character class [: :] syntax is unknown.

Character class syntax [%s] belongs inside character classes

(W unsafe) The character class constructs [: :], [= =], and [. .] go inside character classes, for example: /[012[:alpha:]345]/. Note that the [= =] and [. .] constructs are not currently implemented; they are simply placeholders for future extensions.

Character class syntax [. .] is reserved for future extensions

(W regexp) Within regular expression character classes ([]), the syntax beginning with [. and ending with .] is reserved for future extensions. If you need to represent those character sequences inside a regular expression character class, just quote the square brackets with the backslash: \[. and .\].

Character class syntax [= =] is reserved for future extensions

(W regexp) Within regular expression character classes ([]), the syntax beginning with [= and ending with =] is reserved for future extensions. If you need to represent those character sequences inside a regular expression character class, just quote the square brackets with the backslash: \[= and =\].

chmod() mode argument is missing initial 0

(W chmod) A novice will sometimes say:

chmod 777, $filename
not realizing that 777 will be interpreted as a decimal number, equivalent to 01411. Octal constants are introduced with a leading 0 in Perl, as in C.

Close on unopened file <%s>

(W unopened) You tried to close a filehandle that was never opened.

Compilation failed in require

(F) Perl could not compile a file specified in a require statement. Perl uses this generic message when none of the errors that it encountered were severe enough to halt compilation immediately.

Complex regular subexpression recursion limit (%d) exceeded

(W regexp) The regular expression engine uses recursion in complex situations where backtracking is required. Recursion depth is limited to 32,766, or perhaps less in architectures where the stack cannot grow arbitrarily. ("Simple" and "medium" situations are handled without recursion and are not subject to a limit.) Try shortening the string under examination; looping in Perl code (e.g., with while) rather than in the regular expression engine; or rewriting the regular expression so that it is simpler or backtracks less.

connect() on closed socket %s

(W closed) You tried to do a connect on a closed socket. Did you forget to check the return value of your socket call?

Constant is not %s reference

(F) A constant value (perhaps declared using the use constant pragma) is being dereferenced, but it amounts to the wrong type of reference. The message indicates the type of reference that was expected. This usually indicates a syntax error in dereferencing the constant value.

Constant subroutine %s redefined

(S|W redefine) You redefined a subroutine that had previously been eligible for inlining.

Constant subroutine %s undefined

(W misc) You undefined a subroutine that had previously been eligible for inlining.

constant(%s): %s

(F) The parser found inconsistencies either while attempting to define an overloaded constant or when trying to find the character name specified in the \N{...} escape. Perhaps you forgot to load the corresponding overload or charnames pragma?

Copy method did not return a reference

(F) The method that overloads = is buggy.

CORE::%s is not a keyword

(F) The CORE:: namespace is reserved for Perl keywords.

Corrupt malloc ptr 0x%lx at 0x%lx

(P) The malloc package that comes with Perl had an internal failure.

corrupted regexp pointers

(P) The regular expression engine got confused by what the regular expression compiler gave it.

corrupted regexp program

(P) The regular expression engine got passed a regexp program without a valid magic number.

Deep recursion on subroutine "%s"

(W recursion) This subroutine has called itself (directly or indirectly) 100 times more than it has returned. This probably indicates an infinite recursion, unless you're writing strange benchmark programs, in which case it indicates something else.

defined(@array) is deprecated

(D deprecated) defined is not usually useful on arrays because it checks for an undefined scalar value. If you want to see if the array is empty, just use if (@array) { # not empty }.

defined(%hash) is deprecated

(D deprecated) defined is not usually useful on hashes because it checks for an undefined scalar value. If you want to see if the hash is empty, just use if (%hash) { # not empty }.

Delimiter for here document is too long

(F) In a here document construct like <<FOO, the label FOO is too long for Perl to handle. You have to be seriously twisted to write code that triggers this error.

Did not produce a valid header

See Server error.

(Did you mean &%s instead?)

(W) You probably referred to an imported subroutine &FOO as $FOO or some such.

(Did you mean "local" instead of "our"?)

(W misc) Remember that our does not localize the declared global variable. You have declared it again in the same lexical scope, which seems superfluous.

(Did you mean $ or @ instead of %?)

(W) You probably said %hash{$key} when you meant $hash{$key} or @hash{@keys}. On the other hand, maybe you just meant %hash and got carried away.

Died

(F) You passed die an empty string (the equivalent of die "") or you called it with no args and both $@ and $_ were empty.

(Do you need to predeclare %s?)

(S) This is an educated guess made in conjunction with the message "%s found where operator expected". It often means a subroutine or module name is being referenced that hasn't been declared yet. This may be because of ordering problems in your file or because of a missing sub, package, require, or use statement. If you're referencing something that isn't defined yet, you don't actually have to define the subroutine or package before the current location. You can use an empty sub foo; or package FOO; to enter a "forward" declaration.

Document contains no data

See Server error.

Don't know how to handle magic of type '%s'

(P) The internal handling of magical variables has been cursed.

do_study: out of memory

(P) This should have been caught by safemalloc instead.

Duplicate free() ignored

(S malloc) An internal routine called free on something that had already been freed.

elseif should be elsif

(S) There is no keyword "elseif" in Perl because Larry thinks it's ugly. Your code will be interpreted as an attempt to call a method named elseif for the class returned by the following block. This is unlikely to be what you want.

%s failed--call queue aborted

(F) An untrapped exception was raised while executing a CHECK, INIT, or END subroutine. Processing of the remainder of the queue of such routines has been prematurely ended.

entering effective %s failed

(F) While under the use filetest pragma, switching the real and effective UIDs or GIDs failed.

Error converting file specification %s

(F) This is an error peculiar to VMS. Because Perl may have to deal with file specifications in either VMS or Unix syntax, it converts them to a single form when it must operate on them directly. Either you've passed an invalid file specification to Perl, or you've found a case the conversion routines don't handle. Drat.

%s: Eval-group in insecure regular expression

(F) Perl detected tainted data when trying to compile a regular expression that contains the (?{ ... }) zero-width assertion, which is unsafe.

%s: Eval-group not allowed, use re 'eval'

(F) A regular expression contained the (?{ ... }) zero-width assertion, but that construct is only allowed when the use re 'eval' pragma is in effect.

%s: Eval-group not allowed at run time

(F) Perl tried to compile a regular expression containing the (?{ ... }) zero-width assertion at run time, as it would when the pattern contains interpolated values. Since that is a security risk, it is not allowed. If you insist, you may still do this by explicitly building the pattern from an interpolated string at run time and using that in an eval.

Excessively long <> operator

(F) The contents of a <> operator may not exceed the maximum size of a Perl identifier. If you're just trying to glob a long list of filenames, try using the glob operator or putting the filenames into a variable and globbing that.

Execution of %s aborted due to compilation errors

(F) The final summary message when a Perl compilation fails.

Exiting eval via %s

(W exiting) You are exiting an eval by unconventional means, such as a goto or a loop control statement.

Exiting format via %s

(W exiting) You are exiting a format by unconventional means, such as a goto or a loop control statement.

Exiting pseudoblock via %s

(W exiting) You are exiting a rather special block construct (like a sort block or subroutine) by unconventional means, such as a goto or a loop control statement.

Exiting subroutine via %s

(W exiting) You are exiting a subroutine by unconventional means, such as a goto or a loop control statement.

Exiting substitution via %s

(W exiting) You are exiting a substitution by unconventional means, such as a return, a goto, or a loop control statement.

Explicit blessing to '' (assuming package main)

(W misc) You are blessing a reference to a zero-length string. This has the effect of blessing the reference into the package main. This is usually not what you want. Consider providing a default target package, such as bless($ref, $p || 'MyPackage');

false [] range "%s" in regexp

(W regexp) A character class range must start and end at a literal character, not another character class like \d or [:alpha:]. The - in your false range is interpreted as a literal -. Consider quoting the - like this: \-.

Fatal VMS error at %s, line %d

(P) This is an error peculiar to VMS. Something untoward happened in a VMS system service or RTL routine; Perl's exit status should provide more details. The filename in at%s and the line number in line%d tell you which section of the Perl source code is distressed.

fcntl is not implemented

(F) Your machine apparently doesn't implement fcntl. What is this, a PDP-11 or something?

Filehandle %s never opened

(W unopened) An I/O operation was attempted on a filehandle that was never initialized. You need to do an open or a socket call, or call a constructor from the FileHandle module.

Filehandle %s opened only for input

(W io) You tried to write on a read-only filehandle. If you intended it to be a read-write filehandle, you needed to open it with +< or +> or +>> instead of with < or nothing. If you intended only to write the file, use > or >>.

Filehandle %s opened only for output

(W io) You tried to read from a filehandle opened only for writing. If you intended it to be a read/write filehandle, you needed to open it with +< or +> or +>> instead of with < or nothing. If you intended only to read from the file, use <.

Final $ should be \$ or $name

(F) You must now decide whether the final $ in a string was meant to be a literal dollar sign or was meant to introduce a variable name that happens to be missing. So you have to add either the backslash or the name.

Final @ should be \@ or @name

(F) You must now decide whether the final @ in a string was meant to be a literal "at" sign or was meant to introduce a variable name that happens to be missing. So you have to add either the backslash or the name.

flock() on closed filehandle %s

(W closed) The filehandle you're attempting to flock got itself closed some time before now. Check your logic flow. flock operates on filehandles. Are you attempting to call flock on a dirhandle by the same name?

Format %s redefined

(W redefine) You redefined a format. To suppress this warning, say:

{
    no warnings;
    eval "format NAME =...";
}

Format not terminated

(F) A format must be terminated by a line with a solitary dot. Perl got to the end of your file without finding such a line.

Found = in conditional, should be ==

(W syntax) You said:

if ($foo = 123)
when you meant:
if ($foo == 123)
(or something like that).

gdbm store returned %d, errno %d, key "%s"

(S) A warning from the GDBM_File extension that a store failed.

gethostent not implemented

(F) Your C library apparently doesn't implement gethostent, probably because if it did, it'd feel morally obligated to return every hostname on the Internet.

get%s name() on closed socket %s

(W closed) You tried to get a socket or peer socket name on a closed socket. Did you forget to check the return value of your socket call?

getpwnam returned invalid UIC %#o for user "%s"

(S) A warning peculiar to VMS. The call to sys$getuai underlying the getpwnam operator returned an invalid UIC.

getsockopt() on closed socket %s

(W closed) You tried to get a socket option on a closed socket. Did you forget to check the return value of your socket call?

glob failed (%s)

(W glob) Something went wrong with the external program(s) used for glob and <*.c>. Usually, this means that you supplied a glob pattern that caused the external program to fail and exit with a nonzero status. If the message indicates that the abnormal exit resulted in a core dump, this may also mean that your csh (C shell) is broken. If so, you should change all of the csh-related variables in config.sh: If you have tcsh, make the variables refer to it as if it were csh (e.g., full_csh='/usr/bin/tcsh'); otherwise, make them all empty (except that d_csh should be 'undef') so that Perl will think csh is missing. In either case, after editing config.sh, run ./Configure -S and rebuild Perl.

Glob not terminated

(F) The lexer saw a left angle bracket in a place where it was expecting a term, so it's looking for the corresponding right angle bracket and not finding it. Chances are you left some needed parentheses out earlier in the line, and you really meant a < symbol.

Global symbol "%s" requires explicit package name

(F) You've said use strict vars, which indicates that all variables must either be lexically scoped (using my), declared beforehand using our, or explicitly qualified to say which package the global variable is in (using ::).

Got an error from DosAllocMem

(P) This is an error peculiar to OS/2. Most probably you're using an obsolete version of Perl, so this error should not happen anyway.

goto must have label

(F) Unlike with next or last, you're not allowed to goto an unspecified destination.

Had to create %s unexpectedly

(S internal) A routine asked for a symbol from a symbol table that ought to have existed already, but for some reason it didn't and had to be created on an emergency basis to prevent a core dump.

Hash %%s missing the % in argument %d of %s()

(D deprecated) Really old Perl let you omit the % on hash names in some spots. This is now heavily deprecated.

Hexadecimal number > 0xffffffff non-portable

(W portable) The hexadecimal number you specified is larger than 2**32-1 (4,294,967,295) and therefore nonportable between systems.

Identifier too long

(F) Perl limits identifiers (names for variables, functions, etc.) to about 250 characters for simple names, and somewhat more for compound names (like $A::B). You've exceeded Perl's limits. Future versions of Perl are likely to eliminate these arbitrary limitations.

Ill-formed CRTL environ value "%s"

(W internal) This is a warning peculiar to VMS. Perl tried to read the CRTL's internal environ array and encountered an element without the = delimiter used to separate keys from values. The element is ignored.

Ill-formed message in prime_env_iter: |%s|

(W internal) This is a warning peculiar to VMS. Perl tried to read a logical name or CLI symbol definition when preparing to iterate over %ENV and didn't see the expected delimiter between key and value, so the line was ignored.

Illegal character %s (carriage return)

(F) Perl normally treats carriage returns in the program text as it would any other whitespace, which means you should never see this error when Perl was built using standard options. For some reason, your version of Perl appears to have been built without this support. Talk to your Perl administrator.

Illegal division by zero

(F) You tried to divide a number by 0. Either something was wrong in your logic, or you need to put a conditional in to guard against meaningless input.

Illegal modulus zero

(F) You tried to divide a number by 0 to get the remainder. Most numbers don't take to this kindly.

Illegal binary digit %s

(F) You used a digit other than 0 or 1 in a binary number.

Illegal octal digit %s

(F) You used an 8 or 9 in a octal number.

Illegal binary digit %s ignored

(W digit) You may have tried to use a digit other than 0 or 1 in a binary number. Interpretation of the binary number stopped before the offending digit.

Illegal octal digit %s ignored

(W digit) You may have tried to use an 8 or 9 in a octal number. Interpretation of the octal number stopped before the 8 or 9.

Illegal hexadecimal digit %s ignored

(W digit) You may have tried to use a character other than 0 through 9, A through F, or a through f in a hexadecimal number. Interpretation of the hexadecimal number stopped before the illegal character.

Illegal number of bits in vec

(F) The number of bits in vec (the third argument) must be a power of two from 1 to 32 (or 64, if your platform supports that).

Illegal switch in PERL5OPT: %s

(X) The PERL5OPT environment variable may only be used to set the following switches: -[DIMUdmw].

In string, @%s now must be written as \@%s

(F) It used to be that Perl would try to guess whether you wanted an array interpolated or a literal @. It did this when the string was first used at run time. Now strings are parsed at compile time, and ambiguous instances of @ must be disambiguated, either by prepending a backslash to indicate a literal, or by declaring (or using) the array within the program before the string (lexically). (Someday it will simply assume that an unbackslashed @ interpolates an array.)

Insecure dependency in %s

(F) You tried to do something that the tainting mechanism didn't like. The tainting mechanism is turned on when you're running setuid or setgid, or when you specify -T to turn it on explicitly. The tainting mechanism labels all data that's derived directly or indirectly from the user, who is considered to be unworthy of your trust. If any such data is used in a "dangerous" operation, you get this error.

Insecure directory in %s

(F) You can't use system, exec, or a piped open in a setuid or setgid script if $ENV{PATH} contains a directory that is writable by the world.

Insecure $ENV{%s} while running %s

(F) You can't use system, exec, or a piped open in a setuid or setgid script if any of $ENV{PATH}, $ENV{IFS}, $ENV{CDPATH}, $ENV{ENV}, or $ENV{BASH_ENV} are derived from data supplied (or potentially supplied) by the user. The script must set the path to a known value, using trustworthy data.

Integer overflow in %s number

(W overflow) The hexadecimal, octal, or binary number you have specified either as a literal or as an argument to hex or oct is too big for your architecture and has been converted to a floating-point number. On 32-bit machines, the largest hex, octal, or binary number representable without overflow is 0xFFFFFFFF, 037777777777, or 0b11111111111111111111111111111111 respectively. Note that Perl transparently promotes all numbers to a floating-point representation internally--subject to loss of precision errors in subsequent operations.

Internal inconsistency in tracking vforks

(S) This is a warning peculiar to VMS. Perl keeps track of the number of times you've called fork and exec, to determine whether the current call to exec should affect the current script or a subprocess (see "exec LIST" in perlvms(1)). Somehow, this count has become scrambled, so Perl is making a guess and treating this exec as a request to terminate the Perl script and execute the specified command.

internal disaster in regexp

(P) Something went badly wrong in the regular expression parser.

internal urp in regexp at /%s/

(P) Something went badly awry in the regular expression parser.

Invalid %s attribute: %s

(F) The indicated attribute for a subroutine or variable was not recognized by Perl or by a user-supplied handler.

Invalid %s attributes: %s

(F) The indicated attributes for a subroutine or variable were not recognized by Perl or by a user-supplied handler.

invalid [] range "%s" in regexp

(F) The range specified in a character class had a minimum character greater than the maximum character.

Invalid conversion in %s: "%s"

(W printf) Perl does not understand the given format conversion.

Invalid separator character %s in attribute list

(F) Something other than a colon or whitespace was seen between the elements of an attribute list. If the previous attribute had a parenthesized parameter list, perhaps that list was terminated too soon.

Invalid type in pack: '%s'

(F) The given character is not a valid pack type.

(W pack) The given character is not a valid pack type, but it used to be silently ignored.

Invalid type in unpack: '%s'

(F) The given character is not a valid unpack type.

(W unpack) The given character is not a valid unpack type, but it used to be silently ignored.

ioctl is not implemented

(F) Your machine apparently doesn't implement ioctl, which is pretty strange for a machine that supports C.

junk on end of regexp

(P) The regular expression parser is confused.

Label not found for "last %s"

(F) You named a loop to break out of, but you're not currently in a loop of that name, not even if you count where you were called from.

Label not found for "next %s"

(F) You named a loop to continue, but you're not currently in a loop of that name, not even if you count where you were called from.

Label not found for "redo %s"

(F) You named a loop to restart, but you're not currently in a loop of that name, not even if you count where you were called from.

leaving effective %s failed

(F) While under the use filetest pragma, switching the real and effective UIDs or GIDs failed.

listen() on closed socket %s

(W closed) You tried to do a listen on a closed socket. Did you forget to check the return value of your socket call?

Lvalue subs returning %s not implemented yet

(F) Due to limitations in the current implementation, array and hash values cannot be returned in subroutines used in lvalue context.

Malformed PERLLIB_PREFIX

(F) This is an error peculiar to OS/2. PERLLIB_PREFIX should be of the form:

prefix1;prefix2
or:
prefix1 prefix2
with nonempty prefix1 and prefix2. If prefix1 is indeed a prefix of a built-in library search path, prefix2 is substituted. The error may appear if components are not found, or are too long. See PERLLIB_PREFIX in the README.os2 file bundled with the Perl distribution.

Method for operation %s not found in package %s during blessing

(F) An attempt was made to specify an entry in an overloading table that doesn't resolve to a valid subroutine.

Method %s not permitted

See Server error.

Might be a runaway multi-line %s string starting on line %d

(S) An advisory indicating that the previous error may have been caused by a missing delimiter on a string or pattern, because the string eventually ended earlier on the current line.

Misplaced _ in number

(W syntax) An underline in a decimal constant wasn't at a 3-digit boundary.

Missing $ on loop variable

(F) Apparently, you've been programming in csh too much. Variables are always mentioned with the $ in Perl, unlike in the shells, where it can vary from one line to the next.

Missing %s brace%s on \N{}

(F) You used the wrong syntax of character name literal \N{charname} within double-quotish context.

Missing comma after first argument to %s function

(F) While certain functions allow you to specify a filehandle or an "indirect object" before the argument list, this ain't one of them.

Missing command in piped open

(W pipe) You used the open(FH, "| command") or open(FH, "command |") construction, but the command was missing or blank.

(Missing operator before %s?)

(S) This is an educated guess made in conjunction with the message "%s found where operator expected". Often the missing operator is a comma.

Missing right curly or square bracket

(F) The lexer counted more opening curly or square brackets than closing ones. As a general rule, you'll find it's missing near the place you were last editing.

Modification of a read-only value attempted

(F) You tried, directly or indirectly, to change the value of a constant. You didn't, of course, try 2 = 1, because the compiler catches that. But an easy way to do the same thing is:

sub mod { $_[0] = 1 }
mod(2);
Another way is to assign to a substr that's off the end of the string.

Modification of non-creatable array value attempted, subscript %d

(F) You tried to make an array value spring into existence, and the subscript was probably negative, even counting from end of the array backward.

Modification of non-creatable hash value attempted, subscript "%s"

(P) You tried to make a hash value spring into existence, and it couldn't be created for some peculiar reason.

Module name must be constant

(F) Only a bare module name is allowed as the first argument to a use.

msg%s not implemented

(F) You don't have System V message IPC on your system.

Multidimensional syntax %s not supported

(W syntax) Multidimensional arrays aren't written like $foo[1,2,3]. They're written like $foo[1][2][3], as in C.

Missing name in "my sub"

(F) The reserved syntax for lexically scoped subroutines requires that they have a name with which they can be found.

Name "%s::%s" used only once: possible typo

(W once) Typographical errors often show up as unique variable names. If you had a good reason for having a unique name, then just mention it again somehow to suppress the message. The our declaration is provided for this purpose.

Negative length

(F) You tried to do a read/write/send/recv operation with a buffer length that is less than 0. This is difficult to imagine.

nested *?+ in regexp

(F) You can't quantify a quantifier without intervening parentheses. So things like ** or +* or ?* are illegal.

Note, however, that the minimal matching quantifiers, *?, +?, and ?? appear to be nested quantifiers, but aren't.

No #! line

(F) The setuid emulator requires that scripts have a well-formed #! line even on machines that don't support the #! construct.

No %s allowed while running setuid

(F) Certain operations are deemed to be too insecure for a setuid or setgid script to even attempt. Generally speaking, there will be another way to do what you want that is, if not secure, at least securable.

No -e allowed in setuid scripts

(F) A setuid script can't be specified by the user.

No %s specified for -%c

(F) The indicated command-line switch needs a mandatory argument, but you haven't specified one.

No comma allowed after %s

(F) A list operator that has a filehandle or "indirect object" is not allowed to have a comma between that and the following arguments. Otherwise, it would be interpreted as just another argument.

One obscure situation where this message occurs is when you expect a constant to be imported into your namespace with use or import, but no such importing took place (say, because your operating system doesn't support that particular constant). You should have used an explicit import list for the constants you expect to see. An explicit import list would probably have caught this error earlier. Or maybe there's just a typo in the name of the constant.

No command into which to pipe on command line

(F) This is an error peculiar to VMS. Perl handles its own command-line redirection and found a | at the end of the command line, so it doesn't know where you want to pipe the output from this command.

No DB::DB routine defined

(F) The currently executing code was compiled with the -d switch, but for some reason the perl5db.pl file (or some facsimile thereof) didn't define a routine to be called at the beginning of each statement. Which is odd, because the file should have been required automatically and should have blown up the require if it didn't parse right.

No dbm on this machine

(P) This is counted as an internal error; every machine should supply a DBM nowadays because Perl comes with SDBM.

No DBsub routine

(F) The currently executing code was compiled with the -d switch, but for some reason the perl5db.pl file (or some facsimile thereof) didn't define a DB::sub routine to be called at the beginning of each ordinary subroutine call.

No error file after 2> or 2>> on command line

(F) This is an error peculiar to VMS. Perl handles its own command-line redirection, and found a 2> or a 2>> on the command line, but it can't find the name of the file to which to write data destined for STDERR.

No input file after < on command line

(F) This is an error peculiar to VMS. Perl handles its own command-line redirection and found a < on the command line, but it can't find the name of the file from which to read data for STDIN.

No output file after > on command line

(F) This is an error peculiar to VMS. Perl handles its own command-line redirection and found a lone > at the end of the command line, but it doesn't know where you wanted to redirect STDOUT.

No output file after > or >> on command line

(F) This is an error peculiar to VMS. Perl handles its own command-line redirection and found a > or a >> on the command line, but it can't find the name of the file to which to write data destined for STDOUT.

No package name allowed for variable %s in "our"

(F) Fully qualified variable names are not allowed in our declarations, because they don't make much sense under existing semantics. Such syntax is reserved for future extensions.

No Perl script found in input

(F) You called perl -x, but no line was found in the file beginning with #! and containing the word "perl".

No setregid available

(F) Configure didn't find anything resembling the setregid call for your system.

No setreuid available

(F) Configure didn't find anything resembling the setreuid call for your system.

No space allowed after -%c

(F) The argument to the indicated command-line switch must follow immediately after the switch, without intervening spaces.

No such pseudohash field "%s"

(F) You tried to access an array as a hash, but the field name used is not defined. The hash at index 0 should map all valid field names to array indices for that to work.

No such pseudohash field "%s" in variable %s of type %s

(F) You tried to access a field of a typed variable, but the type does not know about the field name. The field names are looked up in the %FIELDS hash in the type package at compile time. The %FIELDS hash is usually set up with the fields pragma.

No such pipe open

(P) This is an error peculiar to VMS. The internal routine my_pclose tried to close a pipe that hadn't been opened. This should have been caught earlier as an attempt to close an unopened filehandle.

No such signal: SIG%s

(W signal) The signal name you specified as a subscript to %SIG was not recognized. Say kill -l in your shell to see the valid signal names on your system.

no UTC offset information; assuming local time is UTC

(S) This is a warning peculiar to VMS. Perl was unable to find the local time zone offset, so it assumes that the local system time and the UTC are equivalent. If they're not, define the logical name SYS$TIMEZONE_DIFFERENTIAL to translate to the number of seconds that need to be added to UTC to get local time.

Not a CODE reference

(F) Perl was trying to evaluate a reference to a code value (that is, a subroutine) but found a reference to something else instead. You can use the ref function to find out what kind of ref it really was.

Not a format reference

(F) We're not sure how you managed to generate a reference to an anonymous format, but this message indicates that you did and that it didn't exist.

Not a GLOB reference

(F) Perl was trying to evaluate a reference to a "typeglob" (that is, a symbol table entry that looks like *foo) but found a reference to something else instead. You can use the ref function to find out what kind of ref it really was.

Not a HASH reference

(F) Perl was trying to evaluate a reference to a hash value but found a reference to something else instead. You can use the ref function to find out what kind of ref it really was.

Not a perl script

(F) The setuid emulator requires that scripts have a well-formed #! line even on machines that don't support the #! construct. The line must mention "perl".

Not a SCALAR reference

(F) Perl was trying to evaluate a reference to a scalar value but found a reference to something else instead. You can use the ref function to find out what kind of ref it really was.

Not a subroutine reference

(F) Perl was trying to evaluate a reference to a code value (that is, a subroutine) but found a reference to something else instead. You can use the ref function to find out what kind of ref it really was.

Not a subroutine reference in overload table

(F) An attempt was made to specify an entry in an overloading table that doesn't somehow point to a valid subroutine.

Not an ARRAY reference

(F) Perl was trying to evaluate a reference to an array value but found a reference to something else instead. You can use the ref function to find out what kind of ref it really was.

Not enough arguments for %s

(F) The function requires more arguments than you specified.

Not enough format arguments

(W syntax) A format specified more picture fields than the next line supplied.

Null filename used

(F) You can't require the null filename, especially because on many machines that means the current directory!

Null picture in formline

(F) The first argument to formline must be a valid format picture specification. The argument was found to be empty, which probably means you supplied it an uninitialized value.

NULL OP IN RUN

(P debugging) Some internal routine called run with a null opcode pointer.

Null realloc

(P) An attempt was made to realloc NULL.

NULL regexp argument

(P) The internal pattern-matching routines blew it big time.

NULL regexp parameter

(P) The internal pattern-matching routines are out of their gourd.

Number too long

(F) Perl limits the representation of decimal numbers in programs to about about 250 characters. You've exceeded that length. Future versions of Perl are likely to eliminate this arbitrary limitation. In the meantime, try using scientific notation (e.g., 1e6 instead of 1_000_000).

Octal number > 037777777777 non-portable

(W portable) The octal number you specified is larger than 2**32-1 (4,294,967,295) and therefore nonportable between systems.

Octal number in vector unsupported

(F) Numbers with a leading 0 are not currently allowed in vectors. The octal number interpretation of such numbers may be supported in a future version.

Odd number of elements in hash assignment

(W misc) You specified an odd number of elements to initialize a hash, which is odd because hashes come in key/value pairs.

Offset outside string

(F) You tried to do a read/write/send/recv operation with an offset pointing outside the buffer. This is difficult to imagine. The sole exception to this rule is that sysreading past the buffer will extend the buffer and zero-pad the new area.

oops: oopsAV

(S internal) An internal warning indicating that the grammar is screwed up.

oops: oopsHV

(S internal) An internal warning indicating that the grammar is screwed up.

Operation `%s': no method found, %s

(F) An attempt was made to perform an overloaded operation for which no handler was defined. While some handlers can be autogenerated in terms of other handlers, there is no default handler for any operation, unless the fallback overloading key is specified to be true.

Operator or semicolon missing before %s

(S ambiguous) You used a variable or subroutine call when the parser was expecting an operator. The parser has assumed you really meant to use an operator, but this is highly likely to be incorrect. For example, if you accidentally say *foo*foo, it will be interpreted as if you'd said *foo * 'foo'.

Out of memory!

(X) Perl's internal malloc function returned 0, indicating that the remaining memory (or virtual memory) was insufficient to satisfy the request. Perl has no option but to exit immediately.

Out of memory for yacc stack

(F) The yacc parser wanted to grow its stack so it could continue parsing, but realloc wouldn't give it more memory, virtual or otherwise.

Out of memory during request for %s

(X|F) The malloc function returned 0, indicating that the remaining memory (or virtual memory) was insufficient to satisfy the request.

The request was judged to be small, so the possibility to trap it depends on the way Perl was compiled. By default, it is not trappable. However, if compiled for this purpose, Perl may use the contents of $^M as an emergency pool after dieing with this message. In this case, the error is trappable once.

Out of memory during "large" request for %s

(F) Perl's internal malloc function returned 0, indicating that the remaining memory (or virtual memory) was insufficient to satisfy the request. However, the request was judged large enough (compile-time default is 64K), so a possibility to shut down by trapping this error is granted.

Out of memory during ridiculously large request

(F) You can't allocate more than 2**31+"small amount" bytes. This error is most likely to be caused by a typo in the Perl program (e.g., $arr[time] instead of $arr[$time]).

page overflow

(W io) A single call to write produced more lines than can fit on a page.

panic: ck_grep

(P) The program failed an internal consistency check while trying to compile a grep.

panic: ck_split

(P) The program failed an internal consistency check while trying to compile a split.

panic: corrupt saved stack index

(P) The savestack was requested to restore more localized values than there are in the savestack.

panic: del_backref

(P) The program failed an internal consistency check while trying to reset a weak reference.

panic: die %s

(P) We popped the context stack to an eval context and then discovered it wasn't an eval context.

panic: do_match

(P) The internal pp_match routine was called with invalid operational data.

panic: do_split

(P) Something terrible went wrong in setting up for the split.

panic: do_subst

(P) The internal pp_subst routine was called with invalid operational data.

panic: do_trans

(P) The internal do_trans routine was called with invalid operational data.

panic: frexp

(P) The library function frexp failed, making printf("%f") impossible.

panic: goto

(P) We popped the context stack to a context with the specified label and then discovered it wasn't a context in which we know how to do a goto.

panic: INTERPCASEMOD

(P) The lexer got into a bad state at a case modifier.

panic: INTERPCONCAT

(P) The lexer got into a bad state parsing a string with brackets.

panic: kid popen errno read

(F) The forked child returned an incomprehensible message about its errno.

panic: last

(P) We popped the context stack to a block context and then discovered it wasn't a block context.

panic: leave_scope clearsv

(P) A writable lexical variable became read-only somehow within the scope.

panic: leave_scope inconsistency

(P) The savestack probably got out of sync. At least, there was an invalid enum on the top of it.

panic: malloc

(P) Something requested a negative number of bytes of malloc.

panic: magic_killbackrefs

(P) The program failed an internal consistency check while trying to reset all weak references to an object.

panic: mapstart

(P) The compiler is screwed up with respect to the map function.

panic: null array

(P) One of the internal array routines was passed a null AV pointer.

panic: pad_alloc

(P) The compiler got confused about which scratchpad it was allocating and freeing temporaries and lexicals from.

panic: pad_free curpad

(P) The compiler got confused about which scratchpad it was allocating and freeing temporaries and lexicals from.

panic: pad_free po

(P) An invalid scratchpad offset was detected internally.

panic: pad_reset curpad

(P) The compiler got confused about which scratchpad it was allocating and freeing temporaries and lexicals from.

panic: pad_sv po

(P) An invalid scratchpad offset was detected internally.

panic: pad_swipe curpad

(P) The compiler got confused about which scratchpad it was allocating and freeing temporaries and lexicals from.

panic: pad_swipe po

(P) An invalid scratchpad offset was detected internally.

panic: pp_iter

(P) The foreach iterator got called in a nonloop context frame.

panic: realloc

(P) Something requested a negative number of bytes of realloc.

panic: restartop

(P) Some internal routine requested a goto (or something like it) but didn't supply the destination.

panic: return

(P) We popped the context stack to a subroutine or eval context and then discovered it wasn't a subroutine or eval context.

panic: scan_num

(P) Perl's internal scan_num got called on something that wasn't a number.

panic: sv_insert

(P) The sv_insert routine was told to remove more string than there was string.

panic: top_env

(P) The compiler attempted to do a goto, or something weird like that.

panic: yylex

(P) The lexer got into a bad state while processing a case modifier.

panic: %s

(P) An internal error.

Parentheses missing around "%s" list

(W parenthesis) You said something like:

my $foo, $bar = @_;
when you meant:
my ($foo, $bar) = @_;
Remember that my, our, and local bind tighter than the comma.

Perl %3.3f required--this is only version %s, stopped

(F) The module in question uses features of a version of Perl more recent than the currently running version. How long has it been since you upgraded, anyway?

PERL_SH_DIR too long

(F) This is an error peculiar to OS/2. PERL_SH_DIR is the directory that contains the sh shell. See PERL_SH_DIR in the README.os2 file bundled with the Perl distribution.

Permission denied

(F) The setuid emulator in suidperl decided you were up to no good.

pid %x not a child

(W exec) This is a warning peculiar to VMS; waitpid was asked to wait for a process that isn't a subprocess of the current process. While this is fine from VMS's perspective, it's probably not what you intended.

POSIX getpgrp can't take an argument

(F) Your system has POSIX getpgrp, which takes no argument, unlike the BSD version, which takes a PID.

Possible Y2K bug: %s

(W y2k) You are concatenating the number 19 with another number, which could be a potential year 2000 problem.

Possible attempt to put comments in qw() list

(W qw) qw lists contain items separated by whitespace; as with literal strings, comment characters are not ignored but are instead treated as literal data. (You may have used delimiters other than the parentheses shown here; braces are also frequently used.)

You probably wrote something like this:

@list = qw(
    a # a comment
    b # another comment
);
when you should have written this:
@list = qw(
    a
    b
);
If you really want comments, build your list the old-fashioned way, with quotes and commas:
@list = (
    'a',    # a comment
    'b',    # another comment
);

Possible attempt to separate words with commas

(W qw) qw lists contain items separated by whitespace; therefore, commas aren't needed to separate the items. (You may have used delimiters other than the parentheses shown here; braces are also frequently used.)

You probably wrote something like this:

qw( a, b, c );
which puts literal commas into some of the list items. Write it without commas if you don't want them to appear in your data:
qw( a b c );

Possible memory corruption: %s overflowed 3rd argument

(F) An ioctl or fcntl returned more than Perl was bargaining for. Perl guesses a reasonable buffer size but puts a sentinel byte at the end of the buffer just in case. This sentinel byte got clobbered, and Perl assumes that memory is now corrupted.

pragma "attrs" is deprecated, use "sub NAME : ATTRS" instead

(W deprecated) You have written something like this:

sub doit
{
    use attrs qw(locked);
}
You should use the new declaration syntax instead:
sub doit : locked
{
    ...
The use attrs pragma is now obsolete and is only provided for backward compatibility.

Precedence problem: open %s should be open(%s)

(S precedence) The old irregular construct:

open FOO || die;
is now misinterpreted as:
open(FOO || die);
because of the strict regularization of Perl 5's grammar into unary and list operators. (The old open was a little of both.) You must put parentheses around the filehandle or use the new or operator instead of ||.

Premature end of script headers

See Server error.

print() on closed filehandle %s

(W closed) The filehandle you're printing on got itself closed sometime before now. Check your logic flow.

printf() on closed filehandle %s

(W closed) The filehandle you're writing to got itself closed sometime before now. Check your logic flow.

Process terminated by SIG%s

(W) This is a standard message issued by OS/2 applications, while Unix applications die in silence. It is considered a feature of the OS/2 port. One can easily disable this warning by setting appropriate signal handlers. See also "Process terminated by SIGTERM/SIGINT" in the README.os2 file bundled with the Perl distribution.

Prototype mismatch: %s vs %s

(S unsafe) The subroutine being declared or defined had previously been declared or defined with a different function prototype.

Range iterator outside integer range

(F) One (or both) of the numeric arguments of the range operator .. are outside the range that can be represented by integers internally. One possible workaround is to force Perl to use magical string increments by prepending 0 to your numbers.

readline() on closed filehandle %s

(W closed) The filehandle you're reading from got itself closed sometime before now. Check your logic flow.

realloc() of freed memory ignored

(S malloc) An internal routine called realloc on something that had already been freed.

Reallocation too large: %lx

(F) You can't allocate more than 64K on an MS-DOS machine.

Recompile perl with -DDEBUGGING to use -D switch

(F debugging) You can't use the -D option unless the code to produce the desired output is compiled into Perl, which entails some overhead, which is why it's currently left out of your copy.

Recursive inheritance detected in package '%s'

(F) More than 100 levels of inheritance were used. This probably indicates an unintended loop in your inheritance hierarchy.

Recursive inheritance detected while looking for method '%s' in package '%s'

(F) More than 100 levels of inheritance were encountered while a method was invoked. This probably indicates an unintended loop in your inheritance hierarchy.

Reference found where even-sized list expected

(W misc) You gave a single reference when Perl was expecting a list with an even number of elements (for assignment to a hash). This usually means that you used the anonymous hash constructor when you meant to use parens. In any case, a hash requires key/value pairs:

%hash = { one => 1, two => 2, };    # WRONG
%hash = [ qw( an anon array /)];    # WRONG
%hash = ( one => 1, two => 2, );    # right
%hash = qw( one 1 two 2 );          # also fine

Reference is already weak

(W misc) You have attempted to weaken a reference that is already weak. Doing so has no effect.

Reference miscount in sv_replace()

(W internal) The internal sv_replace function was handed a new SV with a reference count of other than 1.

regexp *+ operand could be empty

(F) The part of the regexp subject to either the * or + quantifier could match an empty string.

regexp memory corruption

(P) The regular expression engine got confused by what the regular expression compiler gave it.

regexp out of space

(P) This is a "can't happen" error, because safemalloc should have caught it earlier.

Reversed %s= operator

(W syntax) You wrote your assignment operator backward. The = must always come last, to avoid ambiguity with subsequent unary operators.

Runaway format

(F) Your format contained the ~~ repeat-until-blank sequence, but it produced 200 lines at once, and the 200th line looked exactly like the 199th line. Apparently, you didn't arrange for the arguments to exhaust themselves either by using ^ instead of @ (for scalar variables) or by shifting or popping (for array variables).

Scalar value @%s[%s] better written as $%s[%s]

(W syntax) You've used an array slice (indicated by @) to select a single element of an array. Generally, it's better to ask for a scalar value (indicated by $). The difference is that $foo[&bar] always behaves like a scalar, both when assigning to it and when evaluating its argument, while @foo[&bar] behaves like a list when you assign to it and provides a list context to its subscript, which can do weird things if you're expecting only one subscript.

On the other hand, if you were actually hoping to treat the array element as a list, you need to look into how references work, because Perl will not magically convert between scalars and lists for you.

Scalar value @%s{%s} better written as $%s{%s}

(W syntax) You've used a hash slice (indicated by @) to select a single element of a hash. Generally, it's better to ask for a scalar value (indicated by $). The difference is that $foo{&bar} always behaves like a scalar, both when assigning to it and when evaluating its argument, while @foo{&bar} behaves like a list when you assign to it, and provides a list context to its subscript, which can do weird things if you're expecting only one subscript.

On the other hand, if you were actually hoping to treat the hash element as a list, you need to look into how references work, because Perl will not magically convert between scalars and lists for you.

Script is not setuid/setgid in suidperl

(F) Oddly, the suidperl program was invoked on a script without a setuid or setgid bit set. This doesn't make much sense.

Search pattern not terminated

(F) The lexer couldn't find the final delimiter of a // or m{} construct. Remember that bracketing delimiters count nesting levels. Omitting the leading $ from a variable $m may cause this error.

%s seek() on unopened file

(W unopened) You tried to use the seek or sysseek function on a filehandle that either was never opened or has since been closed.

select not implemented

(F) This machine doesn't implement the select system call.

sem%s not implemented

(F) You don't have System V semaphore IPC on your system.

semi-panic: attempt to dup freed string

(S internal) The internal newSVsv routine was called to duplicate a scalar that had previously been marked as free.

Semicolon seems to be missing

(W semicolon) A nearby syntax error was probably caused by a missing semicolon, or possibly some other missing operator, such as a comma.

send() on closed socket %s

(W closed) The socket you're sending to got itself closed sometime before now. Check your logic flow.

Sequence (? incomplete

(F) A regular expression ended with an incomplete extension (?.

Sequence (?#... not terminated

(F) A regular expression comment must be terminated by a closing parenthesis. Embedded parentheses aren't allowed.

Sequence (?%s...) not implemented

(F) A proposed regular expression extension has reserved the character but has not yet been written.

Sequence (?%s...) not recognized

(F) You used a regular expression extension that doesn't make sense.

Server error

This is the error message generally seen in a browser window when you try to run a CGI program (including SSI) over the web. The actual error text varies widely from server to server. The most frequently seen variants are "500 Server error", "Method(something)not permitted", "Document contains no data", "Premature end of script headers", and "Did not produce a valid header".

This is a CGI error, not a Perl error.

You need to make sure your script is executable, is accessible by the user CGI is running the script under (which is probably not the user account you tested it under), does not rely on any environment variables (like PATH) from the user it isn't running under, and isn't in a location where the CGI server can't find it, basically, more or less. Please see the following for more information:

http://www.perl.com/CPAN/doc/FAQs/cgi/idiots-guide.html
http://www.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html
ftp://rtfm.mit.edu/pub/usenet/news.answers/www/cgi-faq
http://hoohoo.ncsa.uiuc.edu/cgi/interface.html
http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html

You should also look at the Perl FAQ.

setegid() not implemented

(F) You tried to assign to $), but your operating system doesn't support the setegid system call (or equivalent), or at least Configure didn't think so.

seteuid() not implemented

(F) You tried to assign to $>, but your operating system doesn't support the seteuid system call (or equivalent), or at least Configure didn't think so.

setpgrp can't take arguments

(F) Your system has the setpgrp from BSD 4.2, which takes no arguments, unlike POSIX setpgid, which takes a process ID and process group ID.

setrgid() not implemented

(F) You tried to assign to $(, but your operating system doesn't support the setrgid system call (or equivalent), or at least Configure didn't think so.

setruid() not implemented

(F) You tried to assign to $<, but your operating system doesn't support the setruid system call (or equivalent), or at least Configure didn't think so.

setsockopt() on closed socket %s

(W closed) You tried to set a socket option on a closed socket. Did you forget to check the return value of your socket call?

Setuid/gid script is writable by world

(F) The setuid emulator won't run a script that is writable by the world, because the world might have written on it already.

shm%s not implemented

(F) You don't have System V shared memory IPC on your system.

shutdown() on closed socket %s

(W closed) You tried to do a shutdown on a closed socket. Seems a bit superfluous.

SIG%s handler "%s" not defined

(W signal) The signal handler named in %SIG doesn't, in fact, exist. Perhaps you put it into the wrong package?

sort is now a reserved word

(F) An ancient error message that almost nobody ever runs into anymore. But before sort was a keyword, people sometimes used it as a filehandle.

Sort subroutine didn't return a numeric value

(F) A sort comparison routine must return a number. You probably blew it by not using <=> or cmp, or by not using them correctly.

Sort subroutine didn't return single value

(F) A sort comparison subroutine cannot return a list value with more or less than one element.

Split loop

(P) The split was looping infinitely. (Obviously, a split shouldn't iterate more times than there are characters of input, which is what happened.)

Stat on unopened file >%s>

(W unopened) You tried to use the stat function (or an equivalent file test) on a filehandle that either was never opened or has since been closed.

Statement unlikely to be reached

(W exec) You did an exec with some statement after it other than a die. This is almost always an error, because exec never returns unless there was a failure. You probably wanted to use system instead, which does return. To suppress this warning, put the exec in a block by itself.

Strange *+?{} on zero-length expression

(W regexp) You applied a regular expression quantifier in a place where it makes no sense, such as on a zero-width assertion. Try putting the quantifier inside the assertion instead. For example, the way to match abc provided that it is followed by three repetitions of xyz is /abc(?=(?:xyz){3})/, not /abc(?=xyz){3}/.

Stub found while resolving method `%s' overloading `%s' in package `%s'

(P) Overloading resolution over @ISA tree may be broken by importation stubs. Stubs should never be implicitly created, but explicit calls to can may break this.

Subroutine %s redefined

(W redefine) You redefined a subroutine. To suppress this warning, say:

{
    no warnings;
    eval "sub name { ... }";
}

Substitution loop

(P) The substitution was looping infinitely. (Obviously, a substitution shouldn't iterate more times than there are characters of input, which is what happened.)

Substitution pattern not terminated

(F) The lexer couldn't find the interior delimiter of an s/// or s{}{} construct. Remember that bracketing delimiters count nesting levels. Omitting the leading $ from variable $s may cause this error.

Substitution replacement not terminated

(F) The lexer couldn't find the final delimiter of an s/// or s{}{} construct. Remember that bracketing delimiters count nesting levels. Omitting the leading $ from variable $s may cause this error.

substr outside of string

(W substr|F) You tried to reference a substr that pointed outside of a string. That is, the absolute value of the offset was larger than the length of the string. This warning is fatal if substr is used in an lvalue context (as the lefthand side of an assignment or as a subroutine argument, for example).

suidperl is no longer needed since %s

(F) Your Perl was compiled with -DSETUID_SCRIPTS_ARE_SECURE_NOW, but a version of the setuid emulator somehow got run anyway.

switching effective %s is not implemented

(F) While under the use filetest pragma, we cannot switch the real and effective UIDs or GIDs.

syntax error

(F) This message probably means you had a syntax error. Common reasons include:

syntax error at line %d: `%s' unexpected

(A) You've accidentally run your script through the Bourne shell instead of Perl. Check the #! line, or manually feed your script into Perl yourself.

System V %s is not implemented on this machine

(F) You tried to do something with a function beginning with sem, shm, or msg but System V IPC is not implemented in your machine. (In some machines, the functionality can exist but may be unconfigured.)

syswrite() on closed filehandle %s

(W closed) The filehandle you're writing to got itself closed sometime before now. Check your logic flow.

Target of goto is too deeply nested

(F) You tried to use goto to reach a label that was too deeply nested for Perl to reach. Perl is doing you a favor by refusing.

tell() on unopened file

(W unopened) You tried to use the tell function on a filehandle that either was never opened or has since been closed.

Test on unopened file %s

(W unopened) You tried to invoke a file test operator on a filehandle that isn't open. Check your logic.

That use of $[ is unsupported

(F) Assignment to $[ is now strictly circumscribed and interpreted as a compiler directive. You may say only one of:

$[ = 0;
$[ = 1;
...
local $[ = 0;
local $[ = 1;
...
This is to prevent the problem of one module inadvertently changing the array base out from under another module.

The %s function is unimplemented

The function indicated isn't implemented on this architecture, according to the probings of Configure.

The crypt() function is unimplemented due to excessive paranoia

(F) Configure couldn't find the crypt function on your machine, probably because your vendor didn't supply it, probably because they think the U.S. government thinks it's a secret or at least will continue to pretend that it is.

The stat preceding -l _ wasn't an lstat

(F) It makes no sense to test the current stat buffer for symbolic linkhood if the last stat that wrote to the stat buffer already went past the symlink to get to the real file. Use an actual filename instead.

This Perl can't reset CRTL environ elements (%s)
This Perl can't set CRTL environ elements (%s=%s)

(W internal) These are warnings peculiar to VMS. You tried to change or delete an element of the CRTL's internal environ array, but your copy of Perl wasn't built with a CRTL that contained the internal setenv function. You'll need to rebuild Perl with a CRTL that does, or redefine PERL_ENV_TABLES (see perlvms(1)) so that the environ array isn't the target of the change to %ENV that produced the warning.

times not implemented

(F) Your version of the C library apparently doesn't do times. I suspect you're not running on Unix.

Too few args to syscall

(F) There has to be at least one argument to syscall to specify the system call to call, silly dilly.

Too late for "-T" option

(X) The #! line (or local equivalent) in a Perl script contains the -T option, but Perl was not invoked with -T in its command line. This is an error because by the time Perl discovers a -T in a script, it's too late to properly taint everything from the environment. So Perl gives up.

If the Perl script is being executed as a command using the #! mechanism (or its local equivalent), this error can usually be fixed by editing the #! line so that the -T option is a part of Perl's first argument: e.g., change perl -n -T to perl -T -n.

If the Perl script is being executed as perl scriptname, then the -T option must appear on the command line: perl -T scriptname.

Too late for "-%s" option

(X) The #! line (or local equivalent) in a Perl script contains the -M or -m option. This is an error because -M and -m options are not intended for use inside scripts. Use a use declaration instead.

Too late to run %s block

(W void) A CHECK or INIT block is being defined during run time proper, when the opportunity to run them has already passed. Perhaps you are loading a file with require or do when you should be using use instead. Or perhaps you should put the require or do inside a BEGIN block.

Too many ('s
Too many )'s

(A) You've accidentally run your script through csh instead of Perl. Check the #! line, or manually feed your script into Perl yourself.

Too many args to syscall

(F) Perl supports a maximum of only 14 arguments to syscall.

Too many arguments for %s

(F) The function requires fewer arguments than you specified.

trailing \ in regexp

(F) The regular expression ends with an unbackslashed backslash. Backslash it.

Transliteration pattern not terminated

(F) The lexer couldn't find the interior delimiter of a tr/// or tr[][] or y/// or y[][] construct. Omitting the leading $ from variables $tr or $y may cause this error.

Transliteration replacement not terminated

(F) The lexer couldn't find the final delimiter of a tr/// or tr[][] construct.

truncate not implemented

(F) Your machine doesn't implement a file truncation mechanism that Configure knows about.

Type of arg %d to %s must be %s (not %s)

(F) This function requires the argument in that position to be of a certain type. Arrays must be @NAME or @{EXPR}. Hashes must be %NAME or %{EXPR}. No implicit dereferencing is allowed--use the {EXPR} form as an explicit dereference.

umask: argument is missing initial 0

(W umask) A umask of 222 is incorrect. It should be 0222 because octal literals always start with 0 in Perl, as in C.

umask not implemented

(F) Your machine doesn't implement the umask function, and you tried to use it to restrict permissions for yourself (EXPR & 0700).

Unable to create sub named "%s"

(F) You attempted to create or access a subroutine with an illegal name.

Unbalanced context: %d more PUSHes than POPs

(W internal) The exit code detected an internal inconsistency in how many execution contexts were entered and left.

Unbalanced saves: %d more saves than restores

(W internal) The exit code detected an internal inconsistency in how many values were temporarily localized.

Unbalanced scopes: %d more ENTERs than LEAVEs

(W internal) The exit code detected an internal inconsistency in how many blocks were entered and left.

Unbalanced tmps: %d more allocs than frees

(W internal) The exit code detected an internal inconsistency in how many mortal scalars were allocated and freed.

Undefined format "%s" called

(F) The format indicated doesn't seem to exist. Perhaps it's really in another package?

Undefined sort subroutine "%s" called

(F) The sort comparison routine specified doesn't seem to exist. Perhaps it's in a different package?

Undefined subroutine &%s called

(F) The subroutine indicated hasn't been defined, or if it was, it has since been undefined.

Undefined subroutine called

(F) The anonymous subroutine you're trying to call hasn't been defined, or if it was, it has since been undefined.

Undefined subroutine in sort

(F) The sort comparison routine specified is declared but doesn't seem to have been defined yet.

Undefined top format "%s" called

(F) The format indicated doesn't seem to exist. Perhaps it's really in another package?

Undefined value assigned to typeglob

(W misc) An undefined value was assigned to a typeglob, such as *foo = undef. This does nothing. It's possible that you really mean undef *foo.

unexec of %s into %s failed!

(F) The unexec routine failed for some reason. See your local FSF representative, who probably put it there in the first place.

Unknown BYTEORDER

(F) There are no byte-swapping functions for a machine with this byte order.

Unknown open() mode '%s'

(F) The second argument of three-argument open is not in the list of valid modes: <, >, >>, +<, +>, +>>, -|, |-.

Unknown process %x sent message to prime_env_iter: %s

(P) This is an error peculiar to VMS. Perl was reading values for %ENV before iterating over it, and someone else stuck a message in the stream of data Perl expected. Someone's very confused, or perhaps trying to subvert Perl's population of %ENV for nefarious purposes.

unmatched () in regexp

(F) Unbackslashed parentheses must always be balanced in regular expressions. If you're a vi user, the % key is valuable for finding the matching parenthesis.

Unmatched right %s bracket

(F) The lexer counted more closing curly or square brackets than opening ones, so you're probably missing a matching opening bracket. As a general rule, you'll find the missing one (so to speak) near the place you were last editing.

unmatched [] in regexp

(F) The brackets around a character class must match. If you wish to include a closing bracket in a character class, backslash it or put it first.

Unquoted string "%s" may clash with future reserved word

(W reserved) You used a bareword that might someday be claimed as a reserved word. It's best to put such a word in quotes, or capitalize it somehow, or insert an underbar into it. You might also declare it as a subroutine.

Unrecognized character %s

(F) The Perl parser has no idea what to do with the specified character in your Perl script (or eval). Perhaps you tried to run a compressed script, a binary program, or a directory as a Perl program.

Unrecognized escape \\%c passed through

(W misc) You used a backslash-character combination that is not recognized by Perl.

Unrecognized signal name "%s"

(F) You specified a signal name to the kill function that was not recognized. Say kill -l in your shell to see the valid signal names on your system.

Unrecognized switch: -%s (-h will show valid options)

(F) You specified an illegal option to Perl. Don't do that. (If you think you didn't do that, check the #! line to see if it's supplying the bad switch on your behalf.)

Unsuccessful %s on filename containing newline

(W newline) A file operation was attempted on a filename, and that operation failed, probably because the filename contained a newline, probably because you forgot to chop or chomp it off.

Unsupported directory function "%s" called

(F) Your machine doesn't support opendir and readdir.

Unsupported function fork

(F) Your version of executable does not support forking.

Note that under some systems, like OS/2, there may be different flavors of Perl executables, some of which may support fork, some not. Try changing the name you call Perl by to perl_, perl__, and so on.

Unsupported function %s

(F) This machine doesn't implement the indicated function, apparently. At least, Configure doesn't think so.

Unsupported socket function "%s" called

(F) Your machine doesn't support the Berkeley socket mechanism, or at least that's what Configure thought.

Unterminated <> operator

(F) The lexer saw a left angle bracket in a place where it was expecting a term, so it's looking for the corresponding right angle bracket and not finding it. Chances are you left some needed parentheses out earlier in the line, and you really meant a < symbol.

Unterminated attribute parameter in attribute list

(F) The lexer saw an opening (left) parenthesis character while parsing an attribute list, but the matching closing (right) parenthesis character was not found. You may need to add (or remove) a backslash character to get your parentheses to balance.

Unterminated attribute list

(F) The lexer found something other than a simple identifier at the start of an attribute, and it wasn't a semicolon or the start of a block. Perhaps you terminated the parameter list of the previous attribute too soon.

Use of $# is deprecated

(D deprecated) This was an ill-advised attempt to emulate a poorly defined awk feature. Use an explicit printf or sprintf instead.

Use of $* is deprecated

(D deprecated) This variable magically activated multiline pattern matching, both for you and for any luckless subroutine that you happen to call. You should use the //m and //s modifiers now to do that without the dangerous action-at-a-distance effects of $*.

Use of %s in printf format not supported

(F) You attempted to use a feature of printf that is accessible from only C. This usually means there's a better way to do it in Perl.

Use of bare << to mean <<"" is deprecated

(D deprecated) You are now encouraged to use the explicitly quoted form if you wish to use an empty line as the terminator of the here document.

Use of implicit split to @_ is deprecated

(D deprecated) You make a lot of work for the compiler when you clobber a subroutine's argument list, so it's better to assign the results of a split explicitly to an array (or list).

Use of inherited AUTOLOAD for non-method %s() is deprecated

(D deprecated) As an (ahem) accidental feature, AUTOLOAD subroutines were looked up as methods (using the @ISA hierarchy) even when the subroutines to be autoloaded were called as plain functions (e.g., Foo::bar()), not as methods (e.g., Foo->bar() or $obj->bar()).

This bug was rectified in Perl 5.005, which used method lookup only for methods' AUTOLOADs. However, a significant base of existing code may be using the old behavior. So, as an interim step, Perl 5.004 issued this optional warning when nonmethods used inherited AUTOLOADs.

The simple rule is this: inheritance will not work when autoloading nonmethods. The simple fix for old code is this: in any module that used to depend on inheriting AUTOLOAD for nonmethods from a base class named BaseClass, execute *AUTOLOAD = \&BaseClass::AUTOLOAD during startup.

In code that currently says use AutoLoader; @ISA = qw(AutoLoader);, you should remove AutoLoader from @ISA and change use AutoLoader; to use AutoLoader 'AUTOLOAD';.

Use of reserved word "%s" is deprecated

(D deprecated) The indicated bareword is a reserved word. Future versions of Perl may use it as a keyword, so you're better off either explicitly quoting the word in a manner appropriate for its context of use, or using a different name altogether. The warning can be suppressed for subroutine names by either adding an & prefix or using a package qualifier, e.g., &our() or Foo::our().

Use of %s is deprecated

(D deprecated) The construct indicated is no longer recommended, generally because there's a better way to do it, and also because the old way has bad side effects.

Use of uninitialized value%s

(W uninitialized) An undefined value was used as if it were already defined. It was interpreted as a "" or a 0, but maybe it was a mistake. To suppress this warning assign a defined value to your variables.

Useless use of "re" pragma

(W) You did a use re without any arguments. That isn't very useful.

Useless use of %s in void context

(W void) You did something without a side effect in a context that does nothing with the return value, such as a statement that doesn't return a value from a block or the left side of a scalar comma operator. For example, you'd get this if you mixed up your C precedence with Python precedence and said:

$one, $two = 1, 2;
when you meant to say:
($one, $two) = (1, 2);
Another common error is using ordinary parentheses to construct a list reference when you should be using square or curly brackets, for example, if you say:
$array = (1,2);
when you should have said:
$array = [1,2];
The square brackets explicitly turn a list value into a scalar value, while parentheses do not. So when a parenthesized list is evaluated in a scalar context, the comma is treated like C's comma operator, which throws away the left argument, which is not what you want.

untie attempted while %d inner references still exist

(W untie) A copy of the object returned from tie (or tied) was still valid when untie was called.

Value of %s can be "0"; test with defined()

(W misc) In a conditional expression, you used <HANDLE>, <*> (glob), each, or readdir as a Boolean value. Each of these constructs can return a value of "0"; that would make the conditional expression false, which is probably not what you intended. When using these constructs in conditional expressions, test their values with the defined operator.

Value of CLI symbol "%s" too long

(W misc) This is a warning peculiar to VMS. Perl tried to read the value of an %ENV element from a CLI symbol table and found a resultant string longer than 1,024 characters. The return value has been truncated to 1,024 characters.

Variable "%s" is not imported%s

(F) While use strict in effect, you referred to a global variable that you apparently thought was imported from another module, because something else of the same name (usually a subroutine) is exported by that module. It usually means you put the wrong funny character on the front of your variable.

Variable "%s" may be unavailable

(W closure) An inner (nested) anonymous subroutine is inside a named subroutine, and outside that is another subroutine; and the anonymous (innermost) subroutine is referencing a lexical variable defined in the outermost subroutine. For example:

sub outermost { my $a; sub middle { sub { $a } } }
If the anonymous subroutine is called or referenced (directly or indirectly) from the outermost subroutine, it will share the variable as you would expect. But if the anonymous subroutine is called or referenced when the outermost subroutine is not active, it will see the value of the shared variable as it was before and during the first call to the outermost subroutine, which is probably not what you want.

In these circumstances, it is usually best to make the middle subroutine anonymous, using the sub {} syntax. Perl has specific support for shared variables in nested anonymous subroutines; a named subroutine in between interferes with this feature.

Variable "%s" will not stay shared

(W closure) An inner (nested) named subroutine is referencing a lexical variable defined in an outer subroutine.

When the inner subroutine is called, it will probably see the value of the outer subroutine's variable as it was before and during the first call to the outer subroutine; in this case, after the first call to the outer subroutine is complete, the inner and outer subroutines will no longer share a common value for the variable. In other words, the variable will no longer be shared.

Furthermore, if the outer subroutine is anonymous and references a lexical variable outside itself, then the outer and inner subroutines will never share the given variable.

This problem can usually be solved by making the inner subroutine anonymous, using the sub {} syntax. When inner anonymous subs that reference variables in outer subroutines are called or referenced, they are automatically rebound to the current values of such variables.

Variable syntax

(A) You've accidentally run your script through csh instead of Perl. Check the #! line, or manually feed your script into Perl yourself.

Version number must be a constant number

(P) The attempt to translate a use Module n.n LIST statement into its equivalent BEGIN block found an internal inconsistency with the version number.

perl: warning: Setting locale failed.

(S) The whole warning message will look something like:

perl: warning: Setting locale failed.
    perl: warning: Please check that your locale settings:
            LC_ALL = "En_US",
            LANG = (unset)
        are supported and installed on your system.
    perl: warning: Falling back to the standard locale ("C").
(Which locale settings failed will vary.) This error means that Perl detected that you or your system administrator have set up the so-called variable system but Perl could not use those settings. This was not dead serious, fortunately: there is a "default locale" called "C" that Perl can and will use, so the script will be run. Before you really fix the problem, however, you will get the same error message each time you run Perl. How to really fix the problem can be found in perllocale(1), under the section "Locale Problems".

Warning: something's wrong

(W) You passed warn an empty string (the equivalent of warn ""), or you called it with no arguments and $_ was empty.

Warning: unable to close filehandle %s properly

(S) The implicit close done by an open got an error indication on the close. This usually indicates your filesystem ran out of disk space.

Warning: Use of "%s" without parentheses is ambiguous

(S ambiguous) You wrote a unary operator followed by something that looks like a binary operator but could also be interpreted as a term or unary operator. For instance, if you know that the rand function has a default argument of 1.0, and you write:

rand + 5;
you may think you wrote the same thing as:
rand() + 5;
but in actual fact, you got:
rand(+5);
So use parentheses to say what you really mean.

write() on closed filehandle %s

(W closed) The filehandle you're writing to got itself closed sometime before now. Check your logic flow.

X outside of string

(F) You had a pack template that specified a relative position before the beginning of the string being unpacked.

x outside of string

(F) You had a pack template that specified a relative position after the end of the string being unpacked.

Xsub "%s" called in sort

(F) The use of an external subroutine as a sort comparison is not yet supported.

Xsub called in sort

(F) The use of an external subroutine as a sort comparison is not yet supported.

You can't use -l on a filehandle

(F) A filehandle represents an opened file, and when you opened the file, it already went past any symlink you are presumably trying to look for. Use a filename instead.

YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!

(F) And you probably never will, because you probably don't have the sources to your kernel, and your vendor probably doesn't give a rip about what you want. Your best bet is to put a setuid C wrapper around your script with the wrapsuid script in the eg directory of the Perl distribution.

You need to quote "%s"

(W syntax) You assigned a bareword as a signal handler name. Unfortunately, you already have a subroutine of that name declared, which means that Perl 5 will try to call the subroutine when the assignment is executed, which is probably not what you want. (If it is what you want, put an & in front.)

Previous | Home | Next
32.47. User::pwent | Book Index | Glossary
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Glossary (Programming Perl)

 Programming Perl
Previous

Glossary

accessor methods

A method used to indirectly inspect or update an object's state (its instance variables).

actual arguments

The scalar values that you supply to a function or subroutine when you call it. For instance, when you call power("puff"), the string "puff" is the actual argument. See also argument and formal arguments.

address operator

Some languages work directly with the memory addresses of values, but this can be like playing with fire. Perl provides a set of asbestos gloves for handling all memory management. The closest to an address operator in Perl is the backslash operator, but it gives you a hard reference, which is much safer than a memory address.

algorithm

A well-defined sequence of steps, clearly enough explained that even a computer could do them.

alias

A nickname for something, which behaves in all ways as though you'd used the original name instead of the nickname. Temporary aliases are implicitly created in the loop variable for foreach loops, in the $_ variable for map or grep operators, in $a and $b during sort's comparison function, and in each element of @_ for the actual arguments of a subroutine call. Permanent aliases are explicitly created in packages by importing symbols or by assignment to typeglobs. Lexically scoped aliases for package variables are explicitly created by the our declaration.

alternatives

A list of possible choices from which you may select only one, as in "Would you like door A, B, or C?" Alternatives in regular expressions are separated with a single vertical bar: |. Alternatives in normal Perl expressions are separated with a double vertical bar: ||. Logical alternatives in Boolean expressions are separated with either || or or.

anonymous

Used to describe a referent that is not directly accessible through a named variable. Such a referent must be indirectly accessible through at least one hard reference. When the last hard reference goes away, the anonymous referent is destroyed without pity.

architecture

The kind of compluter you're working on, where one "kind" of computer means all those computers sharing a compatible machine language. Since Perl programs are (typically) simple text files, not executable images, a Perl program is much less sensitive to the architecture it's running on than programs in other languages, such as C, that are compiled into machine code. See also platform and operating system.

argument

A piece of data supplied to a program, subroutine, function, or method to tell it what it's supposed to do. Also called a "parameter".

ARGV

The name of the array containing the argumentvector from the command line. If you use the empty <> operator, ARGV is the name of both the filehandle used to traverse the arguments and the scalar containing the name of the current input file.

arithmetical operator

A symbol such as + or / that tells Perl to do the arithmetic you were supposed to learn in grade school.

array

An ordered sequence of values, stored such that you can easily access any of the values using an integer subscript that specifies the value's offset in the sequence.

array context

An archaic expression for what is more correctly referred to as list context.

ASCII

The American Standard Code for Information Interchange (a 7-bit character set adequate only for poorly representing English text). Often used loosely to describe the lowest 128 values of the various ISO-8859-X character sets, a bunch of mutually incompatible 8-bit codes best described as half ASCII. See also Unicode.

assertion

A component of a regular expression that must be true for the pattern to match but does not necessarily match any characters itself. Often used specifically to mean a zero-width assertion.

assignment

An operator whose assigned mission in life is to change the value of a variable.

assignment operator

Either a regular assignment, or a compound operator composed of an ordinary assignment and some other operator, that changes the value of a variable in place, that is, relative to its old value. For example, $a += 2 adds 2 to $a.

associative array

See hash. Please.

associativity

Determines whether you do the left operator first or the right operator first when you have "A operator B operator C" and the two operators are of the same precedence. Operators like + are left associative, while operators like ** are right associative. See Chapter 3, "Unary and Binary Operators", for a list of operators and their associativity.

asynchronous

Said of events or activities whose relative temporal ordering is indeterminate because too many things are going on at once. Hence, an asynchronous event is one you didn't know when to expect.

atom

A regular expression component potentially matching a substring containing one or more characters and treated as an indivisible syntactic unit by any following quantifier. (Contrast with an assertion that matches something of zero width and may not be quantified.)

atomic operation

When Democritus gave the word "atom" to the indivisible bits of matter, he meant literally something that could not be cut: a- (not) + tomos (cuttable). An atomic operation is an action that can't be interrupted, not one forbidden in a nuclear-free zone.

attribute

A new feature that allows the declaration of variables and subroutines with modifiers as in sub foo : locked method. Also, another name for an instance variable of an object.

autogeneration

A feature of operator overloading of objects, whereby the behavior of certain operators can be reasonably deduced using more fundamental operators. This assumes that the overloaded operators will often have the same relationships as the regular operators. See Chapter 13, "Overloading".

autoincrement

To add one to something automatically, hence the name of the the ++ operator. To instead subtract one from something automatically is known as an "autodecrement".

autoload

To load on demand. (Also called "lazy" loading.) Specifically, to call an AUTOLOAD subroutine on behalf of an undefined subroutine.

autosplit

To split a string automatically, as the -a switch does when running under -p or -n in order to emulate awk. (See also the AutoSplit module, which has nothing to do with the -a switch, but a lot to do with autoloading.)

autovivification

A Greco-Roman word meaning "to bring oneself to life". In Perl, storage locations (lvalues) spontaneously generate themselves as needed, including the creation of any hard reference values to point to the next level of storage. The assignment $a[5][5][5][5][5] = "quintet" potentially creates five scalar storage locations, plus four references (in the first four scalar locations) pointing to four new anonymous arrays (to hold the last four scalar locations). But the point of autovivification is that you don't have to worry about it.

AV

Short for "array value", which refers to one of Perl's internal data types that holds an array. The AV type is a subclass of SV.

awk

Descriptive editing term--short for "awkward". Also coincidentally refers to a venerable text-processing language from which Perl derived some of its high-level ideas.

backreference

A substring captured by a subpattern within unadorned parentheses in a regex. Backslashed decimal numbers (\1, \2, etc.) later in the same pattern refer back to the corresponding subpattern in the current match. Outside the pattern, the numbered variables ($1, $2, etc.) continue to refer to these same values, as long as the pattern was the last successful match of the current dynamic scope.

backtracking

The practice of saying, "If I had to do it all over, I'd do it differently," and then actually going back and doing it all over differently. Mathematically speaking, it's returning from an unsuccessful recursion on a tree of possibilities. Perl backtracks when it attempts to match patterns with a regular expression, and its earlier attempts don't pan out. See "The Little Engine That /Could(n't)?/" in Chapter 5, "Pattern Matching".

backward compatibility

Means you can still run your old program because we didn't break any of the features or bugs it was relying on.

bareword

A word sufficiently ambiguous to be deemed illegal under use strict 'subs'. In the absence of that stricture, a bareword is treated as if quotes were around it.

base class

A generic object type; that is, a class from which other, more specific classes are derived genetically by inheritance. Also called a "superclass" by people who respect their ancestors.

big-endian

From Swift: someone who eats eggs big end first. Also used of computers that store the most significant byte of a word at a lower byte address than the least significant byte. Often considered superior to little-endian machines. See also little-endian.

binary

Having to do with numbers represented in base 2. That means there's basically two numbers, 0 and 1. Also used to describe a "non-text file", presumably because such a file makes full use of all the binary bits in its bytes. With the advent of Unicode, this distinction, already suspect, loses even more of its meaning.

binary operator

An operator that takes two operands.

bind

To assign a specific network address to a socket.

bit

An integer in the range from 0 to 1, inclusive. The smallest possible unit of information storage. An eighth of a byte or of a dollar. (The term "Pieces of Eight" comes from being able to split the old Spanish dollar into 8 bits, each of which still counted for money. That's why a 25-cent piece today is still "two bits".)

bit shift

The movement of bits left or right in a computer word, which has the effect of multiplying or dividing by a power of 2.

bit string

A sequence of bits that is actually being thought of as a sequence of bits, for once.

bless

In corporate life, to grant official approval to a thing, as in, "The VP of Engineering has blessed our WebCruncher project." Similarly in Perl, to grant official approval to a referent so that it can function as an object, such as a WebCruncher object. See the bless function in Chapter 29, "Functions".

block

What a process does when it has to wait for something: "My process blocked waiting for the disk." As an unrelated noun, it refers to a large chunk of data, of a size that the operating system likes to deal with (normally a power of two such as 512 or 8192). Typically refers to a chunk of data that's coming from or going to a disk file.

BLOCK

A syntactic construct consisting of a sequence of Perl statements that is delimited by braces. The if and while statements are defined in terms of BLOCKs, for instance. Sometimes we also say "block" to mean a lexical scope; that is, a sequence of statements that act like a BLOCK, such as within an eval or a file, even though the statements aren't delimited by braces.

block buffering

A method of making input and output efficient by passing one block at a time. By default, Perl does block buffering to disk files. See buffer and command buffering.

Boolean

A value that is either true or false.

Boolean context

A special kind of scalar context used in conditionals to decide whether the scalar value returned by an expression is true or false. Does not evaluate as either a string or a number. See context.

breakpoint

A spot in your program where you've told the debugger to stop execution so you can poke around and see whether anything is wrong yet.

broadcast

To send a datagram to multiple destinations simultaneously.

BSD

A psychoactive drug, popular in the 80s, probably developed at U. C. Berkeley or thereabouts. Similar in many ways to the prescription-only medication called "System V", but infinitely more useful. (Or, at least, more fun.) The full chemical name is "Berkeley Standard Distribution".

bucket

A location in a hash table containing (potentially) multiple entries whose keys "hash" to the same hash value according to its hash function. (As internal policy, you don't have to worry about it, unless you're into internals, or policy.)

buffer

A temporary holding location for data. Block buffering means that the data is passed on to its destination whenever the buffer is full. Line buffering means that it's passed on whenever a complete line is received. Command buffering means that it's passed every time you do a print command (or equivalent). If your output is unbuffered, the system processes it one byte at a time without the use of a holding area. This can be rather inefficient.

built-in

A function that is predefined in the language. Even when hidden by overriding, you can always get at a built-in function by qualifying its name with the CORE:: pseudo-package.

bundle

A group of related modules on CPAN. (Also, sometimes refers to a group of command-line switches grouped into one switch cluster.)

byte

A piece of data worth eight bits in most places.

bytecode

A pidgin-like language spoken among 'droids when they don't wish to reveal their orientation (see endian). Named after some similar languages spoken (for similar reasons) between compilers and interpreters in the late 20th century. These languages are characterized by representing everything as a non-architecture-dependent sequence of bytes.

C

A language beloved by many for its inside-out type definitions, inscrutable precedence rules, and heavy overloading of the function-call mechanism. (Well, actually, people first switched to C because they found lowercase identifiers easier to read than upper.) Perl is written in C, so it's not surprising that Perl borrowed a few ideas from it.

C preprocessor

The typical C compiler's first pass, which processes lines beginning with # for conditional compilation and macro definition and does various manipulations of the program text based on the current definitions. Also known as cpp(1).

call by reference

An argument-passing mechanism in which the formal arguments refer directly to the actual arguments, and the subroutine can change the actual arguments by changing the formal arguments. That is, the formal argument is an alias for the actual argument. See also call by value.

call by value

An argument-passing mechanism in which the formal arguments refer to a copy of the actual arguments, and the subroutine cannot change the actual arguments by changing the formal arguments. See also call by reference.

callback

A handler that you register with some other part of your program in the hope that the other part of your program will trigger your handler when some event of interest transpires.

canonical

Reduced to a standard form to facilitate comparison.

capturing

The use of parentheses around a subpattern in a regular expression to store the matched substring as a backreference. (Captured strings are also returned as a list in list context.)

character

A small integer representative of a unit of orthography. Historically, characters were usually stored as fixed-width integers (typically in a byte, or maybe two, depending on the character set), but with the advent of UTF-8, characters are often stored in a variable number of bytes depending on the size of the integer that represents the character. Perl manages this transparently for you, for the most part.

character class

A square-bracketed list of characters used in a regular expression to indicate that any character of the set may occur at a given point. Loosely, any predefined set of characters so used.

character property

A predefined character class matchable by the \p metasymbol. Many standard properties are defined for Unicode.

circumfix operator

An operator that surrounds its operand, like the angle operator, or parentheses, or a hug.

class

A user-defined type, implemented in Perl via a package that provides (either directly or by inheritance) methods (that is, subroutines) to handle instances of the class (its objects). See also inheritance.

class method

A method whose invocant is a package name, not an object reference. A method associated with the class as a whole.

client

In networking, a process that initiates contact with a server process in order to exchange data and perhaps receive a service.

cloister

A cluster used to restrict the scope of a regular expression modifier.

closure

An anonymous subroutine that, when a reference to it is generated at run time, keeps track of the identities of externally visible lexical variables even after those lexical variables have supposedly gone out of scope. They're called "closures" because this sort of behavior gives mathematicians a sense of closure.

cluster

A parenthesized subpattern used to group parts of a regular expression into a single atom.

CODE

The word returned by the ref function when you apply it to a reference to a subroutine. See also CV.

code generator

A system that writes code for you in a low-level language, such as code to implement the backend of a compiler. See program generator.

code subpattern

A regular expression subpattern whose real purpose is to execute some Perl code, for example, the (?{...}) and (??{...}) subpatterns.

collating sequence

The order into which characters sort. This is used by string comparison routines to decide, for example, where in this glossary to put "collating sequence".

command

In shell programming, the syntactic combination of a program name and its arguments. More loosely, anything you type to a shell (a command interpreter) that starts it doing something. Even more loosely, a Perl statement, which might start with a label and typically ends with a semicolon.

command buffering

A mechanism in Perl that lets you store up the output of each Perl command and then flush it out as a single request to the operating system. It's enabled by setting the $| ($AUTOFLUSH) variable to a true value. It's used when you don't want data sitting around not going where it's supposed to, which may happen because the default on a file or pipe is to use block buffering.

command name

T he name of the program currently executing, as typed on the command line. In C, the command name is passed to the program as the first command-line argument. In Perl, it comes in separately as $0.

command-line arguments

The values you supply along with a program name when you tell a shell to execute a command. These values are passed to a Perl program through @ARGV.

comment

A remark that doesn't affect the meaning of the program. In Perl, a comment is introduced by a # character and continues to the end of the line.

compilation unit

The file (or string, in the case of eval) that is currently being compiled.

compile phase

Any time before Perl starts running your main program. See also run phase. Compile phase is mostly spent in compile time, but may also be spent in run time when BEGIN blocks, use declarations, or constant subexpressions are being evaluated. The startup and import code of any use declaration is also run during compile phase.

compile time

The time when Perl is trying to make sense of your code, as opposed to when it thinks it knows what your code means and is merely trying to do what it thinks your code says to do, which is run time.

compiler

Strictly speaking, a program that munches up another program and spits out yet another file containing the program in a "more executable" form, typically containing native machine instructions. The perl program is not a compiler by this definition, but it does contain a kind of compiler that takes a program and turns it into a more executable form (syntax trees) within the perl process itself, which the interpreter then interprets. There are, however, extension modules to get Perl to act more like a "real" compiler. See Chapter 18, "Compiling".

composer

A "constructor" for a referent that isn't really an object, like an anonymous array or a hash (or a sonata, for that matter). For example, a pair of braces acts as a composer for a hash, and a pair of brackets acts as a composer for an array. See the section "Creating References" in Chapter 8, "References".

concatenation

The process of gluing one cat's nose to another cat's tail. Also, a similar operation on two strings.

conditional

Something "iffy". See Boolean context.

connection

In telephony, the temporary electrical circuit between the caller's and the callee's phone. In networking, the same kind of temporary circuit between a client and a server.

construct

As a noun, a piece of syntax made up of smaller pieces. As a transitive verb, to create an object using a constructor.

constructor

Any class method, instance method, or subroutine that composes, initializes, blesses, and returns an object. Sometimes we use the term loosely to mean a composer.

context

The surroundings, or environment. The context given by the surrounding code determines what kind of data a particular expression is expected to return. The three primary contexts are list context, scalar context, and void context. Scalar context is sometimes subdivided into Boolean context, numeric context, string context, and void context. There's also a "don't care" context (which is dealt with in Chapter 2, "Bits and Pieces", if you care).

continuation

The treatment of more than one physical line as a single logical line. Makefile lines are continued by putting a backslash before the newline. Mail headers as defined by RFC 822 are continued by putting a space or tab after the newline. In general, lines in Perl do not need any form of continuation mark, because whitespace (including newlines) is gleefully ignored. Usually.

core dump

The corpse of a process, in the form of a file left in the working directory of the process, usually as a result of certain kinds of fatal error.

CPAN

The Comprehensive Perl Archive Network. (See the Preface and Chapter 22, "CPAN", for details.)

cracker

Someone who breaks security on computer systems. A cracker may be a true hacker or only a script kiddie.

current package

The package in which the current statement is compiled. Scan backwards in the text of your program through the current lexical scope or any enclosing lexical scopes till you find a package declaration. That's your current package name.

current working directory

See working directory.

currently selected output channel

The last filehandle that was designated with select(FILEHANDLE); STDOUT, if no filehandle has been selected.

CV

An internal "code value" typedef, holding a subroutine. The CV type is a subclass of SV.

dangling statement

A bare, single statement, without any braces, hanging off an if or while conditional. C allows them. Perl doesn't.

data structure

How your various pieces of data relate to each other and what shape they make when you put them all together, as in a rectangular table or a triangular-shaped tree.

data type

A set of possible values, together with all the operations that know how to deal with those values. For example, a numeric data type has a certain set of numbers that you can work with and various mathematical operations that you can do on the numbers but would make little sense on, say, a string such as "Kilroy". Strings have their own operations, such as concatenation. Compound types made of a number of smaller pieces generally have operations to compose and decompose them, and perhaps to rearrange them. Objects that model things in the real world often have operations that correspond to real activities. For instance, if you model an elevator, your elevator object might have an open_door()method.

datagram

A packet of data, such as a UDP message, that (from the viewpoint of the programs involved) can be sent independently over the network. (In fact, all packets are sent independently at the IP level, but stream protocols such as TCP hide this from your program.)

DBM

Stands for "Data Base Management" routines, a set of routines that emulate an associative array using disk files. The routines use a dynamic hashing scheme to locate any entry with only two disk accesses. DBM files allow a Perl program to keep a persistent hash across multiple invocations. You can tie your hash variables to various DBM implementations--see AnyDBM_File(3) and the entry on DB_File in Chapter 32, "Standard Modules".

declaration

An assertion that states something exists and perhaps describes what it's like, without giving any commitment as to how or where you'll use it. A declaration is like the part of your recipe that says, "two cups flour, one large egg, four or five tadpoles..." See statement for its opposite. Note that some declarations also function as statements. Subroutine declarations also act as definitions if a body is supplied.

decrement

To subtract a value from a variable, as in "decrement $x" (meaning to remove 1 from its value) or "decrement $x by 3".

default

A value chosen for you if you don't supply a value of your own.

defined

Having a meaning. Perl thinks that some of the things people try to do are devoid of meaning, in particular, making use of variables that have never been given a value and performing certain operations on data that isn't there. For example, if you try to read data past the end of a file, Perl will hand you back an undefined value. See also false, and the defined operator in Chapter 29, "Functions".

delimiter

A character or string that sets bounds to an arbitrarily-sized textual object, not to be confused with a separator or terminator. "To delimit" really just means "to surround" or "to enclose" (like these parentheses are doing).

dereference

A fancy computer science term meaning "to follow a reference to what it points to". The "de" part of it refers to the fact that you're taking away one level of indirection.

derived class

A class that defines some of its methods in terms of a more generic class, called a base class. Note that classes aren't classified exclusively into base classes or derived classes: a class can function as both a derived class and a base class simultaneously, which is kind of classy.

descriptor

See file descriptor.

destroy

To deallocate the memory of a referent (first triggering its DESTROY method, if it has one).

destructor

A special method that is called when an object is thinking about destroying itself. A Perl program's DESTROY method doesn't do the actual destruction; Perl just triggers the method in case the class wants to do any associated cleanup.

device

A whiz-bang hardware gizmo (like a disk or tape drive or a modem or a joystick or a mouse) attached to your computer, that the operating system tries to make look like a file (or a bunch of files). Under Unix, these fake files tend to live in the /dev directory.

directive

A pod directive. See Chapter 26, "Plain Old Documentation".

directory

A special file that contains other files. Some operating systems call these "folders", "drawers", or "catalogs".

directory handle

A name that represents a particular instance of opening a directory to read it, until you close it. See the opendir function.

dispatch

To send something to its correct destination. Often used metaphorically to indicate a transfer of programmatic control to a destination selected algorithmically, often by lookup in a table of function references or, in the case of object methods, by traversing the inheritance tree looking for the most specific definition for the method.

distribution

A standard, bundled release of a system of software. The default usage implies source code is included. If that is not the case, it will be called a "binary-only" distribution.

dweomer

An enchantment, illusion, phantasm, or jugglery. Said when Perl's magical dwimmer effects don't do what you expect, but rather seem to be the product of arcane dweomercraft, sorcery, or wonder working. [From Old English]

dwimmer

DWIM is an acronym for "Do What I Mean", the principle that something should just do what you want it to do without an undue amount of fuss. A bit of code that does "dwimming" is a "dwimmer". Dwimming can require a great deal of behind-the-scenes magic, which (if it doesn't stay properly behind the scenes) is called a dweomer instead.

dynamic scoping

Dynamic scoping works over a dynamic scope, making variables visible throughout the rest of the block in which they are first used and in any subroutines that are called by the rest of the block. Dynamically scoped variables can have their values temporarily changed (and implicitly restored later) by a local operator. (Compare lexical scoping.) Used more loosely to mean how a subroutine that is in the middle of calling another subroutine "contains" that subroutine at run time.

eclectic

Derived from many sources. Some would say too many.

element

A basic building block. When you're talking about an array, it's one of the items that make up the array.

embedding

When something is contained in something else, particularly when that might be considered surprising: "I've embedded a complete Perl interpreter in my editor!"

empty subclass test

The notion that an empty derived class should behave exactly like its base class.

en passant

When you change a value as it is being copied. [From French, "in passing", as in the exotic pawn-capturing maneuver in chess.]

encapsulation

The veil of abstraction separating the interface from the implementation (whether enforced or not), which mandates that all access to an object's state be through methods alone.

endian

See little-endian and big-endian.

environment

The collective set of environment variables your process inherits from its parent. Accessed via %ENV.

environment variable

A mechanism by which some high-level agent such as a user can pass its preferences down to its future offspring (child processes, grandchild processes, great-grandchild processes, and so on). Each environment variable is a key/value pair, like one entry in a hash.

EOF

End of File. Sometimes used metaphorically as the terminating string of a here document.

errno

The error number returned by a syscall when it fails. Perl refers to the error by the name $! (or $OS_ERROR if you use the English module).

error

See exception or fatal error.

escape sequence

See metasymbol.

exception

A fancy term for an error. See fatal error.

exception handling

The way a program responds to an error. The exception handling mechanism in Perl is the eval operator.

exec

To throw away the current process's program and replace it with another without exiting the process or relinquishing any resources held (apart from the old memory image).

executable file

A file that is specially marked to tell the operating system that it's okay to run this file as a program. Usually shortened to "executable".

execute

To run a program or subroutine. (Has nothing to do with the kill built-in, unless you're trying to run a signal handler.)

execute bit

The special mark that tells the operating system it can run this program. There are actually three execute bits under Unix, and which bit gets used depends on whether you own the file singularly, collectively, or not at all.

exit status

See status.

export

To make symbols from a module available for import by other modules.

expression

Anything you can legally say in a spot where a value is required. Typically composed of literals, variables, operators, functions, and subroutine calls, not necessarily in that order.

extension

A Perl module that also pulls in compiled C or C++ code. More generally, any experimental option that can be compiled into Perl, such as multithreading.

false

In Perl, any value that would look like "" or "0" if evaluated in a string context. Since undefined values evaluate to "", all undefined values are false, but not all false values are undefined.

FAQ

Frequently Asked Question (although not necessarily frequently answered, especially if the answer appears in the Perl FAQ shipped standard with Perl).

fatal error

An uncaught exception, which causes termination of the process after printing a message on your standard error stream. Errors that happen inside an eval are not fatal. Instead, the eval terminates after placing the exception message in the $@ ($EVAL_ERROR) variable. You can try to provoke a fatal error with the die operator (known as throwing or raising an exception), but this may be caught by a dynamically enclosing eval. If not caught, the die becomes a fatal error.

field

A single piece of numeric or string data that is part of a longer string, record, or line. Variable-width fields are usually split up by separators (so use split to extract the fields), while fixed-width fields are usually at fixed positions (so use unpack). Instance variables are also known as "fields".

FIFO

First In, First Out. See also LIFO. Also, a nickname for a named pipe.

file

A named collection of data, usually stored on disk in a directory in a filesystem. Roughly like a document, if you're into office metaphors. In modern filesystems, you can actually give a file more than one name. Some files have special properties, like directories and devices.

file descriptor

The little number the operating system uses to keep track of which opened file you're talking about. Perl hides the file descriptor inside a standard I/O stream and then attaches the stream to a filehandle.

file test operator

A built-in unary operator that you use to determine whether something is true about a file, such as -o $filename to test whether you're the owner of the file.

fileglob

A "wildcard" match on filenames. See the glob function.

filehandle

An identifier (not necessarily related to the real name of a file) that represents a particular instance of opening a file until you close it. If you're going to open and close several different files in succession, it's fine to open each of them with the same filehandle, so you don't have to write out separate code to process each file.

filename

One name for a file. This name is listed in a directory, and you can use it in an open to tell the operating system exactly which file you want to open, and associate the file with a filehandle which will carry the subsequent identity of that file in your program, until you close it.

filesystem

A set of directories and files residing on a partition of the disk. Sometimes known as a "partition". You can change the file's name or even move a file around from directory to directory within a filesystem without actually moving the file itself, at least under Unix.

filter

A program designed to take a stream of input and transform it into a stream of output.

flag

We tend to avoid this term because it means so many things. It may mean a command-line switch that takes no argument itself (such as Perl's -n and -p flags) or, less frequently, a single-bit indicator (such as the O_CREAT and O_EXCL flags used in sysopen).

floating point

A method of storing numbers in "scientific notation", such that the precision of the number is independent of its magnitude (the decimal point "floats"). Perl does its numeric work with floating-point numbers (sometimes called "floats"), when it can't get away with using integers. Floating-point numbers are mere approximations of real numbers.

flush

The act of emptying a buffer, often before it's full.

FMTEYEWTK

Far More Than Everything You Ever Wanted To Know. An exhaustive treatise on one narrow topic, something of a super-FAQ. See Tom for far more.

fork

To create a child process identical to the parent process at its moment of conception, at least until it gets ideas of its own. A thread with protected memory.

formal arguments

The generic names by which a subroutine knows its arguments. In many languages, formal arguments are always given individual names, but in Perl, the formal arguments are just the elements of an array. The formal arguments to a Perl program are $ARGV[0], $ARGV[1], and so on. Similarly, the formal arguments to a Perl subroutine are $_[0], $_[1], and so on. You may give the arguments individual names by assigning the values to a my list. See also actual arguments.

format

A specification of how many spaces and digits and things to put somewhere so that whatever you're printing comes out nice and pretty.

freely available

Means you don't have to pay money to get it, but the copyright on it may still belong to someone else (like Larry).

freely redistributable

Means you're not in legal trouble if you give a bootleg copy of it to your friends and we find out about it. In fact, we'd rather you gave a copy to all your friends.

freeware

Historically, any software that you give away, particularly if you make the source code available as well. Now often called open source software. Recently there has been a trend to use the term in contradistinction to open source software, to refer only to free software released under the Free Software Foundation's GPL (General Public License), but this is difficult to justify etymologically.

function

Mathematically, a mapping of each of a set of input values to a particular output value. In computers, refers to a subroutine or operator that returns a value. It may or may not have input values (called arguments).

funny character

Someone like Larry, or one of his peculiar friends. Also refers to the strange prefixes that Perl requires as noun markers on its variables.

garbage collection

A misnamed feature--it should be called, "expecting your mother to pick up after you". Strictly speaking, Perl doesn't do this, but it relies on a reference-counting mechanism to keep things tidy. However, we rarely speak strictly and will often refer to the reference-counting scheme as a form of garbage collection. (If it's any comfort, when your interpreter exits, a "real" garbage collector runs to make sure everything is cleaned up if you've been messy with circular references and such.)

GID

Group ID--in Unix, the numeric group ID that the operating system uses to identify you and members of your group.

glob

Strictly, the shell's * character, which will match a "glob" of characters when you're trying to generate a list of filenames. Loosely, the act of using globs and similar symbols to do pattern matching. See also fileglob and typeglob.

global

Something you can see from anywhere, usually used of variables and subroutines that are visible everywhere in your program. In Perl, only certain special variables are truly global--most variables (and all subroutines) exist only in the current package. Global variables can be declared with our. See "Global Declarations" in Chapter 4, "Statements and Declarations".

global destruction

The garbage collection of globals (and the running of any associated object destructors) that takes place when a Perl interpreter is being shut down. Global destruction should not be confused with the Apocalypse, except perhaps when it should.

glue language

A language such as Perl that is good at hooking things together that weren't intended to be hooked together.

granularity

The size of the pieces you're dealing with, mentally speaking.

greedy

A subpattern whose quantifier wants to match as many things as possible.

grep

Originally from the old Unix editor command for "Globally search for a Regular Expression and Print it", now used in the general sense of any kind of search, especially text searches. Perl has a built-in grep function that searches a list for elements matching any given criterion, whereas the grep(1) program searches for lines matching a regular expression in one or more files.

group

A set of users of which you are a member. In some operating systems (like Unix), you can give certain file access permissions to other members of your group.

GV

An internal "glob value" typedef, holding a typeglob. The GV type is a subclass of SV.

hacker

Someone who is brilliantly persistent in solving technical problems, whether these involve golfing, fighting orcs, or programming. Hacker is a neutral term, morally speaking. Good hackers are not to be confused with evil crackers or clueless script kiddies. If you confuse them, we will presume that you are either evil or clueless.

handler

A subroutine or method that is called by Perl when your program needs to respond to some internal event, such as a signal, or an encounter with an operator subject to operator overloading. See also callback.

hard reference

A scalarvalue containing the actual address of a referent, such that the referent's reference count accounts for it. (Some hard references are held internally, such as the implicit reference from one of a typeglob's variable slots to its corresponding referent.) A hard reference is different from a symbolic reference.

hash

An unordered association of key/value pairs, stored such that you can easily use a string key to look up its associated data value. This glossary is like a hash, where the word to be defined is the key, and the definition is the value. A hash is also sometimes septisyllabically called an "associative array", which is a pretty good reason for simply calling it a "hash" instead.

hash table

A data structure used internally by Perl for implementing associative arrays (hashes) efficiently. See also bucket.

header file

A file containing certain required definitions that you must include "ahead" of the rest of your program to do certain obscure operations. A C header file has a .h extension. Perl doesn't really have header files, though historically Perl has sometimes used translated .h files with a .ph extension. See require in Chapter 29, "Functions". (Header files have been superseded by the module mechanism.)

here document

So called because of a similar construct in shells that pretends that the lines following the command are a separate file to be fed to the command, up to some terminating string. In Perl, however, it's just a fancy form of quoting.

hexadecimal

A number in base 16, "hex" for short. The digits for 10 through 16 are customarily represented by the letters a through f. Hexadecimal constants in Perl start with 0x. See also the hex function in Chapter 29, "Functions".

home directory

The directory you are put into when you log in. On a Unix system, the name is often placed into $ENV{HOME} or $ENV{LOGDIR} by login, but you can also find it with (getpwuid($<))[7]. (Some platforms do not have a concept of a home directory.)

host

The computer on which a program or other data resides.

hubris

Excessive pride, the sort of thing Zeus zaps you for. Also the quality that makes you write (and maintain) programs that other people won't want to say bad things about. Hence, the third great virtue of a programmer. See also laziness and impatience.

HV

Short for a "hash value" typedef, which holds Perl's internal representation of a hash. The HV type is a subclass of SV.

identifier

A legally formed name for most anything in which a computer program might be interested. Many languages (including Perl) allow identifiers that start with a letter and contain letters and digits. Perl also counts the underscore character as a valid letter. (Perl also has more complicated names, such as qualified names.)

impatience

The anger you feel when the computer is being lazy. This makes you write programs that don't just react to your needs, but actually anticipate them. Or at least that pretend to. Hence, the second great virtue of a programmer. See also laziness and hubris.

implementation

How a piece of code actually goes about doing its job. Users of the code should not count on implementation details staying the same unless they are part of the published interface.

import

To gain access to symbols that are exported from another module. See use in Chapter 29, "Functions".

increment

To increase the value of something by 1 (or by some other number, if so specified).

indexing

In olden days, the act of looking up a key in an actual index (such as a phone book), but now merely the act of using any kind of key or position to find the corresponding value, even if no index is involved. Things have degenerated to the point that Perl's index function merely locates the position (index) of one string in another.

indirect filehandle

An expression that evaluates to something that can be used as a filehandle: a string (filehandle name), a typeglob, a typeglob reference, or a low-level IO object.

indirect object

In English grammar, a short noun phrase between a verb and its direct object indicating the beneficiary or recipient of the action. In Perl, print STDOUT "$foo\n"; can be understood as "verb indirect-object object" where STDOUT is the recipient of the print action, and "$foo" is the object being printed. Similarly, when invoking a method, you might place the invocant between the method and its arguments:

$gollum=newPathetic::Creature"Smeagol";
give $gollum "Fisssssh!";
give $gollum "Precious!";

indirect object slot

The syntactic position falling between a method call and its arguments when using the indirect object invocation syntax. (The slot is distinguished by the absence of a comma between it and the next argument.) STDERR is in the indirect object slot here:

print STDERR "Awake!  Awake!  Fear, Fire,
    Foes!  Awake!\n";

indirection

If something in a program isn't the value you're looking for but indicates where the value is, that's indirection. This can be done with either symbolic references or hard references.

infix

An operator that comes in between its operands, such as multiplication in 24 * 7.

inheritance

What you get from your ancestors, genetically or otherwise. If you happen to be a class, your ancestors are called base classes and your descendants are called derived classes. See single inheritance and multiple inheritance.

instance

Short for "an instance of a class", meaning an object of that class.

instance variable

An attribute of an object; data stored with the particular object rather than with the class as a whole.

integer

A number with no fractional (decimal) part. A counting number, like 1, 2, 3, and so on, but including 0 and the negatives.

interface

The services a piece of code promises to provide forever, in contrast to its implementation, which it should feel free to change whenever it likes.

interpolation

The insertion of a scalar or list value somewhere in the middle of another value, such that it appears to have been there all along. In Perl, variable interpolation happens in double-quoted strings and patterns, and list interpolation occurs when constructing the list of values to pass to a list operator or other such construct that takes a LIST.

interpreter

Strictly speaking, a program that reads a second program and does what the second program says directly without turning the program into a different form first, which is what compilers do. Perl is not an interpreter by this definition, because it contains a kind of compiler that takes a program and turns it into a more executable form (syntax trees) within the perl process itself, which the Perl run-time system then interprets.

invocant

The agent on whose behalf a method is invoked. In a class method, the invocant is a package name. In an instance method, the invocant is an object reference.

invocation

The act of calling up a deity, daemon, program, method, subroutine, or function to get it do what you think it's supposed to do. We usually "call" subroutines but "invoke" methods, since it sounds cooler.

I/O

Input from, or output to, a file or device.

IO

An internal I/O object. Can also mean indirect object.

IP

Internet Protocol, or Intellectual Property.

IPC

Interprocess Communication.

is-a

A relationship between two objects in which one object is considered to be a more specific version of the other, generic object: "A camel is a mammal." Since the generic object really only exists in a Platonic sense, we usually add a little abstraction to the notion of objects and think of the relationship as being between a generic base class and a specific derived class. Oddly enough, Platonic classes don't always have Platonic relationships--see inheritance.

iteration

Doing something repeatedly.

iterator

A special programming gizmo that keeps track of where you are in something that you're trying to iterate over. The foreach loop in Perl contains an iterator; so does a hash, allowing you to each through it.

IV

The integer four, not to be confused with six, Tom's favorite editor. IV also means an internal Integer Value of the type a scalar can hold, not to be confused with an NV.

JAPH

"Just Another Perl Hacker," a clever but cryptic bit of Perl code that when executed, evaluates to that string. Often used to illustrate a particular Perl feature, and something of an ungoing Obfuscated Perl Contest seen in Usenix signatures.

key

The string index to a hash, used to look up the value associated with that key.

keyword

See reserved words.

label

A name you give to a statement so that you can talk about that statement elsewhere in the program.

laziness

The quality that makes you go to great effort to reduce overall energy expenditure. It makes you write labor-saving programs that other people will find useful, and document what you wrote so you don't have to answer so many questions about it. Hence, the first great virtue of a programmer. Also hence, this book. See also impatience and hubris.

left shift

A bit shift that multiplies the number by some power of 2.

leftmost longest

The preference of the regular expression engine to match the leftmost occurrence of a pattern, then given a position at which a match will occur, the preference for the longest match (presuming the use of a greedy quantifier). See Chapter 5, "Pattern Matching" for much more on this subject.

lexeme

Fancy term for a token.

lexer

Fancy term for a tokener.

lexical analysis

Fancy term for tokenizing.

lexical scoping

Looking at your Oxford English Dictionary through a microscope. (Also known as static scoping, because dictionaries don't change very fast.) Similarly, looking at variables stored in a private dictionary (namespace) for each scope, which are visible only from their point of declaration down to the end of the lexical scope in which they are declared. --Syn. static scoping. --Ant. dynamic scoping.

lexical variable

A variable subject to lexical scoping, declared by my. Often just called a "lexical". (The our declaration declares a lexically scoped name for a global variable, which is not itself a lexical variable.)

library

Generally, a collection of procedures. In ancient days, referred to a collection of subroutines in a .pl file. In modern times, refers more often to the entire collection of Perl modules on your system.

LIFO

Last In, First Out. See also FIFO. A LIFO is usually called a stack.

line

In Unix, a sequence of zero or more non-newline characters terminated with a newline character. On non-Unix machines, this is emulated by the C library even if the underlying operating system has different ideas.

line buffering

Used by a standard I/O output stream that flushes its buffer after every newline. Many standard I/O libraries automatically set up line buffering on output that is going to the terminal.

line number

The number of lines read previous to this one, plus 1. Perl keeps a separate line number for each source or input file it opens. The current source file's line number is represented by __LINE__. The current input line number (for the file that was most recently read via <FH>) is represented by the $. ($INPUT_LINE_NUMBER) variable. Many error messages report both values, if available.

link

Used as a noun, a name in a directory, representing a file. A given file can have multiple links to it. It's like having the same phone number listed in the phone directory under different names. As a verb, to resolve a partially compiled file's unresolved symbols into a (nearly) executable image. Linking can generally be static or dynamic, which has nothing to do with static or dynamic scoping.

LIST

A syntactic construct representing a comma-separated list of expressions, evaluated to produce a list value. Each expression in a LIST is evaluated in list context and interpolated into the list value.

list

An ordered set of scalar values.

list context

The situation in which an expression is expected by its surroundings (the code calling it) to return a list of values rather than a single value. Functions that want a LIST of arguments tell those arguments that they should produce a list value. See also context.

list operator

An operator that does something with a list of values, such as join or grep. Usually used for named built-in operators (such as print, unlink, and system) that do not require parentheses around their argument list.

list value

An unnamed list of temporary scalar values that may be passed around within a program from any list-generating function to any function or construct that provides a list context.

literal

A token in a programming language such as a number or string that gives you an actual value instead of merely representing possible values as a variable does.

little-endian

From Swift: someone who eats eggs little end first. Also used of computers that store the least significant byte of a word at a lower byte address than the most significant byte. Often considered superior to big-endian machines. See also big-endian.

local

Not meaning the same thing everywhere. A global variable in Perl can be localized inside a dynamic scope via the local operator.

logical operator

Symbols representing the concepts "and", "or", "xor", and "not".

lookahead

An assertion that peeks at the string to the right of the current match location.

lookbehind

An assertion that peeks at the string to the left of the current match location.

loop

A construct that performs something repeatedly, like a roller coaster.

loop control statement

Any statement within the body of a loop that can make a loop prematurely stop looping or skip an iteration. Generally you shouldn't try this on roller coasters.

loop label

A kind of key or name attached to a loop (or roller coaster) so that loop control statements can talk about which loop they want to control.

lvaluable

Able to serve as an lvalue.

lvalue

Term used by language lawyers for a storage location you can assign a new value to, such as a variable or an element of an array. The "l" is short for "left", as in the left side of an assignment, a typical place for lvalues. An lvaluable function or expression is one to which a value may be assigned, as in pos($x) = 10.

lvalue modifier

An adjectival pseudofunction that warps the meaning of an lvalue in some declarative fashion. Currently there are three lvalue modifiers: my, our, and local.

magic

Technically speaking, any extra semantics attached to a variable such as $!, $0, %ENV, or %SIG, or to any tied variable. Magical things happen when you diddle those variables.

magical increment

An increment operator that knows how to bump up alphabetics as well as numbers.

magical variables

Special variables that have side effects when you access them or assign to them. For example, in Perl, changing elements of the %ENV array also changes the corresponding environment variables that subprocesses will use. Reading the $! variable gives you the current system error number or message.

Makefile

A file that controls the compilation of a program. Perl programs don't usually need a Makefile because the Perl compiler has plenty of self-control.

man

The Unix program that displays online documentation (manual pages) for you.

manpage

A "page" from the manuals, typically accessed via the man(1) command. A manpage contains a SYNOPSIS, a DESCRIPTION, a list of BUGS, and so on, and is typically longer than a page. There are manpages documenting commands, syscalls, libraryfunctions, devices, protocols, files, and such. In this book, we call any piece of standard Perl documentation (like perlop or perldelta) a manpage, no matter what format it's installed in on your system.

matching

See pattern matching.

member data

See instance variable.

memory

This always means your main memory, not your disk. Clouding the issue is the fact that your machine may implement virtual memory; that is, it will pretend that it has more memory than it really does, and it'll use disk space to hold inactive bits. This can make it seem like you have a little more memory than you really do, but it's not a substitute for real memory. The best thing that can be said about virtual memory is that it lets your performance degrade gradually rather than suddenly when you run out of real memory. But your program can die when you run out of virtual memory too, if you haven't thrashed your disk to death first.

metacharacter

A character that is not supposed to be treated normally. Which characters are to be treated specially as metacharacters varies greatly from context to context. Your shell will have certain metacharacters, double-quoted Perl strings have other metacharacters, and regular expression patterns have all the double-quote metacharacters plus some extra ones of their own.

metasymbol

Something we'd call a metacharacter except that it's a sequence of more than one character. Generally, the first character in the sequence must be a true metacharacter to get the other characters in the metasymbol to misbehave along with it.

method

A kind of action that an object can take if you tell it to. See Chapter 12, "Objects".

minimalism

The belief that "small is beautiful." Paradoxically, if you say something in a small language, it turns out big, and if you say it in a big language, it turns out small. Go figure.

mode

In the context of the stat(2) syscall, refers to the field holding the permission bits and the type of the file.

modifier

See statement modifier, regular expression modifier, and lvalue modifier, not necessarily in that order.

module

A file that defines a package of (almost) the same name, which can either export symbols or function as an object class. (A module's main .pm file may also load in other files in support of the module.) See the use built-in.

modulus

An integer divisor when you're interested in the remainder instead of the quotient.

monger

Short for Perl Monger, a purveyor of Perl.

mortal

A temporary value scheduled to die when the current statement finishes.

multidimensional array

An array with multiple subscripts for finding a single element. Perl implements these using references--see Chapter 9, "Data Structures".

multiple inheritance

The features you got from your mother and father, mixed together unpredictably. (See also inheritance, and single inheritance.) In computer languages (including Perl), the notion that a given class may have multiple direct ancestors or base classes.

named pipe

A pipe with a name embedded in the filesystem so that it can be accessed by two unrelated processes.

namespace

A domain of names. You needn't worry about whether the names in one such domain have been used in another. See package.

network address

The most important attribute of a socket, like your telephone's telephone number. Typically an IP address. See also port.

newline

A single character that represents the end of a line, with the ASCII value of 012 octal under Unix (but 015 on a Mac), and represented by \n in Perl strings. For Windows machines writing text files, and for certain physical devices like terminals, the single newline gets automatically translated by your C library into a line feed and a carriage return, but normally, no translation is done.

NFS

Network File System, which allows you to mount a remote filesystem as if it were local.

null character

A character with the ASCII value of zero. It's used by C to terminate strings, but Perl allows strings to contain a null.

null list

A list value with zero elements, represented in Perl by ().

null string

A string containing no characters, not to be confused with a string containing a null character, which has a positive length and is true.

numeric context

The situation in which an expression is expected by its surroundings (the code calling it) to return a number. See also context and string context.

NV

Short for Nevada, no part of which will ever be confused with civilization. NV also means an internal floating-point Numeric Value of the type a scalar can hold, not to be confused with an IV.

nybble

Half a byte, equivalent to one hexadecimal digit, and worth four bits.

object

An instance of a class. Something that "knows" what user-defined type (class) it is, and what it can do because of what class it is. Your program can request an object to do things, but the object gets to decide whether it wants to do them or not. Some objects are more accommodating than others.

octal

A number in base 8. Only the digits 0 through 7 are allowed. Octal constants in Perl start with 0, as in 013. See also the oct function.

offset

How many things you have to skip over when moving from the beginning of a string or array to a specific position within it. Thus, the minimum offset is zero, not one, because you don't skip anything to get to the first item.

one-liner

An entire computer program crammed into one line of text.

open source software

Programs for which the source code is freely available and freely redistributable, with no commercial strings attached. For a more detailed definition, see http://www.opensource.org/osd.html.

operand

An expression that yields a value that an operator operates on. See also precedence.

operating system

A special program that runs on the bare machine and hides the gory details of managing processes and devices. Usually used in a looser sense to indicate a particular culture of programming. The loose sense can be used at varying levels of specificity. At one extreme, you might say that all versions of Unix and Unix-lookalikes are the same operating system (upsetting many people, especially lawyers and other advocates). At the other extreme, you could say this particular version of this particular vendor's operating system is different from any other version of this or any other vendor's operating system. Perl is much more portable across operating systems than many other languages. See also architecture and platform.

operator

A gizmo that transforms some number of input values to some number of output values, often built into a language with a special syntax or symbol. A given operator may have specific expectations about what types of data you give as its arguments (operands) and what type of data you want back from it.

operator overloading

A kind of overloading that you can do on built-in operators to make them work on objects as if the objects were ordinary scalar values, but with the actual semantics supplied by the object class. This is set up with the overload pragma--see Chapter 13, "Overloading".

options

See either switches or regular expression modifiers.

overloading

Giving additional meanings to a symbol or construct. Actually, all languages do overloading to one extent or another, since people are good at figuring out things from context.

overriding

Hiding or invalidating some other definition of the same name. (Not to be confused with overloading, which adds definitions that must be disambiguated some other way.) To confuse the issue further, we use the word with two overloaded definitions: to describe how you can define your own subroutine to hide a built-in function of the same name (see "Overriding Built-in Functions" in Chapter 11, "Modules") and to describe how you can define a replacement method in a derived class to hide a base class's method of the same name (see Chapter 12, "Objects").

owner

The one user (apart from the superuser) who has absolute control over a file. A file may also have a group of users who may exercise joint ownership if the real owner permits it. See permission bits.

package

A namespace for global variables, subroutines, and the like, such that they can be kept separate from like-named symbols in other namespaces. In a sense, only the package is global, since the symbols in the package's symbol table are only accessible from code compiled outside the package by naming the package. But in another sense, all package symbols are also globals--they're just well-organized globals.

pad

Short for scratchpad.

parameter

See argument.

parent class

See base class.

parse tree

See syntax tree.

parsing

The subtle but sometimes brutal art of attempting to turn your possibly malformed program into a valid syntax tree.

patch

To fix by applying one, as it were. In the realm of hackerdom, a listing of the differences between two versions of a program as might be applied by the patch(1) program when you want to fix a bug or upgrade your old version.

PATH

The list of directories the system searches to find a program you want to execute. The list is stored as one of your environment variables, accessible in Perl as $ENV{PATH}.

pathname

A fully qualified filename such as /usr/bin/perl. Sometimes confused with PATH.

pattern

A template used in pattern matching.

pattern matching

Taking a pattern, usually a regular expression, and trying the pattern various ways on a string to see whether there's any way to make it fit. Often used to pick interesting tidbits out of a file.

permission bits

Bits that the owner of a file sets or unsets to allow or disallow access to other people. These flag bits are part of the mode word returned by the stat built-in when you ask about a file. On Unix systems, you can check the ls(1) manpage for more information.

Pern

What you get when you do Perl++ twice. Doing it only once will curl your hair. You have to increment it eight times to shampoo your hair. Lather, rinse, iterate.

pipe

A direct connection that carries the output of one process to the input of another without an intermediate temporary file. Once the pipe is set up, the two processes in question can read and write as if they were talking to a normal file, with some caveats.

pipeline

A series of processes all in a row, linked by pipes, where each passes its output stream to the next.

platform

The entire hardware and software context in which a program runs. A program written in a platform-dependent language might break if you change any of: machine, operating system, libraries, compiler, or system configuration. The perl interpreter has to be compiled differently for each platform because it is implemented in C, but programs written in the Perl language are largely platform-independent.

pod

The markup used to embed documentation into your Perl code. See Chapter 26, "Plain Old Documentation".

pointer

A variable in a language like C that contains the exact memory location of some other item. Perl handles pointers internally so you don't have to worry about them. Instead, you just use symbolic pointers in the form of keys and variable names, or hard references, which aren't pointers (but act like pointers and do in fact contain pointers).

polymorphism

The notion that you can tell an object to do something generic, and the object will interpret the command in different ways depending on its type. [<Gk many shapes]

port

The part of the address of a TCP or UDP socket that directs packets to the correct process after finding the right machine, something like the phone extension you give when you reach the company operator. Also, the result of converting code to run on a different platform than originally intended, or the verb denoting this conversion.

portable

Once upon a time, C code compilable under both BSD and SysV. In general, code that can be easily converted to run on another platform, where "easily" can be defined however you like, and usually is. Anything may be considered portable if you try hard enough. See mobile home or London Bridge.

porter

Someone who "carries" software from one platform to another. Porting programs written in platform-dependent languages such as C can be difficult work, but porting programs like Perl is very much worth the agony.

POSIX

The Portable Operating System Interface specification.

postfix

An operator that follows its operand, as in $x++.

pp

An internal shorthand for a "push-pop" code, that is, C code implementing Perl's stack machine.

pragma

A standard module whose practical hints and suggestions are received (and possibly ignored) at compile time. Pragmas are named in all lowercase.

precedence

The rules of conduct that, in the absence of other guidance, determine what should happen first. For example, in the absence of parentheses, you always do multiplication before addition.

prefix

An operator that precedes its operand, as in ++$x.

preprocessing

What some helper process did to transform the incoming data into a form more suitable for the current process. Often done with an incoming pipe. See also C preprocessor.

procedure

A subroutine.

process

An instance of a running program. Under multitasking systems like Unix, two or more separate processes could be running the same program independently at the same time--in fact, the fork function is designed to bring about this happy state of affairs. Under other operating systems, processes are sometimes called "threads", "tasks", or "jobs", often with slight nuances in meaning.

program generator

A system that algorithmically writes code for you in a high-level language. See also code generator.

progressive matching

Pattern matching that picks up where it left off before.

property

See either instance variable or character property.

protocol

In networking, an agreed-upon way of sending messages back and forth so that neither correspondent will get too confused.

prototype

An optional part of a subroutine declaration telling the Perl compiler how many and what flavor of arguments may be passed as actual arguments, so that you can write subroutine calls that parse much like built-in functions. (Or don't parse, as the case may be.)

pseudofunction

A construct that sometimes looks like a function but really isn't. Usually reserved for lvalue modifiers like my, for context modifiers like scalar, and for the pick-your-own-quotes constructs, q//, qq//, qx//, qw//, qr//, m//, s///, y///, and tr///.

pseudohash

A reference to an array whose initial element happens to hold a reference to a hash. You can treat a pseudohash reference as either an array reference or a hash reference.

pseudoliteral

An operator that looks something like a literal, such as the output-grabbing operator, `command`.

public domain

Something not owned by anybody. Perl is copyrighted and is thus not in the public domain--it's just freely available and freely redistributable.

pumpkin

A notional "baton" handed around the Perl community indicating who is the lead integrator in some arena of development.

pumpking

A pumpkin holder, the person in charge of pumping the pump, or at least priming it. Must be willing to play the part of the Great Pumpkin now and then.

PV

A "pointer value", which is Perl Internals Talk for a char*.

qualified

Possessing a complete name. The symbol $Ent::moot is qualified; $moot is unqualified. A fully qualified filename is specified from the top-level directory.

quantifier

A component of a regular expression specifying how many times the foregoing atom may occur.

readable

With respect to files, one that has the proper permission bit set to let you access the file. With respect to computer programs, one that's written well enough that someone has a chance of figuring out what it's trying to do.

reaping

The last rites performed by a parent process on behalf of a deceased child process so that it doesn't remain a zombie. See the wait and waitpid function calls.

record

A set of related data values in a file or stream, often associated with a unique key field. In Unix, often commensurate with a line, or a blank-line-terminated set of lines (a "paragraph"). Each line of the /etc/passwd file is a record, keyed on login name, containing information about that user.

recursion

The art of defining something (at least partly) in terms of itself, which is a naughty no-no in dictionaries but often works out okay in computer programs if you're careful not to recurse forever, which is like an infinite loop with more spectacular failure modes.

reference

Where you look to find a pointer to information somewhere else. (See indirection.) References come in two flavors, symbolic references and hard references.

referent

Whatever a reference refers to, which may or may not have a name. Common types of referents include scalars, arrays, hashes, and subroutines.

regex

See regular expression.

regular expression

A single entity with various interpretations, like an elephant. To a computer scientist, it's a grammar for a little language in which some strings are legal and others aren't. To normal people, it's a pattern you can use to find what you're looking for when it varies from case to case. Perl's regular expressions are far from regular in the theoretical sense, but in regular use they work quite well. Here's a regular expression: /Oh s.*t./. This will match strings like "Oh say can you see by the dawn's early light" and "Oh sit!". See Chapter 5, "Pattern Matching".

regular expression modifier

An option on a pattern or substitution, such as /i to render the pattern case insensitive. See also cloister.

regular file

A file that's not a directory, a device, a named pipe or socket, or a symbolic link. Perl uses the -f file test operator to identify regular files. Sometimes called a "plain" file.

relational operator

An operator that says whether a particular ordering relationship is true about a pair of operands. Perl has both numeric and string relational operators. See collating sequence.

reserved words

A word with a specific, built-in meaning to a compiler, such as if or delete. In many languages (not Perl), it's illegal to use reserved words to name anything else. (Which is why they're reserved, after all.) In Perl, you just can't use them to name labels or filehandles. Also called "keywords".

return value

The value produced by a subroutine or expression when evaluated. In Perl, a return value may be either a list or a scalar.

RFC

Request For Comment, which despite the timid connotations is the name of a series of important standards documents.

right shift

A bit shift that divides a number by some power of 2.

root

The superuser (UID == 0). Also, the top-level directory of the filesystem.

RTFM

What you are told when someone thinks you should Read The Fine Manual.

run phase

Any time after Perl starts running your main program. See also compile phase. Run phase is mostly spent in run time but may also be spent in compile time when require, do FILE, or eval STRING operators are executed or when a substitution uses the /ee modifier.

run time

The time when Perl is actually doing what your code says to do, as opposed to the earlier period of time when it was trying to figure out whether what you said made any sense whatsoever, which is compile time.

run-time pattern

A pattern that contains one or more variables to be interpolated before parsing the pattern as a regular expression, and that therefore cannot be analyzed at compile time, but must be re-analyzed each time the pattern match operator is evaluated. Run-time patterns are useful but expensive.

RV

A recreational vehicle, not to be confused with vehicular recreation. RV also means an internal Reference Value of the type a scalar can hold. See also IV and NV if you're not confused yet.

rvalue

A value that you might find on the right side of an assignment. See also lvalue.

scalar

A simple, singular value; a number, string, or reference.

scalar context

The situation in which an expression is expected by its surroundings (the code calling it) to return a single value rather than a list of values. See also context and list context. A scalar context sometimes imposes additional constraints on the return value--see string context and numeric context. Sometimes we talk about a Boolean context inside conditionals, but this imposes no additional constraints, since any scalar value, whether numeric or string, is already true or false.

scalar literal

A number or quoted string--an actual value in the text of your program, as opposed to a variable.

scalar value

A value that happens to be a scalar as opposed to a list.

scalar variable

A variable prefixed with $ that holds a single value.

scope

How far away you can see a variable from, looking through one. Perl has two visibility mechanisms: it does dynamic scoping of local variables, meaning that the rest of the block, and any subroutines that are called by the rest of the block, can see the variables that are local to the block. Perl does lexical scoping of my variables, meaning that the rest of the block can see the variable, but other subroutines called by the block cannot see the variable.

scratchpad

The area in which a particular invocation of a particular file or subroutine keeps some of its temporary values, including any lexically scoped variables.

script

A text file that is a program intended to be executed directly rather than compiled to another form of file before execution. Also, in the context of Unicode, a writing system for a particular language or group of languages, such as Greek, Bengali, or Klingon.

script kiddie

A cracker who is not a hacker, but knows just enough to run canned scripts. A cargo-cult programmer.

sed

A venerable Stream EDitor from which Perl derives some of its ideas.

semaphore

A fancy kind of interlock that prevents multiple threads or processes from using up the same resources simultaneously.

separator

A character or string that keeps two surrounding strings from being confused with each other. The split function works on separators. Not to be confused with delimiters or terminators. The "or" in the previous sentence separated the two alternatives.

serialization

Putting a fancy data structure into linear order so that it can be stored as a string in a disk file or database or sent through a pipe. Also called marshalling.

server

In networking, a process that either advertises a service or just hangs around at a known location and waits for clients who need service to get in touch with it.

service

Something you do for someone else to make them happy, like giving them the time of day (or of their life). On some machines, well-known services are listed by the getservent function.

setgid

Same as setuid, only having to do with giving away group privileges.

setuid

Said of a program that runs with the privileges of its owner rather than (as is usually the case) the privileges of whoever is running it. Also describes the bit in the mode word (permission bits) that controls the feature. This bit must be explicitly set by the owner to enable this feature, and the program must be carefully written not to give away more privileges than it ought to.

shared memory

A piece of memory accessible by two different processes who otherwise would not see each other's memory.

shebang

Irish for the whole McGillicuddy. In Perl culture, a portmanteau of "sharp" and "bang", meaning the #! sequence that tells the system where to find the interpreter.

shell

A command-line interpreter. The program that interactively gives you a prompt, accepts one or more lines of input, and executes the programs you mentioned, feeding each of them their proper arguments and input data. Shells can also execute scripts containing such commands. Under Unix, typical shells include the Bourne shell (/bin/sh), the C shell (/bin/csh), and the Korn shell (/bin/ksh). Perl is not strictly a shell because it's not interactive (although Perl programs can be interactive).

side effects

Something extra that happens when you evaluate an expression. Nowadays it can refer to almost anything. For example, evaluating a simple assignment statement typically has the "side effect" of assigning a value to a variable. (And you thought assigning the value was your primary intent in the first place!) Likewise, assigning a value to the special variable $| ($AUTOFLUSH) has the side effect of forcing a flush after every write or print on the currently selected filehandle.

signal

A bolt out of the blue; that is, an event triggered by the operating system, probably when you're least expecting it.

signal handler

A subroutine that, instead of being content to be called in the normal fashion, sits around waiting for a bolt out of the blue before it will deign to execute. Under Perl, bolts out of the blue are called signals, and you send them with the kill built-in. See the %SIG hash in Chapter 28, "Special Names", and the section "Signals" in Chapter 16, "Interprocess Communication".

single inheritance

The features you got from your mother, if she told you that you don't have a father. (See also inheritance and multiple inheritance.) In computer languages, the notion that classes reproduce asexually so that a given class can only have one direct ancestor or base class. Perl supplies no such restriction, though you may certainly program Perl that way if you like.

slice

A selection of any number of elements from a list, array, or hash.

slurp

To read an entire file into a string in one operation.

socket

An endpoint for network communication among multiple processes that works much like a telephone or a post office box. The most important thing about a socket is its network address (like a phone number). Different kinds of sockets have different kinds of addresses--some look like filenames, and some don't.

soft reference

See symbolic reference.

source filter

A special kind of module that does preprocessing on your script just before it gets to the tokener.

stack

A device you can put things on the top of, and later take them back off in the opposite order in which you put them on. See LIFO.

standard

Included in the official Perl distribution, as in a standard module, a standard tool, or a standard Perl manpage.

standard error

The default output stream for nasty remarks that don't belong in standard output. Represented within a Perl program by the filehandle STDERR. You can use this stream explicitly, but the die and warn built-ins write to your standard error stream automatically.

standard I/O

A standard C library for doing buffered input and output to the operating system. (The "standard" of standard I/O is only marginally related to the "standard" of standard input and output.) In general, Perl relies on whatever implementation of standard I/O a given operating system supplies, so the buffering characteristics of a Perl program on one machine may not exactly match those on another machine. Normally this only influences efficiency, not semantics. If your standard I/O package is doing block buffering and you want it to flush the buffer more often, just set the $| variable to a true value.

standard input

The default input stream for your program, which if possible shouldn't care where its data is coming from. Represented within a Perl program by the filehandle STDIN.

standard output

The default output stream for your program, which if possible shouldn't care where its data is going. Represented within a Perl program by the filehandle STDOUT.

stat structure

A special internal spot in which Perl keeps the information about the last file on which you requested information.

statement

A command to the computer about what to do next, like a step in a recipe: "Add marmalade to batter and mix until mixed." A statement is distinguished from a declaration, which doesn't tell the computer to do anything, but just to learn something.

statement modifier

A conditional or loop that you put after the statement instead of before, if you know what we mean.

static

Varying slowly compared to something else. (Unfortunately, everything is relatively stable compared to something else, except for certain elementary particles, and we're not so sure about them.) In computers, where things are supposed to vary rapidly, "static" has a derogatory connotation, indicating a slightly dysfunctional variable, subroutine, or method. In Perl culture, the word is politely avoided.

static method

No such thing. See class method.

static scoping

No such thing. See lexical scoping.

static variable

No such thing. Just use a lexical variable in a scope larger than your subroutine.

status

The value returned to the parent process when one of its child processes dies. This value is placed in the special variable $?. Its upper eight bits are the exit status of the defunct process, and its lower eight bits identify the signal (if any) that the process died from. On Unix systems, this status value is the same as the status word returned by wait(2). See system in Chapter 29, "Functions".

STDERR

See standard error.

STDIN

See standard input.

STDIO

See standard I/O.

STDOUT

See standard output.

stream

A flow of data into or out of a process as a steady sequence of bytes or characters, without the appearance of being broken up into packets. This is a kind of interface--the underlying implementation may well break your data up into separate packets for delivery, but this is hidden from you.

string

A sequence of characters such as "He said !@#*&%@#*?!". A string does not have to be entirely printable.

string context

The situation in which an expression is expected by its surroundings (the code calling it) to return a string. See also context and numeric context.

stringification

The process of producing a string representation of an abstract object.

struct

C keyword introducing a structure definition or name.

structure

See data structure.

subclass

See derived class.

subpattern

A component of a regular expression pattern.

subroutine

A named or otherwise accessible piece of program that can be invoked from elsewhere in the program in order to accomplish some sub-goal of the program. A subroutine is often parameterized to accomplish different but related things depending on its input arguments. If the subroutine returns a meaningful value, it is also called a function.

subscript

A value that indicates the position of a particular arrayelement in an array.

substitution

Changing parts of a string via the s/// operator. (We avoid use of this term to mean variable interpolation.)

substring

A portion of a string, starting at a certain character position (offset) and proceeding for a certain number of characters.

superclass

See base class.

superuser

The person whom the operating system will let do almost anything. Typically your system administrator or someone pretending to be your system administrator. On Unix systems, the root user. On Windows systems, usually the Administrator user.

SV

Short for "scalar value". But within the Perl interpreter every referent is treated as a member of a class derived from SV, in an object-oriented sort of way. Every value inside Perl is passed around as a C language SV* pointer. The SV struct knows its own "referent type", and the code is smart enough (we hope) not to try to call a hash function on a subroutine.

switch

An option you give on a command line to influence the way your program works, usually introduced with a minus sign. The word is also used as a nickname for a switch statement.

switch cluster

The combination of multiple command-line switches (e.g., -a -b -c) into one switch (e.g., -abc). Any switch with an additional argument must be the last switch in a cluster.

switch statement

A program technique that lets you evaluate an expression and then, based on the value of the expression, do a multiway branch to the appropriate piece of code for that value. Also called a "case structure", named after the similar Pascal construct. Most switch statements in Perl are spelled for. See "Case Structures" in Chapter 4, "Statements and Declarations".

symbol

Generally, any token or metasymbol. Often used more specifically to mean the sort of name you might find in a symbol table.

symbol table

Where a compiler remembers symbols. A program like Perl must somehow remember all the names of all the variables, filehandles, and subroutines you've used. It does this by placing the names in a symbol table, which is implemented in Perl using a hash table. There is a separate symbol table for each package to give each package its own namespace.

symbolic debugger

A program that lets you step through the execution of your program, stopping or printing things out here and there to see whether anything has gone wrong, and if so, what. The "symbolic" part just means that you can talk to the debugger using the same symbols with which your program is written.

symbolic link

An alternate filename that points to the real filename, which in turn points to the real file. Whenever the operating system is trying to parse a pathname containing a symbolic link, it merely substitutes the new name and continues parsing.

symbolic reference

A variable whose value is the name of another variable or subroutine. By dereferencing the first variable, you can get at the second one. Symbolic references are illegal under use strict 'refs'.

synchronous

Programming in which the orderly sequence of events can be determined; that is, when things happen one after the other, not at the same time.

syntactic sugar

An alternative way of writing something more easily; a shortcut.

syntax

From Greek, "with-arrangement". How things (particularly symbols) are put together with each other.

syntax tree

An internal representation of your program wherein lower-level constructs dangle off the higher-level constructs enclosing them.

syscall

A function call directly to the operating system. Many of the important subroutines and functions you use aren't direct system calls, but are built up in one or more layers above the system call level. In general, Perl programmers don't need to worry about the distinction. However, if you do happen to know which Perl functions are really syscalls, you can predict which of these will set the $! ($ERRNO) variable on failure. Unfortunately, beginning programmers often confusingly employ the term "system call" to mean what happens when you call the Perl system function, which actually involves many syscalls. To avoid any confusion, we nearly always use say "syscall" for something you could call indirectly via Perl's syscall function, and never for something you would call with Perl's system function.

tainted

Said of data derived from the grubby hands of a user and thus unsafe for a secure program to rely on. Perl does taint checks if you run a setuid (or setgid) program, or if you use the -T switch.

TCP

Short for Transmission Control Protocol. A protocol wrapped around the Internet Protocol to make an unreliable packet transmission mechanism appear to the application program to be a reliable stream of bytes. (Usually.)

term

Short for a "terminal", that is, a leaf node of a syntax tree. A thing that functions grammatically as an operand for the operators in an expression.

terminator

A character or string that marks the end of another string. The $/ variable contains the string that terminates a readline operation, which chomp deletes from the end. Not to be confused with delimiters or separators. The period at the end of this sentence is a terminator.

ternary

An operator taking three operands. Sometimes pronounced trinary.

text

A string or file containing primarily printable characters.

thread

Like a forked process, but without fork's inherent memory protection. A thread is lighter weight than a full process, in that a process could have multiple threads running around in it, all fighting over the same process's memory space unless steps are taken to protect threads from each other. See Chapter 17, "Threads".

tie

The bond between a magical variable and its implementation class. See the tie function in Chapter 29, "Functions" and Chapter 14, "Tied Variables".

TMTOWTDI

There's More Than One Way To Do It, the Perl Motto. The notion that there can be more than one valid path to solving a programming problem in context. (This doesn't mean that more ways are always better or that all possible paths are equally desirable--just that there need not be One True Way.)

token

A morpheme in a programming language, the smallest unit of text with semantic significance.

tokener

A module that breaks a program text into a sequence of tokens for later analysis by a parser.

tokenizing

Splitting up a program text into tokens. Also known as "lexing", in which case you get "lexemes" instead of tokens.

toolbox approach

The notion that, with a complete set of simple tools that work well together, you can build almost anything you want. Which is fine if you're assembling a tricycle, but if you're building a defranishizing comboflux regurgalator, you really want your own machine shop in which to build special tools. Perl is sort of a machine shop.

transliterate

To turn one string representation into another by mapping each character of the source string to its corresponding character in the result string. See the tr/// operator in Chapter 5, "Pattern Matching".

trigger

An event that causes a handler to be run.

trinary

Not a stellar system with three stars, but an operator taking three operands. Sometimes pronounced ternary.

troff

A venerable typesetting language from which Perl derives the name of its $% variable and which is secretly used in the production of Camel books.

true

Any scalar value that doesn't evaluate to 0 or "".

truncating

Emptying a file of existing contents, either automatically when opening a file for writing or explicitly via the truncate function.

type

See data type and class.

type casting

Converting data from one type to another. C permits this. Perl does not need it. Nor want it.

typed lexical

A lexical variable that is declared with a class type: my Pony $bill.

typedef

A type definition in the C language.

typeglob

Use of a single identifier, prefixed with *. For example, *name stands for any or all of $name, @name, %name, &name, or just name. How you use it determines whether it is interpreted as all or only one of them. See "Typeglobs and Filehandles" in Chapter 2, "Bits and Pieces".

typemap

A description of how C types may be transformed to and from Perl types within an extension module written in XS.

UDP

User Datagram Protocol, the typical way to send datagrams over the Internet.

UID

A user ID. Often used in the context of file or process ownership.

umask

A mask of those permission bits that should be forced off when creating files or directories, in order to establish a policy of whom you'll ordinarily deny access to. See the umask function.

unary operator

An operator with only one operand, like ! or chdir. Unary operators are usually prefix operators; that is, they precede their operand. The ++ and -- operators can be either prefix or postfix. (Their position does change their meanings.)

Unicode

A character set comprising all the major character sets of the world, more or less. See http://www.unicode.org.

Unix

A very large and constantly evolving language with several alternative and largely incompatible syntaxes, in which anyone can define anything any way they choose, and usually do. Speakers of this language think it's easy to learn because it's so easily twisted to one's own ends, but dialectical differences make tribal intercommunication nearly impossible, and travelers are often reduced to a pidgin-like subset of the language. To be universally understood, a Unix shell programmer must spend years of study in the art. Many have abandoned this discipline and now communicate via an Esperanto-like language called Perl. In ancient times, Unix was also used to refer to some code that a couple of people at Bell Labs wrote to make use of a PDP-7 computer that wasn't doing much of anything else at the time.

value

An actual piece of data, in contrast to all the variables, references, keys, indexes, operators, and whatnot that you need to access the value.

variable

A named storage location that can hold any of various kinds of value, as your program sees fit.

variable interpolation

The interpolation of a scalar or array variable into a string.

variadic

Said of a function that happily receives an indeterminate number of actual arguments.

vector

Mathematical jargon for a list of scalar values.

virtual

Providing the appearance of something without the reality, as in: virtual memory is not real memory. (See also memory.) The opposite of "virtual" is "transparent", which means providing the reality of something without the appearance, as in: Perl handles the variable-length UTF-8 character encoding transparently.

void context

A form of scalar context in which an expression is not expected to return any value at all and is evaluated for its side effects alone.

v-string

A "version" or "vector" string specified with a v followed by a series of decimal integers in dot notation, for instance, v1.20.300.4000. Each number turns into a character with the specified ordinal value. (The v is optional when there are at least three integers.)

warning

A message printed to the STDERR stream to the effect that something might be wrong but isn't worth blowing up over. See warn in Chapter 29, "Functions" and the use warnings pragma in Chapter 31, "Pragmatic Modules".

watch expression

An expression which, when its value changes, causes a breakpoint in the Perl debugger.

whitespace

A character that moves your cursor but doesn't otherwise put anything on your screen. Typically refers to any of: space, tab, line feed, carriage return, or form feed.

word

In normal "computerese", the piece of data of the size most efficiently handled by your computer, typically 32 bits or so, give or take a few powers of 2. In Perl culture, it more often refers to an alphanumeric identifier (including underscores), or to a string of nonwhitespace characters bounded by whitespace or string boundaries.

working directory

Your current directory, from which relative pathnames are interpreted by the operating system. The operating system knows your current directory because you told it with a chdir or because you started out in the place where your parent process was when you were born.

wrapper

A program or subroutine that runs some other program or subroutine for you, modifying some of its input or output to better suit your purposes.

WYSIWYG

What You See Is What You Get. Usually used when something that appears on the screen matches how it will eventually look, like Perl's format declarations. Also used to mean the opposite of magic because everything works exactly as it appears, as in the three-argument form of open.

XS

An extraordinarily exported, expeditiously excellent, expressly eXternal Subroutine, executed in existing C or C++ or in an exciting new extension language called (exasperatingly) XS. Examine Chapter 21, "Internals and Externals", for the exact explanation.

XSUB

An external subroutine defined in XS.

yacc

Yet Another Compiler Compiler. A parser generator without which Perl probably would not have existed. See the file perly.y in the Perl source distribution.

zero width

A subpattern assertion matching the null string between characters.

zombie

A process that has died (exited) but whose parent has not yet received proper notification of its demise by virtue of having called wait or waitpid. If you fork, you must clean up after your child processes when they exit, or else the process table will fill up and your system administrator will Not Be Happy with you.

Previous | Home | Next
33. Diagnostic Messages | Book Index | Index
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Index

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Symbols and Numbers

Book Title

Index: Symbols & Numbers

@+ array of ending positions: 28.2. Special Variables in Alphabetical Order
$!, portability of: 25.4. System Interaction
& (ampersand): 3.10. Named Unary and File Test Operators
address-of operator (in C): 3.21. C Operators Missing from Perl
& (bitwise and) operator: 3.13. Bitwise Operators
&& (AND) operator: 3.14. C-Style Logical (Short-Circuit) Operators
&&= (assignment) operator: 3.17. Assignment Operators
in filenames: 29.2.104. open
Perl version 5, changes in use: 1.2.2. Verbs
prototype character: 6.4. Prototypes
for subroutine names: 1.2.1. Variable Syntax
2.5. Names
2.5. Names
4.6. goto
6.1. Syntax
omitting in prototypes: 6.4. Prototypes
* (asterisk): 3.10. Named Unary and File Test Operators
** (exponentiation)operator: 3.4. Exponentiation
**= (exponentiation assignment) operator: 3.17. Assignment Operators
*= (multiplication assignment) operator: 3.17. Assignment Operators
*? quantifier: 5.3.1. Metasymbol Tables
metacharacter: 5.1. The Regular Expression Bestiary
5.3. Metacharacters and Metasymbols
(multiplicative) operator: 3.1. Terms and List Operators (Leftward)
prototype character: 6.4. Prototypes
quantifier: 1.7.1. Quantifiers
5.3.1. Metasymbol Tables
in quantifiers: 5.5. Quantifiers
typeglob: 1.2.1. Variable Syntax
for typeglob names: 2.5. Names
2.10. Typeglobs and Filehandles
@ (at sign)
for array names: 1.2.1. Variable Syntax
2.4. Variables
@- array: 5.7.1. Capturing
@+ array of ending positions: 5.7.1. Capturing
@_ arrays: 6.2. Semantics
@_ array: 6.2. Semantics
28.2. Special Variables in Alphabetical Order
changes in use, Perl versions: 24.1.5. Previous Perl Traps
in debugger: 20.1. Using the Debugger
inside strings, escaping with backslash: 2.6.2. String Literals
in picture lines: 7. Formats
prototype character: 6.4. Prototypes
(backslash)
... metasymbol: 5.3.1. Metasymbol Tables
entering continued commands in debugger: 20.2. Debugger Commands
to escape metacharacters: 5.1. The Regular Expression Bestiary
5.3. Metacharacters and Metasymbols
interpretation by regex parser: 5.9.2.1. When backslashes happen
metacharacter: 5.1. The Regular Expression Bestiary
for multiline commands: 20.1. Using the Debugger
Q notation for backslashing nonalphanumeric characters: 2.6.2. String Literals
quoted strings, avoiding overuse in: 2.6.3. Pick Your Own Quotes
quotemeta function for: 29.2.118. quotemeta
reference operator: 3.5. Ideographic Unary Operators
8.2.1. The Backslash Operator
(backslash)
double quotes, interpreting with: 1.2.1.1. Singularities
` (backtick) operator
shell programming, Perl vs.: 24.1.4. Shell Traps
! (bang)
! (logical negation) operator
overloading: 13.3. Overloadable Operators
!! debugger command: 20.2.6. Actions and Command Execution
!~ (binding) operator: 3.6. Binding Operators
using with pattern matching operators: 5.2. Pattern-Matching Operators
complemented character sets, using for: 5.4.3.4. Defining your own character properties
in debugger commands: 20.2.6. Actions and Command Execution
logical negation operator: 3.5. Ideographic Unary Operators
!= (not equal to) operator: 1.5.6. Some Numeric and String Comparison Operators
24.1.1. Universal Blunders
{} braces: 24.1.1. Universal Blunders
[] (brackets)
[ metacharacter: 5.1. The Regular Expression Bestiary
5.3. Metacharacters and Metasymbols
[...] character class: 5.3.1. Metasymbol Tables
character classes: 5.3.1. Metasymbol Tables
5.4.1. Custom Character Classes
to match characters: 5.9.4. The Little Engine That /Could(n't)?/
precedence of: 3.1. Terms and List Operators (Leftward)
^ (caret) ;line boundary: 5.6.1. Beginnings: The A and ^ Assertions
: (colon)
:: in module names, translating to system directory separators: 11.1. Using Modules
:: for package identifiers: 2.6.4. Or Leave the Quotes Out Entirely
10. Packages
24.1.5. Previous Perl Traps
:: in fully qualified names: 2.5. Names
, (comma)
delimiting list values: 2.8. List Values and Arrays
2.8. List Values and Arrays
error in print statements: 24.1.1. Universal Blunders
key/value pairs and: 1.2.1.2.2. Hashes.
2.9. Hashes
large numbers and: 2.6.1. Numeric Literals
operator: 3.18. Comma Operators
3.18. Comma Operators
(see also => operator)
in scalar context: 24.1.5. Previous Perl Traps
as separator: 1.2.1.3. Complexities
$^T ($BASETIME): 3.10. Named Unary and File Test Operators
$. ($INPUT_LINE_NUMBER): 3.15. Range Operator
$ (dollar sign): 1.2.1.2.2. Hashes.
prototype character: 6.4. Prototypes
in debugger: 20.1. Using the Debugger
$# prefix: 2.8.2. Array Length
$$ (current process ID): 2.5. Names
$? (exit status, last child process): 2.5. Names
$ variables
$^O variable: 25. Portable Perl
line boundary: 5.6.2. Endings: The z, Z, and $ Assertions
in matching: 5.2.2. The m// Operator (Matching)
metacharacter: 5.1. The Regular Expression Bestiary
5.3. Metacharacters and Metasymbols
for scalar variable names: 1.2.1.2.1. Arrays.
2.4. Variables
scalar variable interpolation and: 2.6.2. String Literals
signifying scalar variables: 1.2.1. Variable Syntax
word boundary: 1.7.3. Nailing Things Down
$! variable: 1.5.5. Logical Operators
$ variables
$0 ($PROGRAM_NAME): 28.2. Special Variables in Alphabetical Order
$a and $b (sort variables): 28.2. Special Variables in Alphabetical Order
@': 5.7.1. Capturing
@&: 5.7.1. Capturing
$' ($POSTMATCH): 24.2.1. Time Efficiency
28.2. Special Variables in Alphabetical Order
$*: 28.2. Special Variables in Alphabetical Order
$@ ($EVAL_ERROR): 28.2. Special Variables in Alphabetical Order
$ ($OUTPUT_RECORD_SEPARATOR): 28.2. Special Variables in Alphabetical Order
$` ($PREMATCH): 24.2.1. Time Efficiency
28.2. Special Variables in Alphabetical Order
$! ($OS_ERROR): 28.2. Special Variables in Alphabetical Order
${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order
$] ($PERL_VERSION): 28.2. Special Variables in Alphabetical Order
$^ ($FORMAT_TOP_NAME): 7.1. Format Variables
7.2. Footers
24.1.1. Universal Blunders
28.2. Special Variables in Alphabetical Order
$^A ($ACCUMULATOR): 7.2.1. Accessing Formatting Internals
28.2. Special Variables in Alphabetical Order
formline function output: 29.2.42. formline
$^C ($COMPILING): 28.2. Special Variables in Alphabetical Order
$^D ($DEBUGGING): 19.1.3. Switches
28.2. Special Variables in Alphabetical Order
$^E ($EXTENDED_OS_ERROR): 28.2. Special Variables in Alphabetical Order
$^F ($SYSTEM_FD_MAX): 28.2. Special Variables in Alphabetical Order
$^H: 28.2. Special Variables in Alphabetical Order
$^I ($INPLACE_EDIT): 28.2. Special Variables in Alphabetical Order
$^L ($FORMAT_LINEFEED): 7.1. Format Variables
$^M: 28.2. Special Variables in Alphabetical Order
$^O ($OSNAME): 28.2. Special Variables in Alphabetical Order
$^P ($PERLDB): 28.2. Special Variables in Alphabetical Order
$^S ($EXCEPTIONS_BEING_CAUGHT): 28.2. Special Variables in Alphabetical Order
$^T ($BASETIME): 28.2. Special Variables in Alphabetical Order
$^V ($PERL_VERSION): 28.2. Special Variables in Alphabetical Order
$^W ($WARNING): 28.2. Special Variables in Alphabetical Order
$^X ($EXECUTABLE_NAME): 28.2. Special Variables in Alphabetical Order
$: ($FORMAT_LINE_BREAK_CHARACTERS): 7. Formats
28.2. Special Variables in Alphabetical Order
$, ($LIST_SEPARATOR): 28.2. Special Variables in Alphabetical Order
$$ ($PROCESS_ID): 28.2. Special Variables in Alphabetical Order
$. ($INPUT_LINE_NUMBER): 28.2. Special Variables in Alphabetical Order
resetting with close function: 29.2.16. close
$= ($FORMAT_LINES_PER_PAGE): 7.1. Format Variables
28.2. Special Variables in Alphabetical Order
@`: 5.7.1. Capturing
$< ($REAL_USER_ID): 28.2. Special Variables in Alphabetical Order
$line: 1.6.2.1. The while and until statements
$- ($FORMAT_LINES_LEFT): 7. Formats
7.2. Footers
28.2. Special Variables in Alphabetical Order
$) ($EFFECTIVE_GROUP_ID): 28.2. Special Variables in Alphabetical Order
28.2. Special Variables in Alphabetical Order
$( ($REAL_GROUP_ID): 28.2. Special Variables in Alphabetical Order
$% ($FORMAT_PAGE_NUMBER): 7.1. Format Variables
28.2. Special Variables in Alphabetical Order
@+: 5.7.1. Capturing
$? ($CHILD_ERROR): 28.2. Special Variables in Alphabetical Order
backtick operator and: 2.11.1. Command Input (Backtick) Operator
close function and: 29.2.16. close
$> ($EFFECTIVE_USER_ID): 28.2. Special Variables in Alphabetical Order
$[semi] ($SUBSCRIPT_SEPARATOR): 28.2. Special Variables in Alphabetical Order
$#
obsolete variable for numeric output: 28.2. Special Variables in Alphabetical Order
$&: 5.2. Pattern-Matching Operators
$`: 5.2. Pattern-Matching Operators
${^ (internal variable names): 2.5. Names
$^W: 4.9.1. Controlling Warnings
$; (SUBSCRIPT_SEPARATOR): 2.9. Hashes
$': 5.2. Pattern-Matching Operators
$/ ($INPUT_RECORD_SEPARATOR): 19.1.3. Switches
28.2. Special Variables in Alphabetical Order
$~ ($FORMAT_NAME): 7.1. Format Variables
28.2. Special Variables in Alphabetical Order
$_ ($ARG) ;glob function with: 2.11.3. Filename Globbing Operator
$_ variable: 1.7. Regular Expressions
1.7.1. Quantifiers
$| ($OUTPUT_AUTOFLUSH): 7.1. Format Variables
28.2. Special Variables in Alphabetical Order
${^WIDE_SYSTEM_CALLS}: 15.1. Building Character
28.2. Special Variables in Alphabetical Order
. (dot) ;concatenation operator: 24.2.1. Time Efficiency
=; (equal sign)
=;> (corresponds to) operator: 3.18. Comma Operators
> (right angle bracket)
in debugger commands: 20.2.6. Actions and Command Execution
for filename globbing: 2.11.3. Filename Globbing Operator
in filenames: 29.2.104. open
greater than operator: 3.11. Relational Operators
> (greater than) operator: 1.4. Filehandles
for line input operator (see angle operator)
for right justification: 7.1. Format Variables
>= (greater than or equal) operator: 3.11. Relational Operators
>> (right-shift) operator: 3.9. Shift Operators
>>= (assignment) operator: 3.17. Assignment Operators
< (left angle bracket)
for left justification: 7.1. Format Variables
in debugger commands: 20.2.6. Actions and Command Execution
for filename globbing: 2.11.3. Filename Globbing Operator
in filenames: 29.2.104. open
<=> (comparison) operator: 1.5.6. Some Numeric and String Comparison Operators
29.2.159. sort
<< for here documents: 2.6.6. "Here" Documents
<<= (assignment) operator: 3.17. Assignment Operators
less than operator: 3.11. Relational Operators
<= (less than or equal) operator: 1.5.6. Some Numeric and String Comparison Operators
3.11. Relational Operators
for line input: 2.11.2. Line Input (Angle) Operator
|| (OR logical operator): 1.5.5. Logical Operators
( ) (parentheses);grouping operator: 5.9.4. The Little Engine That /Could(n't)?/
% (percent sign): 3.10. Named Unary and File Test Operators
for checksums: 29.2.189. unpack
for hash names: 1.2.1.2.2. Hashes.
2.4. Variables
modulus operator: 3.7. Multiplicative Operators
%= (modulus assignment) operator: 3.17. Assignment Operators
prototype character: 6.4. Prototypes
signifying variable type: 1.2.1. Variable Syntax
| (pipe symbol)
for pattern alternation: 5.8. Alternation
+ (plus) ;unary operator: 3.5. Ideographic Unary Operators
?(question mark): 3.10. Named Unary and File Test Operators
" (double quotes): 2.6.2. String Literals
5.2. Pattern-Matching Operators
5.2. Pattern-Matching Operators
8.5. Braces, Brackets, and Quoting
conversion operator, stringification: 13.3. Overloadable Operators
in formline arguments: 29.2.42. formline
in replacement string: 5.2.3. The s/// Operator (Substitution)
translation escape processing: 5.9.2.1. When backslashes happen
; (semicolon)
in filenames, security risks of: 23.1.2. Cleaning Up Your Environment
Perl statements, terminating with: 2.2. Molecules
simple statements, ending in: 4.1. Simple Statements
/ (slash): 3.10. Named Unary and File Test Operators
debugger command: 20.2.5. Locating Code
delimiters, replacing as: 2.6.3. Pick Your Own Quotes
division operator: 3.7. Multiplicative Operators
root directory: 29.2.15. chroot
/=; (assignment) operator: 3.17. Assignment Operators
// (see m// operator)
{ } (braces)
hash key, enclosing in: 1.2.1.2.2. Hashes.
~ (tilde)
bitwise negation operator: 3.5. Ideographic Unary Operators
to suppress blank lines: 7. Formats
_(underscore)
global filehandle: 28.2. Special Variables in Alphabetical Order
| (vertical bar)
for alternation: 5.1. The Regular Expression Bestiary
bitwise or operator: 3.13. Bitwise Operators
for centering: 7.1. Format Variables
debugger command: 20.2.6. Actions and Command Execution
...|... alternation: 5.3.1. Metasymbol Tables
in filenames: 29.2.104. open
-| piping pseudocommand: 16.3.2. Talking to Yourself
metacharacter: 5.1. The Regular Expression Bestiary
5.3. Metacharacters and Metasymbols
|| (logical or) operator: 5.9.1. Letting Perl Do the Work
12.3.3. Syntactic Snafus with Indirect Objects
|= (assignment) operator: 3.17. Assignment Operators
|- piping pseudocommand: 16.3.2. Talking to Yourself
|| debugger command: 20.2.6. Actions and Command Execution
||= (assignment) operator: 3.17. Assignment Operators
32-bit systems: 25.2. Endianness and Number Width
0 but true: 29.2.37. fcntl
-w exemption: 29.2.37. fcntl
-0 command-line switch: 19.1. Command Processing
0+ (numification) operator: 13.3. Overloadable Operators

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

.al filename extensions: 10.2. Autoloading
-a (autosplit) command-line switch: 19.1.3. Switches
-A (access age) file test operator: 3.10. Named Unary and File Test Operators
A (string boundary): 5.6.1. Beginnings: The A and ^ Assertions
Control-A: 5.2.3. The s/// Operator (Substitution)
abbreviations, text: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
abs (absolute value) function: 29.2.1. abs
abstraction: 10. Packages
in object-oriented programming: 12.3. Method Invocation
accept function: 29.2.2. accept
access checks, setting in constructor: 12.7.5. Using Closures for Private Objects
access time, file: 29.2.165. stat
29.2.193. utime
accessing
array of hashes: 9.3.3. Access and Printing of an Array of Hashes
elements, tied arrays: 14.2.1. Array-Tying Methods
hashes of arrays: 9.2.3. Access and Printing of a Hash of Arrays
multidimensional arrays: 9.1.3. Access and Printing
multidimensional hashes: 9.4.3. Access and Printing of a Hash of Hashes
overridden methods: 12.5.2. Accessing Overridden Methods
records of elaborate data structures: 9.6.1. Composition, Access, and Printing of More Elaborate Records
slices of multidimensional arrays: 9.1.4. Slices
accessor methods: 12.4.2. Initializers
class data methods, working like: 12.8. Managing Class Data
creating: 12.7. Managing Instance Data
generating with autoloading: 12.7.3. Generating Accessors with Autoloading
generating with closures: 12.7.4. Generating Accessors with Closures
pseudohashes and: 12.7.1. Field Declarations with use fields
$ACCUMULATOR: 28.2. Special Variables in Alphabetical Order
actions (debugger)
command execution, specifying from debugger: 20.2.6. Actions and Command Execution
listing all: 20.2.2. Breakpoints
ActiveState Perl distribution
installing on Windows systems: 19.1.1. #! and Quoting on Non-Unix Systems
Microsoft-only modules: 32.1.20. Microsoft-Related Modules
PPM (Perl Package Manager): 22.2. Using CPAN Modules
adding additional array elements: 29.2.190. unshift
addition: 1.5.1. Some Binary Arithmetic Operators
overloaded plus (+) operator: 13.2. Overload Handlers
additive operators: 3.8. Additive Operators
address-of operator (in C): 3.21. C Operators Missing from Perl
addresses
C language, Perl vs.: 24.1.3. C Traps
getting from hostnames: 29.2.52. getnetbyname
network, getting from hostnames: 29.2.48. gethostbyname
network, translating to names: 29.2.47. gethostbyaddr
29.2.51. getnetbyaddr
packed socket: 29.2.67. getsockname
reused, displaying contents of: 20.3.3. Debugger Options
socket names as: 29.2.5. bind
alarm function: 29.2.3. alarm
pattern match, timing out: 23.3.2. Code Masquerading as Data
alert (bell): 2.6.2. String Literals
Perl modules for: 22.1. The CPAN modules Directory
for characters: 5.3.2. Specific Characters
debugger command for: 20.2.7. Miscellaneous Commands
in for/foreach loops
searching and replacing elements in arrays: 5.2.3.1. Modifying strings en passant
for/foreach loops, creating with: 4.5.1. Case Structures
symbol table entries: 2.5.1. Name Lookups
2.10. Typeglobs and Filehandles
symbol table key, assignment to typeglob: 10.1. Symbol Tables
aliasing, in foreach loops: 4.4.3. foreach Loops
ALRM signal: 16.1.3. Timing Out Slow Operations
alternation: 5.1. The Regular Expression Bestiary
character classes and: 5.4.1. Custom Character Classes
interior, limiting scope of: 5.7.2. Clustering
match one or the other (...|...): 5.3.1. Metasymbol Tables
in patterns: 5.8. Alternation
precedence, pattern matching: 5.9.4. The Little Engine That /Could(n't)?/
American Standard Code for Information Interchange (see ASCII)
anchors: 1.7.3. Nailing Things Down
5.6. Positions
and (&) bitwise operator: 3.13. Bitwise Operators
and (&&) logical operator: 1.5.5. Logical Operators
3.14. C-Style Logical (Short-Circuit) Operators
3.20. Logical and, or, not, and xor
precedence, and operator vs. &&: 12.3.3. Syntactic Snafus with Indirect Objects
and operator: 24.3. Programming with Style
angle brackets (see right and left angle brackets)
angle operator: 2.11.2. Line Input (Angle) Operator
19.1.3. Switches
24.1.2. Frequently Ignored Advice
reading filehandle from: 14.4.1. Filehandle-Tying Methods
array composer: 8.2.2.1. The anonymous array composer
arrays
hash of, creating: 9.2.1. Composition of a Hash of Arrays
two-dimensional array slice: 9.1.4. Slices
hash composer: 8.2.2.2. The anonymous hash composer
hashes
adding to multidimensional hashes: 9.4.1. Composition of a Hash of Hashes
array of, creating: 9.3.1. Composition of an Array of Hashes
data structue for objects: 12.4. Object Construction
pipes: 16.3.1. Anonymous Pipes
referents: 8.1. What Is a Reference?
subroutine composer: 8.2.2.3. The anonymous subroutine composer
subroutines: 6. Subroutines
giving names at run time: 10.1. Symbol Tables
AnyDBM_File module: 32.1.10. DBM Interfaces
Apache web server: 21.4. Embedding Perl (Using Perl from C)
CGI::Apache module: 32.1.9. World Wide Web
mod_perl extension: 18.3. Executing Your Code
Perl modules for: 22.1. The CPAN modules Directory
appending
elements to arrays: 9.1.2. Growing Your Own
29.2.116. push
members to existing hash: 9.3.2. Generation of an Array of Hashes
arctangents: 29.2.4. atan2
$ARG: 28.2. Special Variables in Alphabetical Order
(see also parameters)
formal: 28.2. Special Variables in Alphabetical Order
@ARGV array: 2.11.2. Line Input (Angle) Operator
28.2. Special Variables in Alphabetical Order
ARGV filehandle: 28.2. Special Variables in Alphabetical Order
$ARGV variable: 28.2. Special Variables in Alphabetical Order
ARGVOUT filehandle: 28.2. Special Variables in Alphabetical Order
arithmetic, overloaded objects and: 13.2. Overload Handlers
arithmetic operators: 3.5. Ideographic Unary Operators
binary arithmetic operators: 1.5.1. Some Binary Arithmetic Operators
order of evaluation: 1.5.1. Some Binary Arithmetic Operators
overloading: 13.3. Overloadable Operators
arity: 3. Unary and Binary Operators
highest to lowest, listing of: 3. Unary and Binary Operators
array context (see list context)
arrayDepth option (debugger): 20.3.3. Debugger Options
arrays: 1.2.1. Variable Syntax
1.2.1.2. Pluralities
2.3. Built-in Data Types
(see also lists)
@_ arrays: 6.2. Semantics
copying values to my list: 6.2.1. Tricks with Parameter Lists
anonymous, objects implemented as: 12.7.1. Field Declarations with use fields
use fields pragma, overcoming problems with: 12.7.1. Field Declarations with use fields
anonymous, references to: 8.2.2.1. The anonymous array composer
appending elements to: 29.2.116. push
associative (see hashes)
AV (array value) typedef in C, corresponding to: 21.2. Internal Data Types
deleting elements of: 29.2.149. shift
29.2.160. splice
elements, giving temporary values to: 29.2.87. local
exists function and: 29.2.34. exists
first element of: 28.2. Special Variables in Alphabetical Order
of hashes: 9.3. Arrays of Hashes
accessing and printing: 9.3.3. Access and Printing of an Array of Hashes
generating: 9.3.2. Generation of an Array of Hashes
hashes of: 9.2. Hashes of Arrays
initializing with x operator: 3.7. Multiplicative Operators
last element of: 2.8.2. Array Length
length of: 2.8.2. Array Length
list values vs.: 2.8. List Values and Arrays
lists and: 2.8. List Values and Arrays
multidimensional: 1.2.1.3. Complexities
9.1. Arrays of Arrays
names for: 2.4. Variables
negative subscripts, counting from end of array: 24.1.5. Previous Perl Traps
nested: 9.1. Arrays of Arrays
two-dimensional arrays, creating and accessing: 9.1.1. Creating and Accessing a Two-Dimensional Array
output style, changing in debugger: 20.3.3. Debugger Options
parsing text into: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
passing by reference into or out of functions: 6.3. Passing References
performance and: 24.2.1. Time Efficiency
pop function and: 29.2.111. pop
prepending elements to: 29.2.190. unshift
processing, functions for: 29.1. Perl Functions by Category
references to: 8.1. What Is a Reference?
replacing/removing elements: 29.2.160. splice
s/// (substitution) operator and: 5.2.3.1. Modifying strings en passant
subscript separator (see $[semi] variable)
taint in: 23.1. Handling Insecure Data
tied, delete function and: 24.1.5. Previous Perl Traps
tying: 14.2. Tying Arrays
methods for: 14.2.1. Array-Tying Methods
notational convenience: 14.2.2. Notational Convenience
Tie::Array module: 32.1.14. Convenient Classes
variables of: 2.6.5. Interpolating Array Values
arrow (->) operator: 8.3.3. Using the Arrow Operator
12.3.1. Method Invocation Using the Arrow Operator
3.2. The Arrow Operator
artificial languages: 1.2. Natural and Artificial Languages
ASCII: 2.1. Atoms
converting to characters: 29.2.14. chr
converting to Unicode: 15.2. Effects of Character Semantics
values for characters: 29.2.106. ord
ASP, Perl modules for: 22.1. The CPAN modules Directory
assertions
defining your own: 5.10.4. Defining Your Own Assertions
lookaround assertions: 5.10.1. Lookaround Assertions
precedence, pattern matching: 5.9.4. The Little Engine That /Could(n't)?/
assertions (in matching)
b and B (word and non word boundary): 5.6.3. Boundaries: The b and B Assertions
positional, z, Z, and $ assertions: 5.6.2. Endings: The z, Z, and $ Assertions
assertions (in patterns): 5.1. The Regular Expression Bestiary
5.3.1. Metasymbol Tables
character classes and: 5.4.1. Custom Character Classes
G positional assertion: 5.2.2. The m// Operator (Matching)
positional: 5.6. Positions
A and ^ assertions (string boundary): 5.6.1. Beginnings: The A and ^ Assertions
assigning to lists: 2.8.1. List Assignment
assignment
to conditional operator: 3.16. Conditional Operator
elements, two-dimsional arrays: 9.1.2. Growing Your Own
of tied variables: 14.1.1. Scalar-Tying Methods
tied array element: 14.2.1. Array-Tying Methods
assignment operators: 1.5.3. Assignment Operators
2.3. Built-in Data Types
3.17. Assignment Operators
overloading: 13.3. Overloadable Operators
13.4. The Copy Constructor (=)
(see also copy constructor)
precedence, Perl versions, differences in: 24.1.5. Previous Perl Traps
values, returning: 1.5.3. Assignment Operators
associative arrays (see also hashes)
29.2.22. dbmopen
3. Unary and Binary Operators
3.11. Relational Operators
astronomy, Perl modules for: 22.1. The CPAN modules Directory
async function: 17.2.1.1. Thread creation
atan function: 29.2.4. atan2
$atime file statistic: 29.2.165. stat
atoms: 5.9.4. The Little Engine That /Could(n't)?/
precedence, pattern matching: 5.9.4. The Little Engine That /Could(n't)?/
attributes: 6.5. Subroutine Attributes
12.4.2. Initializers
attributes module: 32.1.13. Perl Language Extensions and Internals
class: 29.2.99. my
class, storing state for: 12.8. Managing Class Data
files, test operators for: 1.5.7. Some File Test Operators
locked and method, using with threads: 12.7.6. New Tricks
locked, subroutines: 17.2.2.4. The locked attribute
lvalue, subroutines: 12.7.6. New Tricks
objects, hashes of: 1.2.1.3. Complexities
subclass, overriding superclass ancestor: 12.7. Managing Instance Data
subroutines: 6.5. Subroutine Attributes
names, syntax for: 6.5.1. The locked and method Attributes
variable interpolation and: 29.2.107. our
attrs module (obsolete): 32.1.13. Perl Language Extensions and Internals
audio, Perl modules for: 22.1. The CPAN modules Directory
authentication, Perl modules for: 22.1. The CPAN modules Directory
32.1.12. Authentication, Security, and Encryption
authorization, Perl modules for: 22.1. The CPAN modules Directory
autodecrement (--) operator: 1.5.4. Unary Arithmetic Operators
3.3. Autoincrement and Autodecrement
magical: 13.3. Overloadable Operators
autoflushing buffers: 28.2. Special Variables in Alphabetical Order
autogeneration, overloading: 13.3. Overloadable Operators
autoincrement and autodecrement: 13.3. Overloadable Operators
preventing: 13.5. When an Overload Handler Is Missing (nomethod and fallback)
autoincrement (++) operator: 1.5.4. Unary Arithmetic Operators
3.3. Autoincrement and Autodecrement
magical: 3.3. Autoincrement and Autodecrement
13.3. Overloadable Operators
AUTOLOAD method: 12.5.4. Method Autoloading
AUTOLOAD subroutine: 10.2. Autoloading
4.6. goto
12.5.4. Method Autoloading
AutoLoader module: 10.2. Autoloading
32.1.17. Module Installation Support
autoloading
generating accessors with: 12.7.3. Generating Accessors with Autoloading
automatic, line-end processing: 19.1.3. Switches
autosplit mode: 19.1.3. Switches
AutoSplit module: 10.2. Autoloading
32.1.17. Module Installation Support
portability of: 25.3. Files and Filesystems
autosplitting: 10.2. Autoloading
AutoTrace option (debugger): 20.3.3. Debugger Options
autouse module: 32.1.17. Module Installation Support
autouse pragma: 31.2. use autouse
autovivification: 29.2.34. exists
of filehandles: 29.2.104. open
typeglobs: 14.4.1. Filehandle-Tying Methods
AV (internal array value): 21.2. Internal Data Types
awk: 1.7. Regular Expressions
converting to/from Perl: 2.9. Hashes

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

b (backspace assertion in character classes): 5.4.1. Custom Character Classes
5.9.4. The Little Engine That /Could(n't)?/
-b (block special) file test operator: 3.10. Named Unary and File Test Operators
-B (binary file) test operator: 3.10. Named Unary and File Test Operators
B module: 32.1.19. Perl Compiler and Code Generator
B (non word boundary): 5.6.3. Boundaries: The b and B Assertions
b word boundary assertion: 5.1. The Regular Expression Bestiary
5.6.3. Boundaries: The b and B Assertions
1.7.3. Nailing Things Down
B::Asmdata module: 32.1.19. Perl Compiler and Code Generator
B::Assemble module: 32.1.19. Perl Compiler and Code Generator
B::Bblock module: 32.1.19. Perl Compiler and Code Generator
B::Bytecode module: 18.5.1. The Bytecode Generator
32.1.19. Perl Compiler and Code Generator
B::C and B::CC modules: 18.5.2. The C Code Generators
B::C module: 32.1.19. Perl Compiler and Code Generator
B::CC module: 32.1.19. Perl Compiler and Code Generator
B::Debug module: 32.1.19. Perl Compiler and Code Generator
B::Deparse module: 18.6. Code Development Tools
32.1.19. Perl Compiler and Code Generator
B::Disassembler module: 32.1.19. Perl Compiler and Code Generator
B::Lint module: 18.6. Code Development Tools
32.1.19. Perl Compiler and Code Generator
B::Showlex module: 32.1.19. Perl Compiler and Code Generator
B::Stash module: 32.1.19. Perl Compiler and Code Generator
B::Terse module: 32.1.19. Perl Compiler and Code Generator
B::Xref module: 18.6. Code Development Tools
32.1.19. Perl Compiler and Code Generator
backends, compiler: 18.4. Compiler Backends
32.1.19. Perl Compiler and Code Generator
generic interface to: 32.1.19. Perl Compiler and Code Generator
modules: 18.4. Compiler Backends
modules, calling: 18.4. Compiler Backends
backquotes (`): 1.2.1.1. Singularities
backreferences: 1.7.4. Backreferences
5.2.2. The m// Operator (Matching)
5.7.1. Capturing
24.1.1. Universal Blunders
28.2. Special Variables in Alphabetical Order
accessing with numbered variables: 5.7.1. Capturing
creating with parentheses: 5.7.1. Capturing
deriving patterns from matched substrings: 5.10.3.4. Match-time pattern interpolation
backslash ( ), interpreting with double quotes: 1.2.1.1. Singularities
backspace, b assertion in character class: 5.6.3. Boundaries: The b and B Assertions
5.4.1. Custom Character Classes
BACKSPACE character
/b for: 5.9.4. The Little Engine That /Could(n't)?/
backticks, portability of: 25.5. Interprocess Communication (IPC)
backtracking: 5.9.4. The Little Engine That /Could(n't)?/
nonbacktracking subpatterns: 5.10.2. Nonbacktracking Subpatterns
in pattern matching: 5.9.4. The Little Engine That /Could(n't)?/
backup files: 19.1.3. Switches
bare blocks: 4.5. Bare Blocks
case structures, doing with: 4.5.1. Case Structures
bare identifiers: 2.6.4. Or Leave the Quotes Out Entirely
barewords: 2.6.4. Or Leave the Quotes Out Entirely
avoiding, reasons for: 24.1.2. Frequently Ignored Advice
Perl versions, changes in: 24.1.5. Previous Perl Traps
strict pragma, checking use of: 4.9.2. Controlling the Use of Globals
base classes: 12.1. Brief Refresher on Object-Oriented Lingo
32.1.14. Convenient Classes
constructors and: 12.4.2. Initializers
overriding methods of: 12.5.2. Accessing Overridden Methods
for pod filters and translators: 32.1.16. Documentation Support
overridden methods, invoking all: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
UNIVERSAL module, providing for all classes: 32.1.14. Convenient Classes
base module: 32.1.13. Perl Language Extensions and Internals
basename, files: 32.1.4. Filenames, Filesystems, and File Locking
$BASETIME: 28.2. Special Variables in Alphabetical Order
basetime ($^T): 28.2. Special Variables in Alphabetical Order
BASIC programming language
logical operators borrowed from: 1.5.5. Logical Operators
BEGIN blocks: 18.1. The Life Cycle of a Perl Program
21.1. How Perl Works
altering compiler parsing of file: 18.7. Avant-Garde Compiler, Retro Interpreter
initializing variables before calling subroutines: 6.2.3. Scoping Issues
modifications to @INC array, handling with: 11.1. Using Modules
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter
beginnings of strings, matching: 5.6.1. Beginnings: The A and ^ Assertions
Benchmark module: 32.1.18. Development Support
comparing running times of alternate code versions: 32.2. Benchmark
bidirectional communication, pipes: 16.3.3. Bidirectional Communication
bidirectional rendering, Unicode properties: 5.4.3.2. Standard Unicode properties
big-endian: 25.2. Endianness and Number Width
/bin/sh: 19.1. Command Processing
files: 29.2.104. open
decompiling with B::Deparse module: 18.6. Code Development Tools
as regular files: 1.5.7. Some File Test Operators
mode on filehandles: 29.2.6. binmode
operators (see also bitwise operators) : 1.5. Operators
3. Unary and Binary Operators
3. Unary and Binary Operators
class handler, invoking: 13.1. The overload Pragma
pack function: 29.2.108. pack
repetition (x) operator: 1.5.2. String Operators
3.7. Multiplicative Operators
bind function: 29.2.5. bind
DBM file to hash: 29.2.22. dbmopen
operators: 3.6. Binding Operators
variables to packages: 14. Tied Variables
29.2.178. tie
29.2.191. untie
binding operators
=~: 1.7. Regular Expressions
pattern-matching operators, using with: 5.2. Pattern-Matching Operators
tr/// (substitution) operator, use with: 5.2.4. The tr/// Operator (Transliteration)
binmode function: 29.2.6. binmode
binmode: 29.2.104. open
biology, Perl modules for: 22.1. The CPAN modules Directory
bit-shift operators: 3.9. Shift Operators
bit vector, providing array interface to: 14.6. Tie Modules on CPAN
bitmasks: 29.2.141. select (ready file descriptors)
bitwise
negation (~) operator: 3.5. Ideographic Unary Operators
operators: 3.13. Bitwise Operators
3.20. Logical and, or, not, and xor
overloading: 13.3. Overloadable Operators
blank lines, truth value of: 1.6.2.1. The while and until statements
bless function: 12.4. Object Construction
29.2.7. bless
constructors, using with: 12.4. Object Construction
reference as argument for: 8.1. What Is a Reference?
tie vs.: 14. Tied Variables
bless operator: 8.2.3. Object Constructors
8.3.6. Other Tricks You Can Do with Hard References
blib: 21.3.2. Creating Extensions
blib pragma: 31.4. use blib
32.1.17. Module Installation Support
$blksize file statistic: 29.2.165. stat
BLOCK: 4.2. Compound Statements
4.2. Compound Statements
(see also blocks)
block properties, Unicode: 5.4.3.3. Unicode block properties
blocking calls, lock, threads: 17.2.2.1. Synchronizing access with lock
blocking, shared locks: 16.2.1. File Locking
blocking signals: 16.1.4. Blocking Signals
$blocks file statistic: 29.2.165. stat
definition of truth: 1.6.1. What Is Truth?
operators: 1.5.7. Some File Test Operators
Boolean context: 2.7.2. Boolean Context
bool conversion operator: 13.3. Overloadable Operators
m// (match) operator in: 5.2.2. The m// Operator (Matching)
Boolean values: 1.2.1.1. Singularities
bootstrapping modules: 21.3.2. Creating Extensions
32.1.17. Module Installation Support
boundaries, words (matching): 5.6.3. Boundaries: The b and B Assertions
boundary assertions: 1.7.3. Nailing Things Down
bounded array, creating: 14.2.1. Array-Tying Methods
break command (in C): 24.1.3. C Traps
break statement (see last operator)
deleting: 20.2.2. Breakpoints
listing all: 20.2.2. Breakpoints
setting for debugger: 20. The Perl Debugger
setting on load: 20.1. Using the Debugger
setting with debugger commands: 20.2.2. Breakpoints
watch expressions, causing: 20.2.3. Tracing
BSD::Resource module, per-process resource limits, setting: 23.3.2. Code Masquerading as Data
bi-directional pipes, problems with: 16.3.3. Bidirectional Communication
single-character input and: 29.2.43. getc
unflushed buffers in Perl versions: 29.2.40. fork
bug reports: 0.6.3. Bug Reports
bugs: 33. Diagnostic Messages
building CPAN modules: 22.2.2. Building CPAN Modules
data types: 2.3. Built-in Data Types
built-in functions
listing by type: 32.1.16. Documentation Support
overriding: 11.3. Overriding Built-in Functions
subroutines, prototyping to emulate: 6.4. Prototypes
built-in methods, overridden: 12.5.2. Accessing Overridden Methods
built-in operators, operating on character semantics: 15.2. Effects of Character Semantics
bundles: 22.1. The CPAN modules Directory
byte meanings, character class shortcuts: 5.4.2. Classic Perl Character Class Shortcuts
bytecode: 18.1. The Life Cycle of a Perl Program
21. Internals and Externals
Byteloader module: 18.5.1. The Bytecode Generator
bytes: 2.1. Atoms
bit-shift operators: 3.9. Shift Operators
characters vs.: 15. Unicode
29. Functions
reading: 29.2.120. read
29.2.172. sysread
storage locations (see big-endian; little-endian)
bytes module: 32.1.6. Internationalization and Locale

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

%Config hash: 21.4.1. Compiling Embedded Programs
25. Portable Perl
C, matching single byte in C language: 15.2. Effects of Character Semantics
-c (character special) file test: 3.10. Named Unary and File Test Operators
-c (check syntax) command-line switch: 19.1.3. Switches
21.1. How Perl Works
28.2. Special Variables in Alphabetical Order
-C file test operator: 3.10. Named Unary and File Test Operators
accesing Perl from enclosing framework: 18.4. Compiler Backends
C code generators: 18.5.2. The C Code Generators
C stack, storing C variables on: 18.3. Executing Your Code
C-style logical operators: 3.14. C-Style Logical (Short-Circuit) Operators
fcntl.h definitions, loading as Perl constants: 32.1.7. Operating System Interfaces
library functions: 29. Functions
library, signals triggering core dumps in: 16.1. Signals
operators missing in Perl: 3.21. C Operators Missing from Perl
operators, precedence relationships: 3. Unary and Binary Operators
Perl, extending with: 21.3. Extending Perl (Using C from Perl)
creating extensions: 21.3.2. Creating Extensions
external C library, using functions from: 21.3.4. Using Functions from an External C Library
XSUBs and XS language: 21.3.1. XS and XSUBs
Perl extensions and: 21. Internals and Externals
Perl functions, wrapping around: 21.3.1. XS and XSUBs
Perl, running from: 21.4.5. Fiddling with the Perl Stack from C
Perl, using from: 21.4. Embedding Perl (Using Perl from C)
adding Perl interpreter: 21.4.2. Adding a Perl Interpreter to Your C Program
compiling embedded Perl programs: 21.4.1. Compiling Embedded Programs
Perl statement, evaluating: 21.4.4. Evaluating a Perl Statement from C
Perl subroutine, calling from: 21.4.3. Calling a Perl Subroutine from C
XSUB input and output: 21.3.3. XSUB Input and Output
programming, differences from Perl: 24.1.3. C Traps
structs: 29.2.108. pack
syslog functions, using in Perl: 32.1.7. Operating System Interfaces
wrapper programs: 23.2.1. Unix Kernel Security Bugs
/c modifier
failed matches, searching past: 5.6.4. Progressive Matching
-C (native wide characters) command-line switch: 15.1. Building Character
/c pattern modifier: 5.2.4. The tr/// Operator (Transliteration)
C preprocessor: 19.1.3. Switches
C wildcard metasymbol: 5.3.3. Wildcard Metasymbols
Control-C: 2.6.2. String Literals
Control-C or Control-Z, generating signals with: 16.1. Signals
caching: 8.5.2. Garbage Collection, Circular References, and Weak References
callbacks: 8.3.7. Closures
caller function: 29.2.8. caller
Perl versions, changes in return value: 24.1.5. Previous Perl Traps
calling
subroutines indirectly: 6.1. Syntax
can method: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
canonical decomposition, characters: 5.4.3.2. Standard Unicode properties
characters, information on: 15.2. Effects of Character Semantics
capitalization: 2.5. Names
29.2.184. uc
barewords, problems with: 2.6.4. Or Leave the Quotes Out Entirely
changing: 5.2.4. The tr/// Operator (Transliteration)
escape sequences for: 2.6.2. String Literals
label names: 4.4. Loop Statements
lc and lcfirst functions: 29.2.82. lc
method names, tied variables: 14. Tied Variables
in module names: 32.1. Listings by Type
module names: 11.1. Using Modules
package/module names: 24.3. Programming with Style
subroutine names: 6.1. Syntax
uppercase, converting to (u escape): 5.2.3. The s/// Operator (Substitution)
capturing in patterns: 5.7.1. Capturing
suppressing in clustering: 5.7.2. Clustering
words, alphanumeric: 5.2.2. The m// Operator (Matching)
Carp module: 14.1.1. Scalar-Tying Methods
32.1.15. Warnings and Exceptions
32.3. Carp
carriage returns: 25.1. Newlines
(see also newlines)
case
case-sensitive matching, switching off: 5.9.2.1. When backslashes happen
escape sequences for: 5.3.1. Metasymbol Tables
matching, /i operator: 5.2.1. Pattern Modifiers
translation operators, using Unicode tables: 15.2. Effects of Character Semantics
case sensitivity: 5.2.4. The tr/// Operator (Transliteration)
/i modifier (case insensitive): 5.2.1. Pattern Modifiers
case statement: 4.5.1. Case Structures
case structure: 4.5.1. Case Structures
casting
strings and: 2.6. Scalar Values
cat command (Unix): 14.3.1. Hash-Tying Methods
categories of functions: 29.1. Perl Functions by Category
categories, characters: 5.4.3.2. Standard Unicode properties
cbreak option: 29.2.43. getc
C/C++ languages, static variables: 6.2.3. Scoping Issues
centering: 7.1. Format Variables
/cg pattern modifier: 5.2.2. The m// Operator (Matching)
CGI, Perl modules for: 22.1. The CPAN modules Directory
32.1.9. World Wide Web
managing HTML forms with: 32.4. CGI
CGI scripts
input, evaluating (Safe module): 23.3.1.3. Safe examples
taint mode, necessity of running under: 23.1. Handling Insecure Data
CGI::Apache module: 32.1.9. World Wide Web
CGI::Carp module: 32.1.9. World Wide Web
32.5. CGI::Carp
CGI::Cookie module: 32.1.9. World Wide Web
CGI::Fast module: 32.1.9. World Wide Web
CGI::Pretty module: 32.1.9. World Wide Web
CGI::Push module: 32.1.9. World Wide Web
character classes: 1.7. Regular Expressions
5.4. Character Classes
5.9.4. The Little Engine That /Could(n't)?/
confusing with array subscripts: 2.6.5. Interpolating Array Values
custom: 5.4.1. Custom Character Classes
matching against character properties in Unicode: 15.2. Effects of Character Semantics
metasymbols used within: 5.3.1. Metasymbol Tables
Perl classic: 5.4.3.4. Defining your own character properties
Perl shortcuts for: 5.4.2. Classic Perl Character Class Shortcuts
POSIX-style: 5.4.4. POSIX-Style Character Classes
predefined, availability of: 15.2. Effects of Character Semantics
Unicode properties: 5.4.3. Unicode Properties
wildcard metasymbols and: 5.3.3. Wildcard Metasymbols
character metasymbols in character classes: 5.4.1. Custom Character Classes
character semantics, effects of: 15.2. Effects of Character Semantics
character sets
ordering and ranges of characters in: 5.2.4. The tr/// Operator (Transliteration)
portability of: 25.9. Internationalization
Unicode: 15. Unicode
characters: 2.1. Atoms
5.9.4. The Little Engine That /Could(n't)?/
prototype: 6.4. Prototypes
aliases for: 5.3.2. Specific Characters
bytes vs.: 15. Unicode
29. Functions
case of (see capitalization)
converting between fixed 8-bit and variable-length UTF-8: 15.1. Building Character
decomposition of: 5.4.3.2. Standard Unicode properties
deleting: 29.2.11. chomp
$[ variable: 28.2. Special Variables in Alphabetical Order
in formats: 29.2.108. pack
funny characters preceding variable names: 14. Tied Variables
getting ASCII values of: 29.2.106. ord
getting from ASCII values: 29.2.14. chr
getting from Unicode values: 29.2.14. chr
hexadecimal (see hexadecimal characters)
length in: 29.2.84. length
metacharacters: 5.1. The Regular Expression Bestiary
octal (see octal characters)
in patterns: 5.1. The Regular Expression Bestiary
properties: 5.4.3.4. Defining your own character properties
defining your own: 5.4.3.4. Defining your own character properties
replacing in strings: 5.2.4. The tr/// Operator (Transliteration)
single-character input: 29.2.43. getc
special: 5.9.4. The Little Engine That /Could(n't)?/
wildcard matches for: 5.3.3. Wildcard Metasymbols
charnames module: 32.1.6. Internationalization and Locale
charts, generating: 7. Formats
chdir function: 29.2.9. chdir
calling without argument: 19.2. Environment Variables
precedence and: 3.1. Terms and List Operators (Leftward)
CHECK blocks: 18.1. The Life Cycle of a Perl Program
21.1. How Perl Works
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter
checking, taint: 23.1. Handling Insecure Data
checksums: 29.2.189. unpack
chemistry, Perl modules for: 22.1. The CPAN modules Directory
child processes: 29.2.196. wait
(see also processes)
ID, returning: 29.2.40. fork
readable, starting: 16.3.1. Anonymous Pipes
starting writeable: 16.3.1. Anonymous Pipes
$CHILD_ERROR: 28.2. Special Variables in Alphabetical Order
chmod function: 1.3.1. How to Do It
29.2.10. chmod
chomp function: 1.4. Filehandles
29.2.11. chomp
chop function: 1.4. Filehandles
29.2.12. chop
29.2.12. chop
(see also chomp function)
chown function: 29.2.13. chown
chr function: 15.2. Effects of Character Semantics
29.2.14. chr
chroot function: 29.2.15. chroot
chroot syscall: 23.3.1.1. Restricting namespace access
circular references: 8.5.2. Garbage Collection, Circular References, and Weak References
breaking: 12.6.1. Garbage Collection with DESTROY Methods
overloading, avoiding in: 13.3. Overloadable Operators
class inheritance: 12.5. Class Inheritance
class methods: 12.1. Brief Refresher on Object-Oriented Lingo
constructors as: 12.4.1. Inheritable Constructors
package names as invocants for: 12.3. Method Invocation
Thread class: 17.2.1. The Thread Module
Class::Contract module: 12.7.5. Using Closures for Private Objects
classes: 10. Packages
12.1. Brief Refresher on Object-Oriented Lingo
base (see base classes)
data, managing for: 12.8. Managing Class Data
storing references to class data in object itself: 12.8. Managing Class Data
definitions of
object-oriented modules as: 11.1. Using Modules
derived (see derived classes)
functions dealing with: 29.1. Perl Functions by Category
generating with Class::Struct module: 12.7.2. Generating Classes with Class::Struct
implementing tie: 14. Tied Variables
implementing tied filehandles: 14.4. Tying Filehandles
implementing tied hashes: 14.3. Tying Hashes
inheritance among: 12.5. Class Inheritance
base module: 32.1.13. Perl Language Extensions and Internals
method autoloading: 12.5.4. Method Autoloading
overridden methods, accessing: 12.5.2. Accessing Overridden Methods
private methods, avoiding with: 12.5.5. Private Methods
UNIVERSAL class and: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
@ISA array, including with base pragma: 12.5.1. Inheritance Through @ISA
modules vs.: 10. Packages
objects, giving to: 12.4. Object Construction
package: 3.2. The Arrow Operator
29.2.178. tie
29.2.191. untie
packages as: 12.2. Perl's Object System
Perl: 5.4. Character Classes
pseudohash implementations of: 29.2.99. my
quoting packages for: 12.3.4. Package-Quoted Classes
scalar-tying: 14.1.1. Scalar-Tying Methods
version number, returning: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
Class::Multimethods module: 12.5.2. Accessing Overridden Methods
Class::Struct module: 32.1.1. Data Types
32.6. Class::Struct
clearing hashes: 14.3.1. Hash-Tying Methods
networking, getting name of: 16.5.2. Networking Servers
TCP: 16.5.1. Networking Clients
cloisters: 5.7.3. Cloistered Pattern Modifiers
close function: 16.3.1. Anonymous Pipes
29.2.16. close
close-on-exec flag: 28.2. Special Variables in Alphabetical Order
closedir function: 29.2.17. closedir
closing
 server connections (half-close): 16.5.1. Networking Clients
closing tied filehandles: 14.4.1. Filehandle-Tying Methods
closures: 4.8.2. Lexically Scoped Variables: my
8.3.7. Closures
assigning to glob to define subroutine: 10.2. Autoloading
creating: 6.1. Syntax
as function templates: 8.3.7.1. Closures as function templates
generating accessor methods with: 12.7.4. Generating Accessors with Closures
nested subroutines, emulating with: 8.3.7.2. Nested subroutines
private objects, using for: 12.7.5. Using Closures for Private Objects
threads: 17.2.1.1. Thread creation
clustering in patterns: 5.7.2. Clustering
without capturing, reasons for: 5.7.2. Clustering
cmp operator: 1.5.6. Some Numeric and String Comparison Operators
29.2.159. sort
code
effienciency of: 24.2.3. Programmer Efficiency
extracting and displaying with debugger: 20.2.5. Locating Code
insecure, handling: 23.3. Handling Insecure Code
code masquerading as data: 23.3.2. Code Masquerading as Data
safe compartments for: 23.3.1. Safe Compartments
safe examples: 23.3.1.3. Safe examples
mixing character semantics with byte semantics: 15.1. Building Character
reusing: 24.3. Programming with Style
code generators: 18.4. Compiler Backends
32.1.19. Perl Compiler and Code Generator
18.1. The Life Cycle of a Perl Program
18.5. Code Generators
bytecode generator: 18.5.1. The Bytecode Generator
C Code generators: 18.5.2. The C Code Generators
code subpatterns in regular expressions: 5.10.3.3. Match-time code evaluation
combining character sequence, matching with X: 5.3.3. Wildcard Metasymbols
15.2. Effects of Character Semantics
comma (,) (see comma)
command input operator (see backtick operator)
command line
calling perl interpreter from: 1.3.1. How to Do It
modules for processing: 32.1.3. Option, Argument, Parameter, and Configuration File Processing
screen appearance of: 20.3.3. Debugger Options
editing: 22.1. The CPAN modules Directory
flags
: 22.1. The CPAN modules Directory
switches: 22.1. The CPAN modules Directory
command processing: 19.1.2. Location of Perl
commands
accessing under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges
buffering: 28.2. Special Variables in Alphabetical Order
debugger: 20.2. Debugger Commands
actions and: 20.2.6. Actions and Command Execution
breakpoints: 20.2.2. Breakpoints
for display: 20.2.4. Display
20.2.4. Display
documentation, viewing: 20.2.7. Miscellaneous Commands
locating code: 20.2.5. Locating Code
options, manipulating: 20.2.7. Miscellaneous Commands
quitting debugger: 20.2.7. Miscellaneous Commands
restarting debugger: 20.2.7. Miscellaneous Commands
stepping and running: 20.2.1. Stepping and Running
tracing: 20.2.3. Tracing
for loop control: 4.4.4. Loop Control
hashes of functions, storing in: 9.5. Hashes of Functions
history, debugger and: 20.1. Using the Debugger
names for: 1.2.2. Verbs
in pod: 26.1.2. Pod Directives
processing: 19.1. Command Processing
19.1. Command Processing
(see also interpreters; Perl interpreter)
recalling, debugger option: 20.3.3. Debugger Options
multiline: 26.1. Pod in a Nutshell
definition: 2.2. Molecules
discarding before processing: 5.9.1. Letting Perl Do the Work
extending with /x pattern modifier: 5.2.1. Pattern Modifiers
Perl vs. C syntax for: 24.1.3. C Traps
comparing
files: 32.1.4. Filenames, Filesystems, and File Locking
running time of alternate code versions: 32.1.18. Development Support
strings: 3.11. Relational Operators
24.1.1. Universal Blunders
thread objects: 17.2.1.5. Identifying threads
comparison operators: 1.5.6. Some Numeric and String Comparison Operators
1.5.6. Some Numeric and String Comparison Operators
3.12. Equality Operators
overloading: 13.3. Overloadable Operators
sort function and: 29.2.159. sort
compatibility decomposition, characters: 5.4.3.2. Standard Unicode properties
compilation: 21. Internals and Externals
order of: 18.7. Avant-Garde Compiler, Retro Interpreter
compilation phase, processing Perl program: 21.1. How Perl Works
compilation units: 2.5.1. Name Lookups
compile phase vs. compile time: 18.2. Compiling Your Code
compile time, controlling debugger during: 20.1. Using the Debugger
compiler: 28.2. Special Variables in Alphabetical Order
compiler hints: 28.2. Special Variables in Alphabetical Order
compiler, Perl
backends for: 18.4. Compiler Backends
modules related to: 22.1. The CPAN modules Directory
global declarations and: 4.7. Global Declarations
regex compiler: 5.9.3. The Regex Compiler
compilers, Perl
interpreters, interaction with: 18.7. Avant-Garde Compiler, Retro Interpreter
modules related to: 32.1.19. Perl Compiler and Code Generator
compiling: 18. Compiling
compiling your code: 18.2. Compiling Your Code
embedded Perl program (in C): 21.4.1. Compiling Embedded Programs
life cycle, Perl programs
18.1. The Life Cycle of a Perl Program
code generation phase: 18.1. The Life Cycle of a Perl Program
compile phase: 18.1. The Life Cycle of a Perl Program
parse tree reconstruction: 18.1. The Life Cycle of a Perl Program
comp.lang.perl newsgroups: 0.6.2. Usenet Newsgroups
complementation (see negation)
complex data structures
creating in Perl: 9. Data Structures
representing as scalars: 1.2.1.3. Complexities
composite Unicode properties: 5.4.3.1. Perl's Unicode properties
Comprehensive Pearl Archive Network (see CPAN)
COMSPEC environment variable: 19.2. Environment Variables
concatenating strings: 1.5.2. String Operators
concatenation (.) operator: 1.5.2. String Operators
3.8. Additive Operators
24.2.1. Time Efficiency
autogeneration via stringification handler: 13.3. Overloadable Operators
string constants, overloading: 13.6. Overloading Constants
condition variables: 17.2.2.6. Condition variables
conditional (?:) operator: 3.16. Conditional Operator
4.5.1. Case Structures
conditional code execution: 1.5.5. Logical Operators
conditional context (see Boolean context)
conditional statements: 4.3. if and unless Statements
(see also if statements; unless statements)
without braces, writing: 4.2. Compound Statements
conditionals, interpolation into patterns: 5.10.3.5. Conditional interpolation
conditions, expressions in loops: 4.4.2. for Loops
Config module: 32.1.17. Module Installation Support
operating system mapping between signal names and numbers: 16.1. Signals
configuration files, Perl modules for: 22.1. The CPAN modules Directory
configuration, Perl, for debugging: 19.1.3. Switches
connect function: 29.2.18. connect
shutting down: 29.2.154. shutdown
constant pragma: 10.1. Symbol Tables
constants: 10.1. Symbol Tables
inlining constant functions: 6.4.1. Inlining Constant Functions
overloading: 13.6. Overloading Constants
Perl, loading fcntl.h definitions as: 32.1.7. Operating System Interfaces
System V IPC, defining for: 32.1.8. Networking and Interprocess Communication
constructors: 8.2.3. Object Constructors
12.1. Brief Refresher on Object-Oriented Lingo
12.4. Object Construction
access checks, setting in: 12.7.5. Using Closures for Private Objects
bless function and: 12.4. Object Construction
class names or objects, working with: 12.4.1. Inheritable Constructors
inheritable: 12.4.1. Inheritable Constructors
initializers: 12.4.2. Initializers
naming: 12.4.2. Initializers
new method: 29.2.100. new
tied variable classes: 14. Tied Variables
container classes holding pointers to self-referential data structures: 12.6.1. Garbage Collection with DESTROY Methods
context: 2.7. Context
2.7. Context
Boolean context: 2.7.2. Boolean Context
interpolative (double-quoted) context: 2.7.4. Interpolative Context
scalar and list context: 2.7.1. Scalar and List Context
void: 29.2.198. wantarray
void context: 2.7.3. Void Context
context stack: 18.3. Executing Your Code
continuation lines: 4.4.4. Loop Control
28.2. Special Variables in Alphabetical Order
continue block: 4.4.1. while and until Statements
4.4.3. foreach Loops
4.4.4. Loop Control
4.4.4. Loop Control
(see also loops)
continue command (in C): 24.1.3. C Traps
contract between module and user: 11.2.1. Module Privacy and the Exporter
contractions in words, avoiding confusion with single quotes: 5.10.1. Lookaround Assertions
control characters: 2.6.2. String Literals
metasymbols in patterns: 5.3.2. Specific Characters
non-ASCII on Macintosh: 19.1.1. #! and Quoting on Non-Unix Systems
control structures: 1.6. Control Structures
truth, defining: 1.6.1. What Is Truth?
control variables: 4.4.3. foreach Loops
conversion operators
Boolean context, interpreting object in: 13.3. Overloadable Operators
numification (nonnumeric variable converted to number): 13.3. Overloadable Operators
stringification: 13.3. Overloadable Operators
converting
ASCII value to character: 29.2.14. chr
between integers and UTF-8 characters: 15.2. Effects of Character Semantics
between languages: 24.5.2. Generating Perl in Other Languages
characters to ASCII values: 29.2.106. ord
data types between C and Perl: 21.4.5. Fiddling with the Perl Stack from C
decimal numbers to binary digits or octals: 29.2.162. sprintf
decimal numbers to octal or hexadecimal: 29.2.162. sprintf
hexadecimal numbers to decimal: 29.2.73. hex
list values to strings: 29.2.78. join
29.2.108. pack
numbers to/from hexadecimal: 5.2.3. The s/// Operator (Substitution)
octal numbers to decimal: 29.2.103. oct
strings to list values: 29.2.161. split
29.2.189. unpack
time: 29.2.70. gmtime
29.2.88. localtime
Unicode value to character: 29.2.14. chr
cookies (HTTP), setting and getting: 32.1.9. World Wide Web
copy constructor: 13.4. The Copy Constructor (=)
copy-on-write semantics: 17.1. The Process Model
copying filenames or filehandles: 32.1.4. Filenames, Filesystems, and File Locking
denial-of-service problems with pattern matching: 23.3.2. Code Masquerading as Data
dump function for: 29.2.29. dump
Thread::Signal module, preventing with: 17.2.3.3. Other standard threading modules
signals triggering in C library: 16.1. Signals
core files: 19.1.3. Switches
core modules, Perl: 22.1. The CPAN modules Directory
CORE pseudopackage: 11.3. Overriding Built-in Functions
12.5.2. Accessing Overridden Methods
CORE::GLOBAL pseudopackage: 11.3. Overriding Built-in Functions
cos function (cosines): 29.2.19. cos
counters, magical counter variables: 14.1.2. Magical Counter Variables
CPAN (Comprehensive Perl Archive Network): 10. Packages
1.2.1.4. Simplicities
10. Packages
11. Modules
22. CPAN
CPAN module as automated interface to: 32.8. CPAN
modules
32.1.17. Module Installation Support
32.8. CPAN
directory: 22.1. The CPAN modules Directory
installing modules with: 22.2. Using CPAN Modules
portability of: 25.7. Standard Modules
building: 22.2.2. Building CPAN Modules
categories of modules: 22.1. The CPAN modules Directory
creating: 22.3. Creating CPAN Modules
decompressing and unpacking: 22.2.1. Decompressing and Unpacking CPAN Modules
installing and building: 22.2. Using CPAN Modules
installing into Perl library: 22.2.3. Installing CPAN Modules into the Perl Library
subdirectories: 22. CPAN
tie modules on: 14.6. Tie Modules on CPAN
CPU
access in multitasking environment: 23.2. Handling Timing Glitches
condition variables allowing threads to relinquish: 17.2.2.6. Condition variables
CPU time: 29.2.181. times
CPU, yielding (threads): 17.2.1.7. Yielding the processor
creation time (see modification time, file)
credit cards, Perl modules for: 22.1. The CPAN modules Directory
CRLF: 25.1. Newlines
(see also newlines)
in Internet programs: 16.5.2. Networking Servers
crypt function: 29.2.20. crypt
cryptography: 29.2.164. srand
$ctime file statistic: 29.2.165. stat
curly braces (see {})
1.7.1. Quantifiers
Curses, Perl modules for: 22.1. The CPAN modules Directory
customization
debugger: 20.3. Debugger Customization
debugger options: 20.3.3. Debugger Options
editor support for: 20.3.1. Editor Support for Debugging
functions for: 20.5.1. Writing Your Own Debugger
init files, using: 20.3.2. Customizing with Init Files
Cwd module: 32.1.4. Filenames, Filesystems, and File Locking
current working directory for process, determining: 32.9. Cwd

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

^D (Control-D) as eof: 24.5.2. Generating Perl in Other Languages
Control-D as eof: 24.5.2. Generating Perl in Other Languages
Control-D character: 2.6.8. Other Literal Tokens
2.6.8. Other Literal Tokens
-d (debug) command-line switch: 19.1.3. Switches
19.1.3. Switches
20. The Perl Debugger
-D (debugging) command-line switch: 19.1.3. Switches
d for digit=d (for digit): 1.7. Regular Expressions
/d modifier: 5.2.4. The tr/// Operator (Transliteration)
/d pattern modifier: 5.2.4. The tr/// Operator (Transliteration)
-d switch, perl: 20.6. The Perl Profiler
daemons
Perl modules for: 22.1. The CPAN modules Directory
taint mode, importance of enabling for: 23.1. Handling Insecure Data
data
byte-oriented vs. character-oriented: 15. Unicode
fixed-length, functions for: 29.1. Perl Functions by Category
insecure, handling: 23.1. Handling Insecure Data
code masquerading as data: 23.3.2. Code Masquerading as Data
command and file access under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges
detecting and laundering tainted data: 23.1.1. Detecting and Laundering Tainted Data
environment, cleaning up: 23.1.2. Cleaning Up Your Environment
screen dump, providing: 32.1.13. Perl Language Extensions and Internals
data access
threads: 17.2.2. Data Access
condition variables: 17.2.2.6. Condition variables
deadlock: 17.2.2.2. Deadlock
locking methods: 17.2.2.5. Locking methods
locking subroutines: 17.2.2.3. Locking subroutines
synchronizing with lock: 17.2.2.1. Synchronizing access with lock
unlocking: 17.2.2.1. Synchronizing access with lock
DATA filehandle: 28.2. Special Variables in Alphabetical Order
data organization in Perl: 9.1.5. Common Mistakes
data structures: 9. Data Structures
22.1. The CPAN modules Directory
arrays of hashes: 9.3. Arrays of Hashes
complex, representing as scalars: 1.2.1.3. Complexities
flat, linear in Perl: 8. References
hashes of arrays: 9.2. Hashes of Arrays
hashes of functions: 9.5. Hashes of Functions
multidimensional hashes: 9.4. Hashes of Hashes
objects (see objects)
persistent, providing via tie: 14.6. Tie Modules on CPAN
records of elaborate: 9.6. More Elaborate Records
references to: 8.1. What Is a Reference?
saving: 9.7. Saving Data Structures
self-referential, container classes holding pointers to: 12.6.1. Garbage Collection with DESTROY Methods
stringifying: 9.7. Saving Data Structures
__DATA__ token: 2.6.8. Other Literal Tokens
28.2. Special Variables in Alphabetical Order
data types: 1.2.1. Variable Syntax
built-in: 2.3. Built-in Data Types
converting between C and Perl: 21.4.5. Fiddling with the Perl Stack from C
internal, Perl and C: 21.2. Internal Data Types
modules for: 32.1.1. Data Types
scalars (see scalars)
TYPE declarations in Perl: 29.2.99. my
typeglobs: 2.10. Typeglobs and Filehandles
databases
Data Base Management (see DBM files)
Perl connections to: 5. Pattern Matching
Perl modules for operating: 22.1. The CPAN modules Directory
see also DBI: 22.1. The CPAN modules Directory
tying hash variables to: 14. Tied Variables
Data::Dumper: 9.7. Saving Data Structures
32.1.13. Perl Language Extensions and Internals
32.10. Data::Dumper
datagrams: 16.5. Sockets
date function (see localtime function)
dates, Perl modules for: 22.1. The CPAN modules Directory
dates, portability of: 25.8. Dates and Times
DB module: 32.1.13. Perl Language Extensions and Internals
DB package, caller function: 29.2.8. caller
DBD (Database drivers)
Perl modules for: 22.1. The CPAN modules Directory
DB_File module: 32.1.10. DBM Interfaces
Data::Dumper module, using with: 32.10. Data::Dumper
DBI (Database Interface), Perl modules for: 22.1. The CPAN modules Directory
complex data values, storing in: 32.10. Data::Dumper
dbmclose and dbmopen functions: 29.2.21. dbmclose
deleting from: 29.2.24. delete
locking: 16.2.1. File Locking
modules for: 32.1.10. DBM Interfaces
storing complex data values in: 14.6. Tie Modules on CPAN
DBM modules, portability of: 25.7. Standard Modules
dbmclose function: 14. Tied Variables
dbmopen function: 14. Tied Variables
use declarations with: 14. Tied Variables
dbprofpp program: 20.6. The Perl Profiler
deadlock in threads: 17.2.2.2. Deadlock
deallocating memory: 8.5.2. Garbage Collection, Circular References, and Weak References
debugging: 19.1.3. Switches
20. The Perl Debugger
23.1. Handling Insecure Data
(see also taint)
backend modules for: 18.4. Compiler Backends
bug reports: 0.6.3. Bug Reports
controlling from programs: 20.1. Using the Debugger
DB module: 32.1.13. Perl Language Extensions and Internals
debug level, setting through class or instances: 12.8. Managing Class Data
debugger code, command for loading: 19.2. Environment Variables
debugger commands, Perl: 20.2. Debugger Commands
debugger customization: 20.3. Debugger Customization
options: 20.3.3. Debugger Options
debugging flags: 28.2. Special Variables in Alphabetical Order
debugger support, Perl: 20.5. Debugger Support
debugger, unattended execution: 20.4. Unattended Execution
Devel::Peek module for XS programs: 32.1.13. Perl Language Extensions and Internals
global destruction of objects other references, controlling: 19.2. Environment Variables
overloading: 13.10. Overloading Diagnostics
Perl, using C compiler -DDEBUGGING option: 12.5. Class Inheritance
turning on in tied filehandle: 14.4.1. Filehandle-Tying Methods
Unix security bugs: 23.2.1. Unix Kernel Security Bugs
decimal points, lining up: 7. Formats
declarations: 1.1. Getting Started
4. Statements and Declarations
structs: 12.7.2. Generating Classes with Class::Struct
fields with use fields pragma: 12.7.1. Field Declarations with use fields
global: 4.7. Global Declarations
global variables, lexically scoped: 4.8.3. Lexically Scoped Global Declarations: our
methods, lvalues, indicating return of: 12.7.6. New Tricks
packages: 1.2.1.4. Simplicities
4.8. Scoped Declarations
10. Packages
29.2.109. package
scoped: 4.8. Scoped Declarations
subroutines: 4.7. Global Declarations
with definitions: 6.1. Syntax
use declarations: 1.2.1.4. Simplicities
variables: 4. Statements and Declarations
4.8.1. Scoped Variable Declarations
declarative approach, regular expression programming: 5.10.3. Programmatic Patterns
declaring
formats: 7. Formats
subroutines: 29.2.167. sub
without defining: 6.1. Syntax
decomposing characters into simpler ones: 5.4.3.2. Standard Unicode properties
decompressing CPAN modules: 22.2.1. Decompressing and Unpacking CPAN Modules
decrementing variables: 1.5.4. Unary Arithmetic Operators
decryption (see encryption)
default package: 4.8. Scoped Declarations
DEFAULT pseudosignal: 16.1. Signals
defined function: 29.2.23. defined
defining subroutines: 6.2. Semantics
classes (object-oriented modules as): 11.1. Using Modules
subroutines
declarations vs.: 4.7. Global Declarations
loading from other files: 4.7. Global Declarations
loading with AUTOLOAD: 10.2. Autoloading
DEL in hexadecimal: 2.6.2. String Literals
delete function: 29.2.24. delete
tied arrays, not returning deleted value for: 24.1.5. Previous Perl Traps
deleting
all debugger actions: 20.2.6. Actions and Command Execution
array elements: 29.2.111. pop
29.2.149. shift
29.2.160. splice
breakpoints: 20.2.2. Breakpoints
characters: 29.2.11. chomp
directories: 29.2.135. rmdir
29.2.188. unlink
files: 29.2.188. unlink
found but unreplaced characters: 5.2.4. The tr/// Operator (Transliteration)
hash elements: 29.2.24. delete
pattern-matching operators and: 5.2. Pattern-Matching Operators
denial-of-service problems (patterns and regular expressions), security concerns: 23.3.2. Code Masquerading as Data
dereference-address operator (*), C language: 3.21. C Operators Missing from Perl
dereference operators, overloading: 13.3. Overloadable Operators
dereferencing: 8.1. What Is a Reference?
8.1. What Is a Reference?
8.3. Using Hard References
8.3.1. Using a Variable as a Variable Name
8.3.3. Using the Arrow Operator
array elements: 9.1.3. Access and Printing
hash values as functions: 9.5. Hashes of Functions
operator for (see arrow operator)
typeglobs: 10.1. Symbol Tables
derived classes: 12.1. Brief Refresher on Object-Oriented Lingo
methods as wrappers around base class methods: 12.5.2. Accessing Overridden Methods
descriptors (see file descriptors)
destroying threads
detach method: 17.2.1.4. The detach method
join method: 17.2.1.2. Thread destruction
destructors: 12.6. Instance Destructors
controlling: 19.2. Environment Variables
garbage collection with: 12.6.1. Garbage Collection with DESTROY Methods
shared memory and semaphore: 16.4. System V IPC
detach method: 17.2.1.4. The detach method
$dev file statistic: 29.2.165. stat
Devel::Dprof module: 20.6. The Perl Profiler
profiling subroutine execution with: 20.6. The Perl Profiler
development support, modules for: 22.1. The CPAN modules Directory
Devel::Peek module: 32.1.13. Perl Language Extensions and Internals
Devel::SelfStubber module: 32.1.17. Module Installation Support
Devel::SmallProf module: 20.6. The Perl Profiler
diagnostic messages (see error messages[semi] warning messages)
diagnostics module: 32.1.13. Perl Language Extensions and Internals
die function: 29.2.25. die
exit function versus: 29.2.35. exit
quit signal handling and: 16.1. Signals
dieLevel option (debugger): 20.3.3. Debugger Options
digits: 1.7. Regular Expressions
in names: 2.5. Names
directives (pod): 26.1.2. Pod Directives
directories
changing working: 29.2.9. chdir
closing: 29.2.17. closedir
creating: 29.2.94. mkdir
creating or removing portably: 32.1.4. Filenames, Filesystems, and File Locking
current working, getting pathname of: 32.1.4. Filenames, Filesystems, and File Locking
deleting: 29.2.135. rmdir
29.2.188. unlink
DirHandle module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
file test checks on trees: 32.1.4. Filenames, Filesystems, and File Locking
file test operator: 1.5.7. Some File Test Operators
functions dealing with: 29.1. Perl Functions by Category
IO::Dir module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
opendir function: 29.2.105. opendir
Perl modules for: 22.1. The CPAN modules Directory
prepending to @INC: 19.1.3. Switches
reading entries from: 29.2.121. readdir
rewinddir function: 29.2.133. rewinddir
root, redefining: 29.2.15. chroot
seekdir function: 29.2.139. seekdir
disciplines: 29.2.104. open
filehandles, setting up with binmode: 29.2.6. binmode
division (see multiplicative operators)
DNS (domain name server): 16.5. Sockets
do { }: 3.1. Terms and List Operators (Leftward)
BLOCK: 4.1. Simple Statements
29.2.26. do (block)
iterating: 4.5. Bare Blocks
terminating: 4.5. Bare Blocks
loop controls: 4.1. Simple Statements
4.5. Bare Blocks
FILE operator: 29.2.27. do (file)
loops: 24.1.1. Universal Blunders
SUBROUTINE operator: 4.1. Simple Statements
29.2.28. do (subroutine)
doc directory (CPAN), official Perl manpages: 22. CPAN
documentation
books on Perl: 0.5. Offline Documentation
bug reports: 0.6.3. Bug Reports
C library functions: 29. Functions
default system viewer, calling: 20.2.7. Miscellaneous Commands
embedded in Perl programs: 26. Plain Old Documentation
(see also pod)
modules for: 32.1.16. Documentation Support
Perl manpages: 0.4. Online Documentation
standard modules: 11. Modules
dollar sign ($) (see $)
dosish.h file: 19.1.1. #! and Quoting on Non-Unix Systems
double-ended pipe, opening with tied filehandle: 14.4.2. Creative Filehandles
double-quote context: 2.7.4. Interpolative Context
scalar variables, expanding in: 5.2.3. The s/// Operator (Substitution)
double-quoted strings, interpolation and concatenation: 1.5.2. String Operators
double quotes (") 1.2.1.1. Singularities
replacement string, use with: 5.2.3. The s/// Operator (Substitution)
strings, use in: 1.2.1.1. Singularities
translation escape processing: 5.9.2.1. When backslashes happen
down method: 17.2.3.2. Semaphores
DProf (see Devel::Dprof module)
dump function: 29.2.29. dump
Dumpvalue module: 32.1.13. Perl Language Extensions and Internals
duplicate replaced characters, eliminating: 5.2.4. The tr/// Operator (Transliteration)
DynaLoader: 21.3.2. Creating Extensions
10.2. Autoloading
32.1.17. Module Installation Support
dynamic linking: 21.3.1. XS and XSUBs
C source code from Perl: 21.3. Extending Perl (Using C from Perl)
dynamic scoping: 4.8. Scoped Declarations
4.8.1. Scoped Variable Declarations
4.8.1. Scoped Variable Declarations
local operator, using on global variables: 4.8.4. Dynamically Scoped Variables: local
pattern variables: 5.2. Pattern-Matching Operators
5.2.3. The s/// Operator (Substitution)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

@EXPORT array: 28.2. Special Variables in Alphabetical Order
@EXPORT_OK array: 28.2. Special Variables in Alphabetical Order
%EXPORT_TAGS hash: 28.2. Special Variables in Alphabetical Order
-e (execute) command-line switch: 19.1.3. Switches
-e (exists) file test: 1.5.7. Some File Test Operators
3.10. Named Unary and File Test Operators
/e pattern modifier: 5.2.3. The s/// Operator (Substitution)
each function: 9.4.3. Access and Printing of a Hash of Hashes
14.3.1. Hash-Tying Methods
29.2.30. each
editors, support for debugging: 20.3.1. Editor Support for Debugging
effective GID (group ID): 28.2. Special Variables in Alphabetical Order
effective UID ($EFFECTIVE_USER_ID): 28.2. Special Variables in Alphabetical Order
(see also $< and $> variables)
$EFFECTIVE_GROUP_ID: 28.2. Special Variables in Alphabetical Order
28.2. Special Variables in Alphabetical Order
$EFFECTIVE_USER_ID: 28.2. Special Variables in Alphabetical Order
efficiency (see performance)
profiling: 20.6. The Perl Profiler
elements in arrays: 1.2.1.2.1. Arrays.
else-if statements: 1.6.1.1. The if and unless statements
ellipses (...): 5.3.1. Metasymbol Tables
else statements: 1.6.1.1. The if and unless statements
emacs
editor support for debugger: 20.3.1. Editor Support for Debugging
regular expressions, use of: 1.7. Regular Expressions
-*- sequences: 19.1. Command Processing
email: 22.1. The CPAN modules Directory
(see also mail)
embedding Perl: 21.4. Embedding Perl (Using Perl from C)
32.1.17. Module Installation Support
adding Perl interpreter to C program: 21.4.2. Adding a Perl Interpreter to Your C Program
compiling embedded programs: 21.4.1. Compiling Embedded Programs
evaluating Perl statement from C: 21.4.4. Evaluating a Perl Statement from C
perl interpreter program: 21. Internals and Externals
Perl stack, manipulating from C: 21.4.5. Fiddling with the Perl Stack from C
empty angle operator (<>): 1.4. Filehandles
empty subclass test: 12.5. Class Inheritance
encapsulation: 1.2.1.3. Complexities
8.3.4. Using Object Methods
12.1. Brief Refresher on Object-Oriented Lingo
namespace-based: 14.6. Tie Modules on CPAN
objects in closures: 12.7.5. Using Closures for Private Objects
encryption: 29.2.20. crypt
modules for: 32.1.12. Authentication, Security, and Encryption
Perl modules for: 22.1. The CPAN modules Directory
END blocks: 18.1. The Life Cycle of a Perl Program
exit value of program, modifying: 18.7. Avant-Garde Compiler, Retro Interpreter
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter
skipping: 18.7. Avant-Garde Compiler, Retro Interpreter
end of string, matching: 5.6.2. Endings: The z, Z, and $ Assertions
__END__ token: 2.6.8. Other Literal Tokens
24.5.2. Generating Perl in Other Languages
28.2. Special Variables in Alphabetical Order
endgrent function: 29.2.44. getgrent
endhostent function: 29.2.49. gethostent
ending (see terminating)
ending escape sequences for character modification: 2.6.2. String Literals
endless loop (see infinite loops)
endprotoent function: 29.2.60. getprotoent
endpwent function: 29.2.61. getpwent
endservent function: 29.2.66. getservent
English module: 7.1. Format Variables
32.1.13. Perl Language Extensions and Internals
enqueue method: 17.2.3.1. Queues
%ENV hash: 28.2. Special Variables in Alphabetical Order
deleting from: 29.2.24. delete
portability of: 25.4. System Interaction
Env module: 32.1.13. Perl Language Extensions and Internals
env program, starting Perl with: 19.1. Command Processing
cleaning up: 23.1.2. Cleaning Up Your Environment
environment variables: 19.2. Environment Variables
28.2. Special Variables in Alphabetical Order
Env module: 32.1.13. Perl Language Extensions and Internals
modules, Perl use of: 19.2. Environment Variables
PERLDB_OPTS, setting debugger options with: 20.4. Unattended Execution
PERL_DESTRUCT_LEVEL: 12.6.1. Garbage Collection with DESTROY Methods
portability of: 25.4. System Interaction
shells vs. Perl: 24.1.4. Shell Traps
taint checking: 23.1. Handling Insecure Data
eof function: 1.6.2.1. The while and until statements
24.2.1. Time Efficiency
29.2.31. eof
tied filehandle, using on: 14.4.1. Filehandle-Tying Methods
eq operator: 24.1.1. Universal Blunders
equal method: 17.2.1.5. Identifying threads
equal to (=) operator: 3.12. Equality Operators
equality operators: 3.12. Equality Operators
erasing (see deleting)
errno: 28.2. Special Variables in Alphabetical Order
Errno module: 32.1.13. Perl Language Extensions and Internals
error messages: 24.3. Programming with Style
33. Diagnostic Messages
user efficiency, improving with: 24.2.6. User Efficiency
errors: 29.2.38. fileno
33. Diagnostic Messages
Carp module: 32.3. Carp
CGI::Carp module, handling of: 32.5. CGI::Carp
$@ variable for: 28.2. Special Variables in Alphabetical Order
$! variable for: 28.2. Special Variables in Alphabetical Order
$? variable for: 28.2. Special Variables in Alphabetical Order
failed symbol exports: 11.2.1.3. Managing unknown symbols
insecure data: 23.1. Handling Insecure Data
out-of-memory errors: 28.2. Special Variables in Alphabetical Order
subroutines: 6.2.2. Error Indications
warn function, producing error messages: 29.2.199. warn
writing to httpd or other CGI errors logs: 32.1.9. World Wide Web
ESC character: 2.6.2. String Literals
ESC in octal: 2.6.2. String Literals
escape sequences for control characters: 2.6.2. String Literals
/etc/group file: 24.2.1. Time Efficiency
29.2.44. getgrent
/etc/hosts file: 29.2.49. gethostent
/etc/networks file: 29.2.53. getnetent
/etc/passwd file: 24.2.1. Time Efficiency
29.2.61. getpwent
/etc/protocols file: 29.2.60. getprotoent
/etc/services file: 29.2.66. getservent
/etc/utmp file: 29.2.50. getlogin
eval: 2.5.1. Name Lookups
3.1. Terms and List Operators (Leftward)
8. References
24.2.1. Time Efficiency
29.2.32. eval
die function and: 29.2.25. die
loops and: 24.2.1. Time Efficiency
loop controls and: 4.5. Bare Blocks
packages and: 10. Packages
translating with variables: 5.2.4. The tr/// Operator (Transliteration)
restricted (reval): 23.3.1.1. Restricting namespace access
threads, catching exceptions with: 17.2.1.3. Catching exceptions from join
$EVAL_ERROR: 28.2. Special Variables in Alphabetical Order
eval_sv and eval_pv functions: 21.4.4. Evaluating a Perl Statement from C
intercepting: 28.2. Special Variables in Alphabetical Order
in detached child threads: 17.2.1.4. The detach method
die function and: 29.2.25. die
functions raising: 29.2. Perl Functions in Alphabetical Order
insecure data: 23.1. Handling Insecure Data
modules for: 32.1.15. Warnings and Exceptions
raising on failure: 32.1.13. Perl Language Extensions and Internals
raising to indicate subroutine errors: 6.2.2. Error Indications
threads, catching: 17.2.1.3. Catching exceptions from join
trapping: 29.2.32. eval
$EXCEPTIONS_BEING_CAUGHT: 28.2. Special Variables in Alphabetical Order
exclusive file locks: 16.2.1. File Locking
obtaining: 16.2.1. File Locking
exclusive or (xor) operator: 3.13. Bitwise Operators
3.20. Logical and, or, not, and xor
exec function: 29.2.33. exec
filehandles, leaving open across calls: 16.2.2. Passing Filehandles
list argument form, avoiding shell with: 23.3.2. Code Masquerading as Data
portability of: 25.5. Interprocess Communication (IPC)
executable image file: 18.1. The Life Cycle of a Perl Program
$EXECUTABLE_NAME: 28.2. Special Variables in Alphabetical Order
executing
code: 18.3. Executing Your Code
code, conditionally: 1.5.5. Logical Operators
methods: 12.3. Method Invocation
other programs from Perl: 29.2.174. system
Perl program: 1.3.1. How to Do It
Perl programs: 19.1. Command Processing
execution
code, order of: 18.7. Avant-Garde Compiler, Retro Interpreter
Perl programs: 18.1. The Life Cycle of a Perl Program
unattended, debugger: 20.4. Unattended Execution
execv function (in C): 29.2.33. exec
execvp function (in C): 29.2.33. exec
existence of a process: 16.1.1. Signaling Process Groups
exists function: 29.2.34. exists
invoking on hash: 14.3.1. Hash-Tying Methods
exit function: 29.2.35. exit
29.2.40. fork
threads and: 17.2.1.2. Thread destruction
exit status: 28.2. Special Variables in Alphabetical Order
exiting
debugger: 20.3.3. Debugger Options
if or unless blocks: 4.5. Bare Blocks
infinite loop: 4.4.2. for Loops
once-through blocks: 4.5. Bare Blocks
programs: 1.1. Getting Started
Perl debugger: 20.2.7. Miscellaneous Commands
exp function: 29.2.36. exp
expansion, filename: 29.2.69. glob
Expect module: 16.3.3. Bidirectional Communication
22.1. The CPAN modules Directory
explicit method invocations: 12.3. Method Invocation
exponential notation: 2.6.1. Numeric Literals
exponentiation (**) operator: 3.4. Exponentiation
exponentiation of integers: 21.4.5. Fiddling with the Perl Stack from C
Exporter module: 32.1.17. Module Installation Support
21.3.2. Creating Extensions
module privacy and: 11.2.1. Module Privacy and the Exporter
export_fail method: 11.2.1.3. Managing unknown symbols
exporting: 11. Modules
exporting symbols: 11.2. Creating Modules
11.2.1. Module Privacy and the Exporter
without using import method from Exporter: 11.2.1.1. Exporting without using Exporter's import method
export_to_level method: 11.2.1.1. Exporting without using Exporter's import method
EXPR and LIST: 4.2. Compound Statements
loops, separating with commas (,): 4.4.2. for Loops
multiple, in loops: 4.4.2. for Loops
Perl, supplying in replacement strings: 5.10.3. Programmatic Patterns
EXPRs: 4.2. Compound Statements
goto operator, use with: 4.6. goto
$EXTENDED_OS_ERROR: 28.2. Special Variables in Alphabetical Order
extending arrays: 2.8.2. Array Length
extending Perl: 21.3. Extending Perl (Using C from Perl)
extensions, creating: 21.3.2. Creating Extensions
32.1.13. Perl Language Extensions and Internals
using functions from external C libraby: 21.3.4. Using Functions from an External C Library
XSUB input and output: 21.3.3. XSUB Input and Output
XSUBs and XS language, wrapping Perl in: 21.3.1. XS and XSUBs
external subroutines, portability of: 25.6. External Subroutines (XS)
extracting substrings: 29.2.168. substr
ExtUtils::Command module: 32.1.17. Module Installation Support
ExtUtils::Embed module: 21.4.1. Compiling Embedded Programs
32.1.17. Module Installation Support
ExtUtils::Install module: 32.1.17. Module Installation Support
ExtUtils::Installed module: 32.1.17. Module Installation Support
ExtUtils::Liblist module: 32.1.17. Module Installation Support
ExtUtils::MakeMaker: 22.3. Creating CPAN Modules
22.3. Creating CPAN Modules
(see also MakeMaker)
ExtUtils::MakeMaker module: 32.1.17. Module Installation Support
ExtUtils::Manifest module: 32.1.17. Module Installation Support
ExtUtils::Mkbootstrap module: 32.1.17. Module Installation Support
ExtUtils::Mksymlists module: 32.1.17. Module Installation Support
ExtUtils::MM_Cygwin module: 32.1.17. Module Installation Support
ExtUtils::MM_OS2 module: 32.1.17. Module Installation Support
ExtUtils::MM_Unix module: 32.1.17. Module Installation Support
ExtUtils::MM_VMS module: 32.1.17. Module Installation Support
ExtUtils::MM_Win32 module: 32.1.17. Module Installation Support
ExtUtils::Packlist module: 32.1.17. Module Installation Support
ExtUtils::testlib module: 32.1.17. Module Installation Support

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

$^F variable: 29.2.38. fileno
29.2.38. fileno
%FIELDS hash: 28.2. Special Variables in Alphabetical Order
@F array: 28.2. Special Variables in Alphabetical Order
-F (pattern to split on)command-line switch: 19.1.3. Switches
failed matches, searching past position of: 5.6.4. Progressive Matching
fallback overloading key: 13.5. When an Overload Handler Is Missing (nomethod and fallback)
false values: 1.2.1.1. Singularities
FAQ, Perl online: 24.1. Common Goofs for Novices
Fast CGI protocol, using: 32.1.9. World Wide Web
Fatal module: 32.1.13. Perl Language Extensions and Internals
fcntl function: 29.2.37. fcntl
security risks associated with: 23.2.3. Temporary Files
Fcntl module: 32.1.7. Operating System Interfaces
fcntl syscall, filehandle close-on exec flag, manipulating: 16.2.2. Passing Filehandles
field declarations with use fields pragma: 12.7.1. Field Declarations with use fields
field separator, specifying different: 19.1.3. Switches
fields module: 32.1.13. Perl Language Extensions and Internals
FIFOs: 16.3.4. Named Pipes
__FILE__
24.5.2. Generating Perl in Other Languages
2.6.8. Other Literal Tokens
file conversions, Perl modules for: 22.1. The CPAN modules Directory
file descriptors: 29.2.38. fileno
29.2.141. select (ready file descriptors)
filehandles, passing with: 16.2.2. Passing Filehandles
passing through environment variable or command-line option: 16.2.2. Passing Filehandles
returning for tied filehandles: 14.4.1. Filehandle-Tying Methods
file test operators: 3.10. Named Unary and File Test Operators
-p, checking for FIFO: 16.3.4. Named Pipes
race conditions with: 23.2.2. Handling Race Conditions
File::Basename module: 25.3. Files and Filesystems
32.1.4. Filenames, Filesystems, and File Locking
File::CheckTree module: 32.1.4. Filenames, Filesystems, and File Locking
File::chmod module: 29.2.10. chmod
File::Compare module: 32.1.4. Filenames, Filesystems, and File Locking
File::Copy module: 32.1.4. Filenames, Filesystems, and File Locking
File::DosGlob module: 32.1.4. Filenames, Filesystems, and File Locking
File::Find module: 32.1.4. Filenames, Filesystems, and File Locking
File::Glob module: 32.1.4. Filenames, Filesystems, and File Locking
fileglob operator: 2.11.3. Filename Globbing Operator
FileHandle module: 7.1. Format Variables
7.2.1. Accessing Formatting Internals
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
filehandle-tying: 14.4.1. Filehandle-Tying Methods
filehandles: 1.4. Filehandles
anonymous: 8.2.4. Handle References
angle operator and: 2.11.2. Line Input (Angle) Operator
creating: 1.4. Filehandles
duplicating, reasons for: 29.2.104. open
ending with _TOP: 7. Formats
28.2. Special Variables in Alphabetical Order
file locks on: 16.2.1. File Locking
formats associated with, default names of: 7. Formats
functions dealing with: 29.1. Perl Functions by Category
implicit referencing in: 8.1. What Is a Reference?
local, creating: 29.2.87. local
localizing: 2.10. Typeglobs and Filehandles
names for: 2.5. Names
object methods for, using: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
open function: 29.2.104. open
passing: 6.4. Prototypes
passing in IPC: 16.2.2. Passing Filehandles
through standard filehandles: 16.2.2. Passing Filehandles
piped, explicitly closing: 29.2.104. open
positioning file pointer for: 29.2.138. seek
reading bytes of data from: 29.2.120. read
references to: 8.2.4. Handle References
selecting for output: 29.2.140. select (output filehandle)
SelectSaver module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
syslog tying output to: 14.6. Tie Modules on CPAN
tying: 14.4. Tying Filehandles
creative filehandles: 14.4.2. Creative Filehandles
methods for: 14.4.1. Filehandle-Tying Methods
typeglobs for: 2.10. Typeglobs and Filehandles
use instead of filenames, security benefits of: 23.2.2. Handling Race Conditions
filename globbing operator (see glob operator)
filenames: 2.6.8. Other Literal Tokens
& (ampersand) in: 29.2.104. open
changing name of: 29.2.128. rename
expansions of: 29.2.69. glob
external data in, security risks of: 23.1.2. Cleaning Up Your Environment
getting from symbolic links: 29.2.123. readlink
globbing: 25.4. System Interaction
%INC hash of: 28.2. Special Variables in Alphabetical Order
linking symbolically: 29.2.169. symlink
linking with hard links: 29.2.85. link
mode, separating from: 29.2.104. open
viewing different program or eval statement: 20.2.5. Locating Code
fileno (see file descriptors)
fileno function: 29.2.38. fileno
File::Path module: 32.1.4. Filenames, Filesystems, and File Locking
access and modification times: 29.2.165. stat
29.2.193. utime
accessing under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges
ages for: 3.10. Named Unary and File Test Operators
changing name of: 29.2.128. rename
closing: 29.2.16. close
core: 19.1.3. Switches
deleting: 29.2.188. unlink
do FILE operator: 29.2.27. do (file)
end-of-file: 29.2.31. eof
functions dealing with: 29.1. Perl Functions by Category
getting statistics of: 29.2.165. stat
in interprocess communication: 16.2. Files
locking mechanisms: 16.2.1. File Locking
passing filehandles: 16.2.2. Passing Filehandles
lexically scoped variables and: 2.5.1. Name Lookups
modules, autoloading: 10.2. Autoloading
modules for cross-platform access methods: 32.1.4. Filenames, Filesystems, and File Locking
open function: 29.2.104. open
opening via low-level system call: 29.2.171. sysopen
ownership and group, changing: 29.2.13. chown
path components, separators for: 25.3. Files and Filesystems
Perl module, housing in single: 10. Packages
Perl modules for: 22.1. The CPAN modules Directory
22.1. The CPAN modules Directory
permissions: 29.2.10. chmod
29.2.171. sysopen
29.2.186. umask
portably opening: 25.4. System Interaction
read in binary mode: 29.2.6. binmode
reading via low-level system call: 29.2.172. sysread
renaming, program for: 29.2.32. eval
returning current position for: 29.2.176. tell
scopes: 4.8.2. Lexically Scoped Variables: my
symbolically linking: 29.2.169. symlink
test operators: 1.5.7. Some File Test Operators
text/binary distinction: 29.2.104. open
truncating: 29.2.183. truncate
Win32API::File module: 32.1.20. Microsoft-Related Modules
writing via low-level system call: 29.2.175. syswrite
File::Spec module: 25.3. Files and Filesystems
32.1.4. Filenames, Filesystems, and File Locking
File::Spec::Functions module: 32.1.4. Filenames, Filesystems, and File Locking
File::Spec::Mac module: 32.1.4. Filenames, Filesystems, and File Locking
File::Spec::OS2 module: 32.1.4. Filenames, Filesystems, and File Locking
File::Spec::Unix module: 32.1.4. Filenames, Filesystems, and File Locking
File::Spec::VMS module: 32.1.4. Filenames, Filesystems, and File Locking
32.1.4. Filenames, Filesystems, and File Locking
File::Spec::Win32 module: 32.1.4. Filenames, Filesystems, and File Locking
File::stat module: 32.1.4. Filenames, Filesystems, and File Locking
portability: 25.3. Files and Filesystems
File::Temp module, dealing with race conditions: 23.2.3. Temporary Files
filtering output with forking open: 16.3.2. Talking to Yourself
24.5.3. Source Filters
1.8. List Processing
find command: 1.7. Regular Expressions
traversing file trees like: 32.1.4. Filenames, Filesystems, and File Locking
FindBin module: 32.1.17. Module Installation Support
findstr function: 1.7. Regular Expressions
1.7. Regular Expressions
fixed 8-bit chracters: 15.1. Building Character
flags: 5.2.1. Pattern Modifiers
19.1.3. Switches
(see also modifiers, switches)
floating-point numbers: 2.6. Scalar Values
29.2.108. pack
computer storage, order of: 25.2. Endianness and Number Width
Math::BigFloat module: 32.1.1. Data Types
rand function, returning: 29.2.119. rand
flock function: 14.1.1. Scalar-Tying Methods
16.2.1. File Locking
29.2.39. flock
alarms and: 16.1.3. Timing Out Slow Operations
flow of program control, functions for: 29.1. Perl Functions by Category
flushing buffers: 28.2. Special Variables in Alphabetical Order
fmt (Unix utility): 7.1. Format Variables
fonts, Perl modules for: 22.1. The CPAN modules Directory
footers: 7.2. Footers
for, as an alias of foreach: 4.4.3. foreach Loops
for loops: 1.6.2.2. The for statement
searching and replacing elements in arrays: 5.2.3.1. Modifying strings en passant
for modifier: 4.1. Simple Statements
4.4.2. for Loops
foreach loops: 1.6.2.3. The foreach statement
4.4.3. foreach Loops
24.2.1. Time Efficiency
aliasing capability, using: 4.5.1. Case Structures
loop variable, Perl vs. shell programming: 24.1.4. Shell Traps
Perl versions, changes in: 24.1.5. Previous Perl Traps
searching and replacing elements in arrays: 5.2.3.1. Modifying strings en passant
foreach modifier: 4.1. Simple Statements
fork function: 29.2.40. fork
child processes, inheriting parent filehandles: 16.2.2. Passing Filehandles
fork-open: 16.3.2. Talking to Yourself
locks, inheriting across calls to: 29.2.39. flock
pipe open, avoiding shell in: 23.1.3. Accessing Commands and Files Under Reduced Privileges
portability of: 25.5. Interprocess Communication (IPC)
servers, cloning themselves with: 16.5.2. Networking Servers
zombie processes and: 16.1.2. Reaping Zombies
fork syscall: 16.3.1. Anonymous Pipes
forks: 29.2.104. open
cloned interpreter on Windows: 17.1. The Process Model
fork open: 29.2.104. open
open command, two-argument form: 29.2.104. open
form feed: 28.2. Special Variables in Alphabetical Order
formal arguments: 28.2. Special Variables in Alphabetical Order
format: 28.2. Special Variables in Alphabetical Order
format function
declaration: 29.2.41. format
output accumulator: 29.2.42. formline
$FORMAT_FORMFEED: 28.2. Special Variables in Alphabetical Order
$FORMAT_LINE_BREAK_CHARACTERS: 28.2. Special Variables in Alphabetical Order
$FORMAT_LINES_LEFT: 28.2. Special Variables in Alphabetical Order
$FORMAT_LINES_PER_PAGE: 28.2. Special Variables in Alphabetical Order
$FORMAT_NAME: 28.2. Special Variables in Alphabetical Order
$FORMAT_PAGE_NUMBER: 28.2. Special Variables in Alphabetical Order
formats: 7. Formats
accessing formatting internals: 7.2.1. Accessing Formatting Internals
argument lists for, evaluating in list context: 24.1.5. Previous Perl Traps
B::Xref module, cross-references with C: 18.6. Code Development Tools
characters in: 29.2.108. pack
declaring: 7. Formats
fmt (Unix utility): 7.1. Format Variables
footers: 7.2. Footers
integers: 29.2.108. pack
lexical variables in: 7. Formats
pack/unpack: 29.2.108. pack
for strings: 29.2.162. sprintf
top-of-form processing: 7. Formats
variables: 7.1. Format Variables
$FORMAT_TOP_NAME: 28.2. Special Variables in Alphabetical Order
formline function: 29.2.42. formline
formline operator: 7.2.1. Accessing Formatting Internals
Fortran: 2.2. Molecules
frame option (debugger): 20.3.3. Debugger Options
free-form languages: 2.2. Molecules
fully-qualified names: 2.5. Names
function calls: 3.1. Terms and List Operators (Leftward)
pipe, low-level for bi-directional communication: 16.3.3. Bidirectional Communication
function templates, closures as: 8.3.7.1. Closures as function templates
functions: 1.2.2. Verbs
6. Subroutines
29. Functions
29. Functions
autoloading: 10.2. Autoloading
12.5.4. Method Autoloading
built-in, listing by type: 32.1.16. Documentation Support
by category: 29.1. Perl Functions by Category
byte-oriented wrappers for: 15.2. Effects of Character Semantics
C library: 29. Functions
debugger, calling internal: 20.3.2. Customizing with Init Files
debugger customization: 20.5.1. Writing Your Own Debugger
default arguments, avoiding errors with: 24.1.2. Frequently Ignored Advice
generation of: 8.3.7. Closures
hashes of: 9.5. Hashes of Functions
interpolating: 14.2.2. Notational Convenience
in list or scalar context: 29. Functions
modules, exporting to programs: 11.2.1. Module Privacy and the Exporter
named unary operators: 3.10. Named Unary and File Test Operators
names for: 24.3. Programming with Style
operators and: 3. Unary and Binary Operators
for overloading: 13.7. Public Overload Functions
overriding: 11.3. Overriding Built-in Functions
Perl, varying across platforms: 25. Portable Perl
Perl, wrapping around C: 21.3.1. XS and XSUBs
references, using for both input and output: 6.3. Passing References
return operators in: 4.4.4. Loop Control
returning tainted data: 29.2. Perl Functions in Alphabetical Order
signal-handling: 16.1. Signals
socket-related in Perl: 16.5. Sockets
temporary filenames, generating: 23.2.3. Temporary Files
Thread module: 17.2.1. The Thread Module
funny characters: 14. Tied Variables

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

-g (setgid) file test: 3.10. Named Unary and File Test Operators
/g (global) pattern modifier: 5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
/g pattern modifier: 5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
G positional assertion: 5.2.2. The m// Operator (Matching)
5.6.5. Where You Left Off: The G Assertion
games, Perl modules for: 22.1. The CPAN modules Directory
garbage collection: 8.5.2. Garbage Collection, Circular References, and Weak References
with DESTROY methods: 12.6.1. Garbage Collection with DESTROY Methods
objects associated with tied variables: 14.1.1. Scalar-Tying Methods
GDBM_File module: 32.1.10. DBM Interfaces
GDBM files (GNU DBM), locking: 16.2.1. File Locking
generated patterns: 5.10.3.1. Generated patterns
generators, Perl programs: 24.5. Program Generation
in other languages: 24.5.2. Generating Perl in Other Languages
other languages in Perl: 24.5.1. Generating Other Languages in Perl
source filters: 24.5.3. Source Filters
getc function: 24.2.1. Time Efficiency
29.2.43. getc
GETC method: 14.4.1. Filehandle-Tying Methods
getgrent function: 29.2.44. getgrent
getgrgid function: 29.2.45. getgrgid
getgrnam function: 29.2.46. getgrnam
gethost* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication
gethostbyaddr function: 29.2.47. gethostbyaddr
converting characters back into bytes: 15.1. Building Character
gethostbyname function: 29.2.48. gethostbyname
gethostent function: 29.2.49. gethostent
getlogin function: 29.2.50. getlogin
getnet* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication
getnetbyaddr function: 29.2.51. getnetbyaddr
getnetbyname function: 29.2.52. getnetbyname
getnetent function: 29.2.53. getnetent
Getopt::Long module: 32.1.3. Option, Argument, Parameter, and Configuration File Processing
Getopts::* modules: 4.4.4. Loop Control
Getopt::Std module: 32.1.3. Option, Argument, Parameter, and Configuration File Processing
getpeername function: 16.5.2. Networking Servers
29.2.54. getpeername
getpgrp function: 29.2.55. getpgrp
getppid function: 29.2.56. getppid
getpriority function: 29.2.57. getpriority
getproto* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication
getprotobyname function: 29.2.58. getprotobyname
getprotobynumber function: 29.2.59. getprotobynumber
getprotoent function: 29.2.60. getprotoent
getpwent function: 29.2.61. getpwent
getpwnam function: 29.2.62. getpwnam
getpwuid function: 29.2.50. getlogin
29.2.63. getpwuid
getserv* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication
getservbyname function: 29.2.64. getservbyname
getservbyport function: 29.2.65. getservbyport
getservent function: 29.2.66. getservent
getsockname function: 29.2.67. getsockname
getsockopt function: 29.2.68. getsockopt
$gid file statistic: 29.2.165. stat
gid (group ID)
assumed: 16.3.2. Talking to Yourself
GID (group ID), effective: 28.2. Special Variables in Alphabetical Order
GIFs, Perl modules for: 22.1. The CPAN modules Directory
Gimp, Perl modules for: 22.1. The CPAN modules Directory
glob function: 2.11.3. Filename Globbing Operator
2.11.3. Filename Globbing Operator
29.2.69. glob
global declarations: 29.2.107. our
4.7. Global Declarations
(see also our declarations)
global matching (see /g modifier)
global names, prefixing with module name: 1.2.1.4. Simplicities
global search and replace: 5.2.3. The s/// Operator (Substitution)
global variables
4.8.1. Scoped Variable Declarations
controlling use with strict pragma: 4.9.2. Controlling the Use of Globals
declaring: 4.8.3. Lexically Scoped Global Declarations: our
29.2.107. our
local operator, using on: 4.8.4. Dynamically Scoped Variables: local
localizing: 29.2.87. local
package variables as: 10. Packages
predeclaring, vars module: 32.1.13. Perl Language Extensions and Internals
threads, accessing in: 17.2.2. Data Access
globbing filenames: 2.11.3. Filename Globbing Operator
32.1.4. Filenames, Filesystems, and File Locking
portability of: 25.4. System Interaction
glue language, Perl as: 1.4. Filehandles
gmtime function: 29.2.70. gmtime
32.1.1. Data Types
Gnome, Perl modules for: 22.1. The CPAN modules Directory
goto function: 4.6. goto
10.2. Autoloading
24.2.1. Time Efficiency
29.2.71. goto
Perl versions, changes in: 24.1.5. Previous Perl Traps
graphs, Perl modules for: 22.1. The CPAN modules Directory
grave accents (see backticks)
greater than (>) operator: 3.11. Relational Operators
greater than or equal (>=) operator: 3.11. Relational Operators
greedy matching: 1.7.1. Quantifiers
5.5. Quantifiers
5.5. Quantifiers
5.9.4. The Little Engine That /Could(n't)?/
tokens: 2.2. Molecules
Greenwich Mean Time (GMT): 29.2.70. gmtime
grep command: 1.7. Regular Expressions
grep function: 1.7. Regular Expressions
24.3. Programming with Style
29.2.72. grep
grep program: 5.9.2.1. When backslashes happen
group ID (see GID)
group name: 29.2.46. getgrnam
grouping operator: 5.1. The Regular Expression Bestiary
5.3.1. Metasymbol Tables
5.9.4. The Little Engine That /Could(n't)?/
for expressions: 3. Unary and Binary Operators
groupings, nesting of: 5.7.1. Capturing
groups
process
killing: 29.2.80. kill
returning priority of: 29.2.57. getpriority
processes: 16.1.1. Signaling Process Groups
functions dealing with: 29.1. Perl Functions by Category
functions dealing with: 29.1. Perl Functions by Category
group name: 29.2.46. getgrnam
members, login names: 29.2.44. getgrent
Gtk, Perl modules for: 22.1. The CPAN modules Directory
GUIs
Perl modules for: 22.1. The CPAN modules Directory
using PerlTk: 24.2.6. User Efficiency
guts: 21. Internals and Externals
GV (internal glob value): 21.2. Internal Data Types

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

-h (help) command-line switch: 19.1.3. Switches
h2xs utility: 21.3.1. XS and XSUBs
21.3.2. Creating Extensions
h2xs: 22.3. Creating CPAN Modules
overload: 13.1. The overload Pragma
13.2. Overload Handlers
missing: 13.5. When an Overload Handler Is Missing (nomethod and fallback)
overloading, as_string handler: 13.3. Overloadable Operators
for signals: 16.1. Signals
handles: 1.2.1. Variable Syntax
directories: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
references to: 8.2.4. Handle References
tied, base class definitons for: 32.1.14. Convenient Classes
hard links, filenames: 29.2.85. link
hard references: 3.2. The Arrow Operator
8.1. What Is a Reference?
8.2. Creating References
%SIG array: 16.1. Signals
using: 8.3. Using Hard References
closures: 8.3.7. Closures
hardware drivers, Perl modules for interacting with: 22.1. The CPAN modules Directory
hashDepth option (debugger): 20.3.3. Debugger Options
hashes: 1.2.1. Variable Syntax
1.2.1.2. Pluralities
1.2.1.2.2. Hashes.
2.3. Built-in Data Types
2.9. Hashes
printing out in sorted order: 4.4.3. foreach Loops
anonymous
data structure for objects: 12.7. Managing Instance Data
references to: 12.4. Object Construction
anonymous, references to: 8.2.2.2. The anonymous hash composer
binding DBM files to: 29.2.22. dbmopen
cascading conditionals, using instead of: 4.5.1. Case Structures
of complex records: 9.6.3. Generation of a Hash of Complex Records
deleting values from: 29.2.24. delete
elements, giving temporary values to: 29.2.87. local
exists function and: 29.2.34. exists
flat lookup tables, providing access to: 9. Data Structures
HV (hash value) typedef in C: 21.2. Internal Data Types
%INC for modules: 11.1. Using Modules
initializing with x operator: 3.7. Multiplicative Operators
instead of linear searches: 24.2.1. Time Efficiency
inverting: 29.2.132. reverse
keys, finding number in: 2.9. Hashes
keys, returning list of: 29.2.79. keys
key/value pair precedence: 2.9. Hashes
key/value pairs: 2.3. Built-in Data Types
2.9. Hashes
capturing from string with m//g operator: 5.2.2. The m// Operator (Matching)
key/value pairs in: 1.2.1.2.2. Hashes.
multidimensional: 9.4. Hashes of Hashes
accessing and printing: 9.4.3. Access and Printing of a Hash of Hashes
generation of: 9.4.2. Generation of a Hash of Hashes
names for: 2.4. Variables
of arrays: 9.2. Hashes of Arrays
9.3. Arrays of Hashes
access and printing of: 9.2.3. Access and Printing of a Hash of Arrays
generating: 9.2.2. Generation of a Hash of Arrays
9.3.2. Generation of an Array of Hashes
output style, changing in debugger: 20.3.3. Debugger Options
passing by reference into or out of functions: 6.3. Passing References
Perl data organization in: 9.1.5. Common Mistakes
processing, functions for: 29.1. Perl Functions by Category
references as keys: 8.5.1. References Don't Work as Hash Keys
references to: 8.1. What Is a Reference?
restricted, implementing: 12.7.5. Using Closures for Private Objects
returning key/value pairs: 29.2.30. each
returning values of: 29.2.194. values
%SIG, references to signal handlers: 16.1. Signals
symbol tables: 10.1. Symbol Tables
key/value pairs in: 10.1. Symbol Tables
typeglobs in: 10.1. Symbol Tables
taint in: 23.1. Handling Insecure Data
tying: 14. Tied Variables
14.3. Tying Hashes
methods for: 14.3.1. Hash-Tying Methods
Tie::Hash module, providing base class definitions: 32.1.14. Convenient Classes
(see also modules)
headers, format names: 7.2. Footers
here documents: 2.6.6. "Here" Documents
indentation of: 2.6.6. "Here" Documents
semicolon (;), omitting trailing: 24.1.1. Universal Blunders
hex function: 29.2.73. hex
converting numbers to: 5.2.3. The s/// Operator (Substitution)
hexadecimal characters: 2.6.1. Numeric Literals
hexadecimal numbers: 29.2.73. hex
character numbers, specifying as: 5.3.2. Specific Characters
hints, compiler: 28.2. Special Variables in Alphabetical Order
history, command: 20.1. Using the Debugger
history of Perl: 27.1. History Made Practical
home directory: 29.2.9. chdir
home page, Perl: 0.6.1. Perl on the Web
HOME variable: 19.2. Environment Variables
hostnames
getting from network addresses: 29.2.47. gethostbyaddr
Sys::Hostname module: 32.1.7. Operating System Interfaces
translating to addresses: 29.2.48. gethostbyname
29.2.52. getnetbyname
hosts file (see /etc/hosts file)
hosts (remote), checking for reachability: 32.1.8. Networking and Interprocess Communication
household appliances, Perl modules for: 22.1. The CPAN modules Directory
HTML
CGI module, generation of: 32.1.9. World Wide Web
code, producing nicely formatted: 32.1.9. World Wide Web
Perl modules for: 22.1. The CPAN modules Directory
pod files, converting to: 32.1.16. Documentation Support
HTTP
cookies, setting and getting: 32.1.9. World Wide Web
links, searching for: 1.7. Regular Expressions
Perl modules for: 22.1. The CPAN modules Directory
HV (internal hash value): 21.2. Internal Data Types
- (hyphen): 3.10. Named Unary and File Test Operators
5.9.4. The Little Engine That /Could(n't)?/
arithmetic negation operator: 3.5. Ideographic Unary Operators
in character ranges: 5.4.1. Custom Character Classes
character set subtraction: 5.4.3.4. Defining your own character properties
in debugger commands: 20.2.5. Locating Code
-*- for emacs: 19.1. Command Processing
-= (assignment) operator: 3.17. Assignment Operators
-- (autodecrement) operator: 1.5.4. Unary Arithmetic Operators
3.3. Autoincrement and Autodecrement
-> (arrow) operator: 3.2. The Arrow Operator
8.3.3. Using the Arrow Operator
method invocation with: 12.3.1. Method Invocation Using the Arrow Operator
subtractive operator: 3.8. Additive Operators
hyphenating text, Perl module for: 22.1. The CPAN modules Directory

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

-i (in-place editing) command-line switch: 19.1.3. Switches
-I (include path) command-line switch: 19.1.3. Switches
/i pattern modifier: 5.2.1. Pattern Modifiers
5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
identifiers: 2.2. Molecules
2.5. Names
29.2.63. getpwuid
bare, barewords vs.: 2.6.4. Or Leave the Quotes Out Entirely
effective UID or GID, setting back to real: 23.1.3. Accessing Commands and Files Under Reduced Privileges
effective user or group IDs, differing from real: 23.1. Handling Insecure Data
enclosing in braces: 2.6.2. String Literals
line-oriented quoting: 2.6.6. "Here" Documents
names vs.: 2.5. Names
Perl modules: 11.1. Using Modules
PIDs, guessing: 23.2.3. Temporary Files
process group ID: 16.1.1. Signaling Process Groups
processes (pid): 29.2.104. open
semaphores: 29.2.143. semget
shared memory segments: 29.2.151. shmget
single quotes (') in: 2.6.2. String Literals
starting with underscore (_), changes in Perl versions: 24.1.5. Previous Perl Traps
thread IDs: 17.2.1.5. Identifying threads
Unicode alphanumeric characters, containing: 15.2. Effects of Character Semantics
identifiers, package: 10. Packages
in package symbol table: 10. Packages
ideographic unary operators: 3.5. Ideographic Unary Operators
ideographs: 1.7. Regular Expressions
matching with w: 15.2. Effects of Character Semantics
idioms, Perl: 24.4. Fluent Perl
if modifier: 4.1. Simple Statements
if statements: 1.5.5. Logical Operators
1.6.1.1. The if and unless statements
4.3. if and unless Statements
C language, differences from Perl: 24.1.3. C Traps
in case structure: 4.5.1. Case Structures
logical operators and: 1.5.5. Logical Operators
IGNORE pseudosignal: 16.1. Signals
imperative programming style: 5.10.3. Programmatic Patterns
implicit method invocation: 12.3. Method Invocation
implicit referencing or dereferencing: 8.1. What Is a Reference?
import function: 11.1. Using Modules
11.2.1.1. Exporting without using Exporter's import method
29.2.74. import
overloading constants: 13.6. Overloading Constants
importing: 4.7. Global Declarations
semantics into package: 29.2.192. use
subroutines from another module: 6.1. Syntax
symbols from one package to another: 10.1. Symbol Tables
importing symbols: 11.2.1. Module Privacy and the Exporter
(see also Exporter module; exporting symbols)
in interprocess communication
bidirectional communication: 16.3.3. Bidirectional Communication
@INC array;prepending directories to: 19.1.3. Switches
%INC hash: 11.1. Using Modules
28.2. Special Variables in Alphabetical Order
I18N::Collate module: 32.1.6. Internationalization and Locale
incrementing variables: 1.5.4. Unary Arithmetic Operators
index function: 29.2.75. index
indexing arrays: 9.2.3. Access and Printing of a Hash of Arrays
indirect filehandles: 29.2.104. open
indirect object slot: 12.3.2. Method Invocation Using Indirect Objects
indirect object syntax: 12.3.2. Method Invocation Using Indirect Objects
ambiguities in: 12.3.3. Syntactic Snafus with Indirect Objects
explicit path, passing in slot: 23.1. Handling Insecure Data
indirection: 2.5.1. Name Lookups
8. References
(see also hard references; symbolic references)
between class use and implementation: 12.3. Method Invocation
inequality (see equality operators[semi] relational operators)
inet_ntoa function: 29.2.47. gethostbyaddr
infinite loops: 4.4.2. for Loops
infix dereference operator (see arrow operator)
infix operators: 1.5. Operators
inheritance: 12.1. Brief Refresher on Object-Oriented Lingo
base class, establishing at compile time: 32.1.13. Perl Language Extensions and Internals
class: 10. Packages
12.5. Class Inheritance
single or multiple: 12.5. Class Inheritance
class accessors: 12.8. Managing Class Data
classes and objects
pseudohash implementation and: 12.7.1. Field Declarations with use fields
constructors: 12.4.1. Inheritable Constructors
through @ISA array: 12.5.1. Inheritance Through @ISA
modules, from Exporter class: 11.2.1. Module Privacy and the Exporter
overloading and: 13.8. Inheritance and Overloading
restricted access and: 12.7.5. Using Closures for Private Objects
inhibit_exit option (debugger): 20.3.3. Debugger Options
INIT blocks: 18.1. The Life Cycle of a Perl Program
initializing variables before calling subroutine: 6.2.3. Scoping Issues
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter
18.7. Avant-Garde Compiler, Retro Interpreter
init program: 29.2.56. getppid
initial caps (see capitalization)
initialization debugger, customizing with init files: 20.3.2. Customizing with Init Files
initialization expressions: 4.4.2. for Loops
initializing
arrays and hash slices: 3.7. Multiplicative Operators
hash variables: 2.9. Hashes
objects: 12.4.2. Initializers
variables before calling subroutines: 6.2.3. Scoping Issues
inlining constant functions: 6.4.1. Inlining Constant Functions
preventing inlining: 6.4.1. Inlining Constant Functions
$ino file statistic: 29.2.165. stat
inplace editing ($^I, $INPLACE_EDIT): 19.1.3. Switches
inplace edits with $^I: 28.2. Special Variables in Alphabetical Order
$INPLACE_EDIT: 28.2. Special Variables in Alphabetical Order
input: 29.2.38. fileno
(see also STDIN filehandle)
checking file descriptors for: 29.2.141. select (ready file descriptors)
debugger, setting: 20.4. Unattended Execution
files, locating end with eof: 19.1.3. Switches
files, open mode for: 29.2.104. open
functions dealing with: 29.1. Perl Functions by Category
ioctl function: 29.2.77. ioctl
operators: 2.11. Input Operators
pipes: 16.3. Pipes
16.3. Pipes
bidirectional: 16.3.3. Bidirectional Communication
multistage pipelines: 16.3.1. Anonymous Pipes
tridirectional: 16.3.3. Bidirectional Communication
record separator (see $/ variable)
single-character, buffered and unbuffered: 29.2.43. getc
XSUBs: 21.3.3. XSUB Input and Output
input filehandles: 1.4. Filehandles
$INPUT_LINE_NUMBER: 28.2. Special Variables in Alphabetical Order
$INPUT_RECORD_SEPARATOR: 28.2. Special Variables in Alphabetical Order
insecure dependency errors: 23.1. Handling Insecure Data
installation
modules, CPAN: 22.2. Using CPAN Modules
into Perl library: 22.2.3. Installing CPAN Modules into the Perl Library
modules supporting: 32.1.17. Module Installation Support
installed modules, inventory of: 32.1.17. Module Installation Support
managing: 12.7. Managing Instance Data
generating accesors with autoloading: 12.7.3. Generating Accessors with Autoloading
generating accessors with closures: 12.7.4. Generating Accessors with Closures
generating classes with Class::Struct: 12.7.2. Generating Classes with Class::Struct
new features, Perl 5.6: 12.7.6. New Tricks
using closures for private objects: 12.7.5. Using Closures for Private Objects
instance methods: 12.1. Brief Refresher on Object-Oriented Lingo
object references as invocants for: 12.3. Method Invocation
instance variables: 12.4.2. Initializers
separate functions, writing for each: 12.7. Managing Instance Data
instances: 12.1. Brief Refresher on Object-Oriented Lingo
int function: 29.2.76. int
integers: 29.2.76. int
computer storage, order of: 25.2. Endianness and Number Width
converting to UTF-8 characters: 15.2. Effects of Character Semantics
exponentiation: 21.4.5. Fiddling with the Perl Stack from C
formats: 29.2.108. pack
formats for: 29.2.162. sprintf
IV (internal integer values): 21.2. Internal Data Types
IV typedef in C: 21.2. Internal Data Types
Math::BigInt module: 13. Overloading
standard modules for arithmetic with: 32.1.1. Data Types
strings as vectors of: 29.2.195. vec
intercept signals, handler for: 16.1. Signals
interfaces: 12.1. Brief Refresher on Object-Oriented Lingo
byte vs. character semantics in: 15.1. Building Character
internal variable names, Perl: 2.5. Names
internationalization: 2.1. Atoms
25.9. Internationalization
modules for: 32.1.6. Internationalization and Locale
Perl modules for: 22.1. The CPAN modules Directory
textual data, with Unicode: 15. Unicode
Internet protocols, Perl modules for: 22.1. The CPAN modules Directory
Internet services, CPAN modules for: 16.5. Sockets
Internet TCP clients/servers: 16.5.1. Networking Clients
interpolation
array variables: 2.6.5. Interpolating Array Values
backreference variables: 1.7.4. Backreferences
conditionals into patterns: 5.10.3.5. Conditional interpolation
double-quoted strings: 1.5.2. String Operators
double quotes ("), using: 5.2. Pattern-Matching Operators
functions: 14.2.2. Notational Convenience
glob operator, using for: 2.11.3. Filename Globbing Operator
list: 2.8. List Values and Arrays
match-time pattern interpolation: 5.10.3.4. Match-time pattern interpolation
scalar values: 2.6.2. String Literals
characters into double-quoted strings: 2.6.2. String Literals
variables: 1.2.1.1. Singularities
controlling with pattern matching: 5.9.2. Variable Interpolation
in double-quoted strings: 2.6.2. String Literals
into patterns: 5.2. Pattern-Matching Operators
interpolative context: 2.7.4. Interpolative Context
interpreter, Perl: 18.3. Executing Your Code
18.3. Executing Your Code
accessing from C: 21.4. Embedding Perl (Using Perl from C)
adding to C program: 21.4.2. Adding a Perl Interpreter to Your C Program
compiler, interaction with: 18.7. Avant-Garde Compiler, Retro Interpreter
embedding in applications: 18.3. Executing Your Code
invoking with #! (shebang) line: 19.1. Command Processing
multiple, running: 18.3. Executing Your Code
persistent: 21.4. Embedding Perl (Using Perl from C)
interpreters: 1.2. Natural and Artificial Languages
for commands: 19.1. Command Processing
Perl: 1.3.1. How to Do It
quoting on Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems
object destruction at shutdown: 12.6.1. Garbage Collection with DESTROY Methods
threads: 17.1. The Process Model
interprocess communication
pipes: 16.3. Pipes
interrupt signals, handler for: 16.1. Signals
intersection of sets: 6.3. Passing References
ints: 29.2.108. pack
inverting arrays and hashes: 29.2.132. reverse
invocant: 12.3. Method Invocation
invoking (see executing)
(see also indirect objects)
IO module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
ioctl function: 29.2.77. ioctl
IO::Dir module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::File module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::Handle module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::modules: 22.1. The CPAN modules Directory
IO::Pipe module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::Poll module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::Pty module: 16.3.3. Bidirectional Communication
IO::Seekable module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::Select module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
IO::Socket module: 16.5. Sockets
32.1.8. Networking and Interprocess Communication
IO::Socket::INET module: 16.5.1. Networking Clients
32.1.8. Networking and Interprocess Communication
IO::Socket::UNIX module: 32.1.8. Networking and Interprocess Communication
IP addresses
network names and: 29.2.53. getnetent
using v-string notation for: 29.2.47. gethostbyaddr
UTF-8 representation of: 15.1. Building Character
IP (Internet Protocol): 16.5. Sockets
IPC (interprocess communication): 16. Interprocess Communication
between processes on same machine: 16. Interprocess Communication
modules for: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
32.1.8. Networking and Interprocess Communication
portability and: 25.5. Interprocess Communication (IPC)
signals: 16.1. Signals
IPC::Msg module: 32.1.8. Networking and Interprocess Communication
IPC::Open3: 21.4. Embedding Perl (Using Perl from C)
IPC::Open3 module: 32.1.8. Networking and Interprocess Communication
IPC::Semaphore module: 32.1.8. Networking and Interprocess Communication
IPC::Shareable module: 16.4. System V IPC
IPC::SysV module: 32.1.8. Networking and Interprocess Communication
irregular files: 1.5.7. Some File Test Operators
@ISA array: 12.5. Class Inheritance
28.2. Special Variables in Alphabetical Order
inheritance through: 12.5.1. Inheritance Through @ISA
use base pragma and: 31.3. use base
isa method: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
iteration: 4.4.4. Loop Control
(see also loops)
iterative operator, overloading: 13.3. Overloadable Operators
iterative statements: 1.6.2. Iterative (Looping) Constructs
for loops: 1.6.2.2. The for statement
foreach statement: 1.6.2.3. The foreach statement
until statements: 1.6.2.1. The while and until statements
while loops: 1.6.2.1. The while and until statements
ithreads: 17.1. The Process Model
Perl API to: 18.3. Executing Your Code
itimer routines: 29.2.3. alarm
IV (internal integer value): 21.2. Internal Data Types

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

Java, Perl modules for: 22.1. The CPAN modules Directory
17.2.1.2. Thread destruction
join function: 29.2.78. join
catching exceptions from: 17.2.1.3. Catching exceptions from join
jumpenv stack: 18.3. Executing Your Code
justification: 7. Formats

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

-k (sticky) file test: 3.10. Named Unary and File Test Operators
kernels
autoreaping zombies on: 16.1.2. Reaping Zombies
generating signals: 16.1. Signals
signal reliability on: 16.1.2. Reaping Zombies
threads and: 17.2. The Thread Model
Unix, set-id script bug in: 23.2.1. Unix Kernel Security Bugs
key mapping, pseudohashes: 12.7.1. Field Declarations with use fields
keyboard sequences, generating signals with: 16.1. Signals
keys function: 1.8. List Processing
2.9. Hashes
14.3.1. Hash-Tying Methods
29.2.79. keys
keys, hash
braces { }, enclosing in: 1.2.1.2.2. Hashes.
providing references as: 32.1.14. Convenient Classes
keys( ): 1.2.1.2.2. Hashes.
key/value pairs, hashes: 2.3. Built-in Data Types
deleting: 14.3. Tying Hashes
modules, %INC hash: 11.1. Using Modules
organizing and accessing data in: 9.1.5. Common Mistakes
returning with each function: 29.2.30. each
symbol tables: 10.1. Symbol Tables
keywords (see reserved words)
kill function: 16.1. Signals
16.1. Signals
29.2.80. kill
Microsoft systems and: 16.1.1. Signaling Process Groups

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

-l (automatic line ending) command-line switch: 19.1.3. Switches
-l (symbolic link) file test: 3.10. Named Unary and File Test Operators
labels: 4.2. Compound Statements
4.4.4. Loop Control
with goto statement: 4.6. goto
29.2.71. goto
with loops: 4.4. Loop Statements
4.4.4. Loop Control
24.3. Programming with Style
names for: 2.5. Names
packages and: 10. Packages
language extensions, Perl modules for: 22.1. The CPAN modules Directory
languages
checking characters for: 5.4.3.3. Unicode block properties
natural vs. artificial: 1.2. Natural and Artificial Languages
translating: 24.5.2. Generating Perl in Other Languages
last operator: 1.6.2.4. Breaking out: next and last
24.3. Programming with Style
4.4.2. for Loops
4.4.4. Loop Control
4.4.4. Loop Control
4.5.1. Case Structures
24.2.1. Time Efficiency
29.2.81. last
do {} while construct, not taking: 24.1.3. C Traps
used in a do while: 4.5. Bare Blocks
$LAST_PAREN_MATCH: 28.2. Special Variables in Alphabetical Order
lc function: 29.2.82. lc
lcfirst function: 29.2.83. lcfirst
left justification: 7.1. Format Variables
left-shift (<<) operator: 3.9. Shift Operators
leftmost longest matching: 5.5. Quantifiers
length
of matched string: 28.2. Special Variables in Alphabetical Order
of arrays: 2.8.2. Array Length
of strings: 24.2.1. Time Efficiency
LENGTH (awk variable): 28.2. Special Variables in Alphabetical Order
length function: 29.2.84. length
byte-oriented wrapper for: 15.2. Effects of Character Semantics
length, matching: 5.5. Quantifiers
less module: 32.1.13. Perl Language Extensions and Internals
less than (<) operator: 3.11. Relational Operators
less than or equal (<=) operator: 3.11. Relational Operators
lexer: 18.2. Compiling Your Code
lexical analysis: 21.1. How Perl Works
in the Perl compiler: 18.2. Compiling Your Code
lexical scopes: 2.5. Names
4.8.2. Lexically Scoped Variables: my
pragmas and: 4.9. Pragmas
package variables, searching for: 2.5.1. Name Lookups
variables attached to: 2.5. Names
lexical variables: 7. Formats
29.2.99. my
accessing from functions: 6.2.3. Scoping Issues
file-scoped, storing anonymous subroutine in: 12.5.5. Private Methods
in functions or files, showing: 32.1.19. Perl Compiler and Code Generator
persistence across function calls: 6.2.3. Scoping Issues
recursive lexical pad stack: 18.3. Executing Your Code
symbolic references and: 8.4. Symbolic References
threads, accessing in: 17.2.2. Data Access
lexical warnings: 32.1.15. Warnings and Exceptions
${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order
lexically scoped declarations: 4.8. Scoped Declarations
lexicals: 4.8.1. Scoped Variable Declarations
(see also lexical scope)
lib module: 32.1.17. Module Installation Support
lib pragma: 11.1. Using Modules
C/C++, loading as Perl extensions: 32.1.17. Module Installation Support
32.1.17. Module Installation Support
ExtUtils::Liblist module: 32.1.17. Module Installation Support
math library, C: 21.3.4. Using Functions from an External C Library
Perl, installing modules into: 22.2.3. Installing CPAN Modules into the Perl Library
Perl library files, searching for: 19.2. Environment Variables
uninstalled extensions from MakeMaker: 32.1.17. Module Installation Support
life cycle, Perl programs: 18.1. The Life Cycle of a Perl Program
code generation phase: 18.1. The Life Cycle of a Perl Program
compilation phase: 18.1. The Life Cycle of a Perl Program
execution phase: 18.1. The Life Cycle of a Perl Program
parse tree reconstruction: 18.1. The Life Cycle of a Perl Program
__LINE__; setting: 24.5.2. Generating Perl in Other Languages
line counter (see $. variable)
line-end processing, automatic: 19.1.3. Switches
line input operators (see angle operator)
2.6.8. Other Literal Tokens
of input file: 28.2. Special Variables in Alphabetical Order
line-oriented quoting: 2.6.6. "Here" Documents
line reading operator: 1.4. Filehandles
line separator character: 2.2. Molecules
line terminators, Internet programs: 16.5.2. Networking Servers
__LINE__ token: 2.6.8. Other Literal Tokens
LineInfo option (debugger): 20.3.3. Debugger Options
boundary assertions: 5.6.1. Beginnings: The A and ^ Assertions
link function: 29.2.85. link
links: 29.2.123. readlink
HTTP, searching for: 1.7. Regular Expressions
lint (C program verifier): 18.6. Code Development Tools
list interpolation: 2.8. List Values and Arrays
list context: 1.8. List Processing
2.7.1. Scalar and List Context
angle operator in: 2.11.2. Line Input (Angle) Operator
backslash operator, supplying: 8.3.6. Other Tricks You Can Do with Hard References
comma operator in: 3.18. Comma Operators
conditional operator in: 3.16. Conditional Operator
evaluating expressions in (debugger): 20.2.4. Display
expressions in (see LISTs)
forcing scalar context instead: 29.2.137. scalar
foreach statements, providing: 1.6.2.3. The foreach statement
functions in: 29. Functions
hash variables, using in: 2.9. Hashes
hashes in: 1.2.1.2.2. Hashes.
list assignment in: 3.17. Assignment Operators
lvalues in: 4.8.1. Scoped Variable Declarations
m// (match) operator in: 5.2.2. The m// Operator (Matching)
m//g, listing all matches found: 5.2.2. The m// Operator (Matching)
operations behaving differently in: 24.1.2. Frequently Ignored Advice
range (..) operator in: 3.15. Range Operator
recognizing in debugger: 20.1. Using the Debugger
subroutines, calling and evaluating in: 6.2. Semantics
list method, current thread objects in process: 17.2.1.6. Listing current threads
list operators: 3. Unary and Binary Operators
3.1. Terms and List Operators (Leftward)
3.19. List Operators (Rightward)
unary operators, distinguishing from: 3.10. Named Unary and File Test Operators
list values, arrays and
2.8. List Values and Arrays
2.8. List Values and Arrays
listen function: 29.2.86. listen
listing code: 20.2.5. Locating Code
LISTs: 1.8. List Processing
4.2. Compound Statements
$LIST_SEPARATOR: 28.2. Special Variables in Alphabetical Order
literals: 5.1. The Regular Expression Bestiary
numeric (see numeric literals)
pseudoliterals (see input operators)
string (see string literals)
UTF-8, enabling use in: 15.2. Effects of Character Semantics
little-endian: 25.2. Endianness and Number Width
loading data structures: 9.6.3. Generation of a Hash of Complex Records
filehandles: 2.10. Typeglobs and Filehandles
signal handler assignment: 16.1. Signals
variables: 4.8.1. Scoped Variable Declarations
29.2.87. local
my declarations, using for: 24.1.2. Frequently Ignored Advice
local declaration: 29.2.87. local
local function: 4.8.1. Scoped Variable Declarations
4.8.2. Lexically Scoped Variables: my
29.2.87. local
common programming errors with: 24.1.1. Universal Blunders
my declaration, using instead of: 24.1.2. Frequently Ignored Advice
local operator, using on global variables: 4.8.4. Dynamically Scoped Variables: local
locale, Perl modules for: 22.1. The CPAN modules Directory
locale module: 32.1.6. Internationalization and Locale
locales
decimal points in formats: 7. Formats
declarations, string comparisons and: 3.11. Relational Operators
modules for: 32.1.6. Internationalization and Locale
Perl character class shortcuts and: 5.4.2. Classic Perl Character Class Shortcuts
Unicode and: 29.2.82. lc
use locale pragma with POSIX character classes: 5.4.4. POSIX-Style Character Classes
localization: 22.1. The CPAN modules Directory
(see also locale)
localized values, saving: 18.3. Executing Your Code
localtime function: 29.2.88. localtime
32.1.1. Data Types
32.1.7. Operating System Interfaces
lock function
data access control in threads: 17.2.2.1. Synchronizing access with lock
reference as argument for: 8.1. What Is a Reference?
locked attribute: 12.7.6. New Tricks
locked attribute (subroutines): 6.5. Subroutine Attributes
locking: 29.2.89. lock
locking files: 16.2.1. File Locking
DBM files: 16.2.1. File Locking
29.2.22. dbmopen
dissolving locks by closing files: 16.2.1. File Locking
flock function: 29.2.39. flock
shared and exclusive locks: 16.2.1. File Locking
locking methods: 17.2.2.5. Locking methods
locking subroutines: 17.2.2.3. Locking subroutines
log function: 29.2.90. log
logarithm: 29.2.90. log
LOGDIR variable: 19.2. Environment Variables
logfiles, Perl modules for: 22.1. The CPAN modules Directory
logical
AND (&&) operator: 3.14. C-Style Logical (Short-Circuit) Operators
negation (!) operator: 3.5. Ideographic Unary Operators
operators: 3.14. C-Style Logical (Short-Circuit) Operators
3.20. Logical and, or, not, and xor
OR (||) operator: 3.14. C-Style Logical (Short-Circuit) Operators
separation, parent and child processes: 17.1. The Process Model
logical operators: 1.5.5. Logical Operators
or operator use with list operators: 4.7. Global Declarations
overloading: 13.3. Overloadable Operators
Perl, doing alternation: 5.9.1. Letting Perl Do the Work
precedence of: 12.3.3. Syntactic Snafus with Indirect Objects
login names
functions dealing with: 29.1. Perl Functions by Category
getgrent function: 29.2.44. getgrent
getgrgid function, returning: 29.2.45. getgrgid
getgrnam function, returning: 29.2.46. getgrnam
getlogin function for: 29.2.50. getlogin
long longs: 29.2.108. pack
longs: 29.2.108. pack
lookahead: 5.10.1. Lookaround Assertions
lookaround: 5.10.1. Lookaround Assertions
lookbehind: 5.10.1. Lookaround Assertions
loops: 1.6.2. Iterative (Looping) Constructs
4.4. Loop Statements
24.1.1. Universal Blunders
24.3. Programming with Style
comments and blank lines, discarding before processing: 5.9.1. Letting Perl Do the Work
control operators for: 4.4.4. Loop Control
eval function within: 24.2.1. Time Efficiency
extracting slices, multidimensional arrays: 9.1.4. Slices
for loops: 1.6.2.2. The for statement
foreach loops: 1.6.2.3. The foreach statement
G assertion, using in: 5.6.5. Where You Left Off: The G Assertion
infinite: 4.4.2. for Loops
iteration through: 4.4.2. for Loops
labels for: 4.4.4. Loop Control
last operator: 4.4.2. for Loops
29.2.81. last
next and last operators: 1.6.2.4. Breaking out: next and last
next operator: 29.2.101. next
redo operator and: 29.2.126. redo
reset function and: 29.2.130. reset
s/// (substitution) operator, using on arrays: 5.2.3.1. Modifying strings en passant
using for: 4.4.2. for Loops
using in (global substitutions): 5.2.3.2. When a global substitution just isn't global enough
using until: 4.4.1. while and until Statements
using while: 4.4.1. while and until Statements
while loops: 1.6.2.1. The while and until statements
lowercase, converting to: 2.6.2. String Literals
lport manpage, function portability information: 29.2. Perl Functions in Alphabetical Order
lstat function: 29.2.91. lstat
29.2.91. lstat
32.1.4. Filenames, Filesystems, and File Locking
lvalues: 2.4. Variables
assignment operators and: 3.17. Assignment Operators
lvalue attribute, subroutines: 6.5. Subroutine Attributes
6.5.2. The lvalue Attribute
methods, declaring to indicate return of: 12.7.6. New Tricks
modifiers and: 4.8.1. Scoped Variable Declarations
operators and: 1.5.3. Assignment Operators
pattern-matching operators, use on: 5.2. Pattern-Matching Operators

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

-M (modification age) file test operator: 3.10. Named Unary and File Test Operators
m?? (match) operator: 5.2.2. The m// Operator (Matching)
20.2.5. Locating Code
reset function and: 29.2.130. reset
m// (matching) operator: 5.2.2. The m// Operator (Matching)
20.2.5. Locating Code
/m pattern modifier: 5.2.1. Pattern Modifiers
5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
-M (use module) command-line switch: 19.1.3. Switches
Macintosh operating system
command-line interface in versions: 1.3.1. How to Do It
File::Spec::Mac module: 32.1.4. Filenames, Filesystems, and File Locking
invoking Perl application on: 19.1.1. #! and Quoting on Non-Unix Systems
quoting on: 19.1.1. #! and Quoting on Non-Unix Systems
magical autodecrement and autoincrement: 13.3. Overloadable Operators
magical autoincrement: 3.3. Autoincrement and Autodecrement
magical autoincrement operator: 3.15. Range Operator
magical counter variables: 14.1.2. Magical Counter Variables
mail
Perl modules for: 22.1. The CPAN modules Directory
sending, portability and: 25.5. Interprocess Communication (IPC)
main package: 2.5.1. Name Lookups
10. Packages
creating for Perl extensions: 32.1.17. Module Installation Support
Makefile.PL: 21.3.2. Creating Extensions
22.2. Using CPAN Modules
22.3. Creating CPAN Modules
MakeMaker: 22.3. Creating CPAN Modules
22.3. Creating CPAN Modules
malloc errors: 28.2. Special Variables in Alphabetical Order
malloc function, PERL_DEBUG_MSTATS environment variable, using with: 19.2. Environment Variables
man command: 0.4. Online Documentation
11. Modules
20.2.7. Miscellaneous Commands
(see also perldoc)
MANIFEST file: 21.3.2. Creating Extensions
32.1.17. Module Installation Support
manpages: 0.4. Online Documentation
CPAN doc subdirectory, containing: 22. CPAN
Pod::Man module: 32.1.16. Documentation Support
map function: 1.8. List Processing
24.3. Programming with Style
29.2.93. map
mapping keys, pseudohashes: 12.7.1. Field Declarations with use fields
mark stack: 18.3. Executing Your Code
marshalling modules: 32.10. Data::Dumper
$MATCH: 28.2. Special Variables in Alphabetical Order
match (??) operator, reset function and: 29.2.130. reset
match (m//) operator: 24.1.1. Universal Blunders
29.2.92. m//
pos function and: 29.2.112. pos
match-time pattern interpolation: 5.10.3.4. Match-time pattern interpolation
matching patterns: 5. Pattern Matching
5. Pattern Matching
(see also patterns)
math library, C language: 21.3.4. Using Functions from an External C Library
math, Perl modules for: 22.1. The CPAN modules Directory
Math::BigFloat module: 32.1.1. Data Types
Math::BigInt module: 13. Overloading
32.1.1. Data Types
Math::Complex module: 32.1.1. Data Types
mathematical functions, overloading: 13.3. Overloadable Operators
mathematics
operators: 3. Unary and Binary Operators
operators in Perl: 1.5. Operators
Math::Trig module: 32.1.1. Data Types
maximal matching: 5.3.1. Metasymbol Tables
5.5. Quantifiers
maximum and minimum item matches, specifying: 1.7.1. Quantifiers
maxTraceLen option (debugger): 20.3.3. Debugger Options
member data: 12.4.2. Initializers
efficiency of: 24.2.2. Space Efficiency
garbage collection: 8.5.2. Garbage Collection, Circular References, and Weak References
management, destructors and: 12.6. Instance Destructors
running out of: 28.2. Special Variables in Alphabetical Order
shared memory segment ID: 29.2.151. shmget
shared, System V IPC: 16.4. System V IPC
controlled access to: 16.4. System V IPC
statistics on, displaying: 19.2. Environment Variables
message digests, Perl modules for: 22.1. The CPAN modules Directory
messages
functions for: 29.2.95. msgctl
IPC::Msg module: 32.1.8. Networking and Interprocess Communication
passing with UDP: 16.5.3. Message Passing
printing on entry and exit from subroutines: 20.3.3. Debugger Options
receiving on sockets: 29.2.125. recv
script embedded in: 19.1.3. Switches
sending on sockets: 29.2.145. send
System V IPC: 16.4. System V IPC
metacharacters: 5.1. The Regular Expression Bestiary
24.2.1. Time Efficiency
escaping with backslash ( ): 5.3. Metacharacters and Metasymbols
escaping with quotemeta: 29.2.118. quotemeta
in exec arguments: 29.2.33. exec
in patterns: 5.3. Metacharacters and Metasymbols
shell, in pipe commands: 29.2.104. open
structural: 5.1. The Regular Expression Bestiary
alphanumeric, in patterns: 5.3.1. Metasymbol Tables
extension syntax for: 5.3.1. Metasymbol Tables
in patterns: 5.3. Metacharacters and Metasymbols
5.3.2. Specific Characters
method attribute: 12.7.6. New Tricks
subroutines: 6.5. Subroutine Attributes
Method (overload::Method): 13.7. Public Overload Functions
methods: 8.3.4. Using Object Methods
12.1. Brief Refresher on Object-Oriented Lingo
adding to an existing class: 12.5.2. Accessing Overridden Methods
array-tying: 14.2.1. Array-Tying Methods
autoloading: 12.5.4. Method Autoloading
called by tied variables: 14. Tied Variables
class data, working like accessors: 12.8. Managing Class Data
classes implementing tied arrays: 14.2. Tying Arrays
classes implementing tied filehandles: 14.4. Tying Filehandles
classes implementing tied hashes: 14.3. Tying Hashes
declarations, lvalues, indicating return of: 12.7.6. New Tricks
hash-tying: 14.3.1. Hash-Tying Methods
invoking: 12.3. Method Invocation
explicitly or implicitly: 12.3. Method Invocation
using indirect objects: 12.3.2. Method Invocation Using Indirect Objects
subroutine calls vs.: 12.4.1. Inheritable Constructors
using arrow operator: 12.3.1. Method Invocation Using the Arrow Operator
names for: 24.3. Programming with Style
object methods, locking: 17.2.2.5. Locking methods
overriding: 12.5.2. Accessing Overridden Methods
Perl classes inheritance of: 12.7. Managing Instance Data
private methods, ignoring inheritance with: 12.5.5. Private Methods
references to: 8.3.7. Closures
searching for
class inheritance: 12.5. Class Inheritance
inheritance through @ISA array: 12.5.1. Inheritance Through @ISA
subroutines as: 12.2. Perl's Object System
subroutines vs.: 6. Subroutines
12.3. Method Invocation
Thread class: 17.2.1. The Thread Module
tying scalars: 14.1.1. Scalar-Tying Methods
UINVERSAL class
adding to: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
in UNIVERSAL class: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
m//g operator, Perl versions, changes in: 24.1.5. Previous Perl Traps
Microsoft Windows
ActiveState Perl distribution, installing: 19.1.1. #! and Quoting on Non-Unix Systems
CPAN modules, installing on: 22.2.1. Decompressing and Unpacking CPAN Modules
fileglobbing, File::DosGlob module: 32.1.4. Filenames, Filesystems, and File Locking
File::Spec::Win32 module: 32.1.4. Filenames, Filesystems, and File Locking
fork operation, cloning interpreter objects: 17.1. The Process Model
modules for: 32.1.20. Microsoft-Related Modules
Perl modules for: 22.1. The CPAN modules Directory
porting information (perlwin32): 16. Interprocess Communication
registry, manipulating: 14.6. Tie Modules on CPAN
shell, setting alternative for Perl use: 19.2. Environment Variables
signal number 0 on: 16.1.1. Signaling Process Groups
system calls using wide-character APIs: 15.1. Building Character
Windows NT, quoting on: 19.1.1. #! and Quoting on Non-Unix Systems
Win32::Pipe module: 16.3.4. Named Pipes
MIDI, Perl modules for: 22.1. The CPAN modules Directory
MIME, Perl modules for: 22.1. The CPAN modules Directory
minimal matching: 1.7.2. Minimal Matching
5.3.1. Metasymbol Tables
5.5. Quantifiers
minus (-) operator: 3.5. Ideographic Unary Operators
miscellaneous functions: 29.1. Perl Functions by Category
mkdir function: 29.2.94. mkdir
mkfifo function: 16.3.4. Named Pipes
MLDBM module: 14.6. Tie Modules on CPAN
Data::Dumper module, using with: 32.10. Data::Dumper
mmap syscall: 16.4. System V IPC
$mode file statistic: 29.2.165. stat
modems, Perl modules for: 22.1. The CPAN modules Directory
modes, opening files in: 29.2.104. open
modification time, file: 29.2.165. stat
29.2.193. utime
modifiers
pattern
cloistered: 5.7.3. Cloistered Pattern Modifiers
with s/// (substitution) operator: 5.2.3. The s/// Operator (Substitution)
patterns, with tr/// (transliteration) operator: 5.2.4. The tr/// Operator (Transliteration)
statements, quantifiers vs.: 5.1. The Regular Expression Bestiary
statements, simple: 4.1. Simple Statements
mod_perl module: 18.3. Executing Your Code
21.4. Embedding Perl (Using Perl from C)
modules: 0.1. The Pursuit of Happiness
1.2.1.4. Simplicities
10. Packages
10.2. Autoloading
11. Modules
backend: 18.4. Compiler Backends
backend, calling: 18.4. Compiler Backends
built-in functions, overriding: 11.3. Overriding Built-in Functions
class system and: 12.5.1. Inheritance Through @ISA
classes, storing in for privacy: 12.5.5. Private Methods
classes vs.: 10. Packages
CPAN: 22.1. The CPAN modules Directory
building: 22.2.2. Building CPAN Modules
categories of: 22.1. The CPAN modules Directory
collection of: 1.2.1.4. Simplicities
creating: 22.3. Creating CPAN Modules
decompressing and unpacking: 22.2.1. Decompressing and Unpacking CPAN Modules
directory for: 22. CPAN
installing into Perl library: 22.2.3. Installing CPAN Modules into the Perl Library
mail, sending: 25.5. Interprocess Communication (IPC)
making available to programs: 22.2. Using CPAN Modules
portability of: 25.7. Standard Modules
storing in: 10. Packages
creating: 11.2. Creating Modules
privacy and the Exporter: 11.2.1. Module Privacy and the Exporter
symbol exportation, preventing: 11.2.1.3. Managing unknown symbols
version checking: 11.2.1.2. Version checking
exporting names to other modules: 29.2.74. import
functions dealing with: 29.1. Perl Functions by Category
importing: 32.1.17. Module Installation Support
names for: 24.3. Programming with Style
splitting into separate files: 10.2. Autoloading
standard: 32. Standard Modules
base classes and convenience: 32.1.14. Convenient Classes
command-line processing: 32.1.3. Option, Argument, Parameter, and Configuration File Processing
for data types: 32.1.1. Data Types
DBM file management libraries, loading: 32.1.10. DBM Interfaces
development support: 32.1.18. Development Support
documentation support: 32.1.16. Documentation Support
files, cross-platform methods of access: 32.1.4. Filenames, Filesystems, and File Locking
internationalization and locales: 32.1.6. Internationalization and Locale
module installation support: 32.1.17. Module Installation Support
networking and interprocess communication: 32.1.8. Networking and Interprocess Communication
object-oriented file, directory, and IPC access: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
operating system interfaces, manipulating: 32.1.7. Operating System Interfaces
Perl compiler and code generator: 32.1.19. Perl Compiler and Code Generator
Perl language extensions and externals: 32.1.13. Perl Language Extensions and Internals
security, dealing with: 32.1.12. Authentication, Security, and Encryption
text, manipulating with: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
user interfaces, providing: 32.1.11. User Interfaces
warnings and exceptions: 32.1.15. Warnings and Exceptions
testing: 21.3.2. Creating Extensions
21.3.3. XSUB Input and Output
22.3. Creating CPAN Modules
thread modules: 17.2.3. Other Thread Modules
thread safety and: 17.2. The Thread Model
tie modules on CPAN: 14.6. Tie Modules on CPAN
user-defined, capitalization in names: 2.5. Names
modulus (%) operator: 3.7. Multiplicative Operators
more than sign (see >)
mortgages, Perl modules for: 22.1. The CPAN modules Directory
MS-DOS operating system, invoking Perl applications on: 19.1.1. #! and Quoting on Non-Unix Systems
msgctl function: 29.2.95. msgctl
msgget function: 29.2.96. msgget
msgrcv function: 29.2.97. msgrcv
msgsnd function: 29.2.98. msgsnd
$mtime file statistic: 29.2.165. stat
mulitple inheritance, SUPER pseudopackage, working with: 12.5.2. Accessing Overridden Methods
multidimensional arrays: 1.2.1.3. Complexities
9.1. Arrays of Arrays
multidimensional hashes: 9.4. Hashes of Hashes
accessing and printing: 9.4.3. Access and Printing of a Hash of Hashes
generation of: 9.4.2. Generation of a Hash of Hashes
multiple inheritance: 12.5. Class Inheritance
AUTOLOAD subroutine and: 12.5.4. Method Autoloading
methods, invoking all overridden base class: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
multiplication: 1.5.1. Some Binary Arithmetic Operators
strings, repeat operator: 1.5.2. String Operators
multiplicative operators: 1.5.2. String Operators
3.7. Multiplicative Operators
multiprocessing
processer access, unpredictability of: 23.2. Handling Timing Glitches
thread model: 17.2. The Thread Model
multithreading: 17. Threads
mutators, copying and: 13.4. The Copy Constructor (=)
my declarations: 2.5. Names
4. Statements and Declarations
29.2.99. my
closures and: 8.3.7. Closures
context rules and: 2.7.1. Scalar and List Context
local, using instead of: 24.1.2. Frequently Ignored Advice
local vs.: 4.8.4. Dynamically Scoped Variables: local
my function: 4.4.3. foreach Loops
4.8.1. Scoped Variable Declarations
4.8.1. Scoped Variable Declarations
4.8.2. Lexically Scoped Variables: my

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

n: 25.1. Newlines
(see also newlines)
-n (loop) command-line switch: 19.1.3. Switches
named
character: 2.6.2. String Literals
character, metasymbol for: 5.3.2. Specific Characters
characters, inserting: 15.2. Effects of Character Semantics
pipes: 16.3.4. Named Pipes
named unary operators: 2.11.3. Filename Globbing Operator
3.10. Named Unary and File Test Operators
listing of: 3.10. Named Unary and File Test Operators
names: 2.5. Names
arrays: 2.4. Variables
attributes, subroutines: 6.5.1. The locked and method Attributes
capitalization conventions: 2.5. Names
classes, distinguishing from subroutines: 12.3.4. Package-Quoted Classes
commands: 1.2.2. Verbs
constructors: 12.4.2. Initializers
file: 2.6.8. Other Literal Tokens
for files==>filenames: 29.2.128. rename
format (see format names)
formats associated with filehandles: 7. Formats
functions: 1.2.2. Verbs
getting from network addresses: 29.2.47. gethostbyaddr
group names: 29.2.46. getgrnam
hashes: 2.4. Variables
hashes, storing in: 1.2.1.2. Pluralities
hostnames, translating to network addresses: 29.2.48. gethostbyname
identifiers vs.: 2.5. Names
labels and filehandles: 2.5. Names
login (see login names)
lookups of: 2.5.1. Name Lookups
methods, tied variables: 14. Tied Variables
modules: 11.1. Using Modules
capitalization in: 11.1. Using Modules
modules/packages: 24.3. Programming with Style
network addresses, getting from: 29.2.51. getnetbyaddr
packages: 10. Packages
parameters, not requiring: 6.2.1. Tricks with Parameter Lists
ports, getting from number: 29.2.64. getservbyname
program (see $0 variable)
protocols, getting from port numbers: 29.2.65. getservbyport
protocols, translating to/from numbers: 29.2.58. getprotobyname
scope, confining to: 4.8.1. Scoped Variable Declarations
signals: 16.1. Signals
subroutines: 6.1. Syntax
capitalization in: 6.1. Syntax
symbol tables: 10.1. Symbol Tables
temporary files, generating: 23.2.3. Temporary Files
translating to network addresses: 29.2.52. getnetbyname
typeglobs: 2.10. Typeglobs and Filehandles
users: 29.2.62. getpwnam
variable: 24.3. Programming with Style
variables: 1.2.1. Variable Syntax
2.4. Variables
namespace (see also packages)
encapsulation based on: 14.6. Tie Modules on CPAN
modules and: 11.2.1. Module Privacy and the Exporter
namespaces: 2.5. Names
access, restricting with Safe module: 23.3.1.1. Restricting namespace access
for packages: 1.2.1.4. Simplicities
naming, socket: 29.2.5. bind
natural languages: 1.2. Natural and Artificial Languages
environment variables controlling Perl handling of: 19.2. Environment Variables
NDBM_File module: 32.1.10. DBM Interfaces
ne operator: 24.1.1. Universal Blunders
negation
arithmetic (-)operator: 3.5. Ideographic Unary Operators
bitwise (~) operator: 3.5. Ideographic Unary Operators
character classes: 5.4.1. Custom Character Classes
5.4.2. Classic Perl Character Class Shortcuts
logical (!) operator: 3.5. Ideographic Unary Operators
of character class: 1.7.1. Quantifiers
POSIX character classes: 5.4.4. POSIX-Style Character Classes
negation operator (!), overloading: 13.3. Overloadable Operators
negative array subscripts, counting from end of array: 24.1.5. Previous Perl Traps
negative lookahead assertions: 5.9.4. The Little Engine That /Could(n't)?/
5.10.1. Lookaround Assertions
negative subscripts in Perl: 2.3. Built-in Data Types
nested
arrays: 9.1. Arrays of Arrays
data structures: 1.2.1.3. Complexities
data structures, printed: 20.2.4. Display
destruction: 12.6. Instance Destructors
lists: 9.1. Arrays of Arrays
subroutines: 8.3.7.2. Nested subroutines
Net::hostent module: 29.2.49. gethostent
32.1.8. Networking and Interprocess Communication
Class::Struct, using to create objects and accesors: 32.6. Class::Struct
Net::netent module: 29.2.51. getnetbyaddr
32.1.8. Networking and Interprocess Communication
netnews: 22.1. The CPAN modules Directory
(see also Usenet)
Net::Ping module: 32.1.8. Networking and Interprocess Communication
Net::proto module: 29.2.59. getprotobynumber
Net::protoent module: 32.1.8. Networking and Interprocess Communication
Net::servent module: 32.1.8. Networking and Interprocess Communication
networking
clients: 16.5.1. Networking Clients
modules for: 32.1.8. Networking and Interprocess Communication
modules implementing network protocols: 22.1. The CPAN modules Directory
network addresses, translating to names: 29.2.51. getnetbyaddr
29.2.47. gethostbyaddr
network filesystems (see NFS)
network information, functions for retrieving: 29.1. Perl Functions by Category
servers: 16.5.2. Networking Servers
services, Perl module for interacting with: 22.1. The CPAN modules Directory
Win32 network modules: 32.1.20. Microsoft-Related Modules
networking modules: 16.5. Sockets
networks file (see /etc/networks file)
new method: 17.2.1.1. Thread creation
29.2.100. new
newlines: 2.2. Molecules
blank lines, truth values and: 1.6.2.1. The while and until statements
chomp function, deleting with: 29.2.11. chomp
dot (.) metacharacter, matching: 5.3.3. Wildcard Metasymbols
in filenames, security risks of: 23.1.2. Cleaning Up Your Environment
Perl program portability and: 25.1. Newlines
removing: 1.4. Filehandles
in string literals: 2.6.2. String Literals
strings containing, matches against: 5.2.1. Pattern Modifiers
newsgroups: 0.6.2. Usenet Newsgroups
next, used in a do while: 4.5. Bare Blocks
next command, do {} while construct, not taking: 24.1.3. C Traps
next operator: 1.6.2.4. Breaking out: next and last
4.4.1. while and until Statements
4.4.4. Loop Control
4.4.4. Loop Control
29.2.101. next
exiting once-through blocks with: 4.5. Bare Blocks
next if construct: 24.2.1. Time Efficiency
NFA (nondeterministic finite-state automaton): 5.9.4. The Little Engine That /Could(n't)?/
limitations of: 16.5. Sockets
$nlink file statistic: 29.2.165. stat
NNN metasymbol: 5.3.2. Specific Characters
no declarations: 4.7. Global Declarations
4.9. Pragmas
11.1. Using Modules
14.1.3. Magically Banishing $_
29.2.102. no
nomethod overloading key: 13.5. When an Overload Handler Is Missing (nomethod and fallback)
nonbacktracking subpatterns: 5.10.2. Nonbacktracking Subpatterns
nondeterministic finite-state automaton (NFA): 5.9.4. The Little Engine That /Could(n't)?/
noninteractive mode, putting debugger in: 20.4. Unattended Execution
not (!) operator: 3.5. Ideographic Unary Operators
not equal to (!=) operator: 3.12. Equality Operators
notational convenience, tied arrays: 14.2.2. Notational Convenience
nouns: 1.2. Natural and Artificial Languages
packages, handling of: 1.2.1.4. Simplicities
novice programmers, common mistakes of: 24.1. Common Goofs for Novices
null
filehandle ;angle operator and: 2.11.2. Line Input (Angle) Operator
list: 2.8. List Values and Arrays
null device, Unix: 14.4.2. Creative Filehandles
null list, assigning to arrays: 2.8.2. Array Length
null values ("" or 0): 1.2.1.1. Singularities
number width: 25.2. Endianness and Number Width
numbered variables: 28.2. Special Variables in Alphabetical Order
numbers: 1.2.1. Variable Syntax
arrays, storing in: 1.2.1.2. Pluralities
bitwise operators, working with: 3.13. Bitwise Operators
command (see command history, debugger and)
commas, inserting into: 7.1. Format Variables
comparison operators for: 1.5.6. Some Numeric and String Comparison Operators
converting nonnumeric variables to: 13.3. Overloadable Operators
d for digit=d (for digit): 1.7. Regular Expressions
digits in names: 2.5. Names
floating-point (see floating-point numbers)
functions dealing with: 29.1. Perl Functions by Category
hexadecimal: 2.6.1. Numeric Literals
29.2.73. hex
hexadecimal, converting to: 5.2.3. The s/// Operator (Substitution)
integers (see integers)
justifying by decimal point: 7. Formats
large, underscore and: 2.6.1. Numeric Literals
octal: 2.6.1. Numeric Literals
29.2.103. oct
for pages: 28.2. Special Variables in Alphabetical Order
port, getting name for: 29.2.64. getservbyname
ports, getting protocol names from: 29.2.65. getservbyport
protocol: 29.2.59. getprotobynumber
random: 29.2.119. rand
29.2.164. srand
strings, converting to: 2.6. Scalar Values
truncating with int: 29.2.76. int
truth values of: 1.6.1. What Is Truth?
typing in Perl: 2.6. Scalar Values
width of: 25.2. Endianness and Number Width
numeric context: 2.7.1. Scalar and List Context
numeric literals: 2.6.1. Numeric Literals
NV (internal double value): 21.2. Internal Data Types

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

-o (effective UID) file test: 3.10. Named Unary and File Test Operators
/o modifier, recompilation, suppressing with: 5.9.2. Variable Interpolation
O module: 18.4. Compiler Backends
18.6. Code Development Tools
32.1.19. Perl Compiler and Code Generator
/o pattern modifier: 5.2.1. Pattern Modifiers
5.2.1. Pattern Modifiers
5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
-O (real UID) file test: 3.10. Named Unary and File Test Operators
object classes: 10. Packages
object methods: 8.3.4. Using Object Methods
locking: 17.2.2.5. Locking methods
Thread objects: 17.2.1. The Thread Module
object-oriented modules: 11.1. Using Modules
method calls, allowing: 11.2. Creating Modules
object-oriented programming: 10. Packages
12.1. Brief Refresher on Object-Oriented Lingo
abstraction in: 12.3. Method Invocation
modules for file, directory, and IPC access: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
Perl modules for: 22.1. The CPAN modules Directory
portable filename operations: 32.1.4. Filenames, Filesystems, and File Locking
references in Perl, emulating: 10. Packages
objects: 1.2.1.3. Complexities
12. Objects
blessing: 3.2. The Arrow Operator
29.2.7. bless
class data, managing: 12.8. Managing Class Data
constructors: 8.2.3. Object Constructors
12.4. Object Construction
inheritable: 12.4.1. Inheritable Constructors
initializers: 12.4.2. Initializers
destruction of (global), controlling: 19.2. Environment Variables
functions dealing with: 29.1. Perl Functions by Category
indirect (see indirect objects)
inheritance, through @ISA array: 12.5.1. Inheritance Through @ISA
instance data, managing: 12.7. Managing Instance Data
12.7.1. Field Declarations with use fields
generating accesors with closures: 12.7.4. Generating Accessors with Closures
generating accessors with autoloading: 12.7.3. Generating Accessors with Autoloading
generating classes with Class::Struct: 12.7.2. Generating Classes with Class::Struct
new features, Perl 5.6: 12.7.6. New Tricks
private objects, using closures for: 12.7.5. Using Closures for Private Objects
instance destructors: 12.6. Instance Destructors
garbage collection with: 12.6.1. Garbage Collection with DESTROY Methods
methods, references to: 8.3.7. Closures
8.3.7. Closures
(see also closures)
Perl object system: 12.2. Perl's Object System
references to, in scalars: 1.2.1.1. Singularities
storing within other objects vs. inheritance: 12.6. Instance Destructors
stringifying: 8.3.6. Other Tricks You Can Do with Hard References
tied variables, underlying: 14. Tied Variables
breaking reference to: 14.5. A Subtle Untying Trap
oct function: 2.6.1. Numeric Literals
29.2.103. oct
octal characters: 2.6.1. Numeric Literals
octal numbers: 29.2.103. oct
characters, representing: 15.1. Building Character
characters, specifying with: 5.3.2. Specific Characters
specifying $/ as: 19.1.3. Switches
octets (see bytes)
for m// successes: 29.2.112. pos
read function and: 29.2.120. read
seek function: 29.2.138. seek
OLE, Perl modules for: 22.1. The CPAN modules Directory
one-liners: 1.3.1. How to Do It
OOP (see object-oriented programming)
Opcode module: 32.1.12. Authentication, Security, and Encryption
opcodes: 18.2. Compiling Your Code
18.3. Executing Your Code
21.1. How Perl Works
open function: 1.4. Filehandles
16.3.1. Anonymous Pipes
29.2.104. open
converting file descriptor to filehandle: 16.2.2. Passing Filehandles
$. and: 29.2.16. close
fileno function and: 29.2.38. fileno
fork-open: 29.2.104. open
forking open: 16.3.2. Talking to Yourself
modes in three-argument form: 29.2.104. open
piped, list argument form, avoiding shell with: 23.3.2. Code Masquerading as Data
piped (two-argument form): 29.2.104. open
for pipes, security risks posed by: 23.1.2. Cleaning Up Your Environment
pipes, opening with: 16.3.1. Anonymous Pipes
portability of: 25.5. Interprocess Communication (IPC)
Open2, Open3 library modules: 16.3.3. Bidirectional Communication
opendir function: 29.2.105. opendir
opening
files via low-level system call: 29.2.171. sysopen
sockets: 29.2.157. socket
operand stack: 18.3. Executing Your Code
operating system name: 28.2. Special Variables in Alphabetical Order
0.1. The Pursuit of Happiness
#! technique, simulating on non-Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems
command interpreters for: 19.1. Command Processing
flock support on: 16.2.1. File Locking
fork operator, support for: 16.2.2. Passing Filehandles
GUIs, relying on: 25.4. System Interaction
interfaces to, manipulating: 32.1.7. Operating System Interfaces
invoking interpreters with #! line: 19.1. Command Processing
module names, translating to directory names: 11.1. Using Modules
newlines, variations in: 25.1. Newlines
perl interpreter, starting on: 1.3.1. How to Do It
Perl modules for: 22.1. The CPAN modules Directory
Perl ports to: 22. CPAN
Perl program portability: 25. Portable Perl
signal reliability on: 16.1.2. Reaping Zombies
signals and default behaviors of: 16.1. Signals
sockets, support for: 16.5. Sockets
threading libraries: 17.2. The Thread Model
operations, contexts, evaluation in: 2.7.1. Scalar and List Context
operators: 1.5. Operators
3. Unary and Binary Operators
access, restricting with Safe module: 23.3.1.2. Restricting operator access
assignment operators: 1.5.3. Assignment Operators
associativity of: 3. Unary and Binary Operators
C language, missing in Perl: 3.21. C Operators Missing from Perl
for loop control: 4.4.4. Loop Control
logical operators: 1.5.5. Logical Operators
matching and substitution: 5. Pattern Matching
overloadable: 13.3. Overloadable Operators
arithmetic operators: 13.3. Overloadable Operators
assignment operators: 13.3. Overloadable Operators
bitwise operators: 13.3. Overloadable Operators
circular references, problems with: 13.3. Overloadable Operators
comparison operators: 13.3. Overloadable Operators
conversion operators: 13.3. Overloadable Operators
dereference operators: 13.3. Overloadable Operators
iterative operator: 13.3. Overloadable Operators
logical negation operator: 13.3. Overloadable Operators
overloading: 3. Unary and Binary Operators
13. Overloading
32.1.1. Data Types
pattern-matching: 5.2. Pattern-Matching Operators
modifiers for: 5.2.1. Pattern Modifiers
positions or lengths, switching to character positions: 15.2. Effects of Character Semantics
precedence of: 1.5.1. Some Binary Arithmetic Operators
3. Unary and Binary Operators
C precedence, retaining in Perl: 3. Unary and Binary Operators
quotes, syntactical similarity to: 1.2.1.1. Singularities
quoting operators: 2.6.3. Pick Your Own Quotes
scalar context, supplying to parameters: 1.2.1.1. Singularities
string operators: 1.5.2. String Operators
verbs as: 1.2.2. Verbs
ops module: 32.1.12. Authentication, Security, and Encryption
optimizing
in the Perl compiler: 18.2. Compiling Your Code
performance and: 24.2. Efficiency
option processing, Perl modules for: 32.1.3. Option, Argument, Parameter, and Configuration File Processing
22.1. The CPAN modules Directory
options (see switches, command-line)
19.1.3. Switches
OR (||) operator: 3.14. C-Style Logical (Short-Circuit) Operators
list operators and: 4.7. Global Declarations
OR logical operator: 1.5.5. Logical Operators
Or operator: 1.5.5. Logical Operators
ord function: 15.2. Effects of Character Semantics
29.2.106. ord
order (see precedence)
of function precedence: 29. Functions
ornaments option (debugger): 20.3.3. Debugger Options
OS/2 operating system, invoking Perl applications on: 19.1.1. #! and Quoting on Non-Unix Systems
OSBC, Perl modules for: 22.1. The CPAN modules Directory
$OS_ERROR: 28.2. Special Variables in Alphabetical Order
$OSNAME: 28.2. Special Variables in Alphabetical Order
our declarations: 2.5.1. Name Lookups
4. Statements and Declarations
29.2.107. our
context rules and: 2.7.1. Scalar and List Context
global variables, lexically scoped: 4.8.3. Lexically Scoped Global Declarations: our
our function: 4.8.1. Scoped Variable Declarations
4.8.2. Lexically Scoped Variables: my
29.2.107. our
out of memory errors: 28.2. Special Variables in Alphabetical Order
output: 29.2.38. fileno
(see also STDOUT filehandle)
array and hash, changing style (debugger): 20.3.3. Debugger Options
checking file descriptors for: 29.2.141. select (ready file descriptors)
debugger, setting: 20.4. Unattended Execution
field separator (see $, variable)
files, open mode for: 29.2.104. open
format output accumulator: 29.2.42. formline
functions dealing with: 29.1. Perl Functions by Category
ioctl function: 29.2.77. ioctl
pipes: 16.3. Pipes
16.3. Pipes
bidirectional: 16.3.3. Bidirectional Communication
filtering: 16.3.2. Talking to Yourself
STDOUT as pipe to another program: 16.3.1. Anonymous Pipes
tridirectional: 16.3.3. Bidirectional Communication
record separator (see $ variable)
selecting filehandles for: 29.2.140. select (output filehandle)
XSUBs: 21.3.3. XSUB Input and Output
output filehandles: 1.4. Filehandles
1.4. Filehandles
output record formats, declaring: 7. Formats
$OUTPUT_AUTOFLUSH: 28.2. Special Variables in Alphabetical Order
$OUTPUT_FIELD_SEPARATOR: 28.2. Special Variables in Alphabetical Order
$OUTPUT_RECORD_SEPARATOR: 28.2. Special Variables in Alphabetical Order
overloading, mathematical functions: 13.3. Overloadable Operators
overload handlers: 13.2. Overload Handlers
overloaded, functions: 2.7.1. Scalar and List Context
Overloaded (overload::Overloaded): 13.7. Public Overload Functions
overloaded string constants, translating text with: 5.10.4. Defining Your Own Assertions
overloading: 3. Unary and Binary Operators
13. Overloading
autogeneration of: 13.3. Overloadable Operators
13.3. Overloadable Operators
circular references, avoiding: 13.3. Overloadable Operators
constants: 13.6. Overloading Constants
copy constructor (=): 13.4. The Copy Constructor (=)
diagnostics: 13.10. Overloading Diagnostics
functions for: 13.7. Public Overload Functions
inheritance and: 13.8. Inheritance and Overloading
nonmethod and fallback: 13.5. When an Overload Handler Is Missing (nomethod and fallback)
overload module: 32.1.1. Data Types
overload pragma: 13.1. The overload Pragma
overloadable operators: 13.3. Overloadable Operators
at run time: 13.9. Run-Time Overloading
sorting and: 13.3. Overloadable Operators
stringifying: 14.4.1. Filehandle-Tying Methods
overridden methods, base class, invoking all: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
overriding, base class methods: 12.5.2. Accessing Overridden Methods
overriding functions: 11.3. Overriding Built-in Functions
overwriting existing files, race conditions and: 23.2.2. Handling Race Conditions
ownership, file: 29.2.13. chown

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

.pm files, loading associated files with: 11.1. Using Modules
P (doesn't match property): 15.2. Effects of Character Semantics
p (matches property): 15.2. Effects of Character Semantics
-P (C preprocessor) command-line switch: 19.1.3. Switches
-p (named pipe) file test: 3.10. Named Unary and File Test Operators
-p (print while looping) command-line switch: 19.1.3. Switches
pack: 25.2. Endianness and Number Width
pack function: 29.2.108. pack
template characters for: 29.2.108. pack
unpack function, Unicode characters and: 15.2. Effects of Character Semantics
package declaration: 4.8. Scoped Declarations
10. Packages
29.2.109. package
package variable
wrapping declaration in block scope: 12.8. Managing Class Data
storing class data in: 12.8. Managing Class Data
(see also global variables)
2.5.1. Name Lookups
4.8.1. Scoped Variable Declarations
declaring: 29.2.107. our
threads, no protection in: 17.2.2. Data Access
packages: 1.2.1.4. Simplicities
2.5. Names
2.5. Names
10. Packages
10.2. Autoloading
adding methods to existing: 12.5.2. Accessing Overridden Methods
binding variables to: 29.2.191. untie
bless function arguments: 12.4. Object Construction
blessing objects into: 29.2.7. bless
delimiters for: 10. Packages
identifiers: 10. Packages
importing semantics to: 29.2.192. use
in @ISA array, inheritance through: 12.5.1. Inheritance Through @ISA
methods and subroutines, resolving for: 12.3. Method Invocation
names for: 2.6.4. Or Leave the Quotes Out Entirely
24.3. Programming with Style
quoting: 12.3.4. Package-Quoted Classes
splitting for autoloading: 32.1.17. Module Installation Support
symbol tables, displaying: 20.3.3. Debugger Options
symbol tables for: 10.1. Symbol Tables
tying variables to: 29.2.178. tie
packed sockaddr: 29.2.54. getpeername
pads: 2.5. Names
page numbers: 28.2. Special Variables in Alphabetical Order
pager option (debugger): 20.3.3. Debugger Options
pages: 28.2. Special Variables in Alphabetical Order
PalmPilot, Perl modules for: 22.1. The CPAN modules Directory
paragraph mode: 19.1.3. Switches
28.2. Special Variables in Alphabetical Order
paragraph separator character: 2.2. Molecules
parameters (see arguments)
scalar context, providing for: 1.2.1.1. Singularities
subroutines
changing in place: 6.2.1. Tricks with Parameter Lists
working with: 6.2.1. Tricks with Parameter Lists
parent classes: 12.1. Brief Refresher on Object-Oriented Lingo
parent processes (see processes)
parse trees: 18.1. The Life Cycle of a Perl Program
18.2. Compiling Your Code
internal, keeping: 18.4. Compiler Backends
original, reconstituting and splicing into current parse tree: 18.5.1. The Bytecode Generator
reconstruction of: 18.1. The Life Cycle of a Perl Program
parsing: 21.1. How Perl Works
double-quote interpolation and regular expressions: 5.2. Pattern-Matching Operators
in the Perl compiler: 18.2. Compiling Your Code
text, Perl modules for: 22.1. The CPAN modules Directory
passing by reference: 6.2. Semantics
prototypes declaring function calls as: 8.1. What Is a Reference?
copying @_ values to my list: 6.2.1. Tricks with Parameter Lists
passing references: 6.3. Passing References
passwords: 29.2.164. srand
crypt function and: 29.2.20. crypt
passwd file: 29.2.61. getpwent
Perl modules for: 22.1. The CPAN modules Directory
PATH environment variable: 1.3.1. How to Do It
19.1.3. Switches
19.2. Environment Variables
security and: 23.1.2. Cleaning Up Your Environment
path for library searches, %INC: 28.2. Special Variables in Alphabetical Order
pathnames, module installed on Windows system: 11.1. Using Modules
pattern-binding operator: 1.7. Regular Expressions
pattern space: 28.2. Special Variables in Alphabetical Order
patterns
autosplitting via -a switch: 19.1.3. Switches
debugger, commands for matching: 20.2.5. Locating Code
fancy patterns: 5.10.1. Lookaround Assertions
replacements, changes in Perl versions: 24.1.5. Previous Perl Traps
patterns (and regular expressions): 1.7. Regular Expressions
5. Pattern Matching
29.2.92. m//
(see also m// operator[semi] m?? operator)
alphanumeric metasymbols: 5.3.1. Metasymbol Tables
assertions, defining your own: 5.10.4. Defining Your Own Assertions
assertions in: 5.1. The Regular Expression Bestiary
backreferences: 1.7.4. Backreferences
5.7.1. Capturing
capturing in: 5.7. Capturing and Clustering
character classes: 1.7. Regular Expressions
5.4. Character Classes
characters in: 5.1. The Regular Expression Bestiary
clustering in: 5.7.2. Clustering
conditional interpolation in: 5.10.3.5. Conditional interpolation
controlling matching: 5.9. Staying in Control
Perl flow control, deciding pattern execution: 5.9.1. Letting Perl Do the Work
regex compiler: 5.9.3. The Regex Compiler
extension syntax: 5.3.1. Metasymbol Tables
extensions, lookaround assertions: 5.10.1. Lookaround Assertions
finding duplicate words in paragraphs: 5.2.1. Pattern Modifiers
functions for matching: 29.1. Perl Functions by Category
generated: 5.10.3.1. Generated patterns
greedy matching: 1.7.1. Quantifiers
5.9.4. The Little Engine That /Could(n't)?/
grep function and: 29.2.72. grep
match-time code evaluation: 5.10.3.3. Match-time code evaluation
match-time pattern interpolation: 5.10.3.4. Match-time pattern interpolation
matching
operators for: 1.7. Regular Expressions
5.2. Pattern-Matching Operators
special variables for: 5.2. Pattern-Matching Operators
5.2.3. The s/// Operator (Substitution)
substrings corresponding to subpatterns: 5.2. Pattern-Matching Operators
matching precedence: 5.9.4. The Little Engine That /Could(n't)?/
metacharacters and metasymbols in: 5.3. Metacharacters and Metasymbols
metasymbols in: 5.3.2. Specific Characters
minimal matching: 1.7.2. Minimal Matching
modifiers, cloistering: 5.7.3. Cloistered Pattern Modifiers
modifiers for: 5.2.1. Pattern Modifiers
Perl code, interjecting into: 5.10.3. Programmatic Patterns
positions for matching: 5.6. Positions
programming style for: 5.10.3. Programmatic Patterns
quantifiers in: 5.1. The Regular Expression Bestiary
5.3.1. Metasymbol Tables
5.5. Quantifiers
5.9.4. The Little Engine That /Could(n't)?/
quotes in: 2.6.3. Pick Your Own Quotes
re pragma, altering default behavior of: 32.1.13. Perl Language Extensions and Internals
recursive matching: 5.10.3.4. Match-time pattern interpolation
security concerns: 23.3.2. Code Masquerading as Data
split function: 29.2.161. split
split function and: 5.2. Pattern-Matching Operators
study function: 29.2.166. study
substitution evaluation: 5.10.3.2. Substitution evaluations
terminating delimiter for: 5.2. Pattern-Matching Operators
Unicode properties, matching on: 15.2. Effects of Character Semantics
for untainting data: 23.1.1. Detecting and Laundering Tainted Data
PAUSE: 22.3. Creating CPAN Modules
pausing scripts: 29.2.156. sleep
PDL (Perl Data Language): 22.1. The CPAN modules Directory
performance: 0.1. The Pursuit of Happiness
measuring: 29.2.181. times
Perl programs, efficiency in: 24.2. Efficiency
period (see . (dot))
Perl
C, extending with
XSUB input and output: 21.3.3. XSUB Input and Output
C, using from: 21.3. Extending Perl (Using C from Perl)
creating extensions: 21.3.2. Creating Extensions
external C library functions, using: 21.3.4. Using Functions from an External C Library
XSUBs and XS language: 21.3.1. XS and XSUBs
CPAN (Comprehensive Perl Archive Network): 22. CPAN
embedding in C: 21.4. Embedding Perl (Using Perl from C)
compiling embedded programs: 21.4.1. Compiling Embedded Programs
Perl interpreter, adding to C program: 21.4.2. Adding a Perl Interpreter to Your C Program
Perl stack, manipulating from C: 21.4.5. Fiddling with the Perl Stack from C
Perl statement, evaluating from C: 21.4.4. Evaluating a Perl Statement from C
Perl subroutine, calling from C: 21.4.3. Calling a Perl Subroutine from C
extensions and internals, modules for: 32.1.13. Perl Language Extensions and Internals
location of: 19.1.2. Location of Perl
models to interface or emulate other languages: 22.1. The CPAN modules Directory
programming, common practices: 24. Common Practices
programs, life cycle of: 18.1. The Life Cycle of a Perl Program
special characters in: 1.2.1. Variable Syntax
thread programming in: 17.2. The Thread Model
use of Unicode, caveats on: 15.3. Caution, [ren2bold] Working
Perl Data Language (PDL) module: 9.1.4. Slices
Perl, history of: 27.1. History Made Practical
Perl interpreter: 1.3.1. How to Do It
18.1. The Life Cycle of a Perl Program
-a switch: 19.1.3. Switches
-c switch: 19.1.3. Switches
-d switch: 19.1.3. Switches
20. The Perl Debugger
-e switch: 1.3.1. How to Do It
19.1.3. Switches
-F switch: 19.1.3. Switches
19.1.3. Switches
-h switch: 19.1.3. Switches
-- switch: 19.1.3. Switches
-I switch: 19.1. Command Processing
19.1.3. Switches
-l switch: 19.1.3. Switches
-m switch: 19.1.3. Switches
-n switch: 19.1.3. Switches
-p switch: 19.1.3. Switches
-s switch: 19.1.3. Switches
20. The Perl Debugger
switches: 19.1.3. Switches
-T switch: 19.1.3. Switches
-u switch: 19.1.3. Switches
-v switch: 19.1.3. Switches
-w switch: 1.3.1. How to Do It
19.1.3. Switches
-x switch: 19.1. Command Processing
19.1.3. Switches
-0 switch: 19.1. Command Processing
19.1.3. Switches
perl interpreter program
-a switch: 28.2. Special Variables in Alphabetical Order
-d switch: 20.6. The Perl Profiler
sticky bit: 24.2.1. Time Efficiency
-T switch: 16.5.2. Networking Servers
23.1. Handling Insecure Data
-w switch: 33. Diagnostic Messages
Perl library: 22.2.3. Installing CPAN Modules into the Perl Library
Perl virtual machine: 18.3. Executing Your Code
18.3. Executing Your Code
perlapi manpage: 21.4.4. Evaluating a Perl Statement from C
perlcall manpage: 21.4.5. Fiddling with the Perl Stack from C
perlcc: 28.2. Special Variables in Alphabetical Order
perlcc command: 18.4. Compiler Backends
pbyscript resulting from: 18.5.1. The Bytecode Generator
$PERLDB: 28.2. Special Variables in Alphabetical Order
PERL5DB environment variable: 19.2. Environment Variables
debugger, customizing with: 20.3.2. Customizing with Init Files
PERLDB_OPTS environment variable
AutoTrace option, tracing compile-phase statements: 20.1. Using the Debugger
debugger customization via: 20.3. Debugger Customization
PERL_DEBUG_MSTATS environment variable: 19.2. Environment Variables
PERL_DESTRUCT_LEVEL environment variable: 19.2. Environment Variables
PERL_DESTRUCT_LEVEL variable: 12.6.1. Garbage Collection with DESTROY Methods
perldoc command: 0.4. Online Documentation
11. Modules
debugger invoking: 20.2.7. Miscellaneous Commands
perlembed manpage: 21.4. Embedding Perl (Using Perl from C)
eval_sv function, demonstrating: 21.4.4. Evaluating a Perl Statement from C
perlfork documentation: 16. Interprocess Communication
PERL5LIB environment variable: 19.2. Environment Variables
perllocale manpage: 29.2.82. lc
perlmodinstall manpage: 22.2. Using CPAN Modules
PERL5OPT environment variable: 19.2. Environment Variables
perlport documentation: 16. Interprocess Communication
PERL5SHELL environment variable: 19.2. Environment Variables
Perl/Tk: 24.2.6. User Efficiency
Perl modules for: 22.1. The CPAN modules Directory
$PERL_VERSION: 28.2. Special Variables in Alphabetical Order
28.2. Special Variables in Alphabetical Order
perlwin32 documentation: 16. Interprocess Communication
permissions: 29.2.171. sysopen
29.2.186. umask
file permission operators, interpreting: 3.10. Named Unary and File Test Operators
users, granting limited: 23.1. Handling Insecure Data
persistent data structures, providing via tie: 14.6. Tie Modules on CPAN
persistent Perl interpreter: 21.4. Embedding Perl (Using Perl from C)
pi: 29.2.4. atan2
picture lines: 7. Formats
29.2.41. format
pid (see processes)
PID (process ID): 28.2. Special Variables in Alphabetical Order
pipe function: 29.2.110. pipe
portability of: 25.5. Interprocess Communication (IPC)
pipelines
multistage, for input: 16.3.1. Anonymous Pipes
multistage, for output: 16.3.1. Anonymous Pipes
pipes
closing: 29.2.16. close
double-ended, opening with tied filehandle: 14.4.2. Creative Filehandles
in interprocess communication: 16.3. Pipes
named pipes: 16.3.4. Named Pipes
process talking to itself: 16.3.2. Talking to Yourself
IO::Pipe module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
open function, security risks posed by: 23.1.2. Cleaning Up Your Environment
read-only filehandles, opening: 29.2.104. open
plain old documentation (see pod)
pluralities: 1.2.1.2. Pluralities
.pm file extension: 10. Packages
pod
directives: 26.1.2. Pod Directives
embedding in Perl: 2.2. Molecules
format: 26. Plain Old Documentation
modules: 26.2. Pod Translators and Modules
Perl modules for: 22.1. The CPAN modules Directory
translators: 26.1. Pod in a Nutshell
26.2. Pod Translators and Modules
Pod::Checker module: 32.1.16. Documentation Support
Pod::Functions module: 32.1.16. Documentation Support
Pod::Html module: 32.1.16. Documentation Support
Pod::InputObjects module: 32.1.16. Documentation Support
Pod::Man module: 32.1.16. Documentation Support
Pod::Parser module: 32.1.16. Documentation Support
Pod::Select module: 32.1.16. Documentation Support
Pod::Text module: 32.1.16. Documentation Support
Pod::Text::Termcap module: 32.1.16. Documentation Support
Pod::Usage module: 32.1.16. Documentation Support
POE (Perl Object Environment): 22.1. The CPAN modules Directory
poetry in Perl: 27.2. Perl Poetry
pointers: 2.3. Built-in Data Types
references, unable to convert to: 2.6. Scalar Values
to strings: 29.2.108. pack
pointers (C language): 8. References
poll function: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
polluting your namespace: 11.2.1. Module Privacy and the Exporter
polymorphism: 12.1. Brief Refresher on Object-Oriented Lingo
pop function: 9. Data Structures
29.2.111. pop
POP method: 14.2.1. Array-Tying Methods
popen function (C language): 21.4. Embedding Perl (Using Perl from C)
portability
Perl programs: 25. Portable Perl
of files and filesystems: 25.3. Files and Filesystems
functions, information on: 29.2. Perl Functions in Alphabetical Order
scripts using gethostent function: 29.2.49. gethostent
of signals: 25.4. System Interaction
porting, information on: 16. Interprocess Communication
porting, efficiency of: 24.2.5. Porter Efficiency
name/number translations for: 29.2.64. getservbyname
Perl, to operating systems: 22. CPAN
pos function: 5.6.4. Progressive Matching
5.6.5. Where You Left Off: The G Assertion
29.2.112. pos
positional assertions: 5.6.5. Where You Left Off: The G Assertion
ordering of matching, changing with: 5.8. Alternation
positions: 5.6. Positions
beginnings of strings, matching: 5.6.1. Beginnings: The A and ^ Assertions
ends of strings, matching: 5.6.2. Endings: The z, Z, and $ Assertions
operators switching to character positions: 15.2. Effects of Character Semantics
position just after previous match, specifying: 5.6.5. Where You Left Off: The G Assertion
precedence in pattern matching: 5.9.4. The Little Engine That /Could(n't)?/
substr function, manipulating with: 5.6. Positions
word boundaries, matching: 5.6.3. Boundaries: The b and B Assertions
positive lookahead assertions: 5.9.4. The Little Engine That /Could(n't)?/
5.10.1. Lookaround Assertions
POSIX classes: 5.4. Character Classes
POSIX module: 32.1.7. Operating System Interfaces
getattr function: 29.2.43. getc
getting exported functions and variables with: 11.1. Using Modules
signal blocking with: 16.1.4. Blocking Signals
strftime function: 29.2.88. localtime
POSIX-style character classes: 5.4.4. POSIX-Style Character Classes
possible matches, specifying set of: 5.8. Alternation
post-incremented (post-decremented) variables: 1.5.4. Unary Arithmetic Operators
postincrement and postdecrement operators: 3. Unary and Binary Operators
$POSTMATCH: 28.2. Special Variables in Alphabetical Order
Postscript, Perl modules for: 22.1. The CPAN modules Directory
PPM (Perl Package Manager): 22.2. Using CPAN Modules
22.2. Using CPAN Modules
pragmas: 1.2.1.4. Simplicities
4.7. Global Declarations
4.9. Pragmas
10. Packages
19.1.3. Switches
29.2.192. use
lexically scoped: 4.9. Pragmas
modules and: 11.1. Using Modules
names, capitalization in: 2.5. Names
use charnames: 2.6.2. String Literals
pre-extending arrays: 24.2.1. Time Efficiency
pre-incremented (pre-decremented) variables: 1.5.4. Unary Arithmetic Operators
precedence: 29. Functions
diagnostic messages: 33. Diagnostic Messages
key/value pair (hashes): 2.9. Hashes
logical operators: 1.5.5. Logical Operators
3.20. Logical and, or, not, and xor
12.3.3. Syntactic Snafus with Indirect Objects
modifiers vs. commas: 4.8.1. Scoped Variable Declarations
operator, table of: 3. Unary and Binary Operators
Perl versions, changes in: 24.1.5. Previous Perl Traps
regular expression matching: 5.9.4. The Little Engine That /Could(n't)?/
unary operators, higher than binary: 3.10. Named Unary and File Test Operators
predeclaring subroutines: 12.5.4. Method Autoloading
32.1.13. Perl Language Extensions and Internals
prefix operators: 1.5. Operators
3. Unary and Binary Operators
metacharacters working as: 5.3. Metacharacters and Metasymbols
$PREMATCH: 28.2. Special Variables in Alphabetical Order
prepending, directories to @INC: 19.1.3. Switches
prepending elements to arrays: 29.2.190. unshift
preprocessing Perl: 24.5.2. Generating Perl in Other Languages
print function: 1.4. Filehandles
1.8. List Processing
24.2.1. Time Efficiency
24.2.1. Time Efficiency
29.2.113. print
implementing to tied filehandle: 14.4.1. Filehandle-Tying Methods
print statements, comma error in: 24.1.1. Universal Blunders
printf function: 3.16. Conditional Operator
24.2.1. Time Efficiency
29.2.114. printf
29.2.162. sprintf
using on tied filehandle: 14.4.1. Filehandle-Tying Methods
printing
arrays of hashes: 9.3.3. Access and Printing of an Array of Hashes
hashes of arrays: 9.2.3. Access and Printing of a Hash of Arrays
multidimensional arrays: 9.1.3. Access and Printing
9.2. Hashes of Arrays
9.4. Hashes of Hashes
multidimensional hashes: 9.4.3. Access and Printing of a Hash of Hashes
9.6.1. Composition, Access, and Printing of More Elaborate Records
nested data structures: 20.2.4. Display
typeglob contents: 20.3.3. Debugger Options
PrintRet option (debugger): 20.3.3. Debugger Options
priority, process: 29.2.57. getpriority
29.2.147. setpriority
privacy: 12.1. Brief Refresher on Object-Oriented Lingo
Perl modules and: 11.2.1. Module Privacy and the Exporter
private methods, ignoring inheritance with: 12.5.5. Private Methods
private objects, closures, using for: 12.7.5. Using Closures for Private Objects
private variables (see local variables)
procedureal programming style: 5.10.3. Programmatic Patterns
procedures: 1.2.2. Verbs
process groups: 16.1. Signals
29.2.55. getpgrp
29.2.146. setpgrp
process ID (pid)
getting process group from: 29.2.55. getpgrp
returning: 29.2.56. getppid
returning with fork: 29.2.40. fork
waitpid function: 29.2.197. waitpid
processes
checking for existence: 16.1.1. Signaling Process Groups
fork function: 29.2.40. fork
functions dealing with: 29.1. Perl Functions by Category
getting group for: 29.2.146. setpgrp
ID (pid): 29.2.104. open
interprocess communication: 16. Interprocess Communication
between processes on same machine: 16. Interprocess Communication
files: 16.2. Files
on the Internet: 16. Interprocess Communication
sockets: 16.5. Sockets
System V IPC: 16.4. System V IPC
killing: 29.2.80. kill
multitasking environments, CPU access: 23.2. Handling Timing Glitches
priority, setting: 29.2.147. setpriority
process model, threads: 17.1. The Process Model
returning priority of: 29.2.57. getpriority
signaling process groups: 16.1.1. Signaling Process Groups
standard input, output, and error in: 1.4. Filehandles
umask for: 29.2.186. umask
variables for: 28.2. Special Variables in Alphabetical Order
waiting for: 29.2.196. wait
zombie: 16.1.2. Reaping Zombies
$PROCESS_ID: 28.2. Special Variables in Alphabetical Order
processing shell commands: 19.1. Command Processing
processor (see CPU)
profiler, Perl: 20.6. The Perl Profiler
profiling, Devel::DProf module: 32.1.13. Perl Language Extensions and Internals
program arguments, shell vs. Perl: 24.1.4. Shell Traps
program name
of perl executable: 28.2. Special Variables in Alphabetical Order
of perl script: 28.2. Special Variables in Alphabetical Order
programming languages, Perl modules for interfacing with or emulating: 22.1. The CPAN modules Directory
programming, Perl: 24. Common Practices
common mistakes by novices, Perl traps, previous versions: 24.1.5. Previous Perl Traps
common mistakes of novices: 24.1. Common Goofs for Novices
efficiency: 24.2. Efficiency
file-manipulating programs, writing portable: 25.3. Files and Filesystems
fluent: 24.4. Fluent Perl
portability: 25. Portable Perl
program generation: 24.5. Program Generation
generating Perl in other languages: 24.5.2. Generating Perl in Other Languages
program generators
other languages in Perl: 24.5.1. Generating Other Languages in Perl
source filters: 24.5.3. Source Filters
programming with style: 24.3. Programming with Style
programming style, patterns: 5.10.3. Programmatic Patterns
$PROGRAM_NAME: 28.2. Special Variables in Alphabetical Order
programs
controlling debugger from: 20.1. Using the Debugger
core dump of: 29.2.29. dump
executing: 29.2.174. system
exiting: 1.1. Getting Started
29.2.35. exit
stepping through with debugger: 20.2.1. Stepping and Running
progressive matching: 5.6.5. Where You Left Off: The G Assertion
projects, large, benefits of strict pragma in: 1.2.1.4. Simplicities
properties: 12.4.2. Initializers
case, Unicode: 15.2. Effects of Character Semantics
Unicode: 5.4. Character Classes
Unicode database of: 15.2. Effects of Character Semantics
protocols, name/number translations: 29.2.58. getprotobyname
prototypes: 6.4. Prototypes
& (ampersand), omitting from subroutine names: 6.4. Prototypes
built-in functions, emulating: 6.4. Prototypes
careful use of: 6.4.2. Care with Prototypes
closures, giving to: 8.3.7.1. Closures as function templates
implicit pass-by-reference in: 8.1. What Is a Reference?
inlining constant functions: 6.4.1. Inlining Constant Functions
prototyping: 6.4. Prototypes
pseudo-operators, overloading and: 13.3. Overloadable Operators
pseudocommands, piping: 16.3.2. Talking to Yourself
pseudohashes: 8.3.5. Pseudohashes
implementing classes with: 29.2.99. my
inheritance and: 12.7.1. Field Declarations with use fields
simulating with overload function: 13.3. Overloadable Operators
use fields pragma, using with: 12.7.1. Field Declarations with use fields
pseudoliterals (see input operators)
punctuation characters, word boundary matching and: 5.6.3. Boundaries: The b and B Assertions
punctuation variables, English module, handling with: 32.1.13. Perl Language Extensions and Internals
push function: 9. Data Structures
29.2.116. push
pop function: 2.3. Built-in Data Types
push-pop (PP) codes: 18.3. Executing Your Code
PV (internal string value): 21.2. Internal Data Types
pwd command (Unix): 24.2.1. Time Efficiency
Python: 2.2. Molecules

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

q// (pattern match) operator: 13.6. Overloading Constants
qr// (quote regex) operator: 2.7.4. Interpolative Context
5.2. Pattern-Matching Operators
5.9.2.2. The qr// quote regex operator
modifiers for: 5.2.1. Pattern Modifiers
Qt, Perl modules for: 22.1. The CPAN modules Directory
quantifiers: 1.7. Regular Expressions
1.7.1. Quantifiers
24.2.1. Time Efficiency
atoms and: 5.9.4. The Little Engine That /Could(n't)?/
greedy: 5.5. Quantifiers
in matches, dot (.) metacharacter, using with: 5.3.3. Wildcard Metasymbols
in matching: 5.5. Quantifiers
character classes and: 5.4.1. Custom Character Classes
minimal and maximal: 5.3.1. Metasymbol Tables
minimal and maximal: 5.5. Quantifiers
quantifiers (in matching): 5.1. The Regular Expression Bestiary
5.3.1. Metasymbol Tables
quarantining suspicious code: 23.3. Handling Insecure Code
queues: 9. Data Structures
queues, Thread::Queue module: 17.2.3.1. Queues
quit signals, handler for: 16.1. Signals
quitting
infinite loop: 4.4.2. for Loops
Perl debugger: 20.2.7. Miscellaneous Commands
quotation marks: 8.5. Braces, Brackets, and Quoting
(see also " (double quotes) and ' (single quotes) under Symbols)
in braces: 2.6.2. String Literals
double ("): 5.2. Pattern-Matching Operators
in formline arguments: 29.2.42. formline
interpolative context: 2.7.4. Interpolative Context
leaving out: 2.6.4. Or Leave the Quotes Out Entirely
line-oriented quoting: 2.6.6. "Here" Documents
on non-Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems
quoting operators: 2.6.3. Pick Your Own Quotes
strings, changing style of string display: 20.3.3. Debugger Options
strings and: 2.6.2. String Literals
quote operators: 3.1. Terms and List Operators (Leftward)
quoted execution operator (see ` (backtick) operator)
quotemeta function: 29.2.118. quotemeta
quotes, strings, use in: 1.2.1.1. Singularities
quoting, packages: 12.3.4. Package-Quoted Classes
quoting, line oriented: 2.6.6. "Here" Documents
quoting mechanisms: 1.2.1.1. Singularities
qw operator: 2.6.4. Or Leave the Quotes Out Entirely
qw (quote words): 2.8. List Values and Arrays
qx// (quote construct) operator: 29.2.124. readpipe
qx// (quoted execution) operator: 2.7.4. Interpolative Context
2.11.1. Command Input (Backtick) Operator
2.11.1. Command Input (Backtick) Operator
(see also ` (backtick) operator)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

-r (readable by effective uid/gid) file test: 1.5.7. Some File Test Operators
3.10. Named Unary and File Test Operators
-R (readable by real uid/gid file test: 3.10. Named Unary and File Test Operators
race conditions
file locking and: 16.2.1. File Locking
handling: 23.2.2. Handling Race Conditions
rand function: 3.1. Terms and List Operators (Leftward)
29.2.119. rand
random numbers: 29.2.119. rand
29.2.164. srand
producing as handles or scalars: 14.4.2. Creative Filehandles
range (.. and ...) operator: 3.15. Range Operator
ranges
character sets, specifying in: 5.2.4. The tr/// Operator (Transliteration)
characters: 5.4.1. Custom Character Classes
$rdev file statistic: 29.2.165. stat
re-initialization expressions, loops: 4.4.2. for Loops
re module: 32.1.13. Perl Language Extensions and Internals
read function: 14.4.1. Filehandle-Tying Methods
29.2.120. read
readable file test operator: 1.5.7. Some File Test Operators
3.10. Named Unary and File Test Operators
readdir function: 29.2.121. readdir
reading
data via low-level system call: 29.2.172. sysread
shared memory segment ID: 29.2.152. shmread
reading files
open mode and: 29.2.104. open
readline function: 2.11.2. Line Input (Angle) Operator
READLINE method: 14.4.1. Filehandle-Tying Methods
ReadLine module, disabling support to debugger: 20.4. Unattended Execution
readline packages: 32.1.11. User Interfaces
readlink function: 29.2.123. readlink
ready file descriptors: 29.2.141. select (ready file descriptors)
real GID (see $( variable)
real UID (see $< variable)
real values, testing for with defined function: 29.2.23. defined
$REAL_GROUP_ID: 28.2. Special Variables in Alphabetical Order
$REAL_USER_ID: 28.2. Special Variables in Alphabetical Order
reaping zombie processes: 16.1.2. Reaping Zombies
servers: 16.5.2. Networking Servers
recallCommand option (debugger): 20.3.3. Debugger Options
recompiling patterns, limiting with /o modifier: 5.2.1. Pattern Modifiers
record delimiter (see $/ variable)
record mode: 28.2. Special Variables in Alphabetical Order
records
functions dealing with: 29.1. Perl Functions by Category
input, separator for (see $/ variable)
output, separator for (see $ variable)
of various data structures: 9.6. More Elaborate Records
composing, accessing, and printing: 9.6.1. Composition, Access, and Printing of More Elaborate Records
generating hash of: 9.6.3. Generation of a Hash of Complex Records
records, variable-length: 7. Formats
recursion of subroutines: 6.2.3. Scoping Issues
recursive lexical pad stacks: 18.3. Executing Your Code
recursive matching: 5.10.3.4. Match-time pattern interpolation
recursivity, locks: 17.2.2.1. Synchronizing access with lock
recv function: 29.2.125. recv
redo operator: 4.4.4. Loop Control
4.4.4. Loop Control
29.2.126. redo
redundancy in Perl: 1.5.6. Some Numeric and String Comparison Operators
ref function: 12.4. Object Construction
29.2.127. ref
ref operator: 8.3.6. Other Tricks You Can Do with Hard References
references: 1.2.1.1. Singularities
8. References
to anonymous data: 8.2.2. Anonymous Data
blessing: 12.4. Object Construction
braces, brackets and quoting in: 8.5. Braces, Brackets, and Quoting
casting to other pointer types: 2.6. Scalar Values
checking for: 29.2.127. ref
circular, in overloading: 13.3. Overloadable Operators
circular, and memory: 8.5.2. Garbage Collection, Circular References, and Weak References
creating: 8.2. Creating References
with backslash operator: 8.2.1. The Backslash Operator
to data structures: 8.1. What Is a Reference?
defining: 8.1. What Is a Reference?
destruction of, controlling: 19.2. Environment Variables
to filehandles: 8.2.4. Handle References
29.2.104. open
to functions, storing in data structures: 9.5. Hashes of Functions
hard: 3.2. The Arrow Operator
(see also hard references)
hash keys, providing as: 32.1.14. Convenient Classes
indirection: 8. References
locking: 17.2.2.1. Synchronizing access with lock
in multidimsional arrays: 9.1.1. Creating and Accessing a Two-Dimensional Array
object-oriented programming and: 10. Packages
for objects: 12.2. Perl's Object System
objects as: 12.4. Object Construction
passing: 6.3. Passing References
passing by: 6.2. Semantics
Perl, C pointers vs.: 3.21. C Operators Missing from Perl
references and: 2.5.1. Name Lookups
to signal handlers (user-defined): 16.1. Signals
stringifying: 8.3.6. Other Tricks You Can Do with Hard References
8.5.1. References Don't Work as Hash Keys
9.1.3. Access and Printing
9.1.5. Common Mistakes
to subroutines: 6.1. Syntax
retrieving from or passing to: 10.1. Symbol Tables
to symbol table entries: 10.1. Symbol Tables
in symbol tables to other symbol tables: 10.1. Symbol Tables
symbolic: 8.4. Symbolic References
to tied arrays: 14.2.1. Array-Tying Methods
to tied scalar variables: 14.1.1. Scalar-Tying Methods
to tied variable objects, breaking: 14.5. A Subtle Untying Trap
to hashes: 9.1.5. Common Mistakes
multidimensional hashes: 9.6. More Elaborate Records
truth value of: 1.6.1. What Is Truth?
weak: 8.5.2. Garbage Collection, Circular References, and Weak References
weakening or breaking: 12.6.1. Garbage Collection with DESTROY Methods
referents: 8.1. What Is a Reference?
objects as: 12.2. Perl's Object System
reftype function: 12.4. Object Construction
regex (see patterns)
regexes (see patterns)
regexps (see patterns)
registry (Microsoft Windows), manipulating: 14.6. Tie Modules on CPAN
32.1.20. Microsoft-Related Modules
regular expressions (see patterns)
character classes, confusing with array subscripts: 2.6.5. Interpolating Array Values
characters, matching instead of bytes: 15.2. Effects of Character Semantics
functions dealing with: 29.1. Perl Functions by Category
regular files, testing for: 1.5.7. Some File Test Operators
relational databases, hashes, tying to: 14.6. Tie Modules on CPAN
relational operators: 1.5.6. Some Numeric and String Comparison Operators
3.11. Relational Operators
nonassociation of: 3.11. Relational Operators
removing (see deleting)
rename function: 29.2.128. rename
repetition (x) operator: 1.5.2. String Operators
1.5.2. String Operators
3.7. Multiplicative Operators
replacement, matched substrings (see s/// (substitution) operator)
replacement strings, /e modifier, building with: 5.10.3.2. Substitution evaluations
replacing array elements: 29.2.160. splice
reports, generating: 7. Formats
require: 4.7. Global Declarations
require declarations, tie function and: 14. Tied Variables
require function: 11.1. Using Modules
require operator: 4.7. Global Declarations
28.2. Special Variables in Alphabetical Order
29.2.129. require
REs (see patterns)
reserved words: 2.5. Names
barewords, possible conflict with: 2.6.4. Or Leave the Quotes Out Entirely
reset function: 29.2.130. reset
return function: 29.2.131. return
return operators: 4.4.4. Loop Control
return stack: 18.3. Executing Your Code
return value, currently executing subroutine, displaying in debugger: 20.2.1. Stepping and Running
return value, subroutine: 6.2. Semantics
reused addresses, displaying contents of: 20.3.3. Debugger Options
reusing code: 24.3. Programming with Style
reval method, running suspicious code with: 23.3.1.1. Restricting namespace access
reverse, disallowing as sort subroutine name: 24.1.5. Previous Perl Traps
reverse function: 1.8. List Processing
29.2.132. reverse
reversing print and printf statements (tied filehandles): 14.4. Tying Filehandles
revision (see version)
rewinddir function: 29.2.133. rewinddir
right justification: 7.1. Format Variables
right-shift (>>) operator: 3.9. Shift Operators
rindex function: 29.2.134. rindex
rmdir function: 29.2.135. rmdir
root directory, redefining: 29.2.15. chroot
rot13 encryption: 5.2.4. The tr/// Operator (Transliteration)
routines (see subroutines)
RS (awk variable) (see $INPUT_RECORD_SEPARATOR)
RSTART (awk variable): 28.2. Special Variables in Alphabetical Order
RTF, Perl modules for: 22.1. The CPAN modules Directory
run phase: 18.1. The Life Cycle of a Perl Program
run phase vs. run time: 18.2. Compiling Your Code
running (see executing)
RV (internal reference value): 21.2. Internal Data Types
rvalue: 2.3. Built-in Data Types

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

-S file test operator: 3.10. Named Unary and File Test Operators
s for whitespace=s (for whitespace): 1.7. Regular Expressions
s operator (see substitution operator)
/s pattern modifier: 5.2.1. Pattern Modifiers
5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
5.2.4. The tr/// Operator (Transliteration)
-S (search for script) command-line switch: 19.1.3. Switches
s// (substitution) operator: 24.1.1. Universal Blunders
-s (switch) command-line switch: 19.1.3. Switches
20. The Perl Debugger
safe compartments for insecure code: 23.3.1. Safe Compartments
Safe module: 23.3.1. Safe Compartments
32.1.12. Authentication, Security, and Encryption
insecure code, handling with: 23.3.1.2. Restricting operator access
23.3.1. Safe Compartments
save stack: 18.3. Executing Your Code
saving data structures: 9.7. Saving Data Structures
scalar context: 2.7.1. Scalar and List Context
Boolean values and: 2.7.2. Boolean Context
comma operator in: 3.18. Comma Operators
24.1.5. Previous Perl Traps
conditional operator in: 3.16. Conditional Operator
expressions in (see EXPRs)
forcing: 29.2.137. scalar
functions in: 29. Functions
/g pattern modifier, use in: 5.2.2. The m// Operator (Matching)
hash variables, evaluating in: 2.9. Hashes
keys function, calling in: 14.3.1. Hash-Tying Methods
list assignment in: 2.8.1. List Assignment
3.17. Assignment Operators
lvalues in: 4.8.1. Scoped Variable Declarations
m// (match) operator in: 5.2.2. The m// Operator (Matching)
operations behaving differently in: 24.1.2. Frequently Ignored Advice
range (..) operator in: 3.15. Range Operator
recognizing in debugger: 20.1. Using the Debugger
subroutines, calling and evaluating in: 6.2. Semantics
subtypes of: 2.7.1. Scalar and List Context
void context: 2.7.3. Void Context
scalar pseudofunction: 29.2.137. scalar
scalar reverse function: 15.2. Effects of Character Semantics
scalar values: 2.6. Scalar Values
2.6. Scalar Values
here documents: 2.6.6. "Here" Documents
interpolating array values: 2.6.5. Interpolating Array Values
numeric literals: 2.6.1. Numeric Literals
operators fo: 3. Unary and Binary Operators
string literals: 2.6.2. String Literals
v-string literals: 2.6.7. V-String Literals
scalar variables
in angle brackets: 2.11.2. Line Input (Angle) Operator
in double-quote context: 5.2.3. The s/// Operator (Substitution)
scalars: 1.2.1. Variable Syntax
1.2.1.1. Singularities
2.3. Built-in Data Types
2.4. Variables
characters, length of: 29.2.84. length
complex data structures, representing as: 1.2.1.3. Complexities
constants: 10.1. Symbol Tables
10.1. Symbol Tables
(see also constants)
functions for manipulating: 29.1. Perl Functions by Category
hard references as: 8.1. What Is a Reference?
list of (see arrays)
lists, converting to: 1.2.1.3. Complexities
parameter and return lists, subroutines: 6.2. Semantics
pattern-matching operators, applying to: 5.2. Pattern-Matching Operators
Perl, converting to C types: 21.4.4. Evaluating a Perl Statement from C
references: 1.2.1.1. Singularities
SV (scalar value) in C: 21.2. Internal Data Types
truth, evaluating in: 1.6.1. What Is Truth?
tying: 14.1. Tying Scalars
base class definitions, providing: 32.1.14. Convenient Classes
magical counter variables: 14.1.2. Magical Counter Variables
methods for: 14.1.1. Scalar-Tying Methods
preventing unlocalized use of $_ variables: 14.1.3. Magically Banishing $_
unordered set of (see hashes)
scheduling and preemption policies, threads: 17.2. The Thread Model
scopes: 2.5. Names
4.2. Compound Statements
dynamic: 4.8.4. Dynamically Scoped Variables: local
block: 4.8.2. Lexically Scoped Variables: my
blocks: 4.2. Compound Statements
file: 4.8.2. Lexically Scoped Variables: my
lexical scope: 4.8.2. Lexically Scoped Variables: my
loop variable in foreach: 4.4.3. foreach Loops
variables in if statements: 4.3. if and unless Statements
variables in three-part for loops: 4.4.2. for Loops
variables in while loops: 4.4.1. while and until Statements
declarations and: 4.8. Scoped Declarations
functions dealing with: 29.1. Perl Functions by Category
lexically scoped variables: 2.5. Names
my variables: 10. Packages
package declarations: 10. Packages
pattern-matching operations: 5.2. Pattern-Matching Operators
private variables (see lexical variables)
scope modifiers: 4.8.1. Scoped Variable Declarations
scope operators: 4.8.1. Scoped Variable Declarations
scope stack: 18.3. Executing Your Code
signal handling: 16.1. Signals
static (see scopes; lexical)
subroutines: 6.2.3. Scoping Issues
in threads: 17.2.3.1. Queues
variables: 1.2.1. Variable Syntax
strict pragma and: 1.2.1.4. Simplicities
screen appearance of command line: 20.3.3. Debugger Options
scripts
building with -e switch: 19.1.3. Switches
CGI, taint mode and: 23.1. Handling Insecure Data
checking syntax of: 19.1.3. Switches
debugging: 19.1.3. Switches
19.1.3. Switches
(see also debugging)
dumping core files: 19.1.3. Switches
embedding in messages: 19.1.3. Switches
end marker for: 2.6.8. Other Literal Tokens
executing: 29.2.174. system
insecure: 23.3. Handling Insecure Code
interpretation, shells vs. Perl: 24.1.4. Shell Traps
languages, checking for: 5.4.3.3. Unicode block properties
names of (see $0 variable)
pausing: 29.2.156. sleep
Perl
common mistakes of novices: 24.1. Common Goofs for Novices
CPAN directory of: 22. CPAN
idiomatic Perl, using: 24.4. Fluent Perl
performance of: 24.2. Efficiency
perl interpreter, associating with: 1.3.1. How to Do It
programming with style: 24.3. Programming with Style
searching for and compiling: 19.1. Command Processing
test scripts: 32.1.18. Development Support
running time of: 3.10. Named Unary and File Test Operators
searching for: 19.1.3. Switches
terminating with exec: 29.2.33. exec
SDBM_File module: 32.1.10. DBM Interfaces
search and replace, global: 5.2.3. The s/// Operator (Substitution)
search path, %INC: 28.2. Special Variables in Alphabetical Order
search programs: 1.7. Regular Expressions
Search::Dict module: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
searching
grep function for: 29.2.72. grep
linear, versus hashes: 24.2.1. Time Efficiency
rules for name searches: 2.5.1. Name Lookups
for scripts: 19.1.3. Switches
for substrings: 5.2.3. The s/// Operator (Substitution)
29.2.75. index
29.2.134. rindex
text, Perl modules for: 22.1. The CPAN modules Directory
security: 0.1. The Pursuit of Happiness
23. Security
29.2.164. srand
code masquerading as data: 23.3.2. Code Masquerading as Data
insecure code, handling: 23.3. Handling Insecure Code
safe compartments for: 23.3.1. Safe Compartments
insecure data, handling: 23.1. Handling Insecure Data
23.1. Handling Insecure Data
command and file access under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges
detecting and laundering tainted data: 23.1.1. Detecting and Laundering Tainted Data
environment, cleaning up: 23.1.2. Cleaning Up Your Environment
modules for: 32.1.12. Authentication, Security, and Encryption
22.1. The CPAN modules Directory
timing glitches, handling: 23.2. Handling Timing Glitches
race conditions: 23.2.2. Handling Race Conditions
temporary files: 23.2.3. Temporary Files
Unix kernel security bugs: 23.2.1. Unix Kernel Security Bugs
Win32::FileSecurity module: 32.1.20. Microsoft-Related Modules
security, of file test operators: 31.10. use filetest
sed: 1.7. Regular Expressions
5.2.4. The tr/// Operator (Transliteration)
seed, random number: 29.2.164. srand
seek function: 29.2.138. seek
29.2.176. tell
(see also tell function)
SEEK method: 14.4.1. Filehandle-Tying Methods
seekable I/O objects: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
seekdir function: 29.2.139. seekdir
select function: 29.2.38. fileno
29.2.113. print
29.2.140. select (output filehandle)
29.2.141. select (ready file descriptors)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
for format variables: 7.1. Format Variables
7.1. Format Variables
select syscall, multiplexing I/O between clients: 16.5.2. Networking Servers
SelectSaver module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities
self-matching characters: 5.9.4. The Little Engine That /Could(n't)?/
self method, thread accessing own thread object: 17.2.1.5. Identifying threads
SelfLoader module: 10.2. Autoloading
32.1.17. Module Installation Support
Devel::SelfStubber module, using with: 32.1.17. Module Installation Support
semantics: 29.2.192. use
semaphore file, use in file locking: 16.2.1. File Locking
System V IPC: 16.4. System V IPC
functions for: 29.2.142. semctl
IPC::Semaphore module: 32.1.8. Networking and Interprocess Communication
shared memory: 16.4. System V IPC
thread safety and: 17.2. The Thread Model
Thread::Semaphore module: 17.2.3.2. Semaphores
Win32::Semaphore module: 32.1.20. Microsoft-Related Modules
semctl function: 29.2.142. semctl
semget function: 29.2.143. semget
semop function: 29.2.144. semop
send function: 29.2.145. send
separators, split operator, defining: 1.7. Regular Expressions
sequential matches: 5.9.4. The Little Engine That /Could(n't)?/
serial ports, Perl modules for: 22.1. The CPAN modules Directory
serializing Perl data structures: 32.1.13. Perl Language Extensions and Internals
server-push CGI scripting: 32.1.9. World Wide Web
servers
forking clones to handle incoming connections: 16.5.2. Networking Servers
networking: 16.5.2. Networking Servers
Perl modules for: 22.1. The CPAN modules Directory
taint mode, importance of enabling for: 23.1. Handling Insecure Data
TCP: 16.5.1. Networking Clients
service port name/number translations: 29.2.64. getservbyname
set-id program:
23.1. Handling Insecure Data
dangerous operations, UID and GID setting to real: 23.1.3. Accessing Commands and Files Under Reduced Privileges
Unix kernel bugs, security problems with: 23.2.1. Unix Kernel Security Bugs
setgid function: 16.3.2. Talking to Yourself
23.1. Handling Insecure Data
setgrent function: 29.2.44. getgrent
sethostent function: 29.2.49. gethostent
setpgrp function: 29.2.146. setpgrp
16.1.1. Signaling Process Groups
setpriority function: 29.2.147. setpriority
setprotoent function: 29.2.60. getprotoent
setpwent function: 29.2.61. getpwent
sets, intersection: 6.3. Passing References
setservent function: 29.2.66. getservent
setsockopt function: 29.2.148. setsockopt
setuid function: 16.3.2. Talking to Yourself
23.1. Handling Insecure Data
shadow, password entries: 29.2.62. getpwnam
shared file locks: 16.2.1. File Locking
shared memory, System V IPC: 16.4. System V IPC
controlled access to: 16.4. System V IPC
functions for: 29.2.150. shmctl
# (sharp)
for comments: 2.2. Molecules
/x pattern modifier, using with: 5.2.1. Pattern Modifiers
in formats: 7. Formats
quoting character, whitespace and: 2.6.3. Pick Your Own Quotes
#! (shebang) notation: 1.3.1. How to Do It
19.1. Command Processing
security problems caused by: 23.2.1. Unix Kernel Security Bugs
simulating on non-Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems
shell module: 32.1.7. Operating System Interfaces
alternative for Perl, Windows systems: 19.2. Environment Variables
avoiding use of: 23.1.3. Accessing Commands and Files Under Reduced Privileges
avoiding with multi-argument piped open: 16.3.1. Anonymous Pipes
Bourne shell (sh): 19.1. Command Processing
bypassing with -| piping pseudocommand: 16.3.2. Talking to Yourself
debugger commands and: 20.2.6. Actions and Command Execution
environment variables as security hazards: 23.1.2. Cleaning Up Your Environment
environment variables, using with: 19.2. Environment Variables
I/O streams, setting up: 1.4. Filehandles
pipe commands with shell metacharacters, passing to: 29.2.104. open
pipe commands with special characters, handling: 16.3.1. Anonymous Pipes
programming, Perl vs.: 24.1.4. Shell Traps
quotes, passing through: 19.1.3. Switches
security pitfalls with use, avoiding: 23.3.2. Code Masquerading as Data
spawning, characters for: 20.3.3. Debugger Options
shift function: 9. Data Structures
29.2.149. shift
shift operator: 1.6.2.1. The while and until statements
3.9. Shift Operators
3.9. Shift Operators
shmctl function: 29.2.150. shmctl
ShMem package: 16.4. System V IPC
shmget function: 29.2.151. shmget
shmread function: 29.2.152. shmread
shmwrite function: 29.2.153. shmwrite
short-circuit operators: 1.5.5. Logical Operators
3.14. C-Style Logical (Short-Circuit) Operators
overloading and: 13.3. Overloadable Operators
shortening arrays: 2.8.2. Array Length
shorts: 29.2.162. sprintf
shutdown function: 29.2.154. shutdown
shutdown syscall: 16.5.1. Networking Clients
%SIG hash: 16.1. Signals
28.2. Special Variables in Alphabetical Order
sigaction function: 16.1.2. Reaping Zombies
SIGALRM signal: 29.2.3. alarm
signal handlers
defining as strings: 10. Packages
%SIG, Perl vs. C language: 24.1.3. C Traps
signal handling, sigtrap module: 32.1.7. Operating System Interfaces
signal level option (debugger): 20.3.3. Debugger Options
signals: 16. Interprocess Communication
16.1. Signals
%SIG hash: 28.2. Special Variables in Alphabetical Order
blocking: 16.1.4. Blocking Signals
core dumps, triggering in C library: 16.1. Signals
killing processes with: 29.2.80. kill
portability of: 25.4. System Interaction
signaling process groups: 16.1.1. Signaling Process Groups
sources of: 16.1. Signals
threads, delivering to: 17.2. The Thread Model
Thread::Signal module: 17.2.3.3. Other standard threading modules
timing out slow operations: 16.1.3. Timing Out Slow Operations
trapping with sigtrap pragma: 16.1. Signals
zombie processes, reaping: 16.1.2. Reaping Zombies
sigprocmask syscall: 16.1.4. Blocking Signals
sigtrap pragma: 16.1. Signals
16.1. Signals
sin function (sine): 29.2.155. sin
single inheritance: 12.5. Class Inheritance
single quotes (')
contractions in words, avoiding confusion with: 5.10.1. Lookaround Assertions
as package delimiters: 10. Packages
pattern recompilation and: 5.2.1. Pattern Modifiers
suppressing interpolation: 1.2.1.1. Singularities
suppressing variable interpolation and translation escape processing: 5.9.2.1. When backslashes happen
singularities (see singularities)
$size file statistic: 29.2.165. stat
sleep function: 29.2.156. sleep
select function instead of: 29.2.141. select (ready file descriptors)
slices of arrays or hashes: 2.4. Variables
slices of multidimensional arrays: 9.1.4. Slices
Perl, setting value for: 19.1.3. Switches
Socket module: 16.5. Sockets
32.1.8. Networking and Interprocess Communication
inet_ntoa function: 29.2.47. gethostbyaddr
networking client, connecting to server: 16.5.1. Networking Clients
socketpair function: 29.2.158. socketpair
socketpair syscall: 16.3.3. Bidirectional Communication
sockets
accepting connections from clients: 29.2.2. accept
attaching address to: 29.2.5. bind
closing: 29.2.16. close
closing one side: 29.2.154. shutdown
connecting: 29.2.18. connect
functions for: 29.2.67. getsockname
functions (Perl), dealing with: 16.5. Sockets
getting packed sockaddr address: 29.2.54. getpeername
in interprocess communication: 16.5. Sockets
message passing: 16.5.3. Message Passing
networking clients: 16.5.1. Networking Clients
networking servers: 16.5.2. Networking Servers
listen function for: 29.2.86. listen
low-level access, functions for: 29.1. Perl Functions by Category
modules for: 32.1.8. Networking and Interprocess Communication
newlines, sending across: 25.1. Newlines
opening with socket function: 29.2.157. socket
protocols and: 16. Interprocess Communication
receiving messages on: 29.2.125. recv
sending messages on: 29.2.145. send
setting options: 29.2.148. setsockopt
shutting down connection: 29.2.154. shutdown
TCP and: 16.5. Sockets
Unix-domain sockets: 16.5. Sockets
sort variables: 28.2. Special Variables in Alphabetical Order
sort function: 1.8. List Processing
sort subroutines, comparison operators in: 1.5.6. Some Numeric and String Comparison Operators
sorting
arrays in hashes of: 9.2.3. Access and Printing of a Hash of Arrays
hashes: 9.4.3. Access and Printing of a Hash of Hashes
keys and values, hashes: 29.2.79. keys
lists: 29.2.159. sort
overloading and: 13.3. Overloadable Operators
sort function: 29.2.159. sort
sort( ), keys, lists of: 1.2.1.2.2. Hashes.
source code
CPAN, for Perl distribution: 22. CPAN
development tools for: 18.6. Code Development Tools
filter for: 18.5.1. The Bytecode Generator
filters for: 24.5.3. Source Filters
foreign code, executing: 23. Security
window around breakpoint, examining: 20.1. Using the Debugger
source filters: 22.1. The CPAN modules Directory
space: 2.2. Molecules
spaceship operator (<=>): 3.12. Equality Operators
special characters: 5.9.4. The Little Engine That /Could(n't)?/
special variables: 28.1.6. Per-Package Special Functions
speed (see also performance)
24.2. Efficiency
splice function: 29.2.160. splice
Perl versions, changes in: 24.1.5. Previous Perl Traps
splicing tied arrays: 14.2.1. Array-Tying Methods
split function: 1.7. Regular Expressions
5.2. Pattern-Matching Operators
5.7.2. Clustering
24.2.1. Time Efficiency
29.2.161. split
sprintf function: 14.4.1. Filehandle-Tying Methods
29.2.162. sprintf
sqrt function (square root): 29.2.163. sqrt
srand function: 29.2.164. srand
src directory (CPAN): 22. CPAN
stacks: 1.2.1.2.1. Arrays.
9. Data Structures
expression evaluation: 2.3. Built-in Data Types
backtracing with T command: 20.1. Using the Debugger
disciplines: 29.2.104. open
Perl, manipulating from C: 21.4.5. Fiddling with the Perl Stack from C
Perl virtuall machine: 18.3. Executing Your Code
subroutines, current calls: 29.2.8. caller
standard input, scripts, passing by: 19.1. Command Processing
standard Unicode properties: 5.4.3.2. Standard Unicode properties
star (see asterisk)
starting position of matched string: 28.2. Special Variables in Alphabetical Order
stat, file permissions as octal: 29.2.103. oct
stat function: 29.2.165. stat
32.1.4. Filenames, Filesystems, and File Locking
filehandles, calling on: 23.2.2. Handling Race Conditions
state
common, sharing by class objects: 12.8. Managing Class Data
inheritance with class data accessor methods: 12.8. Managing Class Data
statements: 4. Statements and Declarations
compound: 4.2. Compound Statements
global declarations and: 4.7. Global Declarations
if and unless: 4.3. if and unless Statements
labels for (see labels)
loop-control operators vs.: 4.4.4. Loop Control
loops (see loops)
Perl, evaluating from C: 21.4.4. Evaluating a Perl Statement from C
simple: 4.1. Simple Statements
static linking: 21.3.1. XS and XSUBs
static scoping (see lexical scope)
static variables: 6.2.3. Scoping Issues
statistics, Perl modules for: 22.1. The CPAN modules Directory
status of exiting process: 28.2. Special Variables in Alphabetical Order
STDERR filehandle: 24.3. Programming with Style
28.2. Special Variables in Alphabetical Order
29.2.38. fileno
STDIN filehandle: 28.2. Special Variables in Alphabetical Order
STDIN: 1.4. Filehandles
29.2.38. fileno
reading single characters from: 29.2.43. getc
STDIN, STDOUT, and STDERR filehandles: 16.2.2. Passing Filehandles
passing filehandles to new programs through: 16.2.2. Passing Filehandles
reassigning to client connection: 16.5.2. Networking Servers
STDOUT filehandle: 28.2. Special Variables in Alphabetical Order
STDOUT: 1.4. Filehandles
29.2.38. fileno
printing to: 29.2.113. print
stemming text, Perl modules for: 22.1. The CPAN modules Directory
stepping through code: 20.2.1. Stepping and Running
sticky bit: 24.2.1. Time Efficiency
stopping (see terminating)
infinite loop: 4.4.2. for Loops
storage locations
for bytes (see big endian; little endian)
lvalues for: 1.5.3. Assignment Operators
(see also lvalues)
storing complex data values in DBM file: 14.6. Tie Modules on CPAN
strict module: 1.2.1.4. Simplicities
32.1.13. Perl Language Extensions and Internals
strict pragma: 2.5.1. Name Lookups
4.9.2. Controlling the Use of Globals
8.4. Symbolic References
string context: 2.7.1. Scalar and List Context
string literals: 2.6.2. String Literals
newlines in: 2.6.2. String Literals
v-strings (vector or version): 2.6.7. V-String Literals
stringification: 13.3. Overloadable Operators
modules for: 32.10. Data::Dumper
stringifying
data structures: 9.7. Saving Data Structures
objects: 8.3.6. Other Tricks You Can Do with Hard References
references: 8.3.6. Other Tricks You Can Do with Hard References
8.5.1. References Don't Work as Hash Keys
9.1.3. Access and Printing
9.1.5. Common Mistakes
stringifying operator
overloading: 14.4.1. Filehandle-Tying Methods
strings: 1.2.1. Variable Syntax
binary (see binary numbers)
bitwise operators, working with: 3.13. Bitwise Operators
boundary assertions: 1.7.3. Nailing Things Down
5.6.1. Beginnings: The A and ^ Assertions
capitalization of (see capitalization)
comparing: 3.11. Relational Operators
comparison operators: 1.5.6. Some Numeric and String Comparison Operators
as compilation units: 2.5.1. Name Lookups
concatenating: 3.8. Additive Operators
24.2.1. Time Efficiency
containing newlines, matches against: 5.2.1. Pattern Modifiers
converting to list values: 29.2.189. unpack
converting to numbers:of: 2.6.1. Numeric Literals
display, changing in debugger: 20.3.3. Debugger Options
double-quoted
changes in Perl versions: 24.1.5. Previous Perl Traps
character interpolation in: 2.6.2. String Literals
eval function and: 24.2.1. Time Efficiency
extracting substrings: 29.2.168. substr
first character of: 28.2. Special Variables in Alphabetical Order
formats for: 29.2.162. sprintf
hexadecimal (see hexadecimal numbers)
index function: 29.2.75. index
joining: 29.2.78. join
list values, converting to: 29.2.108. pack
modifying: 5.2.3.1. Modifying strings en passant
numbers, converting to: 2.6. Scalar Values
octal (see octal numbers)
operators: 1.5.2. String Operators
24.1.1. Universal Blunders
printing: 29.2.113. print
printing values in: 8.3.6. Other Tricks You Can Do with Hard References
quoted: 1.2.1.1. Singularities
range operator, working with: 3.15. Range Operator
references and: 8.5.1. References Don't Work as Hash Keys
rindex function: 29.2.134. rindex
searching for and replacing substrings (s/// operator): 5.2.3. The s/// Operator (Substitution)
splitting into substrings: 29.2.161. split
study function and: 29.2.166. study
truth values of: 1.6.1. What Is Truth?
vec function and: 29.2.195. vec
stripping (see deleting characters)
Struct::Class module: 12.7. Managing Instance Data
structs
emulating: 12.7.2. Generating Classes with Class::Struct
formatting: 29.2.108. pack
structural metacharacters in regular expressions: 5.1. The Regular Expression Bestiary
structural metasymbols: 5.3.1. Metasymbol Tables
StrVal (overload::StrVal): 13.7. Public Overload Functions
stubs for modules, generating: 32.1.17. Module Installation Support
study function: 29.2.166. study
style, programming with: 24.3. Programming with Style
sub {}: 4.5. Bare Blocks
sub declaration: 8.2.2.3. The anonymous subroutine composer
29.2.167. sub
sub keyword: 6.1. Syntax
6.4. Prototypes
subarrays and subhashes, references to, in arrays: 1.2.1.2.1. Arrays.
subclasses: 12.1. Brief Refresher on Object-Oriented Lingo
attributes, overriding superclass ancestors: 12.7. Managing Instance Data
subnamespaces, for variables: 2.5. Names
subroutine call stack: 29.2.8. caller
subroutine calls, executing without stepping through: 20.2.1. Stepping and Running
subroutines: 1.2.1. Variable Syntax
6. Subroutines
6. Subroutines
12.2. Perl's Object System
arguments: 28.2. Special Variables in Alphabetical Order
aborting with exit: 29.2.35. exit
anonymous references to: 8.2.2.3. The anonymous subroutine composer
atrributes, getting and setting: 32.1.13. Perl Language Extensions and Internals
autoloading: 10.2. Autoloading
12.5.4. Method Autoloading
32.1.17. Module Installation Support
barewords, confusing with: 24.1.5. Previous Perl Traps
B::Xref module, cross-references with C: 18.6. Code Development Tools
calling indirectly: 6.1. Syntax
calling, method invocations vs.: 12.4.1. Inheritable Constructors
classes with same names: 12.3.4. Package-Quoted Classes
constant: 10.1. Symbol Tables
data, passing into and out of: 6.2. Semantics
debugger command for pattern match listings: 20.2.5. Locating Code
declaring: 4.7. Global Declarations
29.2.167. sub
declaring in package for AUTOLOAD management: 12.5.4. Method Autoloading
defining: 6.2. Semantics
definitions, loading from other files: 4.7. Global Declarations
do SUBROUTINE operator: 29.2.28. do (subroutine)
errors, indicating: 6.2.2. Error Indications
external, portability of: 25.6. External Subroutines (XS)
external (XSUBs): 21.3. Extending Perl (Using C from Perl)
importing from another module: 6.1. Syntax
lexically scoped: 29.2.99. my
locking for threads: 17.2.2.3. Locking subroutines
locked attribute: 17.2.2.4. The locked attribute
lvalue attribute: 12.7.6. New Tricks
method resolution, steps for: 12.5. Class Inheritance
methods vs.: 12.3. Method Invocation
named, compiler/interpreter interaction: 18.7. Avant-Garde Compiler, Retro Interpreter
names for: 2.5. Names
2.5. Names
names of: 6.1. Syntax
nested: 8.3.7.2. Nested subroutines
parameter lists, working with: 6.2.1. Tricks with Parameter Lists
passing references in: 6.3. Passing References
performance and: 24.2.1. Time Efficiency
Perl, calling from C: 21.4.3. Calling a Perl Subroutine from C
prototyping, careful use of: 6.4.2. Care with Prototypes
redefining, inlining and: 6.4.1. Inlining Constant Functions
references to, retrieving from or passing to: 10.1. Symbol Tables
references to, in scalars: 1.2.1.1. Singularities
return function: 29.2.131. return
return values: 6.2. Semantics
returning references: 8.2.3. Object Constructors
scoping issues: 6.2.3. Scoping Issues
sorting, reverse disallowed as name for: 24.1.5. Previous Perl Traps
substituting with goto: 4.6. goto
29.2.71. goto
timelocal: 29.2.88. localtime
user-defined: 1.2.2. Verbs
subs module: 32.1.13. Perl Language Extensions and Internals
subs pragma, overriding built-in functions with: 11.3. Overriding Built-in Functions
$SUBSCRIPT_SEPARATOR: 2.9. Hashes
28.2. Special Variables in Alphabetical Order
subscripting: 24.2.1. Time Efficiency
negative: 2.3. Built-in Data Types
subscripts, arrays: 1.2.1.2.1. Arrays.
subshells, environment variables, using with: 19.2. Environment Variables
substitute (s//) operator: 24.1.1. Universal Blunders
5. Pattern Matching
2.7.4. Interpolative Context
5.2. Pattern-Matching Operators
substitution evaluations: 5.10.3.2. Substitution evaluations
substitution, shells versus Perl: 24.1.4. Shell Traps
substr function: 24.2.1. Time Efficiency
29.2.168. substr
chop function and: 29.2.12. chop
manipulating string positions with: 5.6. Positions
searching for and replacing with s/// operator: 5.2.3. The s/// Operator (Substitution)
subtracting, from character sets: 5.4.3.4. Defining your own character properties
subtracting pattern modifiers from cloisters: 5.7.3. Cloistered Pattern Modifiers
subtraction (see also additive operators)
overloaded objects: 13.2. Overload Handlers
SUPER pseudoclass: 12.5.2. Accessing Overridden Methods
12.5.2. Accessing Overridden Methods
superclasses: 12.1. Brief Refresher on Object-Oriented Lingo
SV (internal scalar value): 21.2. Internal Data Types
SWIG: 21.3.1. XS and XSUBs
SWIG system, XSUBs, automatically generating: 21.3.1. XS and XSUBs
switch statement: 4.5.1. Case Structures
24.2.1. Time Efficiency
Perl vs. C programming: 24.1.3. C Traps
switches, command-line: 19.1. Command Processing
19.1.3. Switches
-e switches: 19.1. Command Processing
default, taking switches as: 19.2. Environment Variables
single character, processing with clustering: 32.1.3. Option, Argument, Parameter, and Configuration File Processing
Sx, Perl modules for: 22.1. The CPAN modules Directory
symbol tables: 2.5. Names
2.5. Names
10.1. Symbol Tables
containing references to other symbol tables: 10.1. Symbol Tables
current package, determining use of: 10. Packages
displaying for packages: 20.3.3. Debugger Options
entries, aliasing: 2.10. Typeglobs and Filehandles
format name identifiers in: 29.2.41. format
in fully qualified names: 2.5. Names
local operator, making temporary changes with: 4.8.4. Dynamically Scoped Variables: local
packages: 29.2.109. package
references to: 8.2.5. Symbol Table References
Symbol module: 32.1.1. Data Types
symbolic references naming entries in: 8.1. What Is a Reference?
(see also debugging)
symbolic dereferences, checking with strict pragma: 4.9.2. Controlling the Use of Globals
symbolic links: 29.2.169. symlink
getting filenames from: 29.2.123. readlink
lstat function and: 29.2.91. lstat
security risks in Unix: 23.2.1. Unix Kernel Security Bugs
symbolic references: 8.1. What Is a Reference?
8.4. Symbolic References
symbols
exporting, prevention of 11.2.1.3. Managing unknown symbols
exporting from modules: 11.2. Creating Modules
importing into current package: 11.1. Using Modules
leaving off export list or deleting from import list: 11.2.1. Module Privacy and the Exporter
metasymbols, generic wildcards: 5.3.3. Wildcard Metasymbols
symlink function: 29.2.169. symlink
data access in threads: 17.2.2.1. Synchronizing access with lock
syntax, checking: 19.1.3. Switches
syntax, Perl: 2.3. Built-in Data Types
syscall function: 29.2.3. alarm
29.2.170. syscall
ioctl and fcntl returns: 29.2.77. ioctl
performance and: 24.2.1. Time Efficiency
Perl, C language vs.: 24.1.3. C Traps
restarting: 16.1.3. Timing Out Slow Operations
signal interruption of: 16.1.2. Reaping Zombies
Sys::Hostname module: 32.1.7. Operating System Interfaces
syslog, filehandle tying to: 14.6. Tie Modules on CPAN
sysopen function: 16.2.1. File Locking
16.3.4. Named Pipes
29.2.104. open
29.2.171. sysopen
file overwriting, controlling: 23.2.2. Handling Race Conditions
sysread function: 14.4.1. Filehandle-Tying Methods
29.2.172. sysread
Sys::Syslog module: 32.1.7. Operating System Interfaces
system calls: 29.2.170. syscall
system function: 29.2.174. system
list argument form, avoiding shell with: 23.3.2. Code Masquerading as Data
performance and: 24.2.1. Time Efficiency
portability of: 25.5. Interprocess Communication (IPC)
System V IPC: 16.4. System V IPC
functions dealing with: 29.1. Perl Functions by Category
functions for semaphores: 29.2.142. semctl
IPC::SysV module: 32.1.8. Networking and Interprocess Communication
killing proces groups: 29.2.80. kill
messages, syscalls for: 29.2.95. msgctl
portability of: 25.5. Interprocess Communication (IPC)
shared memory, functions for: 29.2.150. shmctl
System V IPC syscalls: 16. Interprocess Communication
reliable signals, not supporting: 16.1.2. Reaping Zombies
$SYSTEM_FD_MAX: 28.2. Special Variables in Alphabetical Order
syswrite function: 14.4. Tying Filehandles
14.4.1. Filehandle-Tying Methods
29.2.175. syswrite

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

-T (text file) test operator: 3.10. Named Unary and File Test Operators
-T (taint checking) switch: 16.5. Sockets
16.5.2. Networking Servers
19.1.3. Switches
t tab character assertion: 5.1. The Regular Expression Bestiary
-t (tty) file test: 3.10. Named Unary and File Test Operators
tables: 9.1. Arrays of Arrays
(see also multidimensional arrays)
tags (HTML and XML), transforming text to: 5.10.4. Defining Your Own Assertions
tags, symbol sets, Exporter: 11.2.1.4. Tag-handling utility functions
taint
functions returning tainted data: 29.2. Perl Functions in Alphabetical Order
taint checking code: 23.3. Handling Insecure Code
taint checks: 23.1. Handling Insecure Data
taint mode
automatic enabling of: 23.1. Handling Insecure Data
enabling explicitly with -T switch: 23.1. Handling Insecure Data
programs needing to run with: 23.1. Handling Insecure Data
taint mode, using: 23. Security
tainted data, detecting and laundering: 23.1.1. Detecting and Laundering Tainted Data
taint checking: 16.5.2. Networking Servers
19.1.3. Switches
taintperl program: 24.1.5. Previous Perl Traps
tan function: 29.2.4. atan2
tangent: 29.2.4. atan2
tarballs (.tar.gz files): 22.2. Using CPAN Modules
(see also tar files)
tarring, Perl modules for: 22.1. The CPAN modules Directory
over Internet-domain sockets: 16.5. Sockets
TCP clients/servers: 16.5.1. Networking Clients
tee program, Unix: 14.4.2. Creative Filehandles
tell function: 29.2.176. tell
using on tied filehandle: 14.4.1. Filehandle-Tying Methods
telldir function: 29.2.177. telldir
templates, characters for pack/unpack: 29.2.108. pack
templates, strings: 29.2.108. pack
temporary files, security risks with: 23.2.3. Temporary Files
temporary values: 2.3. Built-in Data Types
Tengwar script: 15.2. Effects of Character Semantics
Term::Cap module: 32.1.11. User Interfaces
Term::Complete module: 32.1.11. User Interfaces
terminal, setting for debugging I/O: 20.4. Unattended Execution
terminating
infinite loop: 4.4.2. for Loops
processes: 29.2.80. kill
Term::ReadKey modlue: 29.2.43. getc
Term::ReadKey module: 20.3.1. Editor Support for Debugging
Term::ReadLine module: 20.3.1. Editor Support for Debugging
32.1.11. User Interfaces
Term::Rendezvous module: 20.4. Unattended Execution
precedence of: 3.1. Terms and List Operators (Leftward)
relationships among, expressing with operators: 3. Unary and Binary Operators
terms in Perl: 2.3. Built-in Data Types
ternary operators (see trinary operator)
test command (Unix): 1.3.1. How to Do It
Test module: 32.1.18. Development Support
test operators (files): 1.5.7. Some File Test Operators
Test::Harness module: 32.1.18. Development Support
testing
if defined: 29.2.23. defined
for tainted data: 23.1.1. Detecting and Laundering Tainted Data
testing modules: 22.3. Creating CPAN Modules
external testing: 22.3.2. External Testing
internal testing: 22.3.1. Internal Testing
test.pl: 21.3.2. Creating Extensions
21.3.3. XSUB Input and Output
text
lexical scope and: 2.5. Names
Perl modules for: 22.1. The CPAN modules Directory
32.1.2. String Processing, Language Text Processing, Parsing, and Searching
pod data, converting to formatted ASCII: 32.1.16. Documentation Support
processing, Perl capabilities: 5. Pattern Matching
Unicode as international medium for: 15. Unicode
wrapping: 7.2.1. Accessing Formatting Internals
text editors, scripts, entering into: 1.3.1. How to Do It
text files, -T (file test) operator: 1.5.7. Some File Test Operators
Text::Abbrev module: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
Text::ParseWords module: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
Text::Wrap module: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
Thread method: 17.2.1.1. Thread creation
thread model
control, passing between threads: 17.2.2.6. Condition variables
data access: 17.2.2. Data Access
Thread module: 17.2.1. The Thread Module
detach method, shutting down threads with: 17.2.1.4. The detach method
identifying threads: 17.2.1.5. Identifying threads
join method, catching exceptions from: 17.2.1.3. Catching exceptions from join
thread creation: 17.2.1.1. Thread creation
thread destruction: 17.2.1.2. Thread destruction
yielding the processor: 17.2.1.7. Yielding the processor
Thread::Queue module: 17.2.3.1. Queues
threads: 17. Threads
29.2.89. lock
locked and method attributes, using: 12.7.6. New Tricks
locking: 29.2.89. lock
multiple, in single interpreter: 18.3. Executing Your Code
process model: 17.1. The Process Model
thread model: 17.2. The Thread Model
Thread::Semaphore module: 17.2. The Thread Model
17.2.2.6. Condition variables
17.2.3.2. Semaphores
Thread::Signal module: 17.2.3.3. Other standard threading modules
tid method: 17.2.1.5. Identifying threads
tie function: 14. Tied Variables
29.2.178. tie
use or require declarations and: 14. Tied Variables
tie modules on CPAN: 14.6. Tie Modules on CPAN
Tie::Array module: 14.2. Tying Arrays
32.1.14. Convenient Classes
SPLICE subroutine, using: 14.2.1. Array-Tying Methods
Tie::Counter module: 14.1.2. Magical Counter Variables
tied function: 14. Tied Variables
29.2.179. tied
Tie::DBI module: 14.6. Tie Modules on CPAN
Tie::DevNull module: 14.4.2. Creative Filehandles
Tie::DevRandom module: 14.4.2. Creative Filehandles
Tie::Hash module: 14.3. Tying Hashes
32.1.14. Convenient Classes
Tie::Persistent module: 14.6. Tie Modules on CPAN
Tie::RefHash module: 32.1.14. Convenient Classes
Tie::Scalar module: 14.1. Tying Scalars
32.1.14. Convenient Classes
Tie::SecureHash module: 12.7.5. Using Closures for Private Objects
14.6. Tie Modules on CPAN
Tie::StdArray module: 14.2. Tying Arrays
Tie::StdHash module: 14.3. Tying Hashes
Tie::StdScalar module: 14.1. Tying Scalars
Tie::SubstrHash module: 32.1.14. Convenient Classes
Tie::Syslog module: 14.6. Tie Modules on CPAN
Tie::Tee module: 14.4.2. Creative Filehandles
Tie::VecArray module: 14.6. Tie Modules on CPAN
Tie::Watch module: 14.6. Tie Modules on CPAN
tilde, home directory expansion of: 29.2.69. glob
time: 29.2.180. time
file access/modification: 29.2.165. stat
29.2.193. utime
file age: 3.10. Named Unary and File Test Operators
Greenwich Mean (GMT): 29.2.70. gmtime
for local timezone: 29.2.88. localtime
Perl functions for: 29.1. Perl Functions by Category
sleeping: 29.2.156. sleep
Time::Local module: 32.1.1. Data Types
UDP program, getting from other machines: 16.5.3. Message Passing
time base ($^T): 28.2. Special Variables in Alphabetical Order
time function: 29.2.180. time
32.1.1. Data Types
Time::gmtime module: 32.1.7. Operating System Interfaces
timelocal subroutine: 29.2.88. localtime
Time::localtime module: 32.1.7. Operating System Interfaces
Timer::HiRes module: 29.2.3. alarm
times function: 29.2.181. times
22.1. The CPAN modules Directory
portability of: 25.8. Dates and Times
Time::tm module: 32.1.7. Operating System Interfaces
timing
with alarms: 29.2.3. alarm
comparing for subroutines' execution: 20.6. The Perl Profiler
glitches, handling: 23.2. Handling Timing Glitches
in race conditions, handling: 23.2.2. Handling Race Conditions
temporary files: 23.2.3. Temporary Files
Unix kernel security bugs: 23.2.1. Unix Kernel Security Bugs
running times of alternate code versions, comparing: 32.2. Benchmark
script running: 3.10. Named Unary and File Test Operators
timing out slow operations: 16.1.3. Timing Out Slow Operations
titlecase
u and ucfirst function, using in conversions: 5.2.4. The tr/// Operator (Transliteration)
ucfirst, translating to: 15.2. Effects of Character Semantics
Tk: 22.1. The CPAN modules Directory
24.2.6. User Efficiency
(see also Perl/Tk)
tkRunning option (debugger): 20.3.3. Debugger Options
toggling trace mode (debugger): 20.2.3. Tracing
tokenization: 21.1. How Perl Works
(see also lexical analysis)
tokens: 2.2. Molecules
18.2. Compiling Your Code
ambiguous characters, problems with: 3.10. Named Unary and File Test Operators
parsing text into list of: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching
top-level package: 2.5.1. Name Lookups
top-of-form processing: 7. Formats
29.2.140. select (output filehandle)
29.2.200. write
top-of-page processing: 28.2. Special Variables in Alphabetical Order
topicalization: 1.2.1.4. Simplicities
tr/// (transliteration) operator: 5.2. Pattern-Matching Operators
5.2.4. The tr/// Operator (Transliteration)
29.2.182. tr///
29.2.201. y//
characters, transliterating with: 15.2. Effects of Character Semantics
=~ and !~ binding operators, using with: 5.2. Pattern-Matching Operators
modifiers for: 5.2.1. Pattern Modifiers
tracing,
stack backtrace, debugger T command: 20.2.3. Tracing
tracing, stack backtrace (debugger command): 20.1. Using the Debugger
trailing spaces in string comparisons: 3.11. Relational Operators
translating between languages: 24.5.2. Generating Perl in Other Languages
translation: 29.2.182. tr///
29.2.201. y//
transliteration escapes, processing by Perl regex compiler: 5.9.2.1. When backslashes happen
trapping
exceptions: 29.2.32. eval
out-of-memory errors: 28.2. Special Variables in Alphabetical Order
signals: 16.1. Signals
trigonometry, Math::Trig module: 32.1.1. Data Types
trinary operators: 1.5. Operators
3. Unary and Binary Operators
?: as: 3.16. Conditional Operator
4.5.1. Case Structures
overloading, not working with: 13.1. The overload Pragma
troubleshooting: 20. The Perl Debugger
(see also debugging)
C code: 24.1.3. C Traps
multidimensional arrays: 9.1.5. Common Mistakes
scripts
 24.1. Common Goofs for Novices
shell code: 24.1.4. Shell Traps
true values: 1.2.1.1. Singularities
truncate function: 29.2.183. truncate
argument list: 20.3.3. Debugger Options
arrays: 2.8.2. Array Length
numbers: 29.2.76. int
truth conditions, evaluating with if and unless statements: 1.6.1.1. The if and unless statements
truth values, evaluating for: 1.6.1. What Is Truth?
try block: 29.2.32. eval
tty: 16.3.3. Bidirectional Communication
two-dimensional arrays
creating and accessing: 9.1.1. Creating and Accessing a Two-Dimensional Array
creating your own: 9.1.2. Growing Your Own
tying variables: 8.5.1. References Don't Work as Hash Keys
14. Tied Variables
arrays: 14.2. Tying Arrays
filehandles: 14.4. Tying Filehandles
hashes: 14.3. Tying Hashes
scalars: 14.1. Tying Scalars
untying trap: 14.5. A Subtle Untying Trap
typecasting operator (in C): 3.21. C Operators Missing from Perl
typedefs (C language): 21.2. Internal Data Types
typeglobs: 2.5. Names
1.2.1. Variable Syntax
2.10. Typeglobs and Filehandles
8. References
8.3.6. Other Tricks You Can Do with Hard References
anonymous: 8.2.4. Handle References
anonymous
generating with Symbol module: 32.1.1. Data Types
autovivification of: 14.4.1. Filehandle-Tying Methods
filehandle references, creating: 8.2.4. Handle References
IO::Handle object: 8.2.5. Symbol Table References
local function, using with: 29.2.87. local
printing contents of: 20.3.3. Debugger Options
prototype symbol (*): 1.2.1. Variable Syntax
references to typeglobs vs.: 8.2.4. Handle References
subroutines, resolving to: 12.3. Method Invocation
symbol table aliasing with: 10.1. Symbol Tables
in symbol table hashes: 10.1. Symbol Tables
variables, tying to classes via: 14. Tied Variables
typemap: 21.3.1. XS and XSUBs
types (see data types)
typing variables
scalars: 2.6. Scalar Values
subtypes, converting between: 2.6. Scalar Values

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

-u (dump core) command-line switch: 19.1.3. Switches
u escape: 5.2.3. The s/// Operator (Substitution)
-u (setuid) file test: 3.10. Named Unary and File Test Operators
-U (unsafe) command-line switch: 19.1.3. Switches
uc function: 29.2.184. uc
uc operator: 15.2. Effects of Character Semantics
ucfirst function: 29.2.185. ucfirst
15.2. Effects of Character Semantics
passing messages with: 16.5.3. Message Passing
packets: 16.5. Sockets
$uid file statistic: 29.2.165. stat
UID (user ID): 28.2. Special Variables in Alphabetical Order
29.2.13. chown
assumed: 16.3.2. Talking to Yourself
passwd file entry from: 29.2.63. getpwuid
umask function: 29.2.186. umask
unary operators: 1.5. Operators
3. Unary and Binary Operators
3. Unary and Binary Operators
arithmetic: 1.5.4. Unary Arithmetic Operators
Boolean: 1.5.7. Some File Test Operators
class handler, invoking: 13.1. The overload Pragma
functions, behaving as: 3.1. Terms and List Operators (Leftward)
ideographic: 3.5. Ideographic Unary Operators
list operators, distinguishing from: 3.10. Named Unary and File Test Operators
named: 2.11.3. Filename Globbing Operator
3.1. Terms and List Operators (Leftward)
3.10. Named Unary and File Test Operators
listing of: 3.10. Named Unary and File Test Operators
prototyping functions as: 6.4.2. Care with Prototypes
undef function: 24.2.1. Time Efficiency
2.8.1. List Assignment
29.2.187. undef
arrays, freeing memory from: 2.8.2. Array Length
undefined scalars: 2.6. Scalar Values
undefined subroutines, calling with AUTOLOAD: 10.2. Autoloading
Underscore module: 14.1.3. Magically Banishing $_
unequal (see equality operators)
Unicode: 2.1. Atoms
15. Unicode
case translation tables: 15.2. Effects of Character Semantics
converting to characters: 29.2.14. chr
editors for: 15.2. Effects of Character Semantics
information about: 5.4.3. Unicode Properties
line separator character: 2.2. Molecules
locales and: 29.2.82. lc
paragraph separator character: 2.2. Molecules
Perl properties for: 5.4. Character Classes
properties: 5.4.3. Unicode Properties
bidirectional rendering: 5.4.3.2. Standard Unicode properties
block properties: 5.4.3.3. Unicode block properties
decomposition of characters: 5.4.3.2. Standard Unicode properties
Perl character class shortcuts and: 5.4.2. Classic Perl Character Class Shortcuts
Perl composites: 5.4.3.1. Perl's Unicode properties
standard: 5.4.3.2. Standard Unicode properties
syllabaries, classifying by vowel sounds: 5.4.3.2. Standard Unicode properties
properties database: 15.2. Effects of Character Semantics
smiley face: 29.2.14. chr
summary of, accessing: 15.2. Effects of Character Semantics
support for, turning on: 32.1.6. Internationalization and Locale
titlecase, converting strings to: 5.2.4. The tr/// Operator (Transliteration)
Unicode Standard, Version 3.0: 15.2. Effects of Character Semantics
use in Perl, caveats on: 15.3. Caution, [ren2bold] Working
wildcard metasymbols, matching with: 5.3.3. Wildcard Metasymbols
Unicode characters: 1.7. Regular Expressions
in identifiers: 2.5. Names
smiley: 2.6.2. String Literals
uninitialized, variables: 1.2.1.1. Singularities
UNIVERSAL class: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
methods, adding to: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
UNIVERSAL module: 32.1.14. Convenient Classes
1.2.1.1. Singularities
CPAN modules, installing on: 22.2.1. Decompressing and Unpacking CPAN Modules
fileglobbing: 32.1.4. Filenames, Filesystems, and File Locking
File::Spec::Unix module: 32.1.4. Filenames, Filesystems, and File Locking
security bugs: 23.2.1. Unix Kernel Security Bugs
sockets for: 32.1.8. Networking and Interprocess Communication
test command, test scripts and: 1.3.1. How to Do It
truncating kernel interpretation of #! line: 19.1. Command Processing
unless modifier: 4.1. Simple Statements
unless statements: 1.6.1.1. The if and unless statements
if statements, using instead of: 4.3. if and unless Statements
unlink function: 29.2.188. unlink
2.7.2. Boolean Context
unordered lists (see hashes)
unpack: 25.2. Endianness and Number Width
unpack function: 29.2.189. unpack
template characters for: 29.2.108. pack
unpacking CPAN modules: 22.2.1. Decompressing and Unpacking CPAN Modules
unqualified, names, searching for: 2.5.1. Name Lookups
unsafe operations: 19.1.3. Switches
unshift function: 9. Data Structures
29.2.190. unshift
unsigned integers, lists of, storing: 29.2.195. vec
unsigned shorts: 29.2.162. sprintf
untie function: 14. Tied Variables
14.5. A Subtle Untying Trap
29.2.21. dbmclose
29.2.191. untie
outstanding references, not eliminating: 14.1. Tying Scalars
until loops: 4.4.1. while and until Statements
until modifier: 4.1. Simple Statements
untying trap: 14.5. A Subtle Untying Trap
up method: 17.2.3.2. Semaphores
upcase function: 6.2.1. Tricks with Parameter Lists
uppercase, converting to: 2.6.2. String Literals
5.2.3. The s/// Operator (Substitution)
use: 4.7. Global Declarations
global and lexical scoping of: 4.8. Scoped Declarations
use attributes pragma: 6.5. Subroutine Attributes
use base declarations: 12.5.1. Inheritance Through @ISA
pseudohash implementations, requirement with: 12.7.1. Field Declarations with use fields
use base pragma: 31.3. use base
use blib pragma: 31.4. use blib
use bytes pragma: 15.2. Effects of Character Semantics
use charnames pragma: 15.2. Effects of Character Semantics
use command: 10. Packages
use declarations: 1.2.1.4. Simplicities
4.7. Global Declarations
4.9. Pragmas
(see also pragmas)
modules: 11.1. Using Modules
tie function and: 14. Tied Variables
use strict: 24.1.2. Frequently Ignored Advice
use fields declarations: 12.5.1. Inheritance Through @ISA
use fields pragma: 12.7.1. Field Declarations with use fields
use filetest pragma: 3.10. Named Unary and File Test Operators
use overload pragma: 13.1. The overload Pragma
use statement: 21.1. How Perl Works
use subs declarations: 12.5.4. Method Autoloading
use utf8 pragma: 5.3.3. Wildcard Metasymbols
use warnings pragma: 20. The Perl Debugger
Usenet, Perl modules for: 22.1. The CPAN modules Directory
user-defined functions (see subroutines)
user-defined subroutines: 1.2.2. Verbs
1.2.2. Verbs
(see also subroutines)
user efficiency, Perl programming: 24.2.6. User Efficiency
user ID (see UID)
user interfaces, modules providing: 32.1.11. User Interfaces
User::grent module: 29.2.44. getgrent
32.1.7. Operating System Interfaces
username, passwd file entry from: 29.2.62. getpwnam
User::pwent module: 29.2.63. getpwuid
32.1.7. Operating System Interfaces
Class::Struct, using to create objects and accessors: 32.6. Class::Struct
users
authenticating, Perl modules for: 22.1. The CPAN modules Directory
CPU times: 29.2.181. times
granting limited privileges to: 23.1. Handling Insecure Data
information about, functions for getting: 29.1. Perl Functions by Category
UTF-8: 2.1. Atoms
characters, converting to integers: 15.2. Effects of Character Semantics
globally switching interfaces to: 28.2. Special Variables in Alphabetical Order
module: 32.1.6. Internationalization and Locale
Perl version: 15.1. Building Character
pragma: 15.2. Effects of Character Semantics
strings, converting to/from byte strings: 15.1. Building Character
variable-length character encoding: 15.1. Building Character
utime function: 29.2.193. utime
utmp file (see /etc/utmp file)
UV (internal unsigned integer value): 21.2. Internal Data Types

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

v-strings
in $^V: 28.2. Special Variables in Alphabetical Order
2.6.7. V-String Literals
-v (version) command-line switch: 19.1.3. Switches
values
arrays (see arrays)
hashes, sorting: 29.2.79. keys
list (see list values)
referencing: 8.1. What Is a Reference?
scalar (see scalar values)
scope, confining to: 4.8.1. Scoped Variable Declarations
undefined, truth value of: 1.6.1. What Is Truth?
undefining: 29.2.187. undef
variables vs.: 1.2. Natural and Artificial Languages
values function: 14.3.1. Hash-Tying Methods
29.2.194. values
variable interpolation: 2.6.2. String Literals
glob operator, using: 2.11.3. Filename Globbing Operator
variable-length records: 7. Formats
variable-length UTF-8 characters: 15.1. Building Character
variables: 2.3. Built-in Data Types
2.4. Variables
3.1. Terms and List Operators (Leftward)
8. References
8.3.1. Using a Variable as a Variable Name
anonymous: 8.2.2. Anonymous Data
array: 2.6.5. Interpolating Array Values
attributes, getting and setting: 32.1.13. Perl Language Extensions and Internals
binding to packages: 29.2.191. untie
B::Xref module, cross-references with C: 18.6. Code Development Tools
class: 12.8. Managing Class Data
condition variables: 17.2.2.6. Condition variables
control, in foreach loop: 4.4.3. foreach Loops
debugger, customizing: 20.3.2. Customizing with Init Files
declaring: 4. Statements and Declarations
4.8.1. Scoped Variable Declarations
declaring global: 4.8.3. Lexically Scoped Global Declarations: our
dumping with V command: 10.1. Symbol Tables
environment: 28.2. Special Variables in Alphabetical Order
format: 7.1. Format Variables
fully-qualified, accessing from outside package: 23.3.1.1. Restricting namespace access
global (see global)
hash: 2.9. Hashes
initializing before calling subroutines: 6.2.3. Scoping Issues
interpolating
with double quotes: 5.2. Pattern-Matching Operators
into patterns: 5.2. Pattern-Matching Operators
interpolation: 1.2.1.1. Singularities
pattern matching, controlling with: 5.9.2. Variable Interpolation
lexical scoping: 29.2.99. my
local
common programming errors with: 24.1.1. Universal Blunders
my declarations, using instead of local function: 24.1.2. Frequently Ignored Advice
localizing existing: 29.2.87. local
modules, exporting to programs: 11.2.1. Module Privacy and the Exporter
my (see my declarations)
8.3.6. Other Tricks You Can Do with Hard References
10. Packages
names for: 1.2.1. Variable Syntax
24.3. Programming with Style
names in nested symbol tables: 2.5. Names
our (see our declarations)
package, displaying: 20.2.4. Display
package, memory usage: 20.3.3. Debugger Options
package variables: 2.5. Names
packages, associating with: 10. Packages
Perl vs. C, names of: 24.1.3. C Traps
private (see local variables)
repeated substitutions, performing on: 5.2.3.1. Modifying strings en passant
resetting values of: 29.2.130. reset
scoped, lexical scope: 4.8.2. Lexically Scoped Variables: my
scoping, strict pragma, use of: 1.2.1.4. Simplicities
shell programming, Perl vs.: 24.1.4. Shell Traps
special: 28.1.6. Per-Package Special Functions
strings of, matching against known strings: 5.9.2. Variable Interpolation
taint and: 23.1. Handling Insecure Data
translating with: 5.2.4. The tr/// Operator (Transliteration)
tying: 14. Tied Variables
29.2.178. tie
arrays: 14.2. Tying Arrays
filehandles: 14.4. Tying Filehandles
hashes: 14.3. Tying Hashes
scalars: 14.1. Tying Scalars
untying trap: 14.5. A Subtle Untying Trap
uninitialized: 1.2.1.1. Singularities
values, assignment and: 1.5.3. Assignment Operators
values vs.: 1.2. Natural and Artificial Languages
watch points, placing on: 14.6. Tie Modules on CPAN
variadic functions in Perl: 6.2. Semantics
vars modle (obsolete): 32.1.13. Perl Language Extensions and Internals
vec function: 29.2.195. vec
vectors, strings as: 29.2.162. sprintf
29.2.195. vec
verbosity
debugger, setting levels of: 20.3.3. Debugger Options
warnings, forcing in: 32.1.13. Perl Language Extensions and Internals
verbs: 1.2.2. Verbs
verbs, packages, handling of: 1.2.1.4. Simplicities
versions, Perl 28.2. Special Variables in Alphabetical Order
of Perl ($^V): 28.2. Special Variables in Alphabetical Order
module, checking for: 11.2.1.2. Version checking
changes between release 4 and 5: 24.1.5. Previous Perl Traps
placing in #! line: 19.1. Command Processing
specifying: 19.1.2. Location of Perl
VERSION method: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class
vi editor
debugger, support for: 20.3.1. Editor Support for Debugging
regular expressions, use of: 1.7. Regular Expressions
video, Perl modules for: 22.1. The CPAN modules Directory
virtual circuits (as TCP streams): 16.5. Sockets
virtual machine, Perl: 18.3. Executing Your Code
VMS operating system
File::Spec::VMS module: 32.1.4. Filenames, Filesystems, and File Locking
invoking Perl applications on: 19.1.1. #! and Quoting on Non-Unix Systems
void context: 1.5.4. Unary Arithmetic Operators
2.7.3. Void Context
2.8.1. List Assignment
29.2.198. wantarray
recognizing in debugger: 20.1. Using the Debugger
vowel sounds, classifying syllabaries according to: 5.4.3.2. Standard Unicode properties
VRML, Perl modules for: 22.1. The CPAN modules Directory

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

w, matching ideograph with: 15.2. Effects of Character Semantics
-w command-line switch: 19.1.3. Switches
-W (writeable by real uid/gid) file test: 3.10. Named Unary and File Test Operators
w forward character=w (forward character): 1.7. Regular Expressions
-w switch, Perl: 28.2. Special Variables in Alphabetical Order
wait function: 29.2.196. wait
wait system call: 28.2. Special Variables in Alphabetical Order
waitpid function: 29.2.197. waitpid
wantarray function: 29.2.198. wantarray
warn function: 29.2.199. warn
$WARNING: 28.2. Special Variables in Alphabetical Order
warning messages: 19.1.3. Switches
29.2.199. warn
33. Diagnostic Messages
intercepting: 28.2. Special Variables in Alphabetical Order
-w switch, turning on with: 1.3.1. How to Do It
${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order
lexical; ${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order
about undefined values: 4. Statements and Declarations
disabling unconditionally and permanently: 19.1.3. Switches
modules for: 32.1.15. Warnings and Exceptions
about remaining references to tied objects: 14.5. A Subtle Untying Trap
verbosity, forcing in: 32.1.13. Perl Language Extensions and Internals
warnings module: 32.1.15. Warnings and Exceptions
warnings pragma: 4.9.1. Controlling Warnings
warnLevel option (debugger): 20.3.3. Debugger Options
watch expressions: 20.2.3. Tracing
watch points, placing on Perl variables: 14.6. Tie Modules on CPAN
weak references: 8.5.2. Garbage Collection, Circular References, and Weak References
WeakRef module: 12.6.1. Garbage Collection with DESTROY Methods
weather, Perl modules for: 22.1. The CPAN modules Directory
web, Perl modules for: 22.1. The CPAN modules Directory
32.1.9. World Wide Web
while loops: 1.6.2.1. The while and until statements
4.4.1. while and until Statements
angle operator and $_: 2.11.2. Line Input (Angle) Operator
eof function in: 29.2.31. eof
while modifier: 4.1. Simple Statements
while statements: 1.5.5. Logical Operators
Boolean context, supplying: 2.7.2. Boolean Context
list assignment in: 2.8.1. List Assignment
whitespace: 1.7. Regular Expressions
2.2. Molecules
24.3. Programming with Style
29. Functions
cononicalizing in a variable: 5.2.3.1. Modifying strings en passant
in formats: 7. Formats
leading, removing in here documents: 2.6.6. "Here" Documents
quote characters, use in: 2.6.3. Pick Your Own Quotes
/x modifier in pattern matching: 5.2.1. Pattern Modifiers
whitespaces, use as variable name or delimiter for quote construct, changes in: 24.1.5. Previous Perl Traps
wide character APIs
enabling Perl use of on target system: 19.1.3. Switches
system calls using: 15.1. Building Character
wide, syscalls: 28.2. Special Variables in Alphabetical Order
${^WIDE_SYSTEM_CALLS}: 28.2. Special Variables in Alphabetical Order
width
character representation: 15.1. Building Character
of numbers: 25.2. Endianness and Number Width
wildcard metasymbols: 5.3.3. Wildcard Metasymbols
character classes and: 5.4.1. Custom Character Classes
5.4.1. Custom Character Classes
Win32API::File module: 32.1.20. Microsoft-Related Modules
Win32API::Net module: 32.1.20. Microsoft-Related Modules
Win32API::Registry module: 32.1.20. Microsoft-Related Modules
Win32::ChangeNotify module: 32.1.20. Microsoft-Related Modules
Win32::Console module: 32.1.20. Microsoft-Related Modules
Windows (see Microsoft Windows)
Win32::Event module: 32.1.20. Microsoft-Related Modules
Win32::EventLog module: 32.1.20. Microsoft-Related Modules
Win32::File module: 32.1.20. Microsoft-Related Modules
Win32::FileSecurity module: 32.1.20. Microsoft-Related Modules
Win32::Internet module: 32.1.20. Microsoft-Related Modules
Win32::IPC module: 32.1.20. Microsoft-Related Modules
Win32::Mutex module: 32.1.20. Microsoft-Related Modules
Win32::NetAdmin module: 32.1.20. Microsoft-Related Modules
Win32::NetResource module: 32.1.20. Microsoft-Related Modules
Win32::ODBC module: 32.1.20. Microsoft-Related Modules
Win32::OLE module: 32.1.20. Microsoft-Related Modules
Win32::OLE::Const module: 32.1.20. Microsoft-Related Modules
Win32::OLE::Enum module: 32.1.20. Microsoft-Related Modules
Win32::OLE::NLS module: 32.1.20. Microsoft-Related Modules
Win32::OLE::Variant module: 32.1.20. Microsoft-Related Modules
Win32::PerfLib module: 32.1.20. Microsoft-Related Modules
Win32::Pipe module: 16.3.4. Named Pipes
Win32::Process module: 32.1.20. Microsoft-Related Modules
Win32::Semaphore module: 32.1.20. Microsoft-Related Modules
Win32::Service module: 32.1.20. Microsoft-Related Modules
Win32::Sound module: 32.1.20. Microsoft-Related Modules
Win32::TieRegistry module: 14.6. Tie Modules on CPAN
32.1.20. Microsoft-Related Modules
word character: 1.7. Regular Expressions
word lists: 2.8. List Values and Arrays
b assertion=b assertion: 1.7.3. Nailing Things Down
capturing: 5.2.2. The m// Operator (Matching)
lists of, doing programmable command completion on: 32.1.11. User Interfaces
World Wide Web: 0.6.2. Usenet Newsgroups
World Wide Web (WWW) (see web)
C, around set-id scripts: 23.2.1. Unix Kernel Security Bugs
wrapping text: 7.2.1. Accessing Formatting Internals
32.1.2. String Processing, Language Text Processing, Parsing, and Searching
Perl module for: 22.1. The CPAN modules Directory
writable file test operator: 1.5.7. Some File Test Operators
3.10. Named Unary and File Test Operators
write function: 29.2.200. write
format function, declaring named sequence of picture lines: 29.2.41. format
writing
data via low-level system call: 29.2.113. print
29.2.114. printf
29.2.175. syswrite
29.2.200. write
scripts (see scripts)
to shared memory segment ID: 29.2.153. shmwrite
to files, open mode and: 29.2.104. open

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x=, (assignment) operator: 3.17. Assignment Operators
-x (executable by effective uid/gid) file test: 3.10. Named Unary and File Test Operators
-X (executable by real uid/gid) file test: 3.10. Named Unary and File Test Operators
-x (extract program) command-line switch: 19.1. Command Processing
19.1.3. Switches
/x pattern modifier: 5.2.1. Pattern Modifiers
5.2.1. Pattern Modifiers
5.2.2. The m// Operator (Matching)
5.2.3. The s/// Operator (Substitution)
x (repetition) operator: 1.5.2. String Operators
-X (warning disabling) command-line switch: 19.1.3. Switches
X wildcard metasymbol: 5.3.3. Wildcard Metasymbols
XML, Perl modules for: 22.1. The CPAN modules Directory
Xor logical operator: 1.5.5. Logical Operators
XS language
code, portability of: 25.6. External Subroutines (XS)
debugging tools for: 32.1.13. Perl Language Extensions and Internals
external subroutines, wrapping: 21.3. Extending Perl (Using C from Perl)
functions, mapping between C and Perl: 21.3.1. XS and XSUBs
XSLoader module: 32.1.17. Module Installation Support
xsubpp compiler: 21.3.1. XS and XSUBs
XSUBs: 21.3. Extending Perl (Using C from Perl)
21.3.1. XS and XSUBs
(see also XS)
input and output: 21.3.3. XSUB Input and Output
wrapping subroutines for Perl: 21.3. Extending Perl (Using C from Perl)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

y/// (transliteration) operator: 5.2. Pattern-Matching Operators
5.2.4. The tr/// Operator (Transliteration)
29.2.201. y//
yield function: 17.2.1.7. Yielding the processor

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

^Z (Control-Z)
Control-Z as eof: 24.5.2. Generating Perl in Other Languages
Control-Z character: 2.6.8. Other Literal Tokens
Control-Z key: 2.6.8. Other Literal Tokens
z (string boundary): 5.6.2. Endings: The z, Z, and $ Assertions
-z (zero size) file test: 3.10. Named Unary and File Test Operators
zero-width assertions: 5.1. The Regular Expression Bestiary
5.3.1. Metasymbol Tables
5.6. Positions
quantifiers and: 5.1. The Regular Expression Bestiary
zipping, Perl modules for: 22.1. The CPAN modules Directory
reaping: 16.1.2. Reaping Zombies
servers: 16.5.2. Networking Servers

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2002 O'Reilly & Associates, Inc. All Rights Reserved.


Colophon (Programming Perl)

 Programming Perl
Previous

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal on the cover of Programming Perl, Third Edition is a dromedary (one-hump camel). Camels are large ruminant mammals, weighing between 1,000 and 1,600 pounds and standing six to seven feet tall at the shoulders. They are well known for their use as draft and saddle animals in the desert regions, especially of Africa and Asia. Camels can go for days without water. If food is scarce, they will eat anything, even their owner's tent. Camels live up to 50 years.

Melanie Wang was the production editor and copyeditor for Programming Perl, Third Edition. Colleen Gorman and Maureen Dempsey provided quality control. Maeve O'Meara, Mary Sheehan, Emily Quill, Jeffrey Holcomb, Ann Schirmer, Colleen Gorman, Darren Kelly, Madeleine Newell, and Betty Hugh provided production support. Ellen Troutman-Zaig wrote the index.

Edie Freedman designed the cover of this book using a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

Alicia Cech and David Futato designed the interior layout based on a series design by Nancy Priest. The authors' text in POD was converted by Lenny Muellner into DocBook 3.1 SGML. The print version of this book was created by translating the SGML source into a set of gtroff macros using a Perl filter developed at O'Reilly & Associates by Norman Walsh. Steve Talbott designed and wrote the underlying macro set on the basis of the GNU gtroff -ms macros; Lenny Muellner adapted them to SGML and implemented the book design. The GNU groff text formatter version 1.11 was used to generate PostScript output. Mike Sierra provided crucial help with the Chinese and Japanese Unicode characters in Chapter 15, Unicode. The text and heading fonts are ITC Garamond Light and Garamond Book. The illustrations that appear in the book were produced by Robert Romano and Rhon Porter using Macromedia FreeHand 8 and Adobe Photoshop 5.

Previous | Home
Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.


Table of Contents

Copyright Page
Foreword
Preface
Chapter 1: Introduction
Chapter 2: Building Larger Programs
Chapter 3: Introduction to References
Chapter 4: References and Scoping
Chapter 5: Manipulating Complex Data Structures
Chapter 6: Subroutine References
Chapter 7: Practical Reference Tricks
Chapter 8: Introduction to Objects
Chapter 9: Objects with Data
Chapter 10: Object Destruction
Chapter 11: Some Advanced Object Topics
Chapter 12: Using Modules
Chapter 13: Writing a Distribution
Chapter 14: Essential Testing
Chapter 15: Contributing to CPAN
Appendix A: Answers to Exercises
Index
Colophon
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


(Learning Perl Objects, References & Modules)

 Learning Perl Objects, References & Modules Learning Perl Objects, References & Modules
Previous Next

Copyright © 2003 O'Reilly & Associates, Inc.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com). For more information, contact our corporate/institutional sales department: (800) 998-9938 or corporate@oreilly.com.

Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The association between the image of an alpaca and the topic of Perl is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | Foreword
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Foreword (Learning Perl Objects, References & Modules)

 Learning Perl Objects, References & Modules Learning Perl Objects, References & Modules
Previous Next

Foreword

Perl's object-oriented mechanism is classic prestidigitation. It takes a collection of Perl's existing non-OO features such as packages, references, hashes, arrays, subroutines, and modules, and then—with nothing up its sleeve—manages to conjure up fully functional objects, classes, and methods. Seemingly out of nowhere.

That's a great trick. It means you can build on your existing Perl knowledge and ease your way into OO Perl development, without first needing to conquer a mountain of new syntax or navigate an ocean of new techniques. It also means you can progressively fine-tune OO Perl to meet your own needs, by selecting from the existing constructs the one that best suits your task.

But there's a problem. Since Perl co-opts packages, references, hashes, arrays, subroutines, and modules as the basis of its OO mechanism, to use OO Perl you already need to understand packages, references, hashes, arrays, subroutines, and modules.

And there's the rub. The learning curve hasn't been eliminated; it's merely been pushed back half a dozen steps.

So then: how are you going to learn everything you need to know about non-OO Perl so you can start to learn everything you need to know about OO Perl?

This book is the answer. In the following pages, Randal draws on two decades of using Perl, and four decades of watching Gilligan's Island and Mr. Ed, to explain each of the components of Perl that collectively underpin its OO features. And, better still, he then goes on to show exactly how to combine those components to create useful classes and objects.

So if you still feel like Gilligan when it comes to Perl's objects, references, and modules, this book is just what the Professor ordered.

And that's straight from the horse's mouth.

—Damian Conway, May 2003

Previous | Home | Next
Copyright Page | Book Index | Preface
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Preface

Ten years ago, I wrote the first edition of Learning Perl. In the intervening years, Perl itself has grown substantially from a "cool" scripting language used primarily by Unix system administrators to a robust object-oriented programming language that runs on practically every computing platform known to mankind.

Throughout its three editions, Learning Perl remained the same size (about 300 pages) and continued to cover much of the same material to remain compact and accessible to the beginning programmer. But there is much more to learn about Perl than there was ten years ago.

This book may be entitled Learning Perl Objects, References, and Modules, but I like to think of it as just Learning More Perl.[1] This is the book that picks up where Learning Perl leaves off. It shows how to use Perl to write larger programs.

[1]Don't ask why it isn't called that. We must have had 30 emails on the subject.

As in Learning Perl, each chapter in this book is designed to be small enough to read in just an hour or two. Each chapter ends with a series of exercises to help you practice what you've just learned, with the answers in the Appendix for your reference. And like Learning Perl, the material in this book was developed for a teaching environment and used in that setting, including for our own use at Stonehenge Consulting Services as we present onsite and open-enrollment trainings.

You don't have to be a Unix guru, or even a Unix user, to benefit from this book. Unless otherwise noted, everything in this book applies equally well to Windows ActivePerl from ActiveState, and all other modern implementations of Perl. To use this book, you just need to be familiar with the material in Learning Perl and have the ambition to go further.

0.1. Structure of This Book

It's a good idea to read this book from front to back, stopping to do the exercises. Each chapter builds on preceding chapters. You've been warned.

Chapter 1, Introduction
An introduction to the material.

Chapter 2, Building Larger Programs
How to bring code in from separate files so you can have others do some of your work for you.

Chapter 3, Introduction to References
How to allow the same code to operate on different data structures by introducing a level of indirection.

Chapter 4, References and Scoping
How Perl manages to keep track of pointers to data, and an introduction to anonymous data structures and autovivification.

Chapter 5, Manipulating Complex Data Structures
Viewing, searching, and storing nested arrays and hashes.

Chapter 6, Subroutine References
How to capture behavior as a value to be passed around.

Chapter 7, Practical Reference Tricks
Sorting complex operations, the "Schwartzian Transform," and working with recursively defined data.

Chapter 8, Introduction to Objects
Working with classes, method calls, inheritance, and overriding.

Chapter 9, Objects with Data
Adding per-instance data, including constructors, getters, and setters.

Chapter 10, Object Destruction
Adding behavior to an object that is going away, including object persistence.

Chapter 11, Some Advanced Object Topics
Multiple inheritance, automatic methods, and references to filehandles.

Chapter 12, Using Modules
How use works, from the user's and author's perspectives.

Chapter 13, Writing a Distribution
Packaging up a module for sharing, including portable installation instructions.

Chapter 14, Essential Testing
Providing unit and integration tests with your distribution.

Chapter 15, Contributing to CPAN
Submitting your module to the CPAN.

Appendix A, Answers to Exercises
Where to go to get answers.

Previous | Home | Next
Copyright Page | Book Index | 0.2. Conventions Used in This Book
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.2. Conventions Used in This Book

The following typographic conventions are used in this book:

Constant width
Used for function names, module names, filenames, environment variables, code snippets, and other literal text

Italics
Used for emphasis and for new terms where they are defined

Previous | Home | Next
Preface | Book Index | 0.3. Comments and Questions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.3. Comments and Questions

Please address comments and questions concerning this book to the publisher:

O'Reilly & Associates, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
(800) 998-9938 (in the United States or Canada)
(707) 829-0515 (international or local)
(707) 829-0104 (fax)

There is a web page for this book, which lists errata, examples, or any additional information. You can access this page at:

http://www.oreilly.com/catalog/lrnperlorm

To comment or ask technical questions about this book, send email to:

bookquestions@oreilly.com

For more information about books, conferences, Resource Centers, and the O'Reilly Network, see the O'Reilly web site at:

http://www.oreilly.com
Previous | Home | Next
0.2. Conventions Used in This Book | Book Index | 0.4. Acknowledgments
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


0.4. Acknowledgments

In the preface of the first edition of Learning Perl, I acknowledged the Beaverton McMenamin's Cedar Hills Pub just down the street from my house for the "rent-free booth-office space" while I wrote most of the draft on my Powerbook 140. Well, like wearing your lucky socks every day when your favorite team is in the playoffs, I wrote nearly all of this book (including these words) at the same brewpub, in hopes that the light of success of the first book will shine on me twice.

This McM's has the same great local microbrew beer and greasy sandwiches, but they've gotten rid of my favorite pizza bread, replacing it with new items like marionberry cobbler (a local treat) and spicy jambalaya. (And they added two booths, and put in some pool tables.) Also, instead of the Powerbook 140, I'm using a Titanium Powerbook, with 1,000 times more disk, 500 times more memory, and a 200-times-faster CPU running a real Unix-based operating system (OSX) instead of the limited MacOS. I also uploaded all of the draft sections (including this one) over my 144K cell-phone modem and emailed them directly to the reviewers, instead of having to wait to rush home to my 9600-baud external modem and phone line. How times have changed!

So, thanks once again to the staff of the McMenamin's Cedar Hills Pub for the booth space and hospitality.

Like the third edition of Learning Perl, I also owe much of what I'm saying here and how I'm saying it to the decade of students at Stonehenge Consulting Services who have given me immediate precise feedback (by their glazed eyes and awkwardly constructed questions) when I was exceeding the "huh?" factor threshold. With that feedback over many dozens of presentations, I was able to keep refining and refactoring the materials that paved the way for this book.

Speaking of which, those materials started as a half-day "What's new in Perl 5?" summary commissioned by Margie Levine of Silicon Graphics, in addition to my frequently presented onsite four-day Llama course (targeted primarily for Perl Version 4 at the time). Eventually, I got the idea to beef up those notes into a full course and enlisted fellow Stonehenge presenter Joseph Hall for the task. (He's the one that selected the universe from which the examples are drawn.) Joseph developed a two-day course for Stonehenge in parallel with his excellent Effective Perl Programming book, which we then used as the course textbook (until now).

Other Stonehenge instructors have also dabbled a bit in the "Packages, References, Objects, and Modules" course over the years, including Chip "every source line of the Perl compiler memorized" Salzenberg, "don't mess with my name" brian d foy, and Tad "something clever this way comes" McClellan. But the bulk of the recent changes has been the responsibility of my senior trainer Tom Phoenix, who has been "Stonehenge employee of the month" so often that I may have to finally give up my preferred parking space. Tom manages the materials (just as Tad manages operations) so I can focus on being the president and the janitor of Stonehenge. And since I'm naming the Stonehenge crew, I can't forget my wacky party manager and marketing consultant (and longtime friend) Bill Harp, who at this very moment is planning yet another legendary Stonehenge OSCON party (including the premiere of the book you're now reading).

Tom Phoenix contributed most exercises in this book and a timely set of review notes during my writing process, including entire paragraphs for me to just insert in place of the drivel I had written. We work well as a team, both in the classroom and in our joint writing efforts. It is for this effort that we've acknowledged Tom as a coauthor, but I'll take direct blame for any parts of the book you end up hating: none of that could have possibly been Tom's fault.

I also appreciate my technical reviewers, Mike Stok, Joe Johnston, Paul Grassie, Damian Conway, Neil Bauman, and David H. Adler, for their constructive feedback and kind words, although I really was expecting to be beat up a bit more in the comments. Maybe the time limit kept y'all nice.

And I especially appreciate and acknowledge Linda Mui of O'Reilly, who has shepherded this project through from the beginning, when Tom and I suggested at OSCON 2001 that our next book should be a sequel, and then made it so.

Of course, a book is nothing without a subject and a distribution channel, and for that I must acknowledge longtime associates Larry Wall and Tim O'Reilly. Thanks guys, for creating an industry that has paid for my toys and essentials for over a decade.

And, as always, a special thanks to Lyle and Jack for teaching me nearly everything I know about writing and convincing me that I was much more than a programmer who might learn to write: I was also a writer who happened to know how to program. Thank you.

And to you, the reader of this book, for whom I toiled away the countless hours while sipping a cold microbrew and scarfing down a piece of incredible cheesecake, trying to avoid spilling on my laptop keyboard: thank you for reading what I've written. I sincerely hope I've contributed (in at least a small way) to your Perl proficiency. If you ever meet me on the street, please say "Hi."[2] I'd like that. Thank you.

[2]And yes, you can ask a Perl question at the same time. I don't mind.

Previous | Home | Next
0.3. Comments and Questions | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 1. Introduction

Contents:

What Should You Know Already?
What About All Those Footnotes?
What's with the Exercises?
What if I'm a Perl Course Instructor?

Welcome to next step in your understanding of Perl. You're probably here either because you want to learn to write programs that are more than 100 lines long or because your boss has told you to do so.

See, our Learning Perl book was great because it introduced the use of Perl for short and medium programs (which is most of the programming done in Perl, we've observed). But, to avoid having "the Llama book" be as big and intimidating as "the Camel book," we left a lot of information out, deliberately and carefully.

In the pages that follow, you can get "the rest of the story" in the same style as our friendly Llama book. It covers what you need to write programs that are 100 to 10,000 lines long.

For example, you'll learn how to work with multiple programmers on the same project. This is great, because unless you work 35 hours each day, you'll need some help with larger tasks. You'll also need to ensure that your code all fits with the other code as it is developed for the final application.

This book will also show you how to deal with larger and more complex data structures, such as what we might casually call a "hash of hashes" or an "array of arrays of hashes of arrays."

And then there's the buzzworthy notion of object-oriented programming, which allows parts of your code (or hopefully code from others) to be reused with minor or major variations within the same program. The book will cover that as well, even if you've never seen objects before.

An important aspect of working in teams is having a release cycle and tests for unit and integration testing. You'll learn the basics of packaging your code as a distribution and providing unit tests for that distribution, both for development and for verifying that your code works in the ultimate end environment.

Hopefully, just as was promised and delivered in Learning Perl, you'll be entertained along the way by interesting examples and bad puns. (We've sent Fred and Barney and Betty and Wilma home, though. A new cast of characters will take the starring roles.)

1.1. What Should You Know Already?

We'll presume that you've already read Learning Perl, or at least pretend you have, and that you've played enough with Perl to already have those basics down. For example, you won't see an explanation in this book that shows how to access the elements of an array or return a value from a subroutine.

Make sure you know the following things:

  • How to run a Perl program on your system

  • Scalars

  • Arrays

  • Hashes

  • Control structures such as while, if, for, and foreach

  • Subroutines

  • Perl operators such as grep, map, sort, and print

  • File manipulation such as open, file reading, and -x (file tests)

You might pick up deeper insight into these topics in this book, but we're going to presume you know the basics.

Previous | Home | Next
0.4. Acknowledgments | Book Index | 1.2. What About All Those Footnotes?
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.2. What About All Those Footnotes?

Like Learning Perl, this book relegates some of the more esoteric items out of the way for the first reading and places those items in footnotes.[3] You should skip those the first time through and pick them up on a rereading. You will not find anything in a footnote that is needed to understand any of the later material.

[3]Like this.

Previous | Home | Next
1. Introduction | Book Index | 1.3. What's with the Exercises?
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.3. What's with the Exercises?

Hands-on training gets the job done better. The best way to provide this training is with a series of one or more exercises after every half-hour to hour of presentation. Of course, if you're a speed reader, the end of the chapter may come a bit sooner than a half hour. Slow down. Take a breather. But do the exercises.

Each exercise has a "minutes to complete" rating. This rating hits the midpoint of the bell curve but don't feel bad if you take significantly longer or shorter. Sometimes it's just a matter of how many times you've faced similar programming tasks in your studies or jobs. Use the numbers merely as a guideline.

Every exercise has its answer in Appendix A. Again, try not to peek; you'll ruin the value of the exercise.

Previous | Home | Next
1.2. What About All Those Footnotes? | Book Index | 1.4. What if I'm a Perl Course Instructor?
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


1.4. What if I'm a Perl Course Instructor?

If you're a Perl instructor who has decided to use this as your textbook, you should know that each set of exercises is short enough for most students to complete the whole set in 45 minutes to an hour, with a little time left over for a break. Some chapters' exercises should be quicker, and some may take longer. That's because once all those little numbers in square brackets were written, we discovered that we don't know how to add.

So let's get started. Class begins after you turn the page...

Previous | Home | Next
1.3. What's with the Exercises? | Book Index | 2. Building Larger Programs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 2. Building Larger Programs

Contents:

The Cure for the Common Code
Inserting Code with eval
Using do
Using require
require and @INC
The Problem of Namespace Collisions
Packages as Namespace Separators
Scope of a Package Directive
Packages and Lexicals
Exercises

This chapter looks at how to break up a program into pieces and includes some of the concerns that arise when you put those pieces back together again, or when many people work together on the same program.

2.1. The Cure for the Common Code

Let's say a famous sailor (we'll call him "the Skipper") uses Perl to help navigate his ocean-going vessel (call it "the Minnow"). The Skipper writes many Perl programs to provide navigation for all the common ports of call for the Minnow. He finds himself cutting and pasting a very common routine into each program:

sub turn_towards_heading {
  my $new_heading = shift;
  my $current_heading = current_heading( );
  print "Current heading is ", $current_heading, ".\n";
  print "Come about to $new_heading ";
  my $direction = "right";
  my $turn = ($new_heading - $current_heading) % 360;
  if ($turn > 180) { # long way around
    $turn = 360 - $turn;
    $direction = "left";
  }
  print "by turning $direction $turn degrees.\n";
}

This routine gives the shortest turn to make from the current heading (returned by the subroutine current_heading( )) to a new heading (given as the first parameter to the subroutine).

The first line of this subroutine might have read instead:

my ($new_heading) = @_;

This is mostly a style call: in both cases, the first parameter ends up in $new_heading. However, in later chapters, you'll see that removing the items from @_ as they are identified does have some advantages. So, this book sticks (mostly) with the "shifting" style of argument parsing. Now back to the matter at hand...

Suppose that after having written a dozen programs using this routine, the Skipper realizes that the output is excessively chatty when he's already taken the time to steer the proper course (or perhaps simply started drifting in the proper direction). After all, if the current heading is 234 degrees and he needs to turn to 234 degrees, you see:

Current heading is 234.
Come about to 234 by turning right 0 degrees.

How annoying! The Skipper decides to fix this problem by checking for a zero turn value:

sub turn_towards_heading {
  my $new_heading = shift;
  my $current_heading = current_heading( );
  print "Current heading is ", $current_heading, ".\n";
  my $direction = "right";
  my $turn = ($new_heading - $current_heading) % 360;
  unless ($turn) {
    print "On course (good job!).\n";
    return;
  }
  print "Come about to $new_heading ";
  if ($turn > 180) { # long way around
    $turn = 360 - $turn;
    $direction = "left";
  }
  print "by turning $direction $turn degrees.\n";
}

Great. The new subroutine works nicely in the current navigation program. However, because it had previously been cut-and-pasted into a half dozen other navigation programs, those other programs will still annoy the Skipper with extraneous turning messages.

You need a way to write the code in one place and then share it among many programs. And like most things in Perl, there's more than one way to do it.

Previous | Home | Next
1.4. What if I'm a Perl Course Instructor? | Book Index | 2.2. Inserting Code with eval
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.2. Inserting Code with eval

The Skipper can save disk space (and brainspace) by bringing the definition for turn_towards_heading out into a separate file. For example, suppose the Skipper figures out a half-dozen common subroutines related to navigating the Minnow that he seems to use in most or all of the programs he's writing for the task. He can put them in a separate file called navigation.pl, which consists only of the needed subroutines.

But now, how can you tell Perl to pull in that program snippet from another file? You could do it the hard way:

sub load_common_subroutines {
  open MORE_CODE, "navigation.pl" or die "navigation.pl: $!";
  undef $/; # enable slurp mode
  my $more_code = <MORE_CODE>;
  close MORE_CODE;
  eval $more_code;
  die $@ if $@;
}

The code from navigation.pl is read into the $more_code variable. You then use eval to process that text as Perl code. Any lexical variables in $more_code will remain local to the evaluated code.[4] If there's a syntax error, the $@ variable is set and causes the subroutine to die with the appropriate error message.

[4]Oddly, the variable $more_code is also visible to the evaluated code, not that it is of any use to change that variable during the eval.

Now instead of a few dozen lines of common subroutines to place in each file, you simply have one subroutine to insert in each file.

But that's not very nice, especially if you need to keep doing this kind of task repeatedly. Luckily, there's (at least) one Perl built-in to help you out.

Previous | Home | Next
2. Building Larger Programs | Book Index | 2.3. Using do
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.3. Using do

The Skipper has placed a few common navigation subroutines into navigation.pl. If the Skipper merely inserts:

do "navigation.pl";
die $@ if $@;

into his typical navigation program, it's almost the same as if the eval code were executed earlier.[5]

[5]Except in regard to @INC, %INC, and missing file handling, which you'll see later.

That is, the do operator acts as if the code from navigation.pl were incorporated into the current program, although in its own scope block so that lexicals (my variables) and most directives (such as use strict) from the included file don't leak into the main program.

Now the Skipper can safely update and maintain only one copy of the common subroutines, without having to copy and recopy all the fixes and extensions into the many separate navigation programs he is creating and using. See Figure 2-1 for an illustration.

Figure 2-1. The navigation.pl file being used by the other navigation programs

Of course, this requires a bit of discipline because breaking the expected interface of a given subroutine will now break many programs instead of just one.[6] Careful thought will need to be given as to how to design and write reusable components and modular design. We'll presume The Skipper has had some experience at that.

[6]In later chapters, you'll see how to set up tests to be used while maintaining reused code.

Another advantage to placing some of the code into a separate file is that other programmers can reuse the Skipper's routines and vice versa. For example, suppose the Skipper's sidekick (we'll call him "Gilligan") writes a routine to drop_anchor( ) and places it in the file drop_anchor.pl.[7]

[7]The .pl here stands for "perl library," the common extension used for included Perl code. It is unfortunate that some non-Unix Perl vendors also use to use the same extension for the top-level Perl programs, because you then can't tell whether something is a program or a library. If you have a choice, the experts recommend ending your program filenames with .plx ("Perl executable"), or better yet, with no extension at all unless your system requires one.

Then, the Skipper can use the code with:

do "drop_anchor.pl";
die $@ if $@;
...
drop_anchor( ) if at_dock( ) or in_port( );

Thus, the code is brought into separate files to permit easy maintenance and interprogrammer cooperation.

While the code brought in from a .pl file can have direct executable statements, it's much more common to simply define subroutines that can be called by the code containing the do.

Going back to that drop_anchor.pl library for a second, imagine what would happen if the Skipper wrote a program that needed to "drop anchor" as well as navigate:

do "drop_anchor.pl";
die $@ if $@;
do "navigate.pl";
die $@ if $@;
...
turn_towards_heading(90);
...
drop_anchor( ) if at_dock( );

That works fine and dandy. The subroutines defined in both libraries are available to this program.

Previous | Home | Next
2.2. Inserting Code with eval | Book Index | 2.4. Using require
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.4. Using require

Suppose navigate.pl itself also pulls in drop_anchor.pl for some common navigation task. You'll end up reading the file once directly, and then again while processing the navigation package. This will needlessly redefine drop_anchor( ). Worse than that, if warnings are enabled,[8] you'll get a warning from Perl that you've redefined the subroutine, even though it's the same definition.

[8]You are using warnings, right? You can enable them with either -w or use warnings;.

What you need is a mechanism that tracks what files have been brought in and bring them in only once. Perl has such an operation, called require. Change the previous code to simply:

require "drop_anchor.pl";
require "navigate.pl";

The require operator keeps track of the files it has read.[9] Once a file has been processed successfully, any further require operations on that same file are simply ignored. This means that even if navigate.pl contains require "drop_anchor.pl", the drop_anchor.pl file is brought in exactly once, and you'll get no annoying error messages about duplicate subroutine definitions (see Figure 2-2). Most importantly, you'll also save time by not processing the file more than once .

[9]In the %INC hash, as described in the entry for require in the perlfunc documentation.

Figure 2-2. Once the drop_anchor.pl file is brought in, another attempt to require the file is harmless

The require operator also has two additional features:

  • Any syntax error in the required file causes the program to die, thus the many die $@ if $@ statements are unnecessary.

  • The last expression evaluated in the file must return a true value.

Because of the second point, most files evaluated for require have a cryptic 1; as their last line of code. This ensures that the last evaluated expression is in fact true. Try to carry on this tradition as well.

Originally, the mandatory true value was intended as a way for an included file to signal to the invoker that the code was processed successfully and that no error condition existed. However, nearly everyone has adopted the die if ... strategy instead, deeming the "last expression evaluated is false" strategy a mere historic annoyance.

Previous | Home | Next
2.3. Using do | Book Index | 2.5. require and @INC
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.5. require and @INC

So far, the examples have glossed over the directory structure of where the main code and the included files (either with do or require) are located. That's because it "just works" for the simplest case, in which you have a program and its libraries in the same directory, and you run the program from that directory.

Things get a bit more complicated when the libraries aren't located in the current directory. In fact, Perl searches for libraries along a library search path (similar to what the shell does with the PATH environment variable). The current directory (represented in Unix by a single dot) is an element of the search path, so as long as your libraries are in your current working directory, everything is fine.

The search path is given in the special @INC array. By default, the array contains the current directory and a half-dozen directories built in to the perl binary during the compilation of perl itself. You can see what these directories are by typing perl -V at the command line and noting the last dozen lines of the output. Also at the command line, you can execute the following to get just the @INC directories:[10]

perl -le 'print for @INC'

[10]On a Windows machine, use double quotes instead of single quotes on the command line.

Except for . in that list, you probably won't be able to write to any of the other directories, unless you're the person responsible for maintaining Perl on your machine, in which case you should be able to write to all of them. The remaining directories are where Perl searches for system-wide libraries and modules, as you'll see later.

2.5.1. Extending @INC

Although you may not be able to alter the content of the directories named by @INC, you can alter @INC itself before the require, to bring in libraries from one or more directories of your choosing. The @INC array is an ordinary array, so have the Skipper add a directory below his home directory to the mix:

unshift @INC, "/home/skipper/perl-lib";

Now, in addition to searching the standard directories and the current directory, Perl searches the Skipper's personal Perl library. In fact, Perl searches in that directory first, since it is the first one in @INC. By using unshift rather than push, any conflict in names between the Skipper's private files and the system-installed files are resolved with the Skipper's file taking precedence.

2.5.2. Extending @INC with PERL5LIB

The Skipper must edit each program that uses the private libraries to include this line. If that seems like too much editing, the Skipper can instead set the PERL5LIB environment variable to the directory name. For example, in the C shell, it'd be:

setenv PERL5LIB /home/skipper/perl-lib

In Bourne-style shells, it'd be something like:

PERL5LIB=/home/skipper/perl-lib; export PERL5LIB

The advantage of using PERL5LIB is that the Skipper can set it once and forget it. The disadvantage comes when someone else (like Gilligan) comes along to execute the program. Unless Gilligan has also added the same PERL5LIB environment variable, the program will fail! Thus, while PERL5LIB is interesting for personal use, do not rely on it for programs you intend to share with others. (And don't make your entire team of programmers add a common PERL5LIB variable. That's just wrong.)

The PERL5LIB variable can include multiple directories, separated by colons. Any specified directory is inserted at the beginning of @INC.

While a system administrator might add a setting of PERL5LIB to a system-wide startup script, this process is generally frowned upon. The purpose of PERL5LIB is to enable nonadministrators to extend Perl to recognize additional directories. If a system administrator wants additional directories, he merely needs to recompile and reinstall Perl, answering the appropriate questions during the configuration phase.

2.5.3. Extending @INC with -I

If Gilligan recognizes that one of the Skipper's programs is missing the proper directive, Gilligan can either add the proper PERL5LIB variable or invoke perl directly with one or more -I options. For example, to invoke the Skipper's get_us_home program, the command line might be something like:

perl -I/home/skipper/perl-lib /home/skipper/bin/get_us_home

Obviously, it's easier for Gilligan if the program itself defines the extra libraries. But sometimes just adding a -I fixes things right up.[11]

[11]Extending @INC with either PERL5LIB or -I also automatically adds the version- and architecture-specific subdirectories of the specified directories. Adding these directories automatically simplifies the task of installing Perl modules that include architecture- or version-sensitive components, such as compiled C code.

This works even if Gilligan can't edit the Skipper's program. He still has to be able to read it, of course, but Gilligan can use this technique to try a new version of his library with the Skipper's program, for example.

Previous | Home | Next
2.4. Using require | Book Index | 2.6. The Problem of Namespace Collisions
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.6. The Problem of Namespace Collisions

Suppose that the Skipper has added all his cool and useful routines to navigation.pl and that Gilligan has incorporated the library into his own navigation package head_towards_island:

#!/usr/bin/perl

require 'navigation.pl';

sub turn_toward_port {
  turn_toward_heading(compute_heading_to_island( ));
}

sub compute_heading_to_island {
  .. code here ..
}

.. more program here ..

Gilligan then has his program debugged (perhaps with the aid of a smart person whom we'll call "the Professor"), and everything works well.

However, now the Skipper decides to modify his navigation.pl library, adding a routine called turn_toward_port that makes a 45-degree turn toward the left (known as "port" in nautical jargon).

Gilligan's program will fail in a catastrophic way, as soon as he tries to head to port: he'll start steering the ship in circles! The problem is that the Perl compiler first compiles turn_toward_port from Gilligan's main program, then when the require is evaluated at runtime, the definition for turn_toward_port is redefined as the Skipper's definition. Sure, if Gilligan has warnings enabled, he'll notice something is wrong, but why should he have to count on that?

The problem is that Gilligan defined turn_toward_port as meaning "turn toward the port on the island," while the Skipper defined it as "turn toward the left." How do you resolve this?

One way is to require that the Skipper put an explicit prefix in front of every name defined in the library, say navigation_. Thus, Gilligan's program ends up looking like:

#!/usr/bin/perl

require 'navigation.pl';

sub turn_toward_port {
  navigation_turn_toward_heading(compute_heading_to_island( ));
}

sub compute_heading_to_island {
  .. code here ..
}

.. more program here ..

Clearly, the navigation_turn_toward_heading comes from the navigation.pl file. This is great for Gilligan, but awkward for the Skipper, as his file now becomes:

sub navigation_turn_toward_heading {
  .. code here ..
}

sub navigation_turn_toward_port {
  .. code here ..
}

1;

Yes, every scalar, array, hash, filehandle, or subroutine now has to have a navigation_ prefix in front of it to guarantee that the names won't collide with any potential users of the library. Obviously, for that old sailor, this ain't gonna float his boat. So, what do you do instead?

Previous | Home | Next
2.5. require and @INC | Book Index | 2.7. Packages as Namespace Separators
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.7. Packages as Namespace Separators

If the name prefix of the last example didn't have to be spelled out on every use, things would work much better. Well, you can improve the situation by using a package:

package Navigation;

sub turn_towards_heading {
  .. code here ..
}

sub turn_towards_port {
  .. code here ..
}

1;

The package declaration at the beginning of this file tells Perl to insert Navigation:: in front of most names within the file: Thus, the code above practically says:

sub Navigation::turn_towards_heading {
  .. code here ..
}

sub Navigation::turn_towards_port {
  .. code here ..
}

1;

Now when Gilligan uses this file, he simply adds Navigation:: to the subroutines defined in the library, and leaves the Navigation:: prefix off for subroutines he defines on his own:

#!/usr/bin/perl

require 'navigation.pl';

sub turn_toward_port {
  Navigation::turn_toward_heading(compute_heading_to_island( ));
}

sub compute_heading_to_island {
  .. code here ..
}

.. more program here ..

Package names are like variable names: they consist of alphanumerics and underscores, as long as you don't begin with a digit. Also, for reasons explained in the perlmodlib documentation, a package name should begin with a capital letter and not overlap an existing CPAN or core module name. Package names can also consist of multiple names separated by double colons, such as Minnow::Navigation and Minnow::Food::Storage.

Nearly every scalar, array, hash, subroutine, and filehandle name[12] is actually prefixed by the current package, unless the name already contains one or more double-colon markers.

[12]Except lexicals, as you'll see in a moment.

So, in navigation.pl, you can use variables such as:

package Navigation;
@homeport = (21.1, -157.525);

sub turn_toward_port {
  .. code ..
}

(Trivia note: 21.1 degrees north, 157.525 degrees west is the location of the real-life marina where the opening shot of a famous television series was filmed.)

You can refer to the @homeport variable in the main code as:

@destination = @Navigation::homeport;

If every name has a package name inserted in front of it, what about names in the main program? Yes, they are also in a package, called main. It's as if package main; were at the beginning of each file. Thus, to keep Gilligan from having to say Navigation::turn_towards_heading, the navigation.pl file can say:

sub main::turn_towards_heading {
  .. code here ..
}

Now the subroutine is defined in the main package, not the Navigation package. This isn't an optimal solution (you'll see better solutions in Chapter 12), but at least there's nothing sacred or terribly unique about main compared to any other package.

Previous | Home | Next
2.6. The Problem of Namespace Collisions | Book Index | 2.8. Scope of a Package Directive
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.8. Scope of a Package Directive

All files start as if you had said package main;. Any package directive remains in effect until the next package directive, unless that package directive is inside a curly-braced scope. In that case, the prior package is remembered and restored when the scope ends. Here's an example:

package Navigation;

{  # start scope block
  package main;  # now in package main

  sub turn_towards_heading {  # main::turn_towards_heading
    .. code here ..
  }

}  # end scope block

# back to package Navigation

sub turn_towards_port { # Navigation::turn_towards_port
  .. code here ..
}

The current package is lexically scoped, similar to the scope of my variables, narrowed to the innermost-enclosing brace pair or file in which the package is introduced.

Most libraries have only one package declaration at the top of the file. Most programs leave the package at the default main package. However it's nice to know that you can temporarily have a different current package.[13]

[13]Some names are always in package main regardless of the current package: ARGV, ARGVOUT, ENV, INC, SIG, STDERR, STDIN, and STDOUT. You can always refer to @INC and be assured of getting @main::INC. The punctuation mark variables such as $_, $2, and $! are either all lexicals or forced into package main, so when you write $. you never get $Navigation::. by mistake.

Previous | Home | Next
2.7. Packages as Namespace Separators | Book Index | 2.9. Packages and Lexicals
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.9. Packages and Lexicals

A lexical variable (a variable introduced with my) isn't prefixed by the current package because package variables are always global: you can always reference a package variable if you know its full name. A lexical variable is usually temporary and accessible for only a portion of the program. If a lexical variable is declared, then using that name without a package prefix results in accessing the lexical variable. However, a package prefix ensures that you are accessing a package variable and never a lexical variable.

For example, suppose a subroutine within navigation.pl declares a lexical @homeport variable. Any mention of @homeport will then be the newly introduced lexical variable, but a fully qualified mention of @Navigation::homeport accesses the package variable instead.

package Navigation;
@homeport = (21.1, -157.525);

sub get_me_home {
  my @homeport;

  .. @homeport .. # refers to the lexical variable
  .. @Navigation::homeport .. # refers to the package variable

}

.. @homeport .. # refers to the package variable

Obviously, this can lead to confusing code, so you shouldn't introduce such a duplication needlessly. The results are completely predictable, though.

Previous | Home | Next
2.8. Scope of a Package Directive | Book Index | 2.10. Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


2.10. Exercises

The answers for all exercises can be found in Section A.1.

2.10.1. Exercise 1 [30 min]

The Oogaboogoo natives on the island have unusual names for the days and months. Here is some simple but not very well-written code from Gilligan. Fix it up, add a conversion function for the month names, and make the whole thing into a library. For extra credit, add suitable error checking and consider what should be in the documentation.

@day = qw(ark dip wap sen pop sep kir);
sub number_to_day_name { my $num = shift @_; $day[$num]; }
@month = qw(diz pod bod rod sip wax lin sen kun fiz nap dep);

2.10.2. Exercise 2 [10 min]

Make a program that uses your library and the following code to print out a message, such as Today is dip, sen 11, 2008, meaning that today is a Monday in August. (Hint: The year and month numbers returned by localtime may not be what you'd expect, so you need to check the documentation.)

my($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime;
Previous | Home | Next
2.9. Packages and Lexicals | Book Index | 3. Introduction to References
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 3. Introduction to References

Contents:

Performing the Same Task on Many Arrays
Taking a Reference to an Array
Dereferencing the Array Reference
Dropping Those Braces
Modifying the Array
Nested Data Structures
Simplifying Nested Element References with Arrows
References to Hashes
Exercises

A Perl scalar variable holds a single value. An array holds an ordered list of one or more scalars. A hash holds a collection of scalars as values, keyed by other scalars.

Although a scalar can be an arbitrary string, which allows complex data to be encoded into an array or hash, none of the three data types are well-suited to complex data interrelationships. This is a job for the reference. Let's look at the importance of references by starting with an example.

3.1. Performing the Same Task on Many Arrays

Before the Minnow can leave on an excursion (e.g., a three-hour tour), every passenger and crew member should be checked to ensure they have all the required trip items in their possession. Let's say that for maritime safety, every person on board the Minnow needs to have a life preserver, some sunscreen, a water bottle, and a rain jacket. You can write a bit of code to check for the Skipper's supplies:

my @required = qw(preserver sunscreen water_bottle jacket);
my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
for my $item (@required) {
  unless (grep $item eq $_, @skipper) { # not found in list?
    print "skipper is missing $item.\n";
  }
}

The grep in a scalar context returns the number of times the expression $item eq $_ returns true, which is 1 if the item is in the list and 0 if not.[14] If the value is 0, it's false, and you print the message.

[14]There are more efficient ways to check list membership for large lists, but for a few items, this is probably the easiest way to do so with just a few lines of code.

Of course, if you want to check on Gilligan and the Professor, you might write the following code:

my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
for my $item (@required) {
  unless (grep $item eq $_, @gilligan) { # not found in list?
    print "gilligan is missing $item.\n";
  }
}

my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
for my $item (@required) {
  unless (grep $item eq $_, @professor) { # not found in list?
    print "professor is missing $item.\n";
  }
}

You may start to notice a lot of repeated code here and decide that it would be served best in a subroutine:

sub check_required_items {
  my $who = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  for my $item (@required) {
    unless (grep $item eq $_, @_) { # not found in list?
      print "$who is missing $item.\n";
    }
  }
}

my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
check_required_items("gilligan", @gilligan);

The subroutine is given five items in its @_ array initially: the name gilligan and the four items belonging to Gilligan. After the shift, @_ will have only the items. Thus, the grep checks each required item against the list.

So far, so good. You can check the Skipper and the Professor with just a bit more code:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
check_required_items("skipper", @skipper);
check_required_items("professor", @professor);

And for the other passengers, you repeat as needed. Although this code meets the initial requirements, you've got two problems to deal with:

  • To create @_, Perl copies the entire contents of the array to be scanned. This is fine for a few items, but if the array is large, it seems a bit wasteful to copy the data just to pass it into a subroutine.

  • Suppose you want to modify the original array to force the provisions list to include the mandatory items. Because you have a copy in the subroutine ("pass by value"), any changes made to @_ aren't reflected automatically in the corresponding provisions array.[15]

    [15]Actually, assigning new scalars to elements of @_ after the shift modifies the corresponding variable being passed, but that still wouldn't let you extend the array with additional mandatory provisions.

To solve either or both of these problems, you need pass by reference rather than pass by value. And that's just what the doctor (or Professor) ordered.

Previous | Home | Next
2.10. Exercises | Book Index | 3.2. Taking a Reference to an Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.2. Taking a Reference to an Array

Among its many other meanings, the backslash (\) character is also the "take a reference to" operator. When you use it in front of an array name, e.g., \@skipper, the result is a reference to that array. A reference to the array is like a pointer: it points at the array, but is not the array itself.

A reference fits wherever a scalar fits. It can go into an element of an array or a hash, or into a plain scalar variable, like this:

my $reference_to_skipper = \@skipper;

The reference can be copied:

my $second_reference_to_skipper = $reference_to_skipper;

or even:

my $third_reference_skipper = \@skipper;

All three references are completely interchangeable. You can even say they're identical:

if ($reference_to_skipper == $second_reference_to_skipper) {
  print "They are identical references.\n";
}

This equality compares the numeric forms of the two references. The numeric form of the reference is the unique memory address of the @skipper internal data structure, unchanging during the life of the variable. If you look at the string form instead, with eq or print, you get a debugging string:

ARRAY(0x1a2b3c)

which again is unique for this array because it includes the hexadecimal (base 16) representation of the array's unique memory address. The debugging string also notes that this is an array reference. Of course, if you ever see something like this in your output, it almost certainly means there's a bug; users of your program have little interest in hex dumps of storage addresses!

Because a reference can be copied, and passing an argument to a subroutine is really just copying, you can use this code to pass a reference to the array into the subroutine:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
check_required_items("The Skipper", \@skipper);

sub check_required_items {
  my $who = shift;
  my $items = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  ...
}

Now $items in the subroutine will be a reference to the array of @skipper. But how do you get from a reference back into the original array? By dereferencing the reference.

Previous | Home | Next
3. Introduction to References | Book Index | 3.3. Dereferencing the Array Reference
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.3. Dereferencing the Array Reference

If you look at @skipper, you'll see that it consists of two parts: the @ symbol and the name of the array. Similarly, the syntax $skipper[1] consists of the name of the array in the middle and some syntax around the outside to get at the second element of the array (index value 1 is the second element because you start counting index values at 0).

Here's the trick: any reference to an array can be placed in curly braces and written in place of the name of an array, ending up with a method to access the original array. That is, wherever you write skipper to name the array, you use the reference inside curly braces: { $items }. For example, both of these lines refer to the entire array:

@  skipper
@{ $items }

whereas both of these refer to the second item of the array:[16]

[16]Note that whitespace was added in these two displays to make the similar parts line up. This whitespace is legal in a program, even though most programs won't use it.

$  skipper [1]
${ $items }[1]

By using the reference form, you've decoupled the code and the method of array access from the actual array. Let's see how that changes the rest of this subroutine:

sub check_required_items {
  my $who = shift;
  my $items = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  for my $item (@required) {
    unless (grep $item eq $_, @{$items}) { # not found in list?
      print "$who is missing $item.\n";
    }
  }
}

All you did was replace @_ (the copy of the provisions list) with @{$items}, a dereferencing of the reference to the original provisions array. Now you can call the subroutine a few times as before:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
check_required_items("The Skipper", \@skipper);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
check_required_items("Professor", \@professor);
my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
check_required_items("Gilligan", \@gilligan);

In each case, $items points to a different array, so the same code applies to different arrays each time it is invoked. This is one of the most important uses of references: decoupling the code from the data structure on which it operates so the code can be reused more readily.

Passing the array by reference fixes the first of the two problems mentioned earlier. Now, instead of copying the entire provision list into the @_ array, you get a single element of a reference to that provisions array.

Could you have eliminated the two shift s at the beginning of the subroutine? Sure, at the expense of clarity:

sub check_required_items {
  my @required = qw(preserver sunscreen water_bottle jacket);
  for my $item (@required) {
    unless (grep $item eq $_, @{$_[1]}) { # not found in list?
      print "$_[0] is missing $item.\n";
    }
  }
}

You still have two elements in @_. The first element is the passenger or crew member name and is used in the error message. The second element is a reference to the correct provisions array, used in the grep expression.

Previous | Home | Next
3.2. Taking a Reference to an Array | Book Index | 3.4. Dropping Those Braces
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.4. Dropping Those Braces

Most of the time, the dereferenced array reference is contained in a simple scalar variable, such as @{$items} or ${$items}[1]. In those cases, the curly braces can be dropped, unambiguously, forming @$items or $$items[1].

However, the braces cannot be dropped if the value within the braces is not a simple scalar variable. For example, for @{$_[1]} from that last subroutine rewrite, you can't remove the braces.

This rule also means that it's easy to see where the "missing" braces need to go. When you see $$items[1], a pretty noisy piece of syntax, you can tell that the curly braces must belong around the simple scalar variable, $items. Therefore, $items must be a reference to an array.

Thus, an easier-on-the-eyes version of that subroutine might be:

sub check_required_items {
  my $who = shift;
  my $items = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  for my $item (@required) {
    unless (grep $item eq $_, @$items) { # not found in list?
      print "$who is missing $item.\n";
    }
  }
}

The only difference here is that the braces were removed for @$items.

Previous | Home | Next
3.3. Dereferencing the Array Reference | Book Index | 3.5. Modifying the Array
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.5. Modifying the Array

You've seen how to solve the excessive copying problem with an array reference. Now let's look at modifying the original array.

For every missing provision, push that provision onto an array, forcing the passenger to consider the item:

sub check_required_items {
  my $who = shift;
  my $items = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  my @missing = ( );

  for my $item (@required) {
    unless (grep $item eq $_, @$items) { # not found in list?
      print "$who is missing $item.\n";
      push @missing, $item;
    }
  }

  if (@missing) {
    print "Adding @missing to @$items for $who.\n";
    push @$items, @missing;
  }
}

Note the addition of the @missing array. If you find any items missing during the scan, push them into @missing. If there's anything there at the end of the scan, add it to the original provision list.

The key is in the last line of that subroutine. You're dereferencing the $items array reference, accessing the original array, and adding the elements from @missing. Without passing by reference, you'd modify only a local copy of the data, which has no effect on the original array.

Also, @$items (and its more generic form @{$items}) works within a double-quoted string. Do not include any whitespace between the @ and the immediately following character, although you can include nearly arbitrary whitespace within the curly braces as if it were normal Perl code.

Previous | Home | Next
3.4. Dropping Those Braces | Book Index | 3.6. Nested Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.6. Nested Data Structures

In this example, the array @_ contains two elements, one of which is also an array. What if you take a reference to an array that also contains a reference to an array? You end up with a complex data structure, which can be quite useful.

For example, iterate over the data for the Skipper, Gilligan, and the Professor by first building a larger data structure holding the entire list of provision lists:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my @skipper_with_name = ("Skipper", \@skipper);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
my @professor_with_name = ("Professor", \@professor);
my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
my @gilligan_with_name = ("Gilligan", \@gilligan);

At this point, @skipper_with_name has two elements, the second of which is an array reference, similar to what was passed to the subroutine. Now group them all:

my @all_with_names = (
  \@skipper_with_name,
  \@professor_with_name,
  \@gilligan_with_name,
);

Note that you have just three elements, each of which is a reference to an array, each of which has two elements: the name and its corresponding initial provisions. A picture of that is in Figure 3-1.

Figure 3-1. The array @all_with_names holds a multilevel data structure containing strings and references to arrays

Therefore, $all_with_names[2] will be the array reference for the Gilligan's data. If you dereference it as @{$all_with_names[2]}, you get a two-element array, "Gilligan" and another array reference.

How would you access that array reference? Using your rules again, it's ${$all_with_names[2]}[1]. In other words, taking $all_with_names[2], you dereference it in an expression that would be something like $DUMMY[1] as an ordinary array, so you'll place {$all_with_names[2]} in place of DUMMY.

How do you call the existing check_required_items( ) with this data structure? The following code is easy enough.

for my $person (@all_with_names) {
  my $who = $$person[0];
  my $provisions_reference = $$person[1];
  check_required_items($who, $provisions_reference);
}

This requires no changes to the subroutine. $person will be each of $all_with_names[0], $all_with_names[1], and $all_with_names[2], as the loop progresses. When you dereference $$person[0], you get "Skipper," "Professor," and "Gilligan," respectively. $$person[1] is the corresponding array reference of provisions for that person.

Of course, you can shortcut this as well, since the entire dereferenced array matches the argument list precisely:

for my $person (@all_with_names) {
  check_required_items(@$person);
}

or even:

check_required_items(@$_) for @all_with_names;

As you can see, various levels of optimization can lead to obfuscation. Be sure to consider where your head will be a month from now when you have to reread your own code. If that's not enough, consider the new person who takes over your job after you have left.

Previous | Home | Next
3.5. Modifying the Array | Book Index | 3.7. Simplifying Nested Element References with Arrows
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.7. Simplifying Nested Element References with Arrows

Look at the curly-brace dereferencing again. As in the earlier example, the array reference for Gilligan's provision list is ${$all_with_names[2]}[1]. Now, what if you want to know Gilligan's first provision? You need to dereference this item one more level, so it's Yet Another Layer of Braces: ${${$all_with_names[2]}[1]}[0]. That's a really noisy piece of syntax. Can you shorten that? Yes!

Everywhere you write ${DUMMY}[$y], you can write DUMMY->[$y] instead. In other words, you can dereference an array reference, picking out a particular element of that array by simply following the expression defining the array reference with an arrow and a square-bracketed subscript.

For this example, this means you can pick out the array reference for Gilligan with a simple $all_with_names[2]->[1], and Gilligan's first provision with $all_with_names[2]->[1]->[0]. Wow, that's definitely easier on the eyes.

If that wasn't already simple enough, there's one more rule: if the arrow ends up between "subscripty kinds of things," like square brackets, you can also drop the arrow. $all_with_names[2]->[1]->[0] becomes $all_with_names[2][1][0]. Now it's looking even easier on the eye.

The arrow has to be between subscripty things. Why wouldn't it be between? Well, imagine a reference to the array @all_with_names:

my $root = \@all_with_names;

Now how do you get to Gilligan's first item?

$root -> [2] -> [1] -> [0]

More simply, using the "drop arrow" rule, you can use:

$root -> [2][1][0]

You cannot drop the first arrow, however, because that would mean an array @root's third element, an entirely unrelated data structure. Let's compare this to the full curly-brace form again:

${${${$root}[2]}[1]}[0]

It looks much better with the arrow. Note, however, that no shortcut gets the entire array from an array reference. If you want all of Gilligan's provisions, you say:

@{$root->[2][1]}

Reading this from the inside out, you can think of it like this:

  1. Take $root.

  2. Dereference it as an array reference, taking the third element of that array (index number 2).

  3. Dereference that as an array reference, taking the second element of that array (index number 1).

  4. Dereference that as an array reference, taking the entire array.

The last step doesn't have a shortcut arrow form. Oh well.[17]

[17]It's not that it hasn't been discussed repeatedly by the Perl developers; it's just that nobody has come up with a nice backward-compatible syntax with universal appeal.

Previous | Home | Next
3.6. Nested Data Structures | Book Index | 3.8. References to Hashes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.8. References to Hashes

Just as you can take a reference to an array, you can also take a reference to a hash. Once again, you use the backslash as the "take a reference to" operator:

my %gilligan_info = (
  name => 'Gilligan',
  hat => 'White',
  shirt => 'Red',
  position => 'First Mate',
);
my $hash_ref = \%gilligan_info;

You can dereference a hash reference to get back to the original data. The strategy is similar to dereferencing an array reference. Write the hash syntax as you would have without references, and then replace the name of the hash with a pair of curly braces surrounding the thing holding the reference. For example, to pick a particular value for a given key, use:

my $name = $ gilligan_info { 'name' };
my $name = $ { $hash_ref } { 'name' };

In this case, the curly braces have two different meanings. The first pair denotes the expression returning a reference, while the second pair delimits the expression for the hash key.

To perform an operation on the entire hash, you proceed similarly:

my @keys = keys % gilligan_info;
my @keys = keys % { $hash_ref };

As with array references, you can use shortcuts to replace the complex curly-braced forms under some circumstances. For example, if the only thing inside the curly braces is a simple scalar variable (as shown in these examples so far), you can drop the curly braces:

my $name = $$hash_ref{'name'};
my @keys = keys %$hash_ref;

Like an array reference, when referring to a specific hash element, you can use an arrow form:

my $name = $hash_ref->{'name'};

Because a hash reference fits wherever a scalar fits, you can create an array of hash references:

my %gilligan_info = (
  name => 'Gilligan',
  hat => 'White',
  shirt => 'Red',
  position => 'First Mate',
);
my %skipper_info = (
  name => 'Skipper',
  hat => 'Black',
  shirt => 'Blue',
  position => 'Captain',
);
my @crew = (\%gilligan_info, \%skipper_info);

Thus, $crew[0] is a hash reference to the information about Gilligan. You can get to Gilligan's name via any one of:

${ $crew[0] } { 'name' }
my $ref = $crew[0]; $$ref{'name'}
$crew[0]->{'name'}
$crew[0]{'name'}

On that last one, you can still drop the arrow between "subscripty kinds of things," even though one is an array bracket and one is a hash brace.

Let's print a crew roster:

my %gilligan_info = (
  name => 'Gilligan',
  hat => 'White',
  shirt => 'Red',
  position => 'First Mate',
);
my %skipper_info = (
  name => 'Skipper',
  hat => 'Black',
  shirt => 'Blue',
  position => 'Captain',
);
my @crew = (\%gilligan_info, \%skipper_info);

my $format = "%-15s %-7s %-7s %-15s\n";
printf $format, qw(Name Shirt Hat Position);
for my $crewmember (@crew) {
  printf $format,
    $crewmember->{'name'},
    $crewmember->{'shirt'},
    $crewmember->{'hat'},
    $crewmember->{'position'};
}

That last part looks very repetitive. You can shorten it with a hash slice. Again, if the original syntax is:

@ gilligan_info { qw(name position) }

the hash slice notation from a reference looks like:

@ { $hash_ref } { qw(name position) }

You can drop the first brace pair because the only thing within is a simple scalar value, yielding:

@ $hash_ref { qw(name position) }

Thus, you can replace that final loop with:

for my $crewmember (@crew) {
  printf $format, @$crewmember{qw(name shirt hat position)};
}

There is no shortcut form with an arrow (->) for array slices or hash slices, just as there is no shortcut for entire arrays or hashes.

A hash reference prints as a string that looks like HASH(0x1a2b3c), showing the hexadecimal memory address of the hash. That's not very useful to an end user and only barely more usable to the programmer, except as an indication of the lack of appropriate dereferencing.

Previous | Home | Next
3.7. Simplifying Nested Element References with Arrows | Book Index | 3.9. Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


3.9. Exercises

The answers for all exercises can be found in Section A.2.

3.9.1. Exercise 1 [5 min]

How many different things do these expressions refer to?

$ginger->[2][1]
${$ginger[2]}[1]
$ginger->[2]->[1]
${$ginger->[2]}[1]

3.9.2. Exercise 2 [30 min]

Using the final version of check_required_items, write a subroutine check_items_for_all that takes a hash reference as its only parameter, pointing at a hash whose keys are the people aboard the Minnow, and whose corresponding values are array references of the things they intend to bring on board.

For example, the hash reference might be constructed like so:

my @gilligan = ... gilligan items ...;
my @skipper = ... skipper items ...;
my @professor = ... professor items ...;
my %all = (
  "Gilligan" => \@gilligan,
  "Skipper" => \@skipper,
  "Professor" => \@professor,
);
check_items_for_all(\%all);

The newly constructed subroutine should call check_required_items for each person in the hash, updating their provisions list to include the required items.

Previous | Home | Next
3.8. References to Hashes | Book Index | 4. References and Scoping
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 4. References and Scoping

Contents:

More than One Reference to Data
What if That Was the Name?
Reference Counting and Nested Data Structures
When Reference Counting Goes Bad
Creating an Anonymous Array Directly
Creating an Anonymous Hash
Autovivification
Autovivification and Hashes
Exercises

References can be copied and passed around like any other scalar. At any given time, Perl knows the number of references to a particular data item. Perl can also create references to anonymous data structures (structures that do not have explicit names) and create references automatically as needed to fulfill certain kinds of operations. Let's look at copying references and how it affects scoping and memory usage.

4.1. More than One Reference to Data

Chapter 3 explored how to take a reference to an array @skipper and place it into a new scalar variable:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my $reference_to_skipper = \@skipper;

You can then copy the reference or take additional references, and they'd all refer to the same thing and be interchangeable:

my $second_reference_to_skipper = $reference_to_skipper;
my $third_reference_to_skipper = \@skipper;

At this point, you have four different ways to access the data contained in @skipper:

@skipper
@$reference_to_skipper
@$second_reference_to_skipper
@$third_reference_to_skipper

Perl tracks how many ways the data can be accessed through a mechanism called reference counting. The original name counts as one, and each additional reference that was taken (including copies of references) also counts as one. The total number of references to the array of provisions is now four.

You can add and remove references as you wish, and as long as the reference count doesn't hit zero, the array is maintained in memory and is still accessible via any of the other access paths. For example, you might have a temporary reference:

check_provisions_list(\@skipper)

When this subroutine begins executing, a fifth reference to the data is created and copied into @_ for the subroutine. The subroutine is free to create additional copies of that reference, which Perl notes as needed. Typically, when the subroutine returns, all such references are discarded automatically, and you're back to four references again.

You can kill off each reference by using the variable for something other than a reference to the value of @skipper. For example, you can assign undef to the variable:

$reference_to_skipper = undef;

Or, maybe just let the variable go out of scope:

my @skipper = ...;
{
  ...
  my $ref = \@skipper;
  ...
  ...
} # $ref goes out of scope at this point

In particular, a reference held in a subroutine's private (lexical) variable goes away at the end of the subroutine.

Whether the value is changed or the variable itself goes away, Perl notes it as an appropriate reduction in the number of references to the data.

Perl recycles the memory for the array only when all references (including the name of the array) go away. In this case, memory is reclaimed when @skipper goes out of scope, as well as all other references that had been taken to @skipper are removed or modified to be another value. Such memory is available to Perl for other data later in this program invocation but generally will not be returned to the operating system for use by other processes.

Previous | Home | Next
3.9. Exercises | Book Index | 4.2. What if That Was the Name?
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.2. What if That Was the Name?

Typically, all references to a variable are removed before the variable itself. But what if one of the references outlives the variable name? For example, consider this code:

my $ref;
{
  my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
  $ref = \@skipper;
  print "$ref->[2]\n"; # prints jacket\n
}
print "$ref->[2]\n"; # still prints jacket\n

Immediately after the @skipper array is declared, you have one reference to the five-element list. After $ref is initialized, you'll have two, down to the end of the block. When the block ends, the @skipper name disappears. However, this was only one of the two ways to access the data! Thus, the five-element list is not removed from memory, and $ref is still pointing to that data.

At this point, the five-element list is contained within an anonymous array, which is a fancy term for an array without a name.

Until the value of $ref is changed, or $ref itself disappears, you can still continue to use all the dereferencing strategies you used prior to when the name of the array disappeared. In fact, it's still a fully functional array that you can shrink or grow just as you do any other Perl array:

push @$ref, "sextant"; # add a new provision
print "$ref->[-1]\n"; # prints sextant\n

You can even increase the reference count at this point:

my $copy_of_ref = $ref;

or equivalently:

my $copy_of_ref = \@$ref;

The data remains alive until the last reference is destroyed:

$ref = undef; # not yet...
$copy_of_ref = undef; # poof!
Previous | Home | Next
4. References and Scoping | Book Index | 4.3. Reference Counting and Nested Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.3. Reference Counting and Nested Data Structures

The data remains alive until the last reference is destroyed, even if that reference is contained within a larger active data structure. Suppose an array element is itself a reference. Recall the example from Chapter 3:

my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my @skipper_with_name = ("The Skipper", \@skipper);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
my @professor_with_name = ("The Professor", \@professor);
my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
my @gilligan_with_name = ("Gilligan", \@gilligan);
my @all_with_names = (
  \@skipper_with_name,
  \@professor_with_name,
  \@gilligan_with_name,
);

Imagine for a moment that the intermediate variables are all part of a subroutine:

my @all_with_names;

sub initialize_provisions_list {
  my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
  my @skipper_with_name = ("The Skipper", \@skipper);
  my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
  my @professor_with_name = ("The Professor", \@professor);
  my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
  my @gilligan_with_name = ("Gilligan", \@gilligan);
  @all_with_names = ( # set global
    \@skipper_with_name,
    \@professor_with_name,
    \@gilligan_with_name,
  );
}

initialize_provisions_list( );

The value of @all_with_names is set to contain three references. Inside the subroutine are named arrays with references to arrays first placed into other named arrays. Eventually, the values end up in the global @all_with_names. However, as the subroutine returns, the names for the six arrays disappear. Each array has had one other reference taken to it, making the reference count temporarily two, and then back to one as the name is removed. Because the reference count is not yet zero, the data continues to live on, although it is now referenced only by elements of @all_with_names.

Rather than assign the global variable, you can rewrite this as:

sub get_provisions_list {
  my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
  my @skipper_with_name = ("The Skipper", \@skipper);
  my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
  my @professor_with_name = ("The Professor", \@professor);
  my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
  my @gilligan_with_name = ("Gilligan", \@gilligan);
  return (
    \@skipper_with_name,
    \@professor_with_name,
    \@gilligan_with_name,
  );
}

my @all_with_names = get_provisions_list( );

Here, you create the value that will eventually be stored into @all_with_names as the last expression evaluated in the subroutine. A three-element list is returned and assigned. As long as the named arrays within the subroutine have had at least one reference taken of them, and it is still part of the return value, the data remains alive.[18]

[18]Compare this with having to return an array from a C function. Either a pointer to a static memory space must be returned, making the subroutine nonreentrant, or a new memory space must be malloc'ed, requiring the caller to know to free the data. Perl just does the right thing.

If the references in @all_with_names are altered or discarded, the reference count for the corresponding arrays is reduced. If that means the reference count has become zero (as in this example), those arrays themselves are also eliminated. Because these arrays also contain a reference (such as the reference to @skipper), that reference is also reduced by one. Again, that reduces the reference count to zero, freeing that memory as well, in a cascading effect.

Removing the top of a tree of data generally removes all the data contained within. The exception is when additional copies are made of the references of the nested data. For example, if you copied Gilligan's provisions:

my $gilligan_stuff = $all_with_names[2][1];

then when you remove @all_with_names, you still have one live reference to what was formerly @gilligan, and the data from there downward remains alive.

The bottom line is simply: Perl does the right thing. If you still have a reference to data, you still have the data.

Previous | Home | Next
4.2. What if That Was the Name? | Book Index | 4.4. When Reference Counting Goes Bad
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.4. When Reference Counting Goes Bad

Reference-counting as a way to manage memory has been around for a long time. The downside of reference counting is that it breaks when the data structure is not a directed graph, in which some parts of the structure point back in to other parts in a looping way. For example, suppose each of two data structures contains a reference to the other (see Figure 4-1):

my @data1 = qw(one won);
my @data2 = qw(two too to);
push @data2, \@data1;
push @data1, \@data2;

Figure 4-1. When the references in a data structure form a loop, Perl's reference-counting system may not be able to recognize and recycle the no-longer-needed memory space

At this point, there are two names for the data in @data1: @data1 itself and @{$data2[3]}, and two names for the data in @data2: @data2 itself and @{$data1[2]}. You've created a loop. In fact, you can access won with an infinite number of names, such as $data1[2][3][2][3][2][3][1].

What happens when these two array names go out of scope? Well, the reference count for the two arrays goes down from two to one. But not zero! And because it's not zero, Perl thinks there might still be a way to get to the data, even though there isn't! Thus, you've created a memory leak. Ugh. (A memory leak in a program causes the program to consume more and more memory over time.)

At this point, you're right to think that example is contrived. Of course you would never make a looped data structure in a real program! Actually, programmers often make these loops as part of doubly-linked lists, linked rings, or a number of other data structures. The key is that Perl programmers rarely do so because the most important reasons to use those data structures don't apply in Perl. If you've used other languages, you may have noticed programming tasks that are comparatively easy in Perl. For example, it's easy to sort a list of items or to add or remove items, even in the middle of the list. Those tasks are difficult in some other languages, and using a looped data structure is a common way to get around the language's limitations.

Why mention it here? Well, even Perl programmers sometimes copy an algorithm from another programming language. There's nothing inherently wrong with doing this, although it would be better to decide why the original author used a "loopy" data structure and recode the algorithm to use Perl's strengths. Perhaps a hash should be used instead, or perhaps the data should go into an array that will be sorted later.

A future version of Perl is likely to use garbage collection in addition to or instead of referencing counting. Until then, you must be careful to not create circular references, or if you do, break the circle before the variables go out of scope. For example, the following code doesn't leak:

{
  my @data1 = qw(one won);
  my @data2 = qw(two too to);
  push @data2, \@data1;
  push @data1, \@data2;
  ... use @data1, @data2 ...
  # at the end:
  @data1 = ( );
  @data2 = ( );
}

You have eliminated the reference to @data2 from within @data1, and vice versa. Now the data has only one reference each, which are returned to zero references at the end of the block. In fact, you can clear out either one and not the other, and it still works nicely. Chapter 10 shows how to create weak references, which can help with many of these problems.

Previous | Home | Next
4.3. Reference Counting and Nested Data Structures | Book Index | 4.5. Creating an Anonymous Array Directly
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.5. Creating an Anonymous Array Directly

In the get_provisions_list routine earlier, you created a half dozen array names that were used only so that you could take a reference to them immediately afterward. When the subroutine exited, the array names all went away, but the references remained.

While creating temporarily named arrays would work in the simplest cases, creating such names becomes more complicated as the data structures become more detailed. You'd have to keep thinking of names of arrays just so you can forget them shortly thereafter.

You can reduce the namespace clutter by narrowing down the scope of the various array names. Rather than letting them be declared within the scope of the subroutine, you can create a temporary block:

my @skipper_with_name;
{
  my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
  @skipper_with_name = ("The Skipper", \@skipper);
}

At this point, the second element of @skipper_with_name is a reference to the array formerly known as @skipper. However, the name is no longer relevant.

This is a lot of typing to simply say "the second element should be a reference to an array containing these elements." You can create such a value directly using the anonymous array constructor, which is Yet Another Use for square brackets:

my $ref_to_skipper_provisions =
  [ qw(blue_shirt hat jacket preserver sunscreen) ];

The square brackets take the value within (evaluated in a list context); establish a new, anonymous array initialized to those values; and (here's the important part) return a reference to that array. It's as if you said:

my $ref_to_skipper_provisions;
{
  my @temporary_name =
  ( qw(blue_shirt hat jacket preserver sunscreen) );
  $ref_to_skipper_provisions = \@temporary_name;
}

Here you don't need to come up with a temporary name, and you don't need the extra noise of the temporary block. The result of a square-bracketed anonymous array constructor is an array reference, which fits wherever a scalar variable fits.

Now you can use it to construct the larger list:

my $ref_to_skipper_provisions =
  [ qw(blue_shirt hat jacket preserver sunscreen) ];
my @skipper_with_name = ("The Skipper", $ref_to_skipper_provisions);

Of course, you didn't actually need that scalar temporary, either. You can put a scalar reference to an array as part of a larger list:

my @skipper_with_name = (
  "The Skipper",
  [ qw(blue_shirt hat jacket preserver sunscreen) ]
);

Now let's walk through this. You've declared @skipper_with_name, the first element of which is the Skipper's name string, and the second element is an array reference, obtained by placing the five provisions into an array and taking a reference to it. So @skipper_with_name is only two elements long, just as before.

Don't confuse the square brackets with the parentheses here. They each have their distinct purpose. If you replace the square brackets with parentheses, you end up with a six-element list. If you replace the outer parentheses (on the first and last lines) with square brackets, you construct an anonymous array that's two elements long and then take the reference to that array as the only element of the ultimate @skipper_with_name array.[19]

[19]In classrooms, we've seen that too much indirection (or not enough indirection) tends to contribute to the most common mistakes made when working with references.

So, in summary, the syntax:

my $fruits;
{
  my @secret_variable = ('pineapple', 'papaya', 'mango');
  $fruits = \@secret_variable;
}

can be simply replaced with:

my $fruits = ['pineapple', 'papaya', 'mango'];

Does this work for more complicated structures? Yes! Any time you need an element of a list to be a reference to an array, you can create that reference with an anonymous array constructor. In fact, you can also nest them in your provisions list:

sub get_provisions_list {
  return (
    ["The Skipper",
      [qw(blue_shirt hat jacket preserver sunscreen)]
    ],
    ["The Professor",
      [qw(sunscreen water_bottle slide_rule batteries radio)]
    ],
    ["Gilligan",
      [qw(red_shirt hat lucky_socks water_bottle)]
    ],
  );
}

my @all_with_names = get_provisions_list( );

Walking through this from the outside in, you have a return value of three elements. Each element is an array reference, pointing to an anonymous two-element array. The first element of each array is a name string, while the second element is a reference to an anonymous array of varying lengths naming the provisions—all without having to come up with temporary names for any of the intermediate layers.

To the caller of this subroutine, the return value is identical to the previous version. However, from a maintenance point of view, the reduced clutter of not having all the intermediate names saves screen and brain space.

You can show a reference to an empty anonymous hash using an empty anonymous array constructor. For example, if you add one "Mrs. Howell" to that fictional travel list, as someone who has packed rather light, you'd simply insert:

["Mrs. Howell",
  [  ]
],

This is a single element of the larger list. This item is a reference to an array with two elements, the first of which is the name string, and the second of which is itself a reference to an empty anonymous array. The array is empty because Mrs. Howell hasn't packed anything for this trip.

Previous | Home | Next
4.4. When Reference Counting Goes Bad | Book Index | 4.6. Creating an Anonymous Hash
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.6. Creating an Anonymous Hash

Similar to creating an anonymous array, you can also create an anonymous hash. Consider the crew roster from Chapter 3:

my %gilligan_info = (
  name => 'Gilligan',
  hat => 'White',
  shirt => 'Red',
  position => 'First Mate',
);
my %skipper_info = (
  name => 'Skipper',
  hat => 'Black',
  shirt => 'Blue',
  position => 'Captain',
);
my @crew = (\%gilligan_info, \%skipper_info);

The variables %gilligan_info and %skipper_info are just temporaries, needed to create the hashes for the final data structure. You can construct the reference directly with the anonymous hash constructor, which is Yet Another Meaning for curly braces, as you'll see. Replace this:

my $ref_to_gilligan_info;
{
  my %gilligan_info = (
    name => 'Gilligan',
    hat => 'White',
    shirt => 'Red',
    position => 'First Mate',
  );
  $ref_to_gilligan_info = \%gilligan_info;
}

with the anonymous hash constructor:

my $ref_to_gilligan_info = {
  name => 'Gilligan',
  hat => 'White',
  shirt => 'Red',
  position => 'First Mate',
};

The value between the open and closing curly braces is an eight-element list. The eight-element list becomes a four-element anonymous hash (four key-value pairs). A reference to this hash is taken and returned as a single scalar value, which is placed into the scalar variable. Thus, you cam rewrite the roster creation as:

my $ref_to_gilligan_info = {
  name => 'Gilligan',
  hat => 'White',
  shirt => 'Red',
  position => 'First Mate',
};
my $ref_to_skipper_info = {
  name => 'Skipper',
  hat => 'Black',
  shirt => 'Blue',
  position => 'Captain',
};
my @crew = ($ref_to_gilligan_info, $ref_to_skipper_info);

As before, you can now avoid the temporary variables and insert the values directly into the top-level list:

my @crew = (
  {
    name => 'Gilligan',
    hat => 'White',
    shirt => 'Red',
    position => 'First Mate',
  },
  {
    name => 'Skipper',
    hat => 'Black',
    shirt => 'Blue',
    position => 'Captain',
  },
);

Note the use of trailing commas on the lists when the element is not immediately next to the closing brace, bracket, or parenthesis. This is a nice style element to adopt because it allows for easy maintenance. Lines can be added quickly, rearranged, or commented out without destroying the integrity of the list.

Now @crew is identical to the value it had before, but you no longer need to invent names for the intermediate data structures. As before, the @crew variable contains two elements, each of which is a reference to a hash containing keyword-based information about a particular crew member.

The anonymous hash constructor always evaluates its contents in a list context and then constructs a hash from key/value pairs, just as if you had assigned that list to a named hash. A reference to that hash is returned as a single value that fits wherever a scalar fits.

Now, a word from our parser: because blocks and anonymous hash constructors both use curly braces in roughly the same places in the syntax tree, the compiler has to make ad hoc determinations about which of the two you mean. If the compiler ever decides incorrectly, you might need to provide a hint to get what you want. To show the compiler that you want an anonymous hash constructor, put a plus sign before the opening curly brace: +{ ... }. To be sure to get a block of code, just put a semicolon (representing an empty statement) at the beginning of the block: {; ... }.

Previous | Home | Next
4.5. Creating an Anonymous Array Directly | Book Index | 4.7. Autovivification
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.7. Autovivification

Let's look again at the provisions list. Suppose you were reading the data from a file, in the format:

The Skipper
  blue_shirt
  hat
  jacket
  preserver
  sunscreen
Professor
  sunscreen
  water_bottle
  slide_rule
Gilligan
  red_shirt
  hat
  lucky_socks
  water_bottle

Provisions are indented with some whitespace, following a nonindented line with the person's name. Let's construct a hash of provisions. The keys of the hash will be the person's name, and the value will be an array reference to an array containing a list of provisions.

Initially, you might gather the data using a simple loop:

my %provisions;
my $person;
while (<>) {
  if (/^(\S.*)/) { # a person's name (no leading whitespace)
    $person = $1;
    $provisions{$person} = [  ] unless exists $provisions{$person};
  } elsif (/^\s+(\S.*)/) { # a provision
    die "No person yet!" unless defined $person;
    push @{ $provisions{$person} }, $1;
  } else {
    die "I don't understand: $_";
  }
}

First, you declare the variables for the resulting hash of provisions and the current person. For each line that is read, determine if it's a person or a provision. If it's a person, remember the name and create the hash element for that person. The unless exists test ensures that you won't delete someone's provision list if his list is split in two places in the data file. For example, suppose that "The Skipper" and " sextant" (note the leading whitespace) are at the end of the data file in order to list an additional data item.

The key is the person's name, and the value is initially a reference to an empty anonymous array. If the line is a provision, push it to the end of the correct array, using the array reference.

This code works fine, but it actually says more than it needs to. Why? Because you can leave out the line that initializes the hash element's value to a reference to an empty array:

my %provisions;
my $person;
while (<>) {
  if (/^(\S.*)/) { # a person's name (no leading whitespace)
    $person = $1;
    ## $provisions{$person} = [  ] unless exists $provisions{$person};
  } elsif (/^\s+(\S.*)/) { # a provision
    die "No person yet!" unless defined $person;
    push @{ $provisions{$person} }, $1;
  } else {
    die "I don't understand: $_";
  }
}

What happens when you try to store that blue shirt for the Skipper? While looking at the second line of input, you'll end up with this effect:

push @{ $provisions{"The Skipper"} }, "blue_shirt";

At this point, $provisions{"The Skipper"} doesn't exist, but you're trying to use it as an array reference. To resolve the situation, Perl automatically inserts a reference to a new empty anonymous array into the variable and continues the operation. In this case, the reference to the newly created empty array is dereferenced, and you push the blue shirt to the provisions list.

This process is called autovivification. Any nonexisting variable, or a variable containing undef, which is dereferenced while looking for a variable location (technically called an lvalue context), is automatically stuffed with the appropriate reference to an empty item, and the operation is allowed to proceed.

This is actually the same behavior you've probably been using in Perl all along. Perl creates new variables as needed. Before that statement, $provisions{"The Skipper"} didn't exist, so Perl created it. Then @{ $provisions{"The Skipper"} } didn't exist, so Perl created it as well.

For example, this works:

my $not_yet;                # new undefined variable
@$not_yet = (1, 2, 3);

Here, you dereference the value $not_yet as if it were an array reference. But since it's initially undef, Perl acts as if you had said:

my $not_yet;
$not_yet = [  ]; # inserted through autovivification
@$not_yet = (1, 2, 3);

In other words, an initially empty array becomes an array of three elements.

This autovivification also works for multiple levels of assignment:

my $top;
$top->[2]->[4] = "lee-lou";

Initially, $top contains undef, but because it is dereferenced as if it were an array reference, Perl inserts a reference to an empty anonymous array into $top. The third element (index value 2) is then accessed, which causes Perl to grow the array to be three elements long. That element is also undef, so it is stuffed with a reference to another empty anonymous array. We then spin out along that newly created array, setting the fifth element to lee-lou.

Previous | Home | Next
4.6. Creating an Anonymous Hash | Book Index | 4.8. Autovivification and Hashes
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.8. Autovivification and Hashes

Autovivification also works for hash references. If a variable containing undef is dereferenced as if it were a hash reference, a reference to an empty anonymous hash is inserted, and the operation continues.

One place this comes in very handy is in a typical data reduction task. For example let's say the Professor gets an island-area network up and running (perhaps using Coco-Net or maybe Vines), and now wants to track the traffic from host to host. He begins logging the number of bytes transferred to a log file, giving the source host, the destination host, and the number of transferred bytes:

professor.hut gilligan.crew.hut 1250
professor.hut lovey.howell.hut 910
thurston.howell.hut lovey.howell.hut 1250
professor.hut lovey.howell.hut 450
professor.hut laser3.copyroom.hut 2924
ginger.girl.hut professor.hut 1218
ginger.girl.hut maryann.girl.hut 199
...

Now the Professor wants to produce a summary of the source host, the destination host, and the total number of transferred bytes for the day. Tabulating the data is as simple as:

my %total_bytes;
while (<>) {
  my ($source, $destination, $bytes) = split;
  $total_bytes{$source}{$destination} += $bytes;
}

Let's see how this works on the first line of data. You'll be executing:

$total_bytes{"professor.hut"}{"gilligan.crew.hut"} += 1250;

Because %total_bytes is initially empty, the first key of professor.hut is not found, but it establishes an undef value for the dereferencing as a hash reference. (Keep in mind that an implicit arrow is between the two sets of curly braces here.) Perl sticks in a reference to an empty anonymous hash in that element, which then is immediately extended to include the element with a key of gilligan.crew.hut. Its initial value is undef, which acts like a zero when you add 1250 to it, and the result of 1250 is inserted back into the hash.

Any later data line that contains this same source host and destination host will re-use that same value, adding more bytes to the running total. But each new destination host extends a hash to include a new initially undef byte count, and each new source host uses autovivification to create a destination host hash. In other words, Perl does the right thing, as always.

Once you've processed the file, it's time to display the summary. First, you determine all the sources:

for my $source (keys %total_bytes) {
...

Now, you should get all destinations. The syntax for this is a bit tricky. You want all keys of the hash, resulting from dereferencing the value of the hash element, in the first structure:

for my $source (keys %total_bytes) {
  for my $destination (keys %{ $total_bytes{$source} }) {
....

For good measure, you should probably sort both lists to be consistent:

for my $source (sort keys %total_bytes) {
  for my $destination (sort keys %{ $total_bytes{$source} }) {
    print "$source => $destination:",
     " $total_bytes{$source}{$destination} bytes\n";
  }
  print "\n";
}

This is a typical data-reduction report generation strategy. Simply create a hash-of-hashrefs (perhaps nested even deeper, as you'll see later), using autovivification to fill in the gaps in the upper data structures as needed, and then walk through the resulting data structure to display the results.

Previous | Home | Next
4.7. Autovivification | Book Index | 4.9. Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


4.9. Exercises

The answers for all exercises can be found in Section A.3.

4.9.1. Exercise 1 [5 min]

Without running it, can you see what's wrong with this piece of a program? If you can't see the problem after a minute or two, see whether trying to run it will give you a hint of how to fix it.

my %passenger_1 = {
  name => 'Ginger',
  age => 22,
  occupation => 'Movie Star',
  real_age => 35,
  hat => undef,
};

my %passenger_2 = {
  name => 'Mary Ann',
  age => 19,
  hat => 'bonnet',
  favorite_food => 'corn',
};

my @passengers = (\%passenger_1, \%passenger_2);

4.9.2. Exercise 2 [30 min]

The Professor's data file (mentioned earlier in this chapter) is available as coconet.dat in the files you can download from the O'Reilly web site. There may be comment lines (beginning with a pound sign); be sure to skip them. (That is, your program should skip them. You might find a helpful hint if you read them!)

Modify the code from the chapter so that each source machine's portion of the output shows the total number of bytes from that machine. List the source machines in order from most to least data transferred. Within each group, list the destination machines in order from most to least data transferred to that target from the source machine.

The result should be that the machine that sent the most data will be the first source machine in the list, and the first destination should be the machine to which it sent the most data. The Professor can use this printout to reconfigure the network for efficiency.

Previous | Home | Next
4.8. Autovivification and Hashes | Book Index | 5. Manipulating Complex Data Structures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 5. Manipulating Complex Data Structures

Contents:

Using the Debugger to View Complex Data
Viewing Complex Data with Data::Dumper
Storing Complex Data with Storable
The map and grep Operators
Using map
Applying a Bit of Indirection
Selecting and Altering Complex Data
Exercises

Now that you've seen the basics of references, let's look at additional ways to manipulate complex data. We'll start by using the debugger to examine complex data structures and then use Data::Dumper to show the data under programmatic control. Next, you'll learn to store and retrieve complex data easily and quickly using Storable, and finally we'll wrap up with a review of grep and map and see how they apply to complex data.

5.1. Using the Debugger to View Complex Data

The Perl debugger can display complex data easily. For example, let's single-step through one version of the byte-counting program from Chapter 4:

my %total_bytes;
while (<>) {
  my ($source, $destination, $bytes) = split;
  $total_bytes{$source}{$destination} += $bytes;
}
for my $source (sort keys %total_bytes) {
  for my $destination (sort keys %{ $total_bytes{$source} }) {
    print "$source => $destination:",
     " $total_bytes{$source}{$destination} bytes\n";
  }
  print "\n";
}

Here's the data you'll use to test it:

professor.hut gilligan.crew.hut 1250
professor.hut lovey.howell.hut 910
thurston.howell.hut lovey.howell.hut 1250
professor.hut lovey.howell.hut 450
ginger.girl.hut professor.hut 1218
ginger.girl.hut maryann.girl.hut 199

You can do this a number of ways. One of the easiest is to invoke Perl with a -d switch on the command line:

myhost% perl -d bytecounts bytecounts-in

Loading DB routines from perl5db.pl version 1.19
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(bytecounts:2):        my %total_bytes;
  DB<1> s
main::(bytecounts:3):        while (<>) {
  DB<1> s
main::(bytecounts:4):          my ($source, $destination, $bytes) = split;
  DB<1> s
main::(bytecounts:5):          $total_bytes{$source}{$destination} += $bytes;
  DB<1> x $source, $destination, $bytes
0  'professor.hut'
1  'gilligan.crew.hut'
2  1250

If you're playing along at home, be aware that each new release of the debugger works differently than any other, so your screen probably won't look exactly like this. Also, if you get stuck at any time, type h for help, or look at perldoc perldebug.

Each line of code is shown before it is executed. That means that, at this point, you're about to invoke the autovivification, and you've got your keys established. The s command single-steps the program, while the x command dumps a list of values in a nice format. You can see that $source, $destination, and $bytes are correct, and now it's time to update the data:

  DB<2> s
main::(bytecounts:3):        while (<>) {

You've created the hash entries through autovivification. Let's see what you've got:

   DB<2> x \%total_bytes
 0  HASH(0x132dc)
    'professor.hut' => HASH(0x37a34)
       'gilligan.crew.hut' => 1250

When x is given a hash reference, it dumps the entire contents of the hash, showing the key/value pairs. If any of the values are also hash references, they are dumped as well, recursively. What you'll see is that the %total_bytes hash has a single key of professor.hut, whose corresponding value is another hash reference. The referenced hash contains a single key of gilligan.crew.hut, with a value of 1250, as expected.

Let's see what happens just after the next assignment:

  DB<3> s
main::(bytecounts:4):          my ($source, $destination, $bytes) = split;
  DB<3> s
main::(bytecounts:5):          $total_bytes{$source}{$destination} += $bytes;
  DB<3> x $source, $destination, $bytes
0  'professor.hut'
1  'lovey.howell.hut'
2  910
  DB<4> s
main::(bytecounts:3):        while (<>) {
  DB<4> x \%total_bytes
0  HASH(0x132dc)
   'professor.hut' => HASH(0x37a34)
      'gilligan.crew.hut' => 1250
      'lovey.howell.hut' => 910

Now you've added bytes flowing from professor.hut to lovey.howell.hut. The top-level hash hasn't changed, but the second-level hash has added a new entry. Let's continue:

  DB<5> s
main::(bytecounts:4):          my ($source, $destination, $bytes) = split;
  DB<6> s
main::(bytecounts:5):          $total_bytes{$source}{$destination} += $bytes;
  DB<6> x $source, $destination, $bytes
0  'thurston.howell.hut'
1  'lovey.howell.hut'
2  1250
  DB<7> s
main::(bytecounts:3):        while (<>) {
  DB<7> x \%total_bytes
0  HASH(0x132dc)
   'professor.hut' => HASH(0x37a34)
      'gilligan.crew.hut' => 1250
      'lovey.howell.hut' => 910
   'thurston.howell.hut' => HASH(0x2f9538)
      'lovey.howell.hut' => 1250

Ah, now it's getting interesting. A new entry in the top-level hash has a key of thurston.howell.hut, and a new hash reference, autovivified initially to an empty hash. Immediately after the new empty hash was put in place, a new key/value pair was added, indicating 1250 bytes transferred from thurston.howell.hut to lovey.howell.hut. Let's step some more:

  DB<8> s
main::(bytecounts:4):          my ($source, $destination, $bytes) = split;
  DB<8> s
main::(bytecounts:5):          $total_bytes{$source}{$destination} += $bytes;
  DB<8> x $source, $destination, $bytes
0  'professor.hut'
1  'lovey.howell.hut'
2  450
  DB<9> s
main::(bytecounts:3):        while (<>) {
  DB<9> x \%total_bytes
0  HASH(0x132dc)
   'professor.hut' => HASH(0x37a34)
      'gilligan.crew.hut' => 1250
      'lovey.howell.hut' => 1360
   'thurston.howell.hut' => HASH(0x2f9538)
      'lovey.howell.hut' => 1250

Now you're adding in some more bytes from professor.hut to lovey.howell.hut, reusing the existing value place. Nothing too exciting there. Let's keep stepping:

  DB<10> s
main::(bytecounts:4):          my ($source, $destination, $bytes) = split;
  DB<10> s
main::(bytecounts:5):          $total_bytes{$source}{$destination} += $bytes;
  DB<10> x $source, $destination, $bytes
0  'ginger.girl.hut'
1  'professor.hut'
2  1218
  DB<11> s
main::(bytecounts:3):        while (<>) {
  DB<11> x \%total_bytes
0  HASH(0x132dc)
   'ginger.girl.hut' => HASH(0x297474)
      'professor.hut' => 1218
   'professor.hut' => HASH(0x37a34)
      'gilligan.crew.hut' => 1250
      'lovey.howell.hut' => 1360
   'thurston.howell.hut' => HASH(0x2f9538)
      'lovey.howell.hut' => 1250

This time, you added a new source, ginger.girl.hut. Notice that the top level hash now has three elements, and each element has a different hash reference value. Let's step some more:

  DB<12> s
main::(bytecounts:4):          my ($source, $destination, $bytes) = split;
  DB<12> s
main::(bytecounts:5):          $total_bytes{$source}{$destination} += $bytes;
  DB<12> x $source, $destination, $bytes
0  'ginger.girl.hut'
1  'maryann.girl.hut'
2  199
  DB<13> s
main::(bytecounts:3):        while (<>) {
  DB<13> x \%total_bytes
0  HASH(0x132dc)
   'ginger.girl.hut' => HASH(0x297474)
      'maryann.girl.hut' => 199
      'professor.hut' => 1218
   'professor.hut' => HASH(0x37a34)
      'gilligan.crew.hut' => 1250
      'lovey.howell.hut' => 1360
   'thurston.howell.hut' => HASH(0x2f9538)
      'lovey.howell.hut' => 1250

Now you've added a second destination to the hash that records information for all bytes originating at ginger.girl.hut. Because that was the final line of data (in this run), a step brings you down to the lower foreach loop:

  DB<14> s
main::(bytecounts:8):        for my $source (sort keys %total_bytes) {

Even though you can't directly examine the list value from inside those parentheses, you can display it:

    DB<14> x sort keys %total_bytes
  0  'ginger.girl.hut'
  1  'professor.hut'
  2  'thurston.howell.hut'

This is the list the foreach now scans. These are all the sources for transferred bytes seen in this particular logfile. Here's what happens when you step into the inner loop:

    DB<15> s
  main::(bytecounts:9):          for my $destination (sort keys %{ $total bytes{
$source} }) {

At this point, you can determine from the inside out exactly what values will result from the list value from inside the parentheses. Let's look at them:

  DB<15> x $source
0  'ginger.girl.hut'
  DB<16> x $total_bytes{$source}
0  HASH(0x297474)
   'maryann.girl.hut' => 199
   'professor.hut' => 1218
  DB<18> x keys %{ $total_bytes{$source } }
0  'maryann.girl.hut'
1  'professor.hut'
  DB<19> x sort keys %{ $total_bytes{$source } }
0  'maryann.girl.hut'
1  'professor.hut'

Note that dumping $total_bytes{$source} shows that it was a hash reference. Also, the sort appears not to have done anything, but the output of keys is not necessarily in a sorted order. The next step finds the data:

  DB<20> s
main::(bytecounts:10):            print "$source => $destination:",
main::(bytecounts:11):              " $total_bytes{$source}{$destination} bytes\n";
  DB<20> x $source, $destination
0  'ginger.girl.hut'
1  'maryann.girl.hut'
  DB<21> x $total_bytes{$source}{$destination}
0  199

As you can see, with the debugger, you can easily show the data, even structured data, to help you understand your program.

Previous | Home | Next
4.9. Exercises | Book Index | 5.2. Viewing Complex Data with Data::Dumper
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.2. Viewing Complex Data with Data::Dumper

Another way to visualize a complex data structure rapidly is to dump it. A particularly nice dumping package is included in the Perl core distribution, called Data::Dumper. Let's replace the last half of the byte-counting program with a simple call to Data::Dumper:

use Data::Dumper;

my %total_bytes;
while (<>) {
  my ($source, $destination, $bytes) = split;
  $total_bytes{$source}{$destination} += $bytes;
}

print Dumper(\%total_bytes);

The Data::Dumper module defines the Dumper subroutine. This subroutine is similar to the x command in the debugger. You can give Dumper one or more values, and Dumper turns those values into a printable string. The difference between the debugger's x command and Dumper, however, is that the string generated by Dumper is Perl code:

myhost% perl bytecounts2 <bytecounts-in
$VAR1 = {
          'thurston.howell.hut' => {
                                     'lovey.howell.hut' => 1250
                                   },
          'ginger.girl.hut' => {
                                 'maryann.girl.hut' => 199,
                                 'professor.hut' => 1218
                               },
          'professor.hut' => {
                               'gilligan.crew.hut' => 1250,
                               'lovey.howell.hut' => 1360
                             }
        };
myhost%

The Perl code is fairly understandable; it shows that you have a reference to a hash of three elements, with each value of the hash being a reference to a nested hash. You can evaluate this code and get a hash that's equivalent to the original hash. However, if you're thinking about doing this in order to have a complex data structure persist from one program invocation to the next, please keep reading.

Data::Dumper, like the debugger's x command, handles shared data properly. For example, go back to that "leaking" data from Chapter 4:

use Data::Dumper;
$Data::Dumper::Purity = 1; # declare possibly self-referencing structures
my @data1 = qw(one won);
my @data2 = qw(two too to);
push @data2, \@data1;
push @data1, \@data2;
print Dumper(\@data1, \@data2);

Here's the output from this program:

$VAR1 = [
          'one',
          'won',
          [
            'two',
            'too',
            'to',
            [  ]
          ]
        ];
$VAR1->[2][3] = $VAR1;
$VAR2 = $VAR1->[2];

Notice how you've created two different variables now, since there are two parameters to Dumper. The element $VAR1 corresponds to a reference to @data1, while $VAR2 corresponds to a reference to @data2. The debugger shows the values similarly:

DB<1> x \@data1, \@data2
    0  ARRAY(0xf914)
 0  'one'
 1  'won'
 2  ARRAY(0x3122a8)
    0  'two'
    1  'too'
    2  'to'
    3  ARRAY(0xf914)
       -> REUSED_ADDRESS
    1  ARRAY(0x3122a8)
 -> REUSED_ADDRESS

Note that the phrase REUSED_ADDRESS indicates that some parts of the data are actually references you've already seen.

Previous | Home | Next
5. Manipulating Complex Data Structures | Book Index | 5.3. Storing Complex Data with Storable
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.3. Storing Complex Data with Storable

You can take the output of Data::Dumper's Dumper routine, place it into a file, and then load the file to a different program, evaluating the code as Perl code, and you'd end up with two package variables, $VAR1 and $VAR2, that are equivalent to the original data. This is called marshaling the data: converting complex data into a form that can be written to a file as a stream of bytes for later reconstruction.

However, another Perl core module is much better suited for marshaling: Storable. It's better suited because compared to Data::Dumper, Storable produces smaller and faster-to-process files. (The Storable module is standard in recent versions of Perl, but you can always install it from the CPAN if it's missing.)

The interface is similar to using Data::Dumper, except you must put everything into one reference. For example, let's store the mutually referencing data structures:

use Storable;
my @data1 = qw(one won);
my @data2 = qw(two too to);
push @data2, \@data1;
push @data1, \@data2;
store [\@data1, \@data2], 'some_file';

The file produced by this step was 68 bytes on this system, which was quite a bit shorter than the equivalent Data::Dumper output. It's also much less readable for humans. It's easy for Storable to read, as you'll soon see.[20]

[20]The format used by Storable is architecture byte-order dependent by default. The manpage shows how to create byte-order-independent storage files.

Next, fetch the data, again using the Storable module. The result will be a single array reference. Dump the result to see if it stored the right values:

use Storable;
my $result = retrieve 'some_file';
use Data::Dumper;
$Data::Dumper::Purity = 1;
print Dumper($result);

Here's the result:

$VAR1 = [
          [
            'one',
            'won',
            [
              'two',
              'too',
              'to',
              [  ]
            ]
          ],
          [  ]
        ];
$VAR1->[0][2][3] = $VAR1->[0];
$VAR1->[1] = $VAR1->[0][2];

This is functionally the same as the original data structure. You're now looking at the two array references within one top-level array. To get something closer to what you saw before, you can be more explicit about the return value:

use Storable;
my ($arr1, $arr2) = @{ retrieve 'some_file' };
use Data::Dumper;
$Data::Dumper::Purity = 1;
print Dumper($arr1, $arr2);

or equivalently:

use Storable;
my $result = retrieve 'some_file';
use Data::Dumper;
$Data::Dumper::Purity = 1;
print Dumper(@$result);

and you'll get:

$VAR1 = [
          'one',
          'won',
          [
            'two',
            'too',
            'to',
            [  ]
          ]
        ];
$VAR1->[2][3] = $VAR1;
$VAR2 = $VAR1->[2];

just as you did in the original program. With Storable, you can store data and retrieve it later. More information on Storable can be found in perldoc Storable, as always.

Previous | Home | Next
5.2. Viewing Complex Data with Data::Dumper | Book Index | 5.4. The map and grep Operators
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.4. The map and grep Operators

As the data structures become more complex, it helps to have higher-level constructs deal with common tasks such as selection and transformation. In this regard, Perl's grep and map operators are worth mastering.

Let's review the functionality of grep and map for a moment, without reference to references.

The grep operator takes a list of values and a "testing expression." For each item in the list of values, the item is placed temporarily into the $_ variable, and the testing expression is evaluated (in a scalar context). If the expression results in a true value (defined in the normal Perl sense of truth), the item is considered selected. In a list context, the grep operator returns a list of all such selected items. In a scalar context, the operator returns the number of selected items.[21]

[21]The value in $_ is local to the operation. If there's an existing $_ value, the local value temporarily shadows the global value while the grep executes.

The syntax comes in two forms: the expression form and the block form. The expression form is often easier to type:

my @results = grep $expression, @input_list;
my $count = grep $expression, @input_list;

Here, $expression is a scalar expression that should refer to $_ (explicitly or implicitly). For example, find all the numbers greater than 10:

my @input_numbers = (1, 2, 4, 8, 16, 32, 64);
my @bigger_than_10 = grep $_ > 10, @input_numbers;

The result is just 16, 32, and 64. This uses an explicit reference to $_. Here's an example of an implicit reference to $_ that's similar to pattern matching:

my @end_in_4 = grep /4$/, @input_numbers;

And now you find just 4 and 64.

If the testing expression is complex, you can hide it in a subroutine:

my @odd_digit_sum = grep digit_sum_is_odd($_), @input_numbers;
sub digit_sum_is_odd {
  my $input = shift;
  my @digits = split //, $input;  # Assume no nondigit characters
  my $sum;
  $sum += $_ for @digits;
  return $sum % 2;
}

Now you get back the list of 1, 16, and 32. These numbers have a digit sum with a remainder of "1" in the last line of the subroutine, which counts as true.

However, rather than define an explicit subroutine used for only a single test, you can also put the body of a subroutine directly in line in the grep operator, using the block forms:[22]

[22]In the block form of grep, there's no comma between the block and the input list. In the earlier (expression) form of grep, there must be a comma between the expression and the list.

my @results = grep { block; of; code; } @input_list;
my $count = grep { block; of; code; } @input_list;

Just like the expression form, each element of the input list is placed temporarily into $_. Next, the entire block of code is evaluated. The last expression evaluated in the block (evaluated in a scalar context) is used like the testing expression in the expression form. Because it's a full block, you can introduce variables that are local to the block. Let's rewrite that last example to use the block form:

my @odd_digit_sum = grep {
  my $input = $_;
  my @digits = split //, $input;   # Assume no nondigit characters
  my $sum;
  $sum += $_ for @digits;
  $sum % 2;
} @input_numbers;

Note the two changes: your input value comes in via $_ rather than an argument list, and the keyword return was removed. In fact, it would have been erroneous to retain the return because you're no longer in a separate subroutine: just a block of code.[23]

[23]The return would have exited the subroutine that contains this entire section of code. And yes, some of us have been bitten by that mistake in real, live coding on the first draft.

Of course, you can optimize a few things out of that routine:

my @odd_digit_sum = grep {
  my $sum;
  $sum += $_ for split //;
  $sum % 2;
} @input_numbers;

Feel free to crank up the explicitness if it helps you and your coworkers understand and maintain the code. That's the main thing that matters.

Previous | Home | Next
5.3. Storing Complex Data with Storable | Book Index | 5.5. Using map
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.5. Using map

The map operator has a very similar syntax to the grep operator and shares a lot of the same operational steps. For example, items from a list of values are temporarily placed into $_ one at a time, and the syntax allows both a simple expression form and a more complex block form.

However, the testing expression becomes a mapping expression. This expression is evaluated in a list context (not a scalar context). Each evaluation of the expression gives a portion of the many results. The overall result is the list concatenation of all individual results. (In a scalar context, map returns the number of elements that are returned in a list context. But map should rarely, if ever, be used in anything but a list context.)

Let's start with a simple example:

my @input_numbers = (1, 2, 4, 8, 16, 32, 64);
my @result = map $_ + 100, @input_numbers;

For each of the seven items placed into $_, you get a single output result: the number that is 100 greater than the input number, so the value of @result is 101, 102, 104, 108, 116, 132, and 164.

But you're not limited to having only one output for each input. Let's see what happens when each input produces two output items:

my @result = map { $_, 3 * $_ } @input_numbers;

Now there are two items for each input item: 1, 3, 2, 6, 4, 12, 8, 24, 16, 48, 32, 96, 64, and 192. Those pairs can be stored in a hash, if you need a hash showing what number is three times a small power of two:

my %hash = @result;

Or, without using the intermediate array from the map:

my %hash = map { $_, 3 * $_ } @input_numbers;

You can see that map is pretty versatile; you can produce any number of output items for each input item. And you don't always need to produce the same number of output items. Let's see what happens when you break apart the digits:

my @result = map { split //, $_ } @input_numbers;

Each number is split into its digits. For 1, 2, 4, and 8, you get a single result. For 16, 32, and 64, you get two results per number. When the lists are concatenated, you end up with 1, 2, 4, 8, 1, 6, 3, 2, 6, and 4.

If a particular invocation results in an empty list, that empty result is concatenated into the larger list, contributing nothing to the list. You can use this feature to select and reject items. For example, suppose you want only the split digits of numbers ending in 4:

my @result = map {
  my @digits = split //, $_;
  if ($digits[-1] == 4) {
    @digits;
  } else {
    ( );
  }
} @input_numbers;

If the last digit is 4, you return the digits themselves by evaluating @digits (which is evaluated in a list context). If the last digit is not 4, you return an empty list, effectively removing results for that particular item. (Thus, a map can always be used in place of a grep, but not vice versa.)

Of course, everything you can do with map and grep, you can also do with explicit foreach loops. But then again, you can also code in assembler or by toggling bits into a front panel.[24] The point is that proper application of grep and map can help reduce the complexity of the program, allowing you to concentrate on high-level issues rather than details.

[24]If you're old enough to remember those front panels.

Previous | Home | Next
5.4. The map and grep Operators | Book Index | 5.6. Applying a Bit of Indirection
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.6. Applying a Bit of Indirection

Some problems that may appear very complex are actually simple once you've seen a solution or two. For example, suppose you want to find the items in a list that have odd digit sums but don't want the items themselves. What you want to know is where they occurred in the original list.

All that's required is a bit of indirection.[25]

[25]A famous computing maxim states that "there is no problem so complex that it cannot be solved with appropriate additional layers of indirection." Of course, with indirection comes obfuscation, so there's got to be a magic middle ground somewhere.

First, you have a selection problem, so you use a grep. Let's not grep the values themselves but the index for each item:

my @input_numbers = (1, 2, 4, 8, 16, 32, 64);
my @indices_of_odd_digit_sums = grep {
  ...
} 0..$#input_numbers;

Here, the expression 0..$#input_numbers will be a list of indices for the array. Inside the block, $_ is a small integer, from 0 to 6 (seven items total). Now, you don't want to decide whether $_ has an odd digit sum. You want to know whether the array element at that index has an odd digit sum. Instead of using $_ to get the number of interest, use $input_numbers[$_]:

my @indices_of_odd_digit_sums = grep {
  my $number = $input_numbers[$_];
  my $sum;
  $sum += $_ for split //, $number;
  $sum % 2;
} 0..$#input_numbers;

The result will be the indices at which 1, 16, and 32 appear in the list: 0, 4, and 5. You could use these indices in an array slice to get the original values again:

my @odd_digit_sums = @input_numbers[ @indices_of_odd_digit_sums ];

The strategy here for an indirect grep or map is to think of the $_ values as identifying a particular item of interest, such as the key in a hash or the index of an array, and then use that identification within the block or expression to access the actual values.

Here's another example: select the elements of @x that are larger than the corresponding value in @y. Again, you'll use the indices of @x as your $_ items:

my @bigger_indices = grep {
  if ($_ > $#y or $x[$_] > $y[$_]) {
    1; # yes, select it
  } else {
    0; # no, don't select it
  }
} 0..$#x;
my @bigger = @x[@bigger_indices];

In the grep, $_ varies from 0 to the highest index of @x. If that element is beyond the end of @y, you automatically select it. Otherwise, you look at the individual corresponding values of the two arrays, selecting only the ones that meet your match.

However, this is a bit more verbose than it needs to be. You could simply return the boolean expression rather than a separate 1 or 0:

my @bigger_indices = grep {
  $_ > $#y or $x[$_] > $y[$_];
} 0..$#x;
my @bigger = @x[@bigger_indices];

More easily, you can skip the step of building the intermediate array by simply returning the items of interest with a map:

my @bigger = map {
  if ($_ > $#y or $x[$_] > $y[$_]) {
    $x[$_];
  } else {
    ( );
  }
} 0..$#x;

If the index is good, return the resulting array value. If the index is bad, return an empty list, making that item disappear.

Previous | Home | Next
5.5. Using map | Book Index | 5.7. Selecting and Altering Complex Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.7. Selecting and Altering Complex Data

You can use these operators on more complex data. Taking the provisions list from Chapter 4:

my %provisions = (
  "The Skipper" =>
    [qw(blue_shirt hat jacket preserver sunscreen)],
  "The Professor" =>
    [qw(sunscreen water_bottle slide_rule batteries radio)],
  "Gilligan" =>
    [qw(red_shirt hat lucky_socks water_bottle)],
);

In this case, $provisions{"The Professor"} gives an array reference of the provisions brought by the Professor, and $provisions{"Gilligan"}[-1] gives the last item Gilligan thought to bring.

Run a few queries against this data. Who brought fewer than five items?

my @packed_light = grep @{ $provisions{$_} } < 5, keys %provisions;

In this case, $_ is the name of a person. Take that name, look up the array reference of the provisions for that person, dereference that in a scalar context to get the count of provisions, and then compare it to 5. And wouldn't you know it; the only name is Gilligan.

Here's a trickier one. Who brought a water bottle?

my @all_wet = grep {
  my @items = @{ $provisions{$_} };
  grep $_ eq "water_bottle", @items;
} keys %provisions;

Starting with the list of names again (keys %provisions), pull up all the packed items first, and then use that list in an inner grep to count the number of those items that equal water_bottle. If the count is 0, there's no bottle, so the result is false for the outer grep. If the count is nonzero, you have a bottle, so the result is true for the outer grep. Now you see that the Skipper will be a bit thirsty later, without any relief.

You can also perform transformations. For example, turn this hash into a list of array references, with each array containing two items. The first is the original person's name; the second is a reference to an array of the provisions for that person:

my @remapped_list = map {
  [ $_ => $provisions{$_} ];
} keys %provisions;

The keys of %provisions are names of the people. For each name, construct a two-element list of the name and the corresponding provisions array reference. This list is inside an anonymous array constructor, so you get back a reference to a newly created array for each person. Three names in; three references out.[26]

[26]If you had left the inner brackets off, you'd end up with six items out. That's not very useful, unless you're creating a different hash from them.

Or, let's go a different way. Turn the input hash into a series of references to arrays. Each array will have a person's name and one of the items they brought:

my @person_item_pairs = map {
  my $person = $_;
  my @items = @{ $provisions{$person} };
  map [$person => $_], @items;
} keys %provisions;

Yes, a map within a map. The outer map selects one person at a time. The name is saved into $person, and then the item list is extracted from the hash. The inner map walks over this item list, executing the expression to construct an anonymous array reference for each item. The anonymous array contains the person's name and the provision item.

You had to use $person here to hold the outer $_ temporarily. Otherwise, you can't refer to both temporary values for the outer map and the inner map.

Previous | Home | Next
5.6. Applying a Bit of Indirection | Book Index | 5.8. Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


5.8. Exercises

The answers for all exercises can be found in Section A.4.

5.8.1. Exercise 1 [20 min]

The program from Exercise 2 in Chapter 4 needs to read the entire data file each time it runs. However, the Professor has a new router log file each day and doesn't want to keep all that data in one giant file that takes longer and longer to process.

Fix up that program to keep the running totals in a data file so the Professor can simply run it on each day's logs to get the new totals.

5.8.2. Exercise 2 [5 min]

To make it really useful, what other features should be added to that program? You don't need to implement them!

Previous | Home | Next
5.7. Selecting and Altering Complex Data | Book Index | 6. Subroutine References
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 6. Subroutine References

Contents:

Referencing a Named Subroutine
Anonymous Subroutines
Callbacks
Closures
Returning a Subroutine from a Subroutine
Closure Variables as Inputs
Closure Variables as Static Local Variables
Exercise

So far, you've seen references to arrays and hashes. You can also take a reference to a subroutine (sometimes called a coderef).

Why would you want to do that? Well, in the same way that taking a reference to an array lets you have the same code work on different arrays at different times, taking a reference to a subroutine allows the same code to call different subroutines at different times. Also, references permit complex data structures. A reference to a subroutine allows a subroutine to effectively become part of that complex data structure.

Put another way, a variable or a complex data structure is a repository of values throughout the program. A reference to a subroutine can be thought of as a repository of behavior in a program. The examples in this section show how this works.

6.1. Referencing a Named Subroutine

The Skipper and Gilligan are having a conversation:

sub skipper_greets {
  my $person = shift;
  print "Skipper: Hey there, $person!\n";
}

sub gilligan_greets {
  my $person = shift;
  if ($person eq "Skipper") {
    print "Gilligan: Sir, yes, sir, $person!\n";
  } else {
    print "Gilligan: Hi, $person!\n";
  }
}

skipper_greets("Gilligan");
gilligan_greets("Skipper");

This results in:

Skipper: Hey there, Gilligan!
Gilligan: Sir, yes, sir, Skipper!

So far, nothing unusual has happened. Note however that Gilligan has two different behaviors, depending on whether he's addressing the Skipper or someone else.

Now, have the Professor walk into the hut. Both of the Minnow crew greet the newest participant:

skipper_greets("Professor");
gilligan_greets("Professor");

which results in

Skipper: Hey there, Professor!
Gilligan: Hi, Professor!

Now the Professor feels obligated to respond:

sub professor_greets {
  my $person = shift;
  print "Professor: By my calculations, you must be $person!\n";
}

professor_greets("Gilligan");
professor_greets("Skipper");

resulting in:

Professor: By my calculations, you must be Gilligan!\n";
Professor: By my calculations, you must be Skipper!\n";

Whew. A lot of typing and not very general. If each person's behavior is in a separate named subroutine and a new person walks in the door, you have to figure out what other subroutines to call. You could certainly do it with enough hard-to-maintain code, but you can simplify the process by adding a bit of indirection, just as you did with arrays and hashes.

First, let's introduce the "take a reference to" operator. It actually needs no introduction because it's that very same backslash again:

my $ref_to_greeter = \&skipper_greets;

You're taking a reference to the subroutine skipper_greets( ). Note that the preceding ampersand is mandatory here, and the lack of trailing parentheses is also intentional. The reference to the subroutine (a coderef) is stored within $ref_to_greeter, and like all other references, it fits nearly anywhere a scalar fits.

There's only one reason to get back to the original subroutine by dereferencing the coderef: to invoke it. Dereferencing a code reference is similar to dereferencing other references. First start with the way you would have written it before you heard of references (including the optional ampersand prefix):

& skipper_greets ( "Gilligan" )

Next, you replace the name of the subroutine with curly braces around the thing holding the reference:

& { $ref_to_greeter } ( "Gilligan" )

There you have it. This construct invokes the subroutine currently referenced by $ref_to_greeter, passing it the single Gilligan parameter.

But boy-oh-boy, is that ugly or what? Luckily, the same reference simplification rules apply. If the value inside the curly braces is a simple scalar variable, you can drop the braces:

& $ref_to_greeter ( "Gilligan" )

You can also flip it around a bit with the arrow notation:

$ref_to_greeter -> ( "Gilligan" )

That last form is particularly handy when the coderef is contained within a larger data structure, as you'll see in a moment.

To have both Gilligan and the Skipper greet the Professor, you merely need to iterate over all the subroutines:

for my $greet (\&skipper_greets, \&gilligan_greets) {
  $greet->("Professor");
}

First, inside the parentheses, you create a list of two items, each of which is a coderef. The coderefs are then individually dereferenced, invoking the corresponding subroutine and passing it the Professor string.

You've seen the coderefs in a scalar variable and as an element of a list. Can you put these coderefs into a larger data structure? Certainly. Create a table that maps people to the behavior they exhibit to greet others, and then rewrite that previous example using the table:

sub skipper_greets {
  my $person = shift;
  print "Skipper: Hey there, $person!\n";
}

sub gilligan_greets {
  my $person = shift;
  if ($person eq "Skipper") {
    print "Gilligan: Sir, yes, sir, $person!\n";
  } else {
    print "Gilligan: Hi, $person!\n";
  }
}

sub professor_greets {
  my $person = shift;
  print "Professor: By my calculations, you must be $person!\n";
}

my %greets = (
  "Gilligan" => \&gilligan_greets,
  "Skipper" => \&skipper_greets,
  "Professor" => \&professor_greets,
);

for my $person (qw(Skipper Gilligan)) {
  $greets{$person}->("Professor");
}

Note that $person is a name, which you look up in the hash to get to a coderef. Then you dereference that coderef, passing it the name of the person being greeted, and you get the correct behavior, resulting in:

Skipper: Hey there, Professor!
Gilligan: Hi, Professor!

Now have everyone greet everyone, in a very friendly room:

sub skipper_greets {
  my $person = shift;
  print "Skipper: Hey there, $person!\n";
}

sub gilligan_greets {
  my $person = shift;
  if ($person eq "Skipper") {
    print "Gilligan: Sir, yes, sir, $person!\n";
  } else {
    print "Gilligan: Hi, $person!\n";
  }
}

sub professor_greets {
  my $person = shift;
  print "Professor: By my calculations, you must be $person!\n";
}

my %greets = ... as before ...

my @everyone = sort keys %greets;
for my $greeter (@everyone) {
  for my $greeted (@everyone) {
    $greets{$greeter}->($greeted)
      unless $greeter eq $greeted; # no talking to yourself
  }
}

This results in:

Gilligan: Hi, Professor!
Gilligan: Sir, yes, sir, Skipper!
Professor: By my calculations, you must be Gilligan!
Professor: By my calculations, you must be Skipper!
Skipper: Hey there, Gilligan!
Skipper: Hey there, Professor!

Hmm. That's a bit complex. Let's let them walk into the room one at a time:

sub skipper_greets {
  my $person = shift;
  print "Skipper: Hey there, $person!\n";
}

sub gilligan_greets {
  my $person = shift;
  if ($person eq "Skipper") {
    print "Gilligan: Sir, yes, sir, $person!\n";
  } else {
    print "Gilligan: Hi, $person!\n";
  }
}

sub professor_greets {
  my $person = shift;
  print "Professor: By my calculations, you must be $person!\n";
}

my %greets = ... as before ...

my @room; # initially empty
for my $person (qw(Gilligan Skipper Professor)) {
  print "\n";
  print "$person walks into the room.\n";
  for my $room_person (@room) {
    $greets{$person}->($room_person); # speaks
    $greets{$room_person}->($person); # gets reply
  }
  push @room, $person; # come in, get comfy
}

The result is a typical day on that tropical island:

Gilligan walks into the room.

Skipper walks into the room.
Skipper: Hey there, Gilligan!
Gilligan: Sir, yes, sir, Skipper!

Professor walks into the room.
Professor: By my calculations, you must be Gilligan!
Gilligan: Hi, Professor!
Professor: By my calculations, you must be Skipper!
Skipper: Hey there, Professor!
Previous | Home | Next
5.8. Exercises | Book Index | 6.2. Anonymous Subroutines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.2. Anonymous Subroutines

In that last example, subroutines such as professor_greets( ) were never called explicitly, but indirectly through the coderef. Thus, you wasted some brain cells to come up with a name for the subroutine used only in one other place, to initialize the data structure.

But as you can have anonymous hashes and arrays, you can have anonymous subroutines!

Let's add another island inhabitant: Ginger. But rather than define her greeting behavior as a named subroutine, create an anonymous subroutine:

my $ginger = sub {
  my $person = shift;
  print "Ginger: (in a sultry voice) Well hello, $person!\n";
};
$ginger->("Skipper");

An anonymous subroutine looks like:

sub { ... body of subroutine ... }

The value in $ginger is a coderef, just as if you had defined the following block as a subroutine and then taken a reference to it. When you reach the last statement, you see:

Ginger: (in a sultry voice) Well hello, Skipper!

Although you kept the value in a scalar variable, you could have put that sub { ... } construct directly into the initialization of the greetings hash:

my %greets = (

  "Skipper" => sub {
    my $person = shift;
    print "Skipper: Hey there, $person!\n";
  },

  "Gilligan" => sub {
    my $person = shift;
    if ($person eq "Skipper") {
      print "Gilligan: Sir, yes, sir, $person!\n";
    } else {
      print "Gilligan: Hi, $person!\n";
    }
  },

  "Professor" => sub {
    my $person = shift;
    print "Professor: By my calculations, you must be $person!\n";
  },

  "Ginger" => sub {
    my $person = shift;
    print "Ginger: (in a sultry voice) Well hello, $person!\n";
  },

);

my @room; # initially empty
for my $person (qw(Gilligan Skipper Professor Ginger)) {
  print "\n";
  print "$person walks into the room.\n";
  for my $room_person (@room) {
    $greets{$person}->($room_person); # speaks
    $greets{$room_person}->($person); # gets reply
  }
  push @room, $person; # come in, get comfy
}

Notice how much it simplifies the code. The subroutine definitions are right within the only data structure that references them directly. The result is straightforward:

Gilligan walks into the room.

Skipper walks into the room.
Skipper: Hey there, Gilligan!
Gilligan: Sir, yes, sir, Skipper!

Professor walks into the room.
Professor: By my calculations, you must be Gilligan!
Gilligan: Hi, Professor!
Professor: By my calculations, you must be Skipper!
Skipper: Hey there, Professor!

Ginger walks into the room.
Ginger: (in a sultry voice) Well hello, Gilligan!
Gilligan: Hi, Ginger!
Ginger: (in a sultry voice) Well hello, Skipper!
Skipper: Hey there, Ginger!
Ginger: (in a sultry voice) Well hello, Professor!
Professor: By my calculations, you must be Ginger!

Adding a few more castaways is as simple as putting the entry for the greeting behavior into the hash and adding them into the list of people entering the room. You get this scaling of effort because you've preserved the behavior as data over which you can iterate and look up, thanks to your friendly subroutine references.

Previous | Home | Next
6. Subroutine References | Book Index | 6.3. Callbacks
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.3. Callbacks

A subroutine reference is often used for a callback. A callback defines what to do when a subroutine reaches a particular place in an algorithm.

For example, the File::Find module exports a find subroutine that can efficiently walk through a given filesystem hierarchy in a fairly portable way. In its simplest form, you give the find subroutine two parameters: a starting directory and "what to do" for each file or directory name found recursively below that starting directory. The "what to do" is specified as a subroutine reference:

use File::Find;
sub what_to_do {
  print "$File::Find::name found\n";
}
my @starting_directories = qw(.);

find(\&what_to_do, @starting_directories);

In this case, find starts at the current directory (.) and locates each file or directory. For each item, a call is made to the subroutine what_to_do( ), passing it a few documented values through global variables. In particular, the value of $File::Find::name is the item's full pathname (beginning with the starting directory).

In this case, you're passing both data (the list of starting directories) and behavior as parameters to the find routine.

It's a bit silly to invent a subroutine name just to use the name only once, so you can write the previous code using an anonymous subroutine, such as:

use File::Find;
my @starting_directories = qw(.);

find(
  sub {
    print "$File::Find::name found\n";
  },
  @starting_directories,
);
Previous | Home | Next
6.2. Anonymous Subroutines | Book Index | 6.4. Closures
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.4. Closures

You could also use File::Find to find out some other things about files, such as their size. For the callback's convenience, the current working directory is the item's containing directory, and the item's name within that directory is found in $_.

Maybe you have noticed that, in the previous code, $File::Find::name was used for the item's name. So which name is real, $_ or $File::Find::name?

$File::Find::name gives the name relative to the starting directory, but during the callback, the working directory is the one that holds the item just found. For example, suppose that you want find to look for files in the current working directory, so you give it (".") as the list of directories to search. If you call find when the current working directory is /usr, find looks below that directory. When find has located /usr/bin/perl, the current working directory (during the callback) is /usr/bin. $_ holds "perl"; $File::Find::name holds "./bin/perl", which is the name relative to the directory in which you started the search.

All of this means that the file tests, such as -s, automatically report on the just-found item. Although this is convenient, the current directory inside the callback is different from the search's starting directory.

What if you want to use File::Find to accumulate the total size of all files seen? The callback subroutine doesn't support either parameters to be passed in, nor a result returned from the subroutine. But that doesn't matter. When dereferenced, a subroutine reference can "see" all visible lexical variables when the reference to the subroutine is taken. For example:

use File::Find;

my $total_size = 0;
find(sub { $total_size += -s if -f }, ".");
print $total_size, "\n";

As before, the find routine is called with two parameters: a reference to an anonymous subroutine and the starting directory. When names are found within that directory (and its subdirectories), the subroutine is called.

Note that the subroutine accesses the $total_size variable. This variable is declared outside the scope of the subroutine but still visible to the subroutine. Thus, even though find invokes the callback subroutine (and would not have direct access to $total_size), the callback subroutine accesses and updates the variable.

The kind of subroutine that can access all lexical variables that existed at the time it was declared is called a closure (a term borrowed from the world of mathematics).

Furthermore, the access to the variable from within the closure ensures that the variable remains alive as long as the subroutine reference is alive. For example, let's number the output files:[27]

[27]This code seems to have an extra semicolon at the end of the line that assigns to $callback, doesn't it? But remember, the construct sub { ... } is an expression. Its value (a coderef) is assigned to $callback, and there's a semicolon at the end of that statement. It's easy to forget to put the proper punctuation after the closing curly brace of an anonymous subroutine declaration.

use File::Find;

my $callback;
{
  my $count = 0;
  $callback = sub { print ++$count, ": $File::Find::name\n" };
}
find($callback, ".");

Here, you declare a variable to hold the callback. This variable cannot be declared within the naked block (the block following that is not part of a larger Perl syntax construct), or it would be recycled at the end of that block. Next, the lexical $count variable is initialized to 0. An anonymous subroutine is then declared, and a reference to it is placed into $callback. This subroutine is a closure because it refers to the lexical $count variable.

At the end of the naked block, the $count variable goes out of scope. However, because it is still referenced by subroutine in $callback, it stays alive, now as an anonymous scalar variable.[28]

[28]To be more accurate, the closure declaration increases the reference count of the referent, as if another reference had been taken explicitly. Just before the end of the naked block, the reference count of $count is two, but after the block has exited, the value still has a reference count of one. Although no other code may access $count, it will still be kept in memory as long as the reference to the sub is available in $callback or elsewhere.

When the callback is invoked from find, the value of the variable formerly known as $count is incremented from 1 to 2 to 3, and so on.

Previous | Home | Next
6.3. Callbacks | Book Index | 6.5. Returning a Subroutine from a Subroutine
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.5. Returning a Subroutine from a Subroutine

Although a naked block worked nicely to define the callback, having a subroutine return that subroutine reference instead might be more useful:

use File::Find;

sub create_find_callback_that_counts {
  my $count = 0;
  return sub { print ++$count, ": $File::Find::name\n" };
}

my $callback = create_find_callback_that_counts( );
find($callback, ".");

It's the same process here, just written a bit differently. When you invoke create_find_callback_that_counts( ), a lexical variable $count is initialized to 0. The return value from that subroutine is a reference to an anonymous subroutine that is also a closure because it accesses the $count variable. Even though $count goes out of scope at the end of the create_find_callback_that_counts( ) subroutine, there's still a binding between it and the returned subroutine reference, so the variable stays alive until the subroutine reference is finally discarded.

If you reuse the callback, the same variable still has its most recently used value. The initialization occurred in the original subroutine (create_find_callback_that_counts), not the callback (unnamed) subroutine:

use File::Find;

sub create_find_callback_that_counts {
  my $count = 0;
  return sub { print ++$count, ": $File::Find::name\n" };
}

my $callback = create_find_callback_that_counts( );
print "my bin:\n";
find($callback, "bin");
print "my lib:\n";
find($callback, "lib");

This example prints consecutive numbers starting at 1 for the entries below my bin, but then continues the numbering when you start entries in lib. The same $count variable is used in both cases. However, if you invoke the create_find_callback_that_counts( ) twice, you get two different $count variables:

use File::Find;

sub create_find_callback_that_counts {
  my $count = 0;
  return sub { print ++$count, ": $File::Find::name\n" };
}

my $callback1 = create_find_callback_that_counts( );
my $callback2 = create_find_callback_that_counts( );
print "my bin:\n";
find($callback1, "bin");
print "my lib:\n";
find($callback2, "lib");

In this case, you have two separate $count variables, each accessed from within their own callback subroutine.

How would you get the total size of all found files from the callback? Earlier, you were able to do this by making $total_size visible. If you stick the definition of $total_size into the subroutine that returns the callback reference, you won't have access to the variable. But you can cheat a bit. For one thing, you can determine that the callback subroutine is never called with any parameters, so, if the subroutine is called with a parameter, you can make it return the total size:

use File::Find;

sub create_find_callback_that_sums_the_size {
  my $total_size = 0;
  return sub {
    if (@_) { # it's our dummy invocation
      return $total_size;
    } else { # it's a callback from File::Find:
      $total_size += -s if -f;
    }
  };
}

my $callback = create_find_callback_that_sums_the_size( );
find($callback, "bin");
my $total_size = $callback->("dummy"); # dummy parameter to get size
print "total size of bin is $total_size\n";

Distinguishing actions by the presence or absence of parameters is not a universal solution. Fortunately, more than one subroutine reference can be created in create_find_callback_that_counts( ):

use File::Find;

sub create_find_callbacks_that_sum_the_size {
  my $total_size = 0;
  return(sub { $total_size += -s if -f }, sub { return $total_size });
}

my ($count_em, $get_results) = create_find_callbacks_that_sum_the_size( );
find($count_em, "bin");
my $total_size = &$get_results( );
print "total size of bin is $total_size\n";

Because both subroutine references were created from the same scope, they both have access to the same $total_size variable. Even though the variable has gone out of scope before either subroutine is called, they still share the same heritage and can use the variable to communicate the result of the calculation.

The two subroutine references are not invoked by returning their references from the creating subroutine. The references are just data at that point. It's not until you invoke them as a callback or an explicit subroutine derefencing that they actually do their duty.

What if you invoke this new subroutine more than once?

use File::Find;

sub create_find_callbacks_that_sum_the_size {
  my $total_size = 0;
  return(sub { $total_size += -s if -f }, sub { return $total_size });
}

## set up the subroutines
my %subs;
foreach my $dir (qw(bin lib man)) {
  my ($callback, $getter) = create_find_callbacks_that_sum_the_size( );
  $subs{$dir}{CALLBACK} = $callback;
  $subs{$dir}{GETTER} = $getter;
}

## gather the data
for (keys %subs) {
  find($subs{$_}{CALLBACK}, $_);
}

## show the data
for (sort keys %subs) {
  my $sum = $subs{$_}{GETTER}->( );
  print "$_ has $sum bytes\n";
}

In the "set up the subroutines" section, you create three instances of callback-and-getter pairs. Each callback has a corresponding subroutine to get the results. Next, in the "gather the data" section, you call find three times with each corresponding callback subroutine reference. This updates the individual $total_size variables associated with each callback. Finally, in the "show the data" section, you call the getter routines to fetch the results.

The six subroutines (and the three $total_size variables they share) are reference-counted. When %subs goes away or is modified, the values have their reference counts reduced, recycling the contained data. (If that data also references further data, those reference counts are also reduced appropriately.)

Previous | Home | Next
6.4. Closures | Book Index | 6.6. Closure Variables as Inputs
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.6. Closure Variables as Inputs

While the previous examples showed closure variables being modified, closure variables are also useful to provide initial or lasting input to the subroutine. For example, let's write a subroutine to create a File::Find callback that prints files exceeding a certain size:

use File::Find;

sub print_bigger_than {
  my $minimum_size = shift;
  return sub { print "$File::Find::name\n" if -f and -s >= $minimum_size };
}

my $bigger_than_1024 = print_bigger_than(1024);
find($bigger_than_1024, "bin");

The 1024 parameter is passed into the print_bigger_than, which then gets shifted into the $minimum_size lexical variable. Because you access this variable within the subroutine referenced by the return value of the print_bigger_than variable, it becomes a closure variable, with a value that persists for the duration of that subroutine reference. Again, invoking this subroutine multiple times creates distinct "locked-in" values for $minimum_size, each bound to its corresponding subroutine reference.

Closures are "closed" only on lexical variables, since lexical variables eventually go out of scope. Because a package variable (which is a global) never goes out of scope, a closure never closes on a package variable. All subroutines refer to the same single instance of the global variable.

Previous | Home | Next
6.5. Returning a Subroutine from a Subroutine | Book Index | 6.7. Closure Variables as Static Local Variables
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.7. Closure Variables as Static Local Variables

A subroutine doesn't have to be an anonymous subroutine to be a closure. If a named subroutine accesses lexical variables and those variables go out of scope, the named subroutine retains a reference to the lexicals, just as you saw with anonymous subroutines. For example, consider two routines that count coconuts for Gilligan:

{
  my $count;
  sub count_one { ++$count }
  sub count_so_far { return $count }
}

If you place this code at the beginning of the program, the variable $count is declared, and the two subroutines that reference the variable become closures. However, because they have a name, they will persist beyond the end of the scope (as do all named subroutines). Since the subroutines persist beyond the scope and access variables declared within that scope, they become closures and thus can continue to access $count throughout the lifetime of the program.

So, with a few calls, you can see an incremented count:

count_one( );
count_one( );
count_one( );
print "we have seen ", count_so_far( ), " coconuts!\n";

$count retains its value between calls to count_one( ) or count_so_far( ), but no other section of code can access this $count at all.

In C, this is known as a static local variable: a variable that is visible to only a subset of the program's subroutines but persists throughout the life of the program, even between calls to those subroutines.

What if you wanted to count down? Something like this will do:

{
  my $countdown = 10;
  sub count_down { $countdown-- }
  sub count_remaining { $countdown }
}

count_down( );
count_down( );
count_down( );
print "we're down to ", count_remaining( ), " coconuts!\n";

That is, it'll do as long as you put it near the beginning of the program, before any invocations of count_down( ) or count_remaining( ). Why?

This block doesn't work when you put it after those invocations because there are two functional parts to the first line:

my $countdown = 10;

One part is the declaration of $countdown as a lexical variable. That part is noticed and processed as the program is parsed during the compile phase. The second part is the assignment of 10 to the allocated storage. This is handled as the code is executed during the run phase. Unless the run phase is executed for this code, the variable has its initial undef value.

One practical solution to this problem is to change the block in which the static local appears into a BEGIN block:

BEGIN {
  my $countdown = 10;
  sub count_down { $countdown-- }
  sub count_remaining { $countdown }
}

The BEGIN keyword tells the Perl compiler that as soon as this block has been parsed successfully (during the compile phase), jump for a moment to run phase and run the block as well. Presuming the block doesn't cause a fatal error, compilation then continues with the text following the block. The block itself is also discarded, ensuring that the code within is executed precisely once in a program, even if it had appeared syntactically within a loop or subroutine.

Previous | Home | Next
6.6. Closure Variables as Inputs | Book Index | 6.8. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


6.8. Exercise

The answers for all exercises can be found in Section A.5.

6.8.1. Exercise [30 min]

The Professor modified some files on Monday afternoon, and now he's forgotten which ones they were. This happens all the time. He wants you to make a subroutine called gather_mtime_between, which, given a starting and ending timestamp, returns a pair of coderefs. The first one will be used with File::Find to gather the names of only the items that were modified between those two times; the second one should return the list of items found.

Here's some code to try; it should list only items that were last modified on the most recent Monday, although you could easily change it to work with a different day. (You don't have to type all of this code. This program should be available as the file named ex6-1.plx in the downloadable files, available on the O'Reilly web site.)

Hint: You can find a file's timestamp (mtime) with code such as:

 my $timestamp = (stat $file_name)[9];

Because it's a slice, remember that those parentheses are mandatory. Don't forget that the working directory inside the callback isn't necessarily the starting directory in which find was called.

use File::Find;
use Time::Local;

my $target_dow = 1;        # Sunday is 0, Monday is 1, ...
my @starting_directories = (".");

my $seconds_per_day = 24 * 60 * 60;
my($sec, $min, $hour, $day, $mon, $yr, $dow) = localtime;
my $start = timelocal(0, 0, 0, $day, $mon, $yr);        # midnight today
while ($dow != $target_dow) {
  # Back up one day
  $start -= $seconds_per_day;        # hope no DST! :-)
  if (--$dow < 0) {
    $dow += 7;
  }
}
my $stop = $start + $seconds_per_day;

my($gather, $yield)  = gather_mtime_between($start, $stop);
find($gather, @starting_directories);
my @files = $yield->( );

for my $file (@files) {
  my $mtime = (stat $file)[9];        # mtime via slice
  my $when = localtime $mtime;
  print "$when: $file\n";
}

Note the comment about DST. In many parts of the world, on the days when daylight savings time or summer time kicks in and out, the day is no longer 86,400 seconds long. The program glosses over this issue, but a more pedantic coder might take it into consideration appropriately.

Previous | Home | Next
6.7. Closure Variables as Static Local Variables | Book Index | 7. Practical Reference Tricks
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 7. Practical Reference Tricks

Contents:

Review of Sorting
Sorting with Indices
Sorting Efficiently
The Schwartzian Transform
Recursively Defined Data
Building Recursively Defined Data
Displaying Recursively Defined Data
Exercises

This chapter looks at optimizing sorting and dealing with recursively defined data.

7.1. Review of Sorting

Perl's built-in sort operator sorts text strings in their natural text order, by default.[29]

[29]My friends call that the "ASCIIbetical" ordering. Normally modern Perl doesn't use ASCII; instead, it uses a default sort order, depending on the current locale and character set; see the perllocale (not perllocal!) manpage.

This is fine if you want to sort text strings:

my @sorted = sort qw(Gilligan Skipper Professor Ginger Mary_Ann);

but gets pretty messy when you want to sort numbers:

my @wrongly_sorted = sort 1, 2, 4, 8, 16, 32;

The resulting list is 1, 16, 2, 32, 4, 8. Why didn't sort order these properly? It treats each item as a string and sorts them in string order. Any string that begins with 3 sorts before any string that begins with 4.

You can fix this by overriding how Perl compares pairs of items in the list. By default, as Perl orders the items, a string comparison is used. A new comparison is specified using a sort block, placed between the sort keyword and the list of things to sort.[30]

[30]A sort block can also be specified as a subroutine name, causing the subroutine to be invoked when a comparison is needed.

Within the sort block, $a and $b stand in for two of the items to be sorted. The last evaluated expression must return a -1, 0, or +1 value.[31] If the value is -1, the value currently in $a must appear before the value in $b in the final sorted list. If the value is +1, then the value in $a must appear after the value in $b in the final sorted list. If the value is 0, you don't know or can't tell, so the results are unpredictable.[32]

[31]Actually, you can use any negative or positive number in place of -1 and +1, respectively.

[32]Recent Perl versions include a default sorting engine that is stable, so zero returns from the sort block cause the relative ordering of $a and $b to reflect their order in the original list. Older versions of Perl didn't guarantee such stability, and a future version might not use a stable sort, so don't rely on it.

For example, to sort those numbers in their proper order, you can use a sort block comparing $a and $b, like so:

my @numerically_sorted = sort {
  if ($a < $b)    { -1 }
  elsif ($a > $b) { +1 }
  else            {  0 }
} 1, 2, 4, 8, 16, 32;

Now you have a proper numeric comparison, so you have a proper numeric sort. Of course, this is far too much typing, so you can use the spaceship operator instead:

my @numerically_sorted = sort { $a <=> $b } 1, 2, 4, 8, 16, 32;

The spaceship operator returns -1, 0, and +1, according to the rules discussed. A descending sort is as simple as reversing the position of $a and $b:

my @numerically_descending = sort { $b <=> $a } 1, 2, 4, 8, 16, 32;

In every place the previous sort expression returned -1, this expression returns +1, and vice versa. Thus, the sort is in the opposite order. It's also easy to remember because if $a is to the left of $b, you get out the lower items first, just like a and b would be in the resulting list.

Likewise, a string sort can be indicated with cmp, although this is used less often because it is the default comparison. The cmp operator is handier when you have a more complex comparison, as you'll see shortly.

Previous | Home | Next
6.8. Exercise | Book Index | 7.2. Sorting with Indices
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.2. Sorting with Indices

In the same way you used indices to solve a few problems with grep and map back in Chapter 5, you can also use indices with sort to get some interesting results. For example, let's sort the list of names from earlier:

my @sorted = sort qw(Gilligan Skipper Professor Ginger Mary_Ann);
print "@sorted\n";

which necessarily results in:

Gilligan Ginger Mary_Ann Professor Skipper

But what if you wanted to look at the original list and determine which element of the original list now appears as the first, second, third, and so on, element of the sorted list? For example, Ginger is the second element of the sorted list and was the fourth element of the original list. How do you determine that the second element of the final list was the fourth element of the original list?

Well, you can apply a bit of indirection. Let's not sort the actual names but rather the indices of each name:

my @input = qw(Gilligan Skipper Professor Ginger Mary_Ann);
my @sorted_positions = sort { $input[$a] cmp $input[$b] } 0..$#input;
print "@sorted_positions\n";

This prints 0 3 4 2 1, which means that the first element of the sorted list is element 0 of the original list, Gilligan. The second element of the sorted list is element 3 of the original list, which is Ginger, and so on. Now you can rank information rather than just move the names around.

Actually, you have the inverse of the rank. You still don't know for a given name in the original list about which position it occupies in the output list. But with a bit more magic, you can get there as well:

my @input = qw(Gilligan Skipper Professor Ginger Mary_Ann);
my @sorted_positions = sort { $input[$a] cmp $input[$b] } 0..$#input;
my @ranks;
@ranks[@sorted_positions] = (0..$#sorted_positions);
print "@ranks\n";

The code prints 0 4 3 1 2. This means that Gilligan is position 0 in the output list, Skipper is position 4, Professor is position 2, and so on. The positions here are 0-based, so add 1 to get "human" ordinal values. One way to cheat is to use 1..@sorted_positions instead of 0..$#sorted_positions, so a way to dump it all out might look like:

my @input = qw(Gilligan Skipper Professor Ginger Mary_Ann);
my @sorted_positions = sort { $input[$a] cmp $input[$b] } 0..$#input;
my @ranks;
@ranks[@sorted_positions] = (1..@sorted_positions);
for (0..$#ranks) {
  print "$input[$_] sorts into position $ranks[$_]\n";
}

This results in:

Gilligan sorts into position 1
Skipper sorts into position 5
Professor sorts into position 4
Ginger sorts into position 2
Mary_Ann sorts into position 3
Previous | Home | Next
7. Practical Reference Tricks | Book Index | 7.3. Sorting Efficiently
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.3. Sorting Efficiently

As the Professor tries to maintain the community computing facility (built entirely out of bamboo, coconuts, and pineapples, and powered by a live monkey), he continues to discover that people are leaving entirely too much data on the single monkey-powered filesystem and decides to print a list of offenders.

The Professor has written a subroutine called ask_monkey_about( ) which is given a castaway's name and returns the number of pineapples of storage they use. You have to ask the monkey because he's in charge of the pineapples. An initial naive approach to find the offenders from greatest to least might be something like:

my @castaways =
  qw(Gilligan Skipper Professor Ginger Mary_Ann Thurston Lovey);
my @wasters = sort {
  ask_monkey_about($b) <=> ask_monkey_about($a)
} @castaways;

In theory, this would be fine. For the first pair of names (Gilligan and Skipper), you ask the monkey "how many pineapples does Gilligan have?" and "how many pineapples does Skipper have?" You get back two values from the monkey and use them to order Gilligan and Skipper in the final list.

However, at some point, you have to compare the number of pineapples that Gilligan has with another castaway as well. For example, suppose the pair is Ginger and Gilligan. Ask the monkey about Ginger, get a number back, and then ask the monkey about Gilligan...again. This will probably annoy the monkey a bit, since you already asked earlier. But you need to ask for each value two, three, or maybe even four times just to put the seven values into order.

This can be a problem because it irritates the monkey.

How do you keep the number of monkey requests to a minimum? Well, you can build a table first. Use a map with seven inputs and seven outputs, turning each castaway item into a separate array reference, with each referenced array consisting of the castaway name and the pineapple count reported by the monkey:

my @names_and_pineapples = map {
  [ $_, ask_monkey_about($_) ]
} @castaways;

At this point, you asked the monkey seven questions in a row, but that's the last time you have to talk to the monkey! You now have everything you need to finish the task.

For the next step, sort the arrayrefs, ordering them by the monkey-returned value:

my @sorted_names_and_pineapples = sort {
  $b->[1] <=> $a->[1];
} @names_and_pineapples;

In this subroutine, $a and $b are still two elements from the list of things to be sorted. When you're sorting numbers, $a and $b are numbers; when you're sorting references, $a and $b are references. Dereference them to get to the corresponding array itself, and pick out item 1 from the array (the monkey's pineapple value). Because $b appears to the left of $a, it'll be a descending sort as well. (You want a descending sort because the Professor wants the first name on the list to be the person who uses the most pineapples.)

You're almost done, but what if you just wanted the top names, rather than the names and pineapple counts? You merely need to perform another map to transform the references back to the original data:

my @names = map $_->[0], @sorted_names_and_pineapples;

Each element of the list ends up in $_, so you'll dereference that to pick out the element 0 of that array, which is just the name.

Now you have a list of names, ordered by their pineapple counts, and a calm monkey, all in three easy steps.

Previous | Home | Next
7.2. Sorting with Indices | Book Index | 7.4. The Schwartzian Transform
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.4. The Schwartzian Transform

The intermediate variables between each of these steps were not necessary, except as input to the next step. You can save yourself some brainpower by just stacking all the steps together:

my @names =
  map $_->[0],
  sort { $b->[1] <=> $a->[1] }
  map [ $_, ask_monkey_about($_) ],
  @castaways;

Because the map and sort operators are right to left, you have to read this construct from the bottom up. Take a list of @castaways, create some arrayrefs by asking the monkey a simple question, sort the list of arrayrefs, and then extract the names from each arrayref. This gives you the list of names in the desired order.

This construct is commonly called the Schwartzian Transform, which was named after me (but not by me), thanks to a Usenet posting I made many years ago. It has proven to be a very nice thing to have in your bag of sorting tricks.

If this transform looks like it might be too complex to memorize or come up with from first principles, it might help to look at the flexible and constant parts:

my @output_data =
  map $_->[0],
  sort { SORT COMPARISON USING $a->[1] AND $b->[1] }
  map [ $_, EXPENSIVE FUNCTION OF $_ ],
  @input_data;

The basic structure maps the original list into a list of arrayrefs, computing the expensive function only once for each; sorts those array refs, looking at the cached value of each expensive function invocation;[33] and then extracts the original values back out in the new order. All you have to do is plug in the proper two operations, and you're done.

[33]An expensive operation is one that takes a relatively long time or a relatively large amount of memory.

Previous | Home | Next
7.3. Sorting Efficiently | Book Index | 7.5. Recursively Defined Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.5. Recursively Defined Data

While the data you've processed with references up to this point has been rather fixed-structure, sometimes you have to deal with hierarchical data, which is often defined recursively.

For example, a company organization chart has managers with direct reports, some of whom may also be managers themselves, or an HTML table that has rows containing cells—and some of those cells may also contain entire tables. The chart could also show a filesystem consisting of directories containing files and other directories.

You can use references to acquire, store, and process such hierarchical information. Frequently, the routines to manage the data structures end up as recursive subroutines. A recursive subroutine has a branch from which it calls itself to handle a portion of the task, and a branch that doesn't call itself to handle the base cases.

For example, a recursive subroutine handling the factorial function, which is one of the simplest recursive functions, might look like:

sub factorial {
  my $n = shift;
  if ($n <= 1) {
    return 1;
  } else {
    return $n * factorial($n - 1);
  }
}

Here you have a base case where $n is less than or equal to 1, that does not invoke the recursive instance, along with a recursive case for $n greater than 1, which calls the routine to handle a portion of the problem (i.e., compute the factorial of the next lower number).

This task would probably be solved better using iteration rather than recursion, even though the classic definition of factorial is often given as a recursive operation.

Previous | Home | Next
7.4. The Schwartzian Transform | Book Index | 7.6. Building Recursively Defined Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.6. Building Recursively Defined Data

Suppose you wanted to capture information about a filesystem, including the filenames and directory names, and their included contents. Represent a directory as a hash, in which the keys are the names of the entries within the directory, and values are undef for plain files. A sample /bin directory might look like:

my $bin_directory = {
  "cat" => undef,
  "cp" => undef,
  "date" => undef,
  ... and so on ...
};

Similarly, the Skipper's home directory might also contain a personal bin directory (at something like ~skipper/bin) that contains personal tools:

my $skipper_bin = {
  "navigate" => undef,
  "discipline_gilligan" => undef,
  "eat" => undef,
};

nothing in either structure tells where the directory is located in the hierarchy. It just represents the contents of some directory.

Go up one level to the Skipper's home directory, which is likely to contain a few files along with the personal bin directory:

my $skipper_home = {
  ".cshrc" => undef,
  "Please_rescue_us.pdf" => undef,
  "Things_I_should_have_packed" => undef,
  "bin" => $skipper_bin,
};

Ahh, notice that you have three files, but the fourth entry "bin" doesn't have undef for a value but rather the hash reference created earlier for the Skipper's personal bin directory. This is how you indicate subdirectories. If the value is undef, it's a plain file; if it's a hash reference, you have a subdirectory, with its own files and subdirectories. Of course, you can have combined these two initializations:

my $skipper_home = {
  ".cshrc" => undef,
  "Please_rescue_us.pdf" => undef,
  "Things_I_should_have_packed" => undef,
  "bin" => {
    "navigate" => undef,
    "discipline_gilligan" => undef,
    "eat" => undef,
  },
};

Now the hierarchical nature of the data starts to come into play.

Obviously, you don't want to create and maintain a data structure by changing literals in the program. You should fetch the data by using a subroutine. Write a subroutine that for a given pathname returns undef if the path is a file, or a hash reference of the directory contents if the path is a directory. The base case of looking at a file is the easiest, so let's write that:

sub data_for_path {
  my $path = shift;
  if (-f $path) {
    return undef;
  }
  if (-d $path) {
    ...
  }
  warn "$path is neither a file nor a directory\n";
  return undef;
}

If the Skipper calls this on .cshrc, he'll get back an undef value, indicating that a file was seen.

Now for the directory part. You need a hash reference to be returned, which you declare as a named hash inside the subroutine. For each element of the hash, you call yourself to populate the value of that hash element. It goes something like this:

sub data_for_path {
  my $path = shift;
  if (-f $path or -l $path) {        # files or symbolic links
    return undef;
  }
  if (-d $path) {
    my %directory;
    opendir PATH, $path or die "Cannot opendir $path: $!";
    my @names = readdir PATH;
    closedir PATH;
    for my $name (@names) {
      next if $name eq "." or $name eq "..";
      $directory{$name} = data_for_path("$path/$name");
    }
    return \%directory;
  }
  warn "$path is neither a file nor a directory\n";
  return undef;
}

For each file within the directory being examined, the response from the recursive call to data_for_path is undef. This populates most elements of the hash. When the reference to the named hash is returned, the reference becomes a reference to an anonymous hash because the name immediately goes out of scope. (The data itself doesn't change, but the number of ways in which you can access the data changes.)

If there is a subdirectory, the nested subroutine call uses readdir to extract the contents of that directory and returns a hash reference, which is inserted into the hash structure created by the caller.

At first, it may look a bit mystifying, but if you walk through the code slowly, you'll see it's always doing the right thing.

Test the results of this subroutine by calling it on . (the current directory) and seeing the result:

use Data::Dumper;
print Dumper(data_for_path("."));

Obviously, this will be more interesting if your current directory contains subdirectories.

Previous | Home | Next
7.5. Recursively Defined Data | Book Index | 7.7. Displaying Recursively Defined Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.7. Displaying Recursively Defined Data

The Dumper routine of Data::Dumper displays the output nicely, but what if you don't like the format being used? You can write a routine to display the data. Again, for recursively defined data, a recursive subroutine is usually the key.

To dump the data, you need to know the name of the directory at the top of the tree because that's not stored within the structure:

sub dump_data_for_path {
  my $path = shift;
  my $data = shift;
  if (not defined $data) { # plain file
    print "$path\n";
    return;
  }
  ...
}

For a plain file, dump the pathname; for a directory, $data is a hash reference. Let's walk through the keys and dump the values:

sub dump_data_for_path {
  my $path = shift;
  my $data = shift;
  if (not defined $data) { # plain file
    print "$path\n";
    return;
  }
  my %directory = %$data;
  for (sort keys %directory) {
    dump_data_for_path("$path/$_", $directory{$_});
  }
}

For each element of the directory, you pass a path consisting of the incoming path followed by the current directory entry, and the data pointer is either undef for a file or a subdirectory hash reference for another directory. You can see the results by running:

dump_data_for_path(".", data_for_path("."));

Again, this is more interesting in a directory that has subdirectories, but the output should be similar to:

find . -print

from the shell prompt.

Previous | Home | Next
7.6. Building Recursively Defined Data | Book Index | 7.8. Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


7.8. Exercises

The answers for all exercises can be found in Section A.6.

7.8.1. Exercise 1 [15 min]

Using the glob operator, a naive sort of every name in the /bin directory by their relative sizes might be written as:

my @sorted = sort { -s $a <=> -s $b } glob "/bin/*";

Rewrite this using the Schwartzian Transform technique.

If you don't have many files in the /bin directory, perhaps because you don't have a Unix machine, change the argument to glob as needed.

7.8.2. Exercise 2 [15 min]

Read up on the Benchmark module, included with Perl. Write a program that will answer the question, "How much does using the Schwartzian Transform speed up the task of Exercise 1?"

7.8.3. Exercise 3 [10 min]

Using a Schwartzian Transform, read a list of words, and sort them in "dictionary order." Dictionary order ignores all capitalization and internal punctuation. Hint: The following transformation might be useful:

my $string = "Mary-Ann";
$string =~ tr/A-Z/a-z/;       # force all lowercase
$string =~ tr/a-z//cd;        # strip all but a-z from the string
print $string;                # prints "maryann"

Be sure you don't mangle the data! If the input includes the Professor, and The skipper, the output should have them listed in that order, with that capitalization.

7.8.4. Exercise 4 [20 min]

Modify the recursive directory dumping routine so it shows the nested directories through indentation. An empty directory should show up as:

sandbar, an empty directory

while a nonempty directory should appear with nested contents, indented two spaces:

uss_minnow, with contents:
  anchor
  broken_radio
  galley, with contents:
    captain_crunch_cereal
    gallon_of_milk
    tuna_fish_sandwich
  life_preservers
Previous | Home | Next
7.7. Displaying Recursively Defined Data | Book Index | 8. Introduction to Objects
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 8. Introduction to Objects

Contents:

If We Could Talk to the Animals...
Introducing the Method Invocation Arrow
The Extra Parameter of Method Invocation
Calling a Second Method to Simplify Things
A Few Notes About @ISA
Overriding the Methods
Starting the Search from a Different Place
The SUPER Way of Doing Things
What to Do with @_
Where We Are So Far...
Exercises

Object-oriented programming (often called OOP) helps programmers run code sooner and maintain it easier at the cost of making the resulting programs slower. That is to say, a typical program written in an OO language will normally run more slowly than the corresponding one written in a language without objects.

So why would anyone want their programs to run more slowly? Your programs will take less time to read, write, debug, and maintain, and on large projects, these factors are important. How much slowdown are we talking about? Well, that depends. But in general, the more heavily you use objects, the more it will save time for the programmer, and the more it will cost time at runtime. Still, you should remember that computers keep getting faster. Even if using OOP slows down your program, using next year's hardware will probably make up for it.

The benefits of OOP become worthwhile when your program (including all external libraries and modules) exceeds about N lines of code. Unfortunately, nobody can agree on what the value of N is, but for Perl programs, it's arguably around 1,000 lines of code. If your whole program is only be a couple hundred lines of code, using objects is probably a waste.

Like references, Perl's object architecture was grafted on after a substantial amount of existing pre-Perl5 code was already in use, so we had to ensure that it wouldn't break existing syntax. Amazingly, the only additional syntax to achieve object nirvana is the method call, introduced shortly. But the meaning of that syntax requires a bit of study, so let's proceed.

The Perl object architecture relies heavily on packages, subroutines, and references, so if you're skipping around in this book, please go back to the beginning. Ready? Here we go.

8.1. If We Could Talk to the Animals...

Obviously, the castaways can't survive on coconuts and pineapples alone. Luckily for them, a barge carrying random farm animals crashed on the island not long after they arrived, and the castaways began farming and raising animals.

Let's let those animals talk for a moment:

sub Cow::speak {
  print "a Cow goes moooo!\n";
}
sub Horse::speak {
  print "a Horse goes neigh!\n";
}
sub Sheep::speak {
  print "a Sheep goes baaaah!\n";
}

Cow::speak;
Horse::speak;
Sheep::speak;

This results in:

a Cow goes moooo!
a Horse goes neigh!
a Sheep goes baaaah!

Nothing spectacular here: simple subroutines, albeit from separate packages, and called using the full package name. Let's create an entire pasture:

sub Cow::speak {
  print "a Cow goes moooo!\n";
}
sub Horse::speak {
  print "a Horse goes neigh!\n";
}
sub Sheep::speak {
  print "a Sheep goes baaaah!\n";
}

my @pasture = qw(Cow Cow Horse Sheep Sheep);
foreach my $beast (@pasture) {
  &{$beast."::speak"};                # Symbolic coderef
}

This results in:

a Cow goes moooo!
a Cow goes moooo!
a Horse goes neigh!
a Sheep goes baaaah!
a Sheep goes baaaah!

Wow. That symbolic coderef dereferencing there in the body of the loop is pretty nasty. We're counting on no strict 'refs' mode, certainly not recommended for larger programs.[34] And why was that necessary? Because the name of the package seems inseparable from the name of the subroutine you want to invoke within that package.

[34]Although all examples in this book should be valid Perl code, some examples in this chapter will break the rules enforced by use strict to make them easier to understand. By the end of the chapter, though, you'll learn how to make strict-compliant code again.

Or is it?

Previous | Home | Next
7.8. Exercises | Book Index | 8.2. Introducing the Method Invocation Arrow
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.2. Introducing the Method Invocation Arrow

A class is a group of things with similar behaviors and traits. For now, let's say that Class->method invokes subroutine method in package Class. That's not completely accurate, but you'll catch on one step at a time. Let's use it like so:

sub Cow::speak {
  print "a Cow goes moooo!\n";
}
sub Horse::speak {
  print "a Horse goes neigh!\n";
}
sub Sheep::speak {
  print "a Sheep goes baaaah!\n";
}

Cow->speak;
Horse->speak;
Sheep->speak;

And once again, this results in:

a Cow goes moooo!
a Horse goes neigh!
a Sheep goes baaaah!

That's not fun yet. You've got the same number of characters, all constant, no variables. However, the parts are separable now:

my $beast = "Cow";
$beast->speak;                # invokes Cow->speak

Ahh! Now that the package name is separated from the subroutine name, you can use a variable package name. This time, you've got something that works even when use strict 'refs' is enabled.

Take the arrow invocation and put it back in the barnyard example:

sub Cow::speak {
  print "a Cow goes moooo!\n";
}
sub Horse::speak {
  print "a Horse goes neigh!\n";
}
sub Sheep::speak {
  print "a Sheep goes baaaah!\n";
}

my @pasture = qw(Cow Cow Horse Sheep Sheep);
foreach my $beast (@pasture) {
  $beast->speak;
}

There! Now all the animals are talking, and safely at that, without the use of symbolic coderefs.

But look at all that common code. Each speak routine has a similar structure: a print operator and a string that contains common text, except for two words. One of OOP's core features minimizes common code: if you write it only once, you'll save time. If you test and debug it only once, you'll save more time.

Now that you've learned more about what the method invocation arrow actually does, we've got an easier way to do the same thing.

Previous | Home | Next
8. Introduction to Objects | Book Index | 8.3. The Extra Parameter of Method Invocation
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.3. The Extra Parameter of Method Invocation

The invocation of:

Class->method(@args)

attempts to invoke the subroutine Class::method as:

Class::method("Class", @args);

(If the subroutine can't be found, inheritance kicks in, but you'll learn about that later.) This means that you get the class name as the first parameter or the only parameter, if no arguments are given. You can rewrite the Sheep speaking subroutine as:

sub Sheep::speak {
  my $class = shift;
  print "a $class goes baaaah!\n";
}

The other two animals come out similarly:

sub Cow::speak {
  my $class = shift;
  print "a $class goes moooo!\n";
}
sub Horse::speak {
  my $class = shift;
  print "a $class goes neigh!\n";
}

In each case, $class gets the value appropriate for that subroutine. But once again, you have a lot of similar structure. Can you factor out that commonality even further? Yes—by calling another method in the same class.

Previous | Home | Next
8.2. Introducing the Method Invocation Arrow | Book Index | 8.4. Calling a Second Method to Simplify Things
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.4. Calling a Second Method to Simplify Things

You can call out from speak to a helper method called sound. This method provides the constant text for the sound itself:

{ package Cow;
  sub sound { "moooo" }
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}

Now, when you call Cow->speak, you get a $class of Cow in speak. This, in turn, selects the Cow->sound method, which returns moooo. How different would this be for the Horse?

{ package Horse;
  sub sound { "neigh" }
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}

Only the name of the package and the specific sound change. So can you share the definition for speak between the cow and the horse? Yes, with inheritance!

Now let's define a common subroutine package called Animal with the definition for speak:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}

Then, for each animal, you can say it inherits from Animal, along with the animal-specific sound:

{ package Cow;
  @ISA = qw(Animal);
  sub sound { "moooo" }
}

Note the added @ISA array. We'll get to that in a minute.

What happens when you invoke Cow->speak now?

First, Perl constructs the argument list. In this case, it's just Cow. Then Perl looks for Cow::speak. That's not there, so Perl checks for the inheritance array @Cow::ISA. It's there, and contains the single name Animal.

Perl next checks for speak inside Animal instead, as in Animal::speak. That found, Perl invokes that subroutine with the already frozen argument list, as if you had said:

Animal::speak("Cow");

Inside the Animal::speak subroutine, $class becomes Cow as the first argument is shifted off. When you get to the step of invoking $class->sound while performing the print, it looks for Cow->sound:

print "a $class goes ", $class->sound, "!\n";
# but $class is Cow, so...
print "a Cow goes ", Cow->sound, "!\n";
# which invokes Cow->sound, returning "moooo", so
print "a Cow goes ", "moooo", "!\n";

and you get your desired output.

Previous | Home | Next
8.3. The Extra Parameter of Method Invocation | Book Index | 8.5. A Few Notes About @ISA
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.5. A Few Notes About @ISA

This magical @ISA variable (pronounced "is a" not "ice-uh"), declares that Cow "is a" Animal.[35] Note that it's an array, not a simple single value, because on rare occasions it makes sense to have more than one parent class searched for the missing methods. You'll learn more about that later.

[35]ISA is actually a linguistic term. Once again, Larry Wall's background as a linguist has come back to influence Perl.

If Animal also had an @ISA, you can check there too.[36] Typically, each @ISA has only one element (multiple elements means multiple inheritance and multiple headaches), so you get a nice tree of inheritance. (There is also inheritance through UNIVERSAL and AUTOLOAD; see the perlobj manpage for the whole story.)

[36]The search is recursive, depth-first and left to right in each @ISA.

When you turn on use strict, you'll get complaints on @ISA because it's not a variable containing an explicit package name, nor is it a lexical (my) variable. You can't make it a lexical variable though: it has to belong to the package to be found by the inheritance mechanism.

There are a couple of straightforward ways to handle the declaration and setting of @ISA. The easiest is to just spell out the package name:

@Cow::ISA = qw(Animal);

You can also allow it as an implicitly named package variable:

package Cow;
use vars qw(@ISA);
@ISA = qw(Animal);

If you're on a recent-enough Perl (5.6 or later), you can use the our declaration to shorten it to:

package Cow;
our @ISA = qw(Animal);

However, if you think your code might be used by people stuck with Perl 5.005 or earlier, it's be best to avoid our.

If you're bringing in the class from outside, via an object-oriented module, change:

package Cow;
use Animal;
use vars qw(@ISA);
@ISA = qw(Animal);

to just:

package Cow;
use base qw(Animal);

That's pretty darn compact. Furthermore, use base has the advantage that it's performed at compile time, eliminating a few potential errors from setting @ISA at runtime, like some of the other solutions.

Previous | Home | Next
8.4. Calling a Second Method to Simplify Things | Book Index | 8.6. Overriding the Methods
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.6. Overriding the Methods

Let's add a mouse that can barely be heard:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}
{ package Mouse;
  @ISA = qw(Animal);
  sub sound { "squeak" }
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
    print "[but you can barely hear it!]\n";
  }
}

Mouse->speak;

which results in:

a Mouse goes squeak!
[but you can barely hear it!]

Here, Mouse has its own speaking routine, so Mouse->speak doesn't immediately invoke Animal->speak. This is known as overriding. You use overriding to shadow the method in the derived class (Mouse) because you have a specialized version of the routine, instead of calling the more general base class's method (in Animal). In fact, you didn't even need to initialize @Mouse::ISA to say that a Mouse was an Animal at all because all the methods needed for speak are defined completely with Mouse.

You've now duplicated some of the code from Animal->speak; this can be a maintenance headache. For example, suppose someone decides that the word goes in the output of the Animal class is a bug. Now the maintainer of that class changes goes to says. Your mice will still say goes, which means the code still has the bug. The problem is that you invoked cut and paste to duplicate code, and in OOP, that is a sin. You should reuse code through inheritance, not by cut and paste.

How can you avoid that? Can you say somehow that a Mouse does everything any other Animal does, but add in the extra comment? Sure!

As your first attempt, you can invoke the Animal::speak method directly:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}
{ package Mouse;
  @ISA = qw(Animal);
  sub sound { "squeak" }
  sub speak {
    my $class = shift;
    Animal::speak($class);
    print "[but you can barely hear it!]\n";
  }
}

Note that because you've stopped using the method arrow, you have to include the $class parameter (almost surely the value of "Mouse") as the first parameter to Animal::speak,.

Why did you stop using the arrow? Well, if you invoke Animal->speak there, the first parameter to the method is "Animal," not "Mouse", and when the time comes for it to call for the sound, it won't have the right class to select the proper methods for this object.

Invoking Animal::speak directly is a mess, however. What if Animal::speak didn't exist before and was inherited from a class mentioned in @Animal::ISA? For example, suppose the code was:

{ package LivingCreature;
  sub speak { ... }
  ...
}
{ package Animal;
  @ISA = qw(LivingCreature);
  # no definition for speak( )
  ...
}
{ package Mouse;
  @ISA = qw(Animal);
  sub speak {
    ...
    Animal::speak(  ... );
  }
  ...
}

Because you no longer use the method arrow, you get one and only one chance to hit the right subroutine. You'll look for it in Animal, and not find it, and the program aborts.

The Animal classname is now hardwired into the subroutine selection. This is a mess if someone maintains the code, changing @ISA for Mouse, and didn't notice Animal there in speak. Thus, this is probably not the right way to go.

Previous | Home | Next
8.5. A Few Notes About @ISA | Book Index | 8.7. Starting the Search from a Different Place
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.7. Starting the Search from a Different Place

A better solution is to tell Perl to search from a different place in the inheritance chain:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}
{ package Mouse;
  @ISA = qw(Animal);
  sub sound { "squeak" }
  sub speak {
    my $class = shift;
    $class->Animal::speak(@_);
    print "[but you can barely hear it!]\n";
  }
}

Ahh. As ugly as this is, it works. Using this syntax, start with Animal to find speak and use all of Animal's inheritance chain if not found immediately. The first parameter is $class (because you're using an arrow again), so the found speak method gets Mouse as its first entry and eventually works its way back to Mouse::sound for the details.

This isn't the best solution, however. You still have to keep the @ISA and the initial search package in sync (changes in one must be considered for changes in the other). Worse, if Mouse had multiple entries in @ISA, you wouldn't necessarily know which one had actually defined speak.

So, is there an even better way?

Previous | Home | Next
8.6. Overriding the Methods | Book Index | 8.8. The SUPER Way of Doing Things
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.8. The SUPER Way of Doing Things

By changing the Animal class to the SUPER class in that invocation, you get a search of all your superclasses (classes listed in @ISA) automatically:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}
{ package Mouse;
  @ISA = qw(Animal);
  sub sound { "squeak" }
  sub speak {
    my $class = shift;
    $class->SUPER::speak;
    print "[but you can barely hear it!]\n";
  }
}

Thus, SUPER::speak means to look in the current package's @ISA for speak, invoking the first one found if there's more than one. In this case, you look in the one and only base class, Animal, find Animal::speak, and pass it "Mouse" as its only parameter.

Previous | Home | Next
8.7. Starting the Search from a Different Place | Book Index | 8.9. What to Do with @_
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.9. What to Do with @_

In that last example, had there been any additional parameters to the speak routine (like how many times, or in what pitch for singing, for example), the parameters would be ignored by the Mouse::speak routine. If you want them to be passed uninterpreted to the parent class, you can add it as a parameter:

$class->SUPER::speak(@_);

This invokes the speak routine of the parent class, including all the parameters that you've not yet shifted off of your parameter list.

Which one is correct? It depends. If you are writing a class that simply adds to some of the parent class behavior, it's best to simply pass along arguments you haven't dealt with. However, if you want precise control over the parent class behavior, you should determine the argument list explicitly, and pass it.

Previous | Home | Next
8.8. The SUPER Way of Doing Things | Book Index | 8.10. Where We Are So Far...
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.10. Where We Are So Far...

So far, you've seen the method arrow syntax:

Class->method(@args);

or the equivalent:

my $beast = "Class";
$beast->method(@args);

which constructs an argument list of:

("Class", @args)

and attempts to invoke:

Class::method("Class", @args);

However, if Class::method is not found, @Class::ISA is examined (recursively) to locate a package that does indeed contain method, and that subroutine is invoked instead.

Chapter 9 shows how to distinguish the individual animals by giving them associated properties, called instance variables.

Previous | Home | Next
8.9. What to Do with @_ | Book Index | 8.11. Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


8.11. Exercises

The answers for all exercises can be found in Section A.7.

8.11.1. Exercise 1 [20 min]

Type in the Animal, Cow, Horse, Sheep, and Mouse class definitions. Make it work with use strict. Use our if you're using a recent enough version of Perl. Your program should ask the user to enter the names of one or more barnyard animals. Create a barnyard with those animals, and have each animal speak once.

8.11.2. Exercise 2 [40 min]

Add a Person class at the same level as Animal, and have both of them inherit from a new class called LivingCreature. Also make the speak method take a parameter of what to say, falling back to the sound (humming for a Person) if no parameter is given. Since this isn't Dr. Doolittle, make sure the animals can't talk. (That is, don't let speak have any parameters for an animal.) Try not to duplicate any code, but be sure to catch likely errors of usage, such as forgetting to define a sound for an animal.

Demonstrate the Person class by invoking a person with nothing to say, and then demonstrate it a second time by invoking a person with something to say.

Previous | Home | Next
8.10. Where We Are So Far... | Book Index | 9. Objects with Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 9. Objects with Data

Contents:

A Horse Is a Horse, of Course of Course—or Is It?
Invoking an Instance Method
Accessing the Instance Data
How to Build a Horse
Inheriting the Constructor
Making a Method Work with Either Classes or Instances
Adding Parameters to a Method
More Interesting Instances
A Horse of a Different Color
Getting Your Deposit Back
Don't Look Inside the Box
Faster Getters and Setters
Getters That Double as Setters
Restricting a Method to Class-Only or Instance-Only
Exercise

Using the simple syntax introduced in Chapter 8, you have class methods, (multiple) inheritance, overriding, and extending. You've been able to factor out common code and provide a way to reuse implementations with variations. This is at the core of what objects provide, but objects also provide instance data, which we haven't even begun to cover.

9.1. A Horse Is a Horse, of Course of Course—or Is It?

Let's look at the code used in Chapter 8 for the Animal classes and Horse classes:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n"
  }
}
{ package Horse;
  @ISA = qw(Animal);
  sub sound { "neigh" }
}

This lets you invoke Horse->speak to ripple upward to Animal::speak, calling back to Horse::sound to get the specific sound, and the output of:

a Horse goes neigh!

But all Horse objects would have to be absolutely identical. If you add a subroutine, all horses automatically share it. That's great for making horses identical, but how do you capture the properties of an individual horse? For example, suppose you want to give your horse a name. There's got to be a way to keep its name separate from those of other horses.

You can do so by establishing an instance. An instance is generally created by a class, much like a car is created by a car factory. An instance will have associated properties, called instance variables (or member variables, if you come from a C++ or Java background). An instance has a unique identity (like the serial number of a registered horse), shared properties (the color and talents of the horse), and common behavior (i.e., pulling the reins back tells the horse to stop).

In Perl, an instance must be a reference to one of the built-in types. Start with the simplest reference that can hold a horse's name: a scalar reference:[37]

[37]The simplest, but rarely used in real code for reasons you'll see shortly

my $name = "Mr. Ed";
my $tv_horse = \$name;

Now $tv_horse is a reference to what will be the instance-specific data (the name). The final step in turning this into a real instance involves a special operator called bless:

bless $tv_horse, "Horse";

The bless operator follows the reference to find what variable it points to—in this case the scalar $name. Then it "blesses" that variable, turning $tv_horse into an object —a Horse object, in fact. (Imagine that a little sticky-note that says Horse is now attached to $name.)

At this point, $tv_horse is an instance of Horse.[38] That is, it's a specific horse. The reference is otherwise unchanged and can still be used with traditional dereferencing operators.[39]

[38]Actually, $tv_horse points to the object, but in common terms, you nearly always deal with objects by references to those objects. Hence, it's simpler to say that $tv_horse is the horse, not "the thing that $tv_horse is referencing."

[39]Although doing so outside the class is a bad idea, as you'll see later.

Previous | Home | Next
8.11. Exercises | Book Index | 9.2. Invoking an Instance Method
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.2. Invoking an Instance Method

The method arrow can be used on instances, as well as names of packages (classes). Let's get the sound that $tv_horse makes:

my $noise = $tv_horse->sound;

To invoke sound, Perl first notes that $tv_horse is a blessed reference, and thus an instance. Perl then constructs an argument list, similar to the way an argument list was constructed when you used the method arrow with a class name. In this case, it'll be just ($tv_horse). (Later you'll see that arguments will take their place following the instance variable, just as with classes.)

Now for the fun part: Perl takes the class in which the instance was blessed, in this case Horse, and uses it to locate the subroutine to invoke the method, as if you had said Horse->sound instead of $tv_horse->sound. The purpose of the original blessing is to associate a class with that reference to allow the proper method (subroutine) to be found.

In this case, Horse::sound is found directly (without using inheritance), yielding the final subroutine invocation:

Horse::sound($tv_horse)

Note that the first parameter here is still the instance, not the name of the class as before. neigh is the return value, which ends up as the earlier $noise variable.

If Horse::sound had not been found, you'd wander up the @Horse::ISA list to try to find the method in one of the superclasses, just as for a class method. The only difference between a class method and an instance method is whether the first parameter is an instance (a blessed reference) or a class name (a string).[40]

[40]This is perhaps different from other OOP languages with which you may be familiar.

Previous | Home | Next
9. Objects with Data | Book Index | 9.3. Accessing the Instance Data
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.3. Accessing the Instance Data

Because you get the instance as the first parameter, you can now access the instance-specific data. In this case, let's add a way to get at the name:

{ package Horse;
  @ISA = qw(Animal);
  sub sound { "neigh" }
  sub name {
    my $self = shift;
    $$self;
  }
}

Now you call for the name:

print $tv_horse->name, " says ", $tv_horse->sound, "\n";

Inside Horse::name, the @_ array contains just $tv_horse, which the shift stores into $self. It's traditional to shift the first parameter into a variable named $self for instance methods, so stay with that unless you have strong reasons otherwise. Perl places no significance on the name $self, however.[41]

[41]If you come from another OO language background, you might choose $this or $me for the variable name, but you'll probably confuse most other Perl OO-hackers.

Then $self is dereferenced as a scalar reference, yielding Mr. Ed. The result is:

Mr. Ed says neigh.
Previous | Home | Next
9.2. Invoking an Instance Method | Book Index | 9.4. How to Build a Horse
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.4. How to Build a Horse

If you constructed all your horses by hand, you'd most likely make mistakes from time to time. Making the "inside guts" of a Horse visible also violates one of the principles of OOP. That's good if you're a veterinarian but not if you just like to own horses. Let the Horse class build a new horse:

{ package Horse;
  @ISA = qw(Animal);
  sub sound { "neigh" }
  sub name {
    my $self = shift;
    $$self;
  }
  sub named {
    my $class = shift;
    my $name = shift;
    bless \$name, $class;
  }
}

Now with the new named method, build a Horse:

my $tv_horse = Horse->named("Mr. Ed");

You're back to a class method, so the two arguments to Horse::named are "Horse" and "Mr. Ed". The bless operator not only blesses $name, it also returns the reference to $name, so that's fine as a return value. And that's how to build a horse.

You called the constructor named here so it quickly denotes the constructor's argument as the name for this particular Horse. You can use different constructors with different names for different ways of "giving birth" to the object (such as recording its pedigree or date of birth). However, you'll find that most people coming to Perl from less-flexible languages (such as Java or C++) use a single constructor named new, with various ways of interpreting the arguments to new. Either style is fine, as long as you document your particular way of giving birth to an object. Most core and CPAN modules use new, with notable exceptions, such as DBI's DBI->connect( ). It's really up to the author. It all works, as long as it's documented.

Previous | Home | Next
9.3. Accessing the Instance Data | Book Index | 9.5. Inheriting the Constructor
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.5. Inheriting the Constructor

Was there anything specific to Horse in that method? No. Therefore, it's also the same recipe for building anything else inherited from Animal, so let's put it there:

{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n"
  }
  sub name {
    my $self = shift;
    $$self;
  }
  sub named {
    my $class = shift;
    my $name = shift;
    bless \$name, $class;
  }
}
{ package Horse;
  @ISA = qw(Animal);
  sub sound { "neigh" }
}

Ahh, but what happens if you invoke speak on an instance?

my $tv_horse = Horse->named("Mr. Ed");
$tv_horse->speak;

You get a debugging value:

a Horse=SCALAR(0xaca42ac) goes neigh!

Why? Because the Animal::speak routine expects a classname as its first parameter, not an instance. When the instance is passed in, you'll use a blessed scalar reference as a string, which shows up as you saw it just now—similar to a stringified reference, but with the class name in front.

Previous | Home | Next
9.4. How to Build a Horse | Book Index | 9.6. Making a Method Work with Either Classes or Instances
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.6. Making a Method Work with Either Classes or Instances

All you need to fix this is a way to detect whether the method is called on a class or an instance. The most straightforward way to find out is with the ref operator. This operator returns a string (the classname) when used on a blessed reference, and undef when used on a string (like a classname). Modify the name method first to notice the change:

sub name {
  my $either = shift;
  ref $either
    ? $$either                # it's an instance, return name
    : "an unnamed $either";   # it's a class, return generic
}

Here the ?: operator selects either the dereference or a derived string. Now you can use it with either an instance or a class. Note that you changed the first parameter holder to $either to show that it is intentional:

print Horse->name, "\n";      # prints "an unnamed Horse\n"

my $tv_horse = Horse->named("Mr. Ed");
print $tv_horse->name, "\n";   # prints "Mr Ed.\n"

and now you'll fix speak to use this:

sub speak {
  my $either = shift;
  print $either->name, " goes ", $either->sound, "\n";
}

Since sound already worked with either a class or an instance, you're done!

Previous | Home | Next
9.5. Inheriting the Constructor | Book Index | 9.7. Adding Parameters to a Method
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.7. Adding Parameters to a Method

Let's train your animals to eat:

{ package Animal;
  sub named {
    my $class = shift;
    my $name = shift;
    bless \$name, $class;
  }
  sub name {
    my $either = shift;
    ref $either
      ? $$either # it's an instance, return name
      : "an unnamed $either"; # it's a class, return generic
  }
  sub speak {
    my $either = shift;
    print $either->name, " goes ", $either->sound, "\n";
  }
  sub eat {
    my $either = shift;
    my $food = shift;
    print $either->name, " eats $food.\n";
  }
}
{ package Horse;
  @ISA = qw(Animal);
  sub sound { "neigh" }
}
{ package Sheep;
  @ISA = qw(Animal);
  sub sound { "baaaah" }
}

Now try it out:

my $tv_horse = Horse->named("Mr. Ed");
$tv_horse->eat("hay");
Sheep->eat("grass");

It prints:

Mr. Ed eats hay.
an unnamed Sheep eats grass.

An instance method with parameters gets invoked with the instance, and then the list of parameters. That first invocation is like:

Animal::eat($tv_horse, "hay");

The instance methods form the Application Programming Interface (API) for an object. Most of the effort involved in designing a good object class goes into the API design because the API defines how reusable and maintainable the object and its subclasses will be. Do not rush to freeze an API design before you've considered how the object will be used.

Previous | Home | Next
9.6. Making a Method Work with Either Classes or Instances | Book Index | 9.8. More Interesting Instances
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.8. More Interesting Instances

What if an instance needs more data? Most interesting instances are made of many items, each of which can in turn be a reference or another object. The easiest way to store these items is often in a hash. The keys of the hash serve as the names of parts of the object (also called instance or member variables), and the corresponding values are, well, the values.

How do you turn the horse into a hash?[42] Recall that an object is any blessed reference. You can just as easily make it a blessed hash reference as a blessed scalar reference, as long as everything that looks at the reference is changed accordingly.

[42]Other than calling on a butcher, that is.

Let's make a sheep that has a name and a color:

my $lost = bless { Name => "Bo", Color => "white" }, Sheep;

$lost->{Name} has Bo, and $lost->{Color} has white. But you want to make $lost->name access the name, and that's now messed up because it's expecting a scalar reference. Not to worry, because it's pretty easy to fix up:

## in Animal
sub name {
  my $either = shift;
  ref $either
    ? $either->{Name}
    : "an unnamed $either";
}

named still builds a scalar sheep, so let's fix that as well:

## in Animal
sub named {
  my $class = shift;
  my $name = shift;
  my $self = { Name => $name, Color => $class->default_color };
  bless $self, $class;
}

What's this default_color? If named has only the name, you still need to set a color, so you'll have a class-specific initial color. For a sheep, you might define it as white:

## in Sheep
sub default_color { "white" }

Then to keep from having to define one for each additional class, define a backstop method, which serves as the "default default," directly in Animal:

## in Animal
sub default_color { "brown" }

Thus, all animals are brown (muddy, perhaps), unless a specific animal class gives a specific override to this method.

Now, because name and named were the only methods that referenced the structure of the object, the remaining methods can stay the same, so speak still works as before. This supports another basic rule of OOP: if the structure of the object is accessed only by the object's own methods or inherited methods, there's less code to change when it's time to modify that structure.

Previous | Home | Next
9.7. Adding Parameters to a Method | Book Index | 9.9. A Horse of a Different Color
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.9. A Horse of a Different Color

Having all horses be brown would be boring. Let's add a method or two to get and set the color:

## in Animal
sub color {
  my $self = shift;
  $self->{Color};
}
sub set_color {
  my $self = shift;
  $self->{Color} = shift;
}

Now you can fix that color for Mr. Ed:

my $tv_horse = Horse->named("Mr. Ed");
$tv_horse->set_color("black-and-white");
print $tv_horse->name, " is colored ", $tv_horse->color, "\n";

which results in:

Mr. Ed is colored black-and-white
Previous | Home | Next
9.8. More Interesting Instances | Book Index | 9.10. Getting Your Deposit Back
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.10. Getting Your Deposit Back

Because of the way the code is written, the setter also returns the updated value. Think about this (and document it) when you write a setter. What does the setter return? Here are some common variations:

  • The updated parameter (same as what was passed in)

  • The previous value (similar to the way umask or the single-argument form of select works)

  • The object itself

  • A success/fail code

Each has advantages and disadvantages. For example, if you return the updated parameter, you can use it again for another object:

$tv_horse->set_color( $eating->set_color( color_from_user( ) ));

The implementation given earlier returns the newly updated value. Frequently, this is the easiest code to write, and often the fastest to execute.

If you return the previous parameter, you can easily create "set this value temporarily to that" functions:

{
  my $old_color = $tv_horse->set_color("orange");
  ... do things with $tv_horse ...
  $tv_horse->set_color($old_color);
}

This is implemented as:

sub set_color {
  my $self = shift;
  my $old = $self->{Color};
  $self->{Color} = shift;
  $old;
}

For more efficiency, you can avoid stashing the previous value when in a void context using the wantarray function:

sub set_color {
  my $self = shift;
  if (defined wantarray) {
    # this method call is not in void context, so
    # the return value matters
    my $old = $self->{Color};
    $self->{Color} = shift;
    $old;
  } else {
    # this method call is in void context
    $self->{Color} = shift;
  }
}

If you return the object itself, you can chain settings:

my $tv_horse =
  Horse->named("Mr. Ed")
       ->set_color("grey")
       ->set_age(4)
       ->set_height("17 hands");

This works because the output of each setter is the original object, becoming the object for the next method call. Implementing this is again relatively easy:

sub set_color {
  my $self = shift;
  $self->{Color} = shift;
  $self;
}

The void context trick can be used here too, although with questionable value because you've already established $self.

Finally, returning a success status is useful if it's fairly common for an update to fail, rather than an exceptional event. The other variations would have to indicate failure by throwing an exception with die.

In summary: use what you want, be consistent if you can, but document it nonetheless (and don't change it after you've already released one version).

Previous | Home | Next
9.9. A Horse of a Different Color | Book Index | 9.11. Don't Look Inside the Box
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.11. Don't Look Inside the Box

You might have obtained or set the color outside the class simply by following the hash reference: $tv_horse->{Color}. However, this violates the encapsulation of the object by exposing its internal structure. The object is supposed to be a black box, but you've pried off the hinges and looked inside.

One purpose of OOP is to enable the maintainer of Animal or Horse to make reasonably independent changes to the implementation of the methods and still have the exported interface work properly. To see why accessing the hash directly violates this, let's say that Animal no longer uses a simple color name for the color, but instead changes to use a computed RGB triple to store the color (holding it as an arrayref), as in:

use Color::Conversions qw(color_name_to_rgb rgb_to_color_name);
...
sub set_color {
  my $self = shift;
  my $new_color = shift;
  $self->{Color} = color_name_to_rgb($new_color);  # arrayref
}
sub color {
  my $self = shift;
  rgb_to_color_name($self->{Color});               # takes arrayref
}

The old interface can be maintained if you use a setter and getter because they can perform the translations. You can also add new interfaces now to enable the direct setting and getting of the RGB triple:

sub set_color_rgb {
  my $self = shift;
  $self->{Color} = [@_];                # set colors to remaining parameters
}
sub get_color_rgb {
  my $self = shift;
  @{ $self->{Color} };                  # return RGB list
}

If you use code outside the class that looks at $tv_horse->{Color} directly, this change is no longer possible. Store a string ('blue') where an arrayref is needed ([0,0,255]) or use an arrayref as a string.

Previous | Home | Next
9.10. Getting Your Deposit Back | Book Index | 9.12. Faster Getters and Setters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.12. Faster Getters and Setters

Because you're going to play nice and always call the getters and setters instead of reaching into the data structure, getters and setters are called frequently. To save a teeny-tiny bit of time, you might see these getters and setters written as:

## in Animal
sub color {
  $_[0]->{Color}
}
sub set_color {
  $_[0]->{Color} = $_[1];
}

Here's an alternate way to access the arguments: $_[0] is used in place, rather than with a shift. Functionally, this example is identical to the previous implementation, but it's slightly faster, at the expense of some ugliness.

Previous | Home | Next
9.11. Don't Look Inside the Box | Book Index | 9.13. Getters That Double as Setters
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.13. Getters That Double as Setters

Another alternative to the pattern of creating two different methods for getting and setting a parameter is to create one method that notes whether or not it gets any additional arguments. If the arguments are absent, it's a get operation; if the arguments are present, it's a set operation. A simple version looks like:

sub color {
  my $shift;
  if (@_) {              # are there any more parameters?
    # yes, it's a setter:
    $self->{Color} = shift;
  } else {
    # no, it's a getter:
    $self->{Color};
  }
}

Now you can say:

my $tv_horse = Horse->named("Mr. Ed");
$tv_horse->color("black-and-white");
print $tv_horse->name, " is colored ", $tv_horse->color, "\n";

The presence of the parameter in the second line denotes that you are setting the color, while its absence in the third line indicates a getter.

While this strategy might at first seem attractive because of its apparent simplicity, it complicates the actions of the getter (which will be called frequently). This strategy also makes it difficult to search through your listings to find only the setters of a particular parameter, which are often more important than the getters. In fact, we've been burned by this in the past when a setter became a getter because another function returned more parameters than expected after an upgrade.

Previous | Home | Next
9.12. Faster Getters and Setters | Book Index | 9.14. Restricting a Method to Class-Only or Instance-Only
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.14. Restricting a Method to Class-Only or Instance-Only

Setting the name of an unnameable generic Horse is probably not a good idea; neither is calling named on an instance. Nothing in the Perl subroutine definition says "this is a class method" or "this is an instance method." Fortunately, the ref operator lets you throw an exception when called incorrectly. As an example of instance- or class-only methods, consider the following:

use Carp qw(croak);

sub instance_only {
  ref(my $self = shift) or croak "instance variable needed";
  ... use $self as the instance ...
}

sub class_only {
  ref(my $class = shift) and croak "class name needed";
  ... use $class as the class ...
}

Here, the ref function returns true for an instance or false for a class. If the undesired value is returned, you'll croak, which has the added advantage of placing the blame on the caller, not on you. The caller will get an error message like this, giving the line number in their code where the wrong method was called:

instance variable needed at their_code line 1234

While this seems like a good thing to do all the time, practically no CPAN or core modules add this extra checking. Maybe it's only for the ultra-paranoid.

Previous | Home | Next
9.13. Getters That Double as Setters | Book Index | 9.15. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


9.15. Exercise

The answers for all exercises can be found in Section A.8.

9.15.1. Exercise [45 min]

Give the Animal class the ability to get and set the name and color. Be sure that your result works under use strict. Also make sure your get methods work with both a generic animal and a specific animal instance. Test your work with:

my $tv_horse = Horse->named("Mr. Ed");
$tv_horse->set_name("Mister Ed");
$tv_horse->set_color("grey");
print $tv_horse->name, " is ", $tv_horse->color, "\n";
print Sheep->name, " colored ", Sheep->color, " goes ", Sheep->sound, "\n";

What should you do if you're asked to set the name or color of a generic animal?

Previous | Home | Next
9.14. Restricting a Method to Class-Only or Instance-Only | Book Index | 10. Object Destruction
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 10. Object Destruction

Contents:

Nested Object Destruction
Beating a Dead Horse
Indirect Object Notation
Additional Instance Variables in Subclasses
Using Class Variables
Weakening the Argument
Exercise

In the previous two chapters, we looked at basic object creation and manipulation. In this chapter, we'll look at an equally important topic: what happens when objects go away.

As you saw in Chapter 4, when the last reference to a Perl data structure goes away, Perl automatically reclaims the memory of that data structure, including destroying any links to other data. Of course, that in turn may cause other ("contained") structures to be destroyed as well.

By default, objects work in this manner because objects use the same reference structure to make more complex objects. An object built of a hash reference is destroyed when the last reference to that hash goes away. If the values of the hash elements are also references, they're similarly removed, possibly causing further destruction.

Suppose an object uses a temporary file to hold data that won't fit entirely in memory. The filehandle for this temporary file can be included as one of the object's instance variables. While the normal object destruction sequence will properly close the handle, you still have the temporary file on disk unless you take further action.

To perform the proper cleanup operations when an object is destroyed, you need to be notified when that happens. Thankfully, Perl provides such notification upon request. You can request this notification by giving the object a DESTROY method.

When the last reference to an object, say $bessie, is destroyed, Perl invokes:

$bessie->DESTROY

This method call is like most other method calls: Perl starts at the class of the object and works its way up the inheritance hierarchy until it finds a suitable method. However, unlike other method calls, there's no error if no suitable method is found.[43]

[43]Normally, your own method calls will cause an error if the method isn't found. If you want to prevent that, just put a do-nothing method into the base class.

For example, going back to the Animal class defined in Chapter 9, you can add a DESTROY method to know when objects go away, purely for debugging purposes:

## in Animal
sub DESTROY {
  my $self = shift;
  print "[", $self->name, " has died.]\n";
}

Now when you create any Animal s in the program, you get notification as they leave. For example:

## include animal classes from previous chapter...

sub feed_a_cow_named {
  my $name = shift;
  my $cow = Cow->named($name);
  $cow->eat("grass");
  print "Returning from the subroutine.\n";    # $cow is destroyed here
}
print "Start of program.\n";
my $outer_cow = Cow->named("Bessie");
print "Now have a cow named ", $outer_cow->name, ".\n";
feed_a_cow_named("Gwen");
print "Returned from subroutine.\n";

This prints:

Start of program.
Now have a cow named Bessie.
Gwen eats grass.
Returning from the subroutine.
[Gwen has died.]
Returned from subroutine.
[Bessie has died.]

Note that Gwen is active inside the subroutine. However, as the subroutine exits, Perl notices there are no references to Gwen; Gwen's DESTROY method is then automatically invoked, printing the Gwen has died message.

What happens at the end of the program? Since objects don't live beyond the end of the program, Perl makes one final pass over all remaining data and destroys it. This is true whether the data is held in lexical variables or package global variables. Because Bessie was still alive at the end of the program, she needed to be recycled, and so you get the message for Bessie after all other steps in the program are complete.[44]

[44]This is just after the END blocks are executed and follows the same rules as END blocks: there must be a nice exit of the program rather than an abrupt end. If Perl runs out of memory, all bets are off.

10.1. Nested Object Destruction

If an object holds another object (say, as an element of an array or the value of a hash element), the containing object is DESTROY ed before any of the contained objects begin their discarding process. This is reasonable because the containing object may need to reference its contents in order to be cleanly discarded. To illustrate this, let's build a "barn" and tear it down. And just to be interesting, we'll make the barn a blessed array reference, not a hash reference.

{ package Barn;
  sub new { bless [  ], shift }
  sub add { push @{+shift}, shift }
  sub contents { @{+shift} }
  sub DESTROY {
    my $self = shift;
    print "$self is being destroyed...\n";
    for ($self->contents) {
      print "  ", $_->name, " goes homeless.\n";
    }
  }
}

Here, we're really being minimalistic in the object definition. To create a new barn, simply bless an empty array reference into the class name passed as the first parameter. Adding an animal just pushes it to the back of the barn. Asking for the barn contents merely dereferences the object array reference to return the contents.[45]

[45]Did you wonder why there's a plus sign (+) before shift in two of those subroutines? That's due to one of the quirks in Perl's syntax. If the code were simply @{shift}, because the curly braces contain nothing but a bareword, it would be interpreted as a soft reference: @{"shift"}. In Perl, the unary plus (a plus sign at the beginning of a term) is defined to do nothing (not even turning what follows into a number), just so it can distinguish cases such as this.

The fun part is the destructor. Let's take the reference to ourselves, display a debugging message about the particular barn being destroyed, and then ask for the name of each inhabitant in turn. In action, this would be:

my $barn = Barn->new;
$barn->add(Cow->named("Bessie"));
$barn->add(Cow->named("Gwen"));
print "Burn the barn:\n";
$barn = undef;
print "End of program.\n";

This prints:

Burn the barn:
Barn=ARRAY(0x541c) is being destroyed...
  Bessie goes homeless.
  Gwen goes homeless.
[Gwen has died.]
[Bessie has died.]
End of program.

Note that the barn is destroyed first, letting you get the name of the inhabitants cleanly. However, once the barn is gone, the inhabitants have no additional references, so they also go away, and thus their destructors are also invoked. Compare that with the cows having a life outside the barn:

my $barn = Barn->new;
my @cows = (Cow->named("Bessie"), Cow->named("Gwen"));
$barn->add($_) for @cows;
print "Burn the barn:\n";
$barn = undef;
print "Lose the cows:\n";
@cows = ( );
print "End of program.\n";

This produces:

Burn the barn:
Barn=ARRAY(0x541c) is being destroyed...
  Bessie goes homeless.
  Gwen goes homeless.
Lose the cows:
[Gwen has died.]
[Bessie has died.]
End of program.

The cows will now continue to live until the only other reference to the cows (from the @cows array) goes away.

The references to the cows are removed only when the barn destructor is completely finished. In some cases, you may wish instead to shoo the cows out of the barn as you notice them. In this case, it's as simple as destructively altering the barn array, rather than iterating over it.[46]

[46]If you're using a hash instead, use delete on the elements you wish to process immediately.

Let's alter the Barn to Barn2 to illustrate this:

{ package Barn2;
  sub new { bless [  ], shift }
  sub add { push @{+shift}, shift }
  sub contents { @{+shift} }
  sub DESTROY {
    my $self = shift;
    print "$self is being destroyed...\n";
    while (@$self) {
      my $homeless = shift @$self;
      print "  ", $homeless->name, " goes homeless.\n";
    }
  }
}

Now use it in the previous scenarios:

my $barn = Barn2->new;
$barn->add(Cow->named("Bessie"));
$barn->add(Cow->named("Gwen"));
print "Burn the barn:\n";
$barn = undef;
print "End of program.\n";

This produces:

Burn the barn:
Barn2=ARRAY(0x541c) is being destroyed...
  Bessie goes homeless.
[Bessie has died.]
  Gwen goes homeless.
[Gwen has died.]
End of program.

As you can see, Bessie had no home by being booted out of the barn immediately, so she also died. (Poor Gwen suffers the same fate.) There were no references to her at that moment, even before the destructor for the barn was complete.

Thus, back to the temporary file problem. If you have an associated temporary file for an animal, you merely need to close it and delete the file during the destructor:

## in Animal
use File::Temp qw(tempfile);

sub named {
  my $class = shift;
  my $name = shift;
  my $self = { Name => $name, Color => $class->default_color };
  ## new code here...
  my ($fh, $filename) = tempfile( );
  $self->{temp_fh} = $fh;
  $self->{temp_filename} = $filename;
  ## .. to here
  bless $self, $class;
}

You now have a filehandle and its filename stored as instance variables of the Animal (or any class derived from Animal). In the destructor, close it down, and delete the file:[47]

[47]As it turns out, you can tell File::Temp to do this automatically, but then we wouldn't be able to illustrate doing it manually. Doing it manually allows you to store a summary of the information from the temporary file into a database. However, that's too complex to show here.

sub DESTROY {
  my $self = shift;
  my $fh = $self->{temp_fh};
  close $fh;
  unlink $self->{temp_filename};
  print "[", $self->name, " has died.]\n";
}

When the last reference to the Animal-ish object is destroyed (even at the end of the program), also automatically remove the temporary file to avoid a mess.

Previous | Home | Next
9.15. Exercise | Book Index | 10.2. Beating a Dead Horse
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.2. Beating a Dead Horse

Because the destructor method is inherited, you can also override and extend superclass methods. For example, we'll decide the dead horses need a further use:

## in Horse
sub DESTROY {
  my $self = shift;
  $self->SUPER::DESTROY;
  print "[", $self->name, " has gone off to the glue factory.]\n";
}

my @tv_horses = map Horse->named($_), ("Trigger", "Mr. Ed");
$_->eat("an apple") for @tv_horses;     # their last meal
print "End of program.\n";

This prints:

Trigger eats an apple.
Mr. Ed eats an apple.
End of program.
[Mr. Ed has died.]
[Mr. Ed has gone off to the glue factory.]
[Trigger has died.]
[Trigger has gone off to the glue factory.]

We'll feed each horse a last meal; at the end of the program, each horse's destructor is called.

The first step of this destructor is to call the parent destructor. Why is this important? Without calling the parent destructor, the steps taken by superclasses of this class will not properly execute. That's not much if it's simply a debugging statement as we've shown, but if it was the "delete the temporary file" cleanup method, you wouldn't have deleted that file!

So, the rule is:

Always include a call to $self->SUPER::DESTROY in your destructors (even if you don't yet have any base/parent classes).

Whether you call it at the beginning or the end of your own destructor is a matter of hotly contested debate. If your derived class needs some superclass instance variables, you should probably call the superclass destructor after you complete your operations because the superclass destructor will likely alter them in annoying ways. On the other hand, in the example, we called the superclass destructor before the added behavior, because we wanted the superclass behavior first. There's no rule of thumb, even. Sorry.

Previous | Home | Next
10. Object Destruction | Book Index | 10.3. Indirect Object Notation
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.3. Indirect Object Notation

The arrow syntax used to invoke a method is sometimes called the direct object syntax because there's also the indirect object syntax, also known as the "only works sometimes" syntax, for reasons explained in a moment. When you write:

Class->class_method(@args);
$instance->instance_method(@other);

you can generally replace it with:

classmethod Class @args;
instancemethod $instance @other;

A typical use of this is with the new method, replacing:

my $obj = Some::Class->new(@constructor_params);

with:

my $obj = new Some::Class @constructor_params;

making the C++ people feel right at home. Of course, in Perl, there's nothing special about the name new, but at least the syntax is hauntingly familiar.

Why the previous "generally" caveat? Well, if the instance is something more complicated than a simple scalar variable:

$somehash->{$somekey}->[42]->instance_method(@parms);

then you can't just swap it around like:

instance_method $somehash->{$somekey}->[42] @parms;

because the only things acceptable to indirect object syntax are a bareword (e.g., a class name), a simple scalar variable, or braces denoting a block returning either a blessed reference or a classname.[48]

[48]Astute readers will note that these are the same rules as for an indirect filehandle syntax, from which indirect object syntax directly mirrors, as well as the rules for specifying a reference to be dereferenced.

This means you have to write it like so:

instance_method { $somehash->{$somekey}->[42] } @parms;

And that goes from simple to uglier in one step. There's another downside: ambiguous parsing. When we developed the classroom materials concerning indirect object references, we wrote:

my $cow = Cow->named("Bessie");
print name $cow, " eats.\n";

because we were thinking about the indirect object equivalents for:

my $cow = Cow->named("Bessie");
print $cow->name, " eats.\n";

However, the latter works; the former doesn't. We were getting no output. Finally, we enabled warnings (via -w on the command line)[49] and got this interesting series of messages:

[49]Using -w should be the first step when Perl does something you don't understand. Or maybe it should be the zeroth because you should normally have -w in effect whenever you're developing code.

Unquoted string "name" may clash with future reserved word at ./foo line 92.
Name "main::name" used only once: possible typo at ./foo line 92.
print( ) on unopened filehandle name at ./foo line 92.

Ahh, so that line was being parsed as:

print name ($cow, " eats.\n");

In other words, print the list of items to the filehandle named name. That's clearly not what we wanted, so we had to add additional syntax to disambiguate the call.

This leads us to our next strong suggestion:

Use direct object syntax at all times, except perhaps for the constructor call.

That exception acknowledges that most people write new Class ... rather than Class->new(...) and that most of us are fine with that. However, there are circumstances in which even that can lead to ambiguity (e.g., when a subroutine named new has been seen, and the class name itself has not been seen as a package). When in doubt, ignore indirect object syntax. Your maintenance programmer will thank you.

Previous | Home | Next
10.2. Beating a Dead Horse | Book Index | 10.4. Additional Instance Variables in Subclasses
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.4. Additional Instance Variables in Subclasses

One of the nice things about using a hash for a data structure is that derived classes can add additional instance variables without the superclass needing to know of their addition. For example, let's derive a RaceHorse class that is everything a Horse is but also tracks its win/place/show/lose standings. The first part of this is trivial:

{ package RaceHorse;
  our @ISA = qw(Horse);
  ...
}

You'll also want to initialize "no wins of no races" when you create the RaceHorse. You do this by extending the named subroutine and adding four additional fields (wins, places, shows, losses, for first-, second-, and third-place finishes, and none of the above):

{ package RaceHorse;
  our @ISA = qw(Horse);
  ## extend parent constructor:
  sub named {
    my $self = shift->SUPER::named(@_);
    $self->{$_} = 0 for qw(wins places shows losses);
    $self;
  }
}

Here, you pass all parameters to the superclass, which should return a fully formed Horse. However, because you pass RaceHorse as the class, it'd be already blessed into the RaceHorse class.[50] Next, add the four instance variables that go beyond those defined in the superclass, setting their initial values to 0. Finally, return the modified RaceHorse to the caller.

[50]Similar to the way the Animal constructor creates a Horse, not an Animal, when passed Horse as the class.

It's important to note here that we've actually "opened the box" a bit while writing this derived class. You know that the superclass uses a hash reference and that the superclass hierarchy doesn't use the four names chosen for a derived class. This is because RaceHorse will be a "friend" class (in C++ or Java terminology), accessing the instance variables directly. If the maintainer of Horse or Animal ever changes representation or names of variables, there could be a collision, which might go undetected except for that important day when you're showing off your code to the investors. Things get even more interesting if the hashref is changed to an arrayref as well.

One way to decouple this dependency is to use composition rather than inheritance as a way to create a derived class. In this example, you need to make a Horse object an instance variable of a RaceHorse and put the rest of the data in separate instance variables. You also need to pass any inherited method calls on the RaceHorse down to the Horse instance, through delegation. However, even though Perl can certainly support the needed operations, that approach is usually slower and more cumbersome. Enough on that for this discussion, however.

Next, let's provide some access methods:

{ package RaceHorse;
  our @ISA = qw(Horse);
  ## extend parent constructor:
  sub named {
    my $self = shift->SUPER::named(@_);
    $self->{$_} = 0 for qw(wins places shows losses);
    $self;
  }
  sub won { shift->{wins}++; }
  sub placed { shift->{places}++; }
  sub showed { shift->{shows}++; }
  sub lost { shift->{losses}++; }
  sub standings {
    my $self = shift;
    join ", ", map "$self->{$_} $_", qw(wins places shows losses);
  }
}

my $racer = RaceHorse->named("Billy Boy");
# record the outcomes: 3 wins, 1 show, 1 loss
$racer->won;
$racer->won;
$racer->won;
$racer->showed;
$racer->lost;
print $racer->name, " has standings of: ", $racer->standings, ".\n";

This prints:

Billy Boy has standings of: 3 wins, 0 places, 1 shows, 1 losses.
[Billy Boy has died.]
[Billy Boy has gone off to the glue factory.]

Note that we're still getting the Animal and Horse destructor. The superclasses are unaware that we've added four additional elements to the hash and so, still function as they always have.

Previous | Home | Next
10.3. Indirect Object Notation | Book Index | 10.5. Using Class Variables
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.5. Using Class Variables

What if you want to iterate over all the animals we've made so far? Animals may exist all over the program namespace and are lost once they're handed back from the named constructor method.

However, you can record the created animal in a hash and iterate over that hash. The key to the hash can be the stringified form of the animal reference,[51] while the value can be the actual reference, allowing you to access its name or class.

[51]Or any other convenient and unique string.

For example, let's extend named as follows:

## in Animal
our %REGISTRY;
sub named {
  my $class = shift;
  my $name = shift;
  my $self = { Name => $name, Color => $class->default_color };
  bless $self, $class;
  $REGISTRY{$self} = $self;  # also returns $self
}

The uppercase name for %REGISTRY is a reminder that this variable is more global than most variables. In this case, it's a metavariable that contains information about many instances.

Note that when used as a key, $self stringifies, which means it turns into a string unique to the object.

We also need to add a new method:

sub registered {
  return map { "a ".ref($_)." named ".$_->name } values %REGISTRY;
}

Now you can see all the animals we've made:

my @cows = map Cow->named($_), qw(Bessie Gwen);
my @horses = map Horse->named($_), ("Trigger", "Mr. Ed");
my @racehorses = RaceHorse->named("Billy Boy");
print "We've seen:\n", map("  $_\n", Animal->registered);
print "End of program.\n";

This prints:

We've seen:
  a RaceHorse named Billy Boy
  a Horse named Mr. Ed
  a Horse named Trigger
  a Cow named Gwen
  a Cow named Bessie
End of program.
[Billy Boy has died.]
[Billy Boy has gone off to the glue factory.]
[Bessie has died.]
[Gwen has died.]
[Trigger has died.]
[Trigger has gone off to the glue factory.]
[Mr. Ed has died.]
[Mr. Ed has gone off to the glue factory.]

Note that the animals die at their proper time because the variables holding the animals are all being destroyed at the final step. Or are they?

Previous | Home | Next
10.4. Additional Instance Variables in Subclasses | Book Index | 10.6. Weakening the Argument
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.6. Weakening the Argument

The %REGISTRY variable also holds a reference to each animal. So even if you toss away the containing variables:

{
  my @cows = map Cow->named($_), qw(Bessie Gwen);
  my @horses = map Horse->named($_), ("Trigger", "Mr. Ed");
  my @racehorses = RaceHorse->named("Billy Boy");
}
print "We've seen:\n", map("  $_\n", Animal->registered);
print "End of program.\n";

you'll still see the same result. The animals aren't destroyed even though none of the code is holding the animals. At first glance, it looks like you can fix this by altering the destructor:

## in Animal
sub DESTROY {
  my $self = shift;
  print "[", $self->name, " has died.]\n";
  delete $REGISTRY{$self};
}

But this still results in the same output. Why? Because the destructor isn't called until the last reference is gone, but the last reference won't be destroyed until the destructor is called.[52]

[52]We'd make a reference to chickens and eggs, but that would introduce yet another derived class to Animal.

One solution for fairly recent Perl versions[53] is to use weak references. A weak reference is a reference that doesn't count as far as the reference counting, uh, counts. It's best illustrated by example.

[53]5.6 and later.

The weak reference mechanism is already built into the core of recent Perl versions, but as of this writing, the user interface is still accessed by a CPAN module called WeakRef. After installing this module,[54] you can update the constructor as follows:

[54]See Chapter 15 for information on installing modules.

## in Animal
use WeakRef qw(weaken); ## new

sub named {
  ref(my $class = shift) and croak "class only";
  my $name = shift;
  my $self = { Name => $name, Color => $class->default_color };
  bless $self, $class;
  $REGISTRY{$self} = $self;
  weaken($REGISTRY{$self});
  $self;
}

When Perl counts the number of active references to a thingy,[55] it won't count any that have been converted to weak references by weaken. If all ordinary references are gone, Perl deletes the thingy and turns any weak references to undef.

[55]A thingy as defined in Perl's own documentation, is anything a reference points to, such as an object. If you are an especially boring person, you could call it a referent instead.

Now you'll get the right behavior for:

my @horses = map Horse->named($_), ("Trigger", "Mr. Ed");
print "alive before block:\n", map("  $_\n", Animal->registered);
{
  my @cows = map Cow->named($_), qw(Bessie Gwen);
  my @racehorses = RaceHorse->named("Billy Boy");
  print "alive inside block:\n", map("  $_\n", Animal->registered);
}
print "alive after block:\n", map("  $_\n", Animal->registered);
print "End of program.\n";

This prints:

alive before block:
  a Horse named Trigger
  a Horse named Mr. Ed
alive inside block:
  a RaceHorse named Billy Boy
  a Cow named Gwen
  a Horse named Trigger
  a Horse named Mr. Ed
  a Cow named Bessie
[Billy Boy has died.]
[Billy Boy has gone off to the glue factory.]
[Gwen has died.]
[Bessie has died.]
alive after block:
  a Horse named Trigger
  a Horse named Mr. Ed
End of program.
[Mr. Ed has died.]
[Mr. Ed has gone off to the glue factory.]
[Trigger has died.]
[Trigger has gone off to the glue factory.]

Notice that the racehorses and cows die at the end of the block, but the ordinary horses die at the end of the program. Success!

Weak references can also solve some memory leak issues. For example, suppose an animal wanted to record its pedigree. The parents might want to hold references to all their children while each child might want to hold references to each parent.

One or the other (or even both) of these links can be weakened. If the link to the child is weakened, the child can be destroyed when all other references are lost, and the parent's link simply becomes undef (or you can set a destructor to completely remove it). However, a parent won't disappear as long as it still has offspring. Similarly, if the link to the parent is weakened, you'll simply get it as undef when the parent is no longer referenced by other data structures. It's really quite flexible.[56]

[56]When using weak references, always make sure you don't dereference a weakened reference that has turned to undef.

Without weakening, as soon as any parent-child relationship is created, both the parent and the child remain in memory until the final global destruction phase, regardless of the destruction of the other structures holding either the parent or the child.

Be aware though: weak references should be used carefully, not just thrown at a problem of circular references. If you destroy data that is held by a weak reference before its time, you may have some very confusing programming problems to solve and debug.

Previous | Home | Next
10.5. Using Class Variables | Book Index | 10.7. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


10.7. Exercise

The answers for all exercises can be found in Section A.9.

10.7.1. Exercise [45 min]

Modify the RaceHorse class to get the previous standings from a DBM hash (keyed by the horse's name) when the horse is created, and update the standings when the horse is destroyed. For example, running this program four times:

my $runner = RaceHorse->named("Billy Boy");
$runner->won;
print $runner->name, " has standings ", $runner->standings, ".\n";

should show four additional wins. Make sure that a RaceHorse still does everything a normal Horse does otherwise.

For simplicity, use four space-separated integers for the value in the DBM hash.

Previous | Home | Next
10.6. Weakening the Argument | Book Index | 11. Some Advanced Object Topics
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 11. Some Advanced Object Topics

Contents:

UNIVERSAL Methods
Testing Your Objects for Good Behavior
AUTOLOAD as a Last Resort
Using AUTOLOAD for Accessors
Creating Getters and Setters More Easily
Multiple Inheritance
References to Filehandles
Exercise

You might wonder, "do all objects inherit from a common class?" "What if a method is missing?" "What about multiple inheritance?" "How come we haven't seen a reference to a filehandle yet?" Well, wonder no more. This chapter covers these subjects and more.

11.1. UNIVERSAL Methods

As you define classes, you create inheritance hierarchies through the global @ISA variables in each package. To search for a method, Perl wanders through the @ISA tree until it finds a match or fails.

After the search fails however, Perl always looks in one special class called UNIVERSAL and invokes a method from there, if found, just as if it had been located in any other class or superclass.

One way to look at this is that UNIVERSAL is the base class from which all objects are derived. Any method you place here, such as:

sub UNIVERSAL::fandango {
  warn "object ", shift, " can do the fandango!\n";
}

enables all objects of your program to be called as $some_object->fandango.

Generally, you should provide a fandango method for specific classes of interest, and then provide a definition in UNIVERSAL::fandango as a backstop, in case a more specific method can't be found. A practical example might be a data-dumping routine for debugging or maybe a marshalling strategy to dump all application objects to a file. Simply provide the general method in UNIVERSAL and override it in the specific classes for unusual objects.

Obviously, UNIVERSAL should be used sparingly because there's only one universe of objects, and your fandango might collide with some other included module's fandango. For this reason, UNIVERSAL is hardly used for anything except methods which must be completely, well, universal. Like during debugging.

Previous | Home | Next
10.7. Exercise | Book Index | 11.2. Testing Your Objects for Good Behavior
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.2. Testing Your Objects for Good Behavior

Besides providing a place for you to put universally available methods, the UNIVERSAL package comes preloaded with two very useful utility methods: isa and can. Because these methods are defined in UNIVERSAL, they are automatically available to all objects.

The isa method tests to see whether a given class or instance is a member of a given class or a member of a class that inherits from the given class. For example, continuing on with the Animal-family from the past chapters:

if (Horse->isa("Animal")) {    # does Horse inherit from Animal?
  print "A Horse is an Animal.\n";
}

my $tv_horse = Horse->named("Mr. Ed");
if ($tv_horse->isa("Animal")) { # is it an Animal?
  print $tv_horse->name, " is an Animal.\n";
  if ($tv_horse->isa("Horse")) { # is it a Horse?
    print "In fact, ", $tv_horse->name, " is a Horse.\n";
  } else {
    print "...but it's not a Horse.\n";
  }
}

This is handy when you have a heterogeneous mix of objects in a data structure and want to distinguish particular categories of objects:

my @horses = grep $_->isa("Horse"), @all_animals;

The result will be only the horses (or race horses) from the array. Compare that with:

my @horses_only = ref $_ eq "Horse", @all_animals;

which picks out just the horses because a RaceHorse won't return Horse for ref.

In general, you shouldn't use:

 ref($some_object) eq "SomeClass"

in your programs because it prevents future users from subclassing that class. Use the isa construct as given earlier.

One downside of the isa call here is that it works only on blessed references or scalars that look like class names. If you happen to pass it an unblessed reference, you get a fatal (but trappable) error of:

Can't call method "isa" on unblessed reference at ...

To call isa more robustly, don't call it as a method. Instead, call it as a subroutine:

if (UNIVERSAL::isa($unknown_thing, "Animal")) {
  ... it's an Animal! ...
}

This works regardless of what $unknown_thing contains.

As in the case of isa, you can test for acceptable behaviors with the can method. For example:

if ($tv_horse->can("eat")) {
  $tv_horse->eat("hay");
}

If the result of can is true, then somewhere in the inheritance hierarchy, a class has defined an eat method. Again, the caveats about $tv_horse being only either a blessed reference or a class name as a scalar still apply, so the robust solution when you might deal with nearly anything looks like:

if (UNIVERSAL::can($tv_horse, "eat")) { ... }

Note that if you defined UNIVERSAL::fandango earlier, then:

 $object->can("fandango")

always returns true because all objects can do the fandango.

Previous | Home | Next
11. Some Advanced Object Topics | Book Index | 11.3. AUTOLOAD as a Last Resort
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.3. AUTOLOAD as a Last Resort

After Perl searches the inheritance tree and UNIVERSAL for a method, it doesn't just stop there if the search is unsuccessful. Perl repeats the search through the very same hierarchy (including UNIVERSAL), looking for a method named AUTOLOAD.

If an AUTOLOAD exists, the subroutine is called in place of the original method, passing it the normal predetermined argument list: the class name or instance reference, followed by any arguments provided to the method call. The original method name is passed in the package variable called $AUTOLOAD (in the package where the subroutine was compiled) and contains the fully qualified method name, so you should generally strip everything up to the final double colon if you want a simple method name.

The AUTOLOAD subroutine can execute the desired operation itself, install a subroutine and then jump into it, or perhaps just die if asked to perform an unknown method.

One use of AUTOLOAD defers the compilation of a large subroutine until it is actually needed. For example, suppose the eat method for an animal is complex but unused in nearly every invocation of the program. You can defer its compilation as follows:

## in Animal
sub AUTOLOAD {
  our $AUTOLOAD;
  (my $method = $AUTOLOAD) =~ s/.*:://s; # remove package name
  if ($method eq "eat") {
    ## define eat:
    eval q{
      sub eat {
        ...
        long
        definition
        goes
        here
        ...
      }
    };                # End of eval's q{  } string
    die $@ if $@;                        # if typo snuck in
    goto &eat;                           # jump into it
  } else {                               # unknown method
    croak "$_[0] does not know how to $method\n";
  }
}

If the method name is eat, you'll define eat (which had previously been held in a string but not compiled), and then jump into it with a special construct that replaces the current subroutine invocation with an invocation to eat.[57] After the first AUTOLOAD hit, the eat subroutine is now defined, so won't be coming back here. This is great for compile-as-you-go programs because it minimizes startup overhead.

[57]Although goto is generally (and rightfully) considered evil, this form of goto, which gives a subroutine name as a target, is not really the evil goto; it's the good goto.

For a more automated way of creating code to do this, which makes it easy to turn the autoloading off during development and debugging, see the AutoLoader and SelfLoader core module documentation.

Previous | Home | Next
11.2. Testing Your Objects for Good Behavior | Book Index | 11.4. Using AUTOLOAD for Accessors
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.4. Using AUTOLOAD for Accessors

Chapter 9 showed how to create color and set_color to get and set the color of an animal. If you had 20 attributes instead of one or two, the code would be painfully repetitive. However, using an AUTOLOAD method, you can construct the nearly identical accessors as needed, saving both compilation time and wear-and-tear on the developer's keyboard.

Use a code reference as a closure to do the job. First, set up an AUTOLOAD for the object and define a list of hash keys for which you want trivial accessors:

sub AUTOLOAD {
  my @elements = qw(color age weight height);

Next, you'll see if the method is a getter for one of these keys, and if so, install a getter and jump to it:

our $AUTOLOAD;
if ($AUTOLOAD =~ /::(\w+)$/ and grep $1 eq $_, @elements) {
  my $field = ucfirst $1;
  {
    no strict 'refs';
    *{$AUTOLOAD} = sub { $_[0]->{$field} };
  }
  goto &{$AUTOLOAD};
}

You need to use ucfirst because you named the method color to fetch the hash element called Color. The glob notation here installs a wanted subroutine as defined by the coderef closure, which fetches the corresponding key from the object hash. Consider this part to be magic that you just cut and paste into your program. Finally, the goto construct jumps into the newly defined subroutine.

Otherwise, perhaps it's a setter:

if ($AUTOLOAD =~ /::set_(\w+)$/ and grep $1 eq $_, @elements) {
  my $field = ucfirst $1;
  {
    no strict 'refs';
    *{$AUTOLOAD} = sub { $_[0]->{$field} = $_[1] };
  }
  goto &{$AUTOLOAD};
}

If it is neither, death awaits:

  die "$_[0] does not understand $method\n";
}

Again, you pay the price for the AUTOLOAD only on the first hit of a particular getter or setter. After that, a subroutine is now already defined, and you can just invoke it directly.

Previous | Home | Next
11.3. AUTOLOAD as a Last Resort | Book Index | 11.5. Creating Getters and Setters More Easily
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.5. Creating Getters and Setters More Easily

If all that coding for creating accessors using AUTOLOAD looks messy, rest assured that you really don't need to tackle it, because there's a CPAN module that does it a bit more directly: Class::MethodMaker.

For example, a simplified version of the Animal class might be defined as follows:

package Animal;
use Class::MethodMaker
  new_with_init => 'new',
  get_set => [-eiffel => [qw(color height name age)]],
  abstract => [qw(sound)],
;
sub init {
  my $self = shift;
  $self->set_color($self->default_color);
}
sub named {
  my $self = shift->new;
  $self->set_name(shift);
  $self;
}
sub speak {
  my $self = shift;
  print $self->name, " goes ", $self->sound, "\n";
}
sub eat {
  my $self = shift;
  my $food = shift;
  print $self->name, " eats $food\n";
}
sub default_color {
  "brown";
}

The getters and setters for the four instance attributes (name, height, color, and age) are defined automatically, using the method color to get the color and set_color to set the color. (The eiffel flag says "do it the way the Eiffel language does it," which is the way it should be done here.) The messy blessing step is now hidden behind a simple new method. The initial color is defined as the default color, as before, because the init method is automatically called from new.

However, you can still call Horse->named('Mr. Ed') because it immediately calls the new routine as well.

The sound method is automatically generated as an abstract method. Abstract methods are placeholders, meant to be defined in a subclass. If a subclass fails to define the method, the method generated for Animal's sound dies.

You lose the ability to call the getters (such as name) on the class itself, rather than an instance. In turn, this breaks your prior usage of calling speak and eat on generic animals, since they call the accessors. One way around this is to define a more general version of name to handle either a class or instance and then change the other routines to call it:

sub generic_name {
  my $either = shift;
  ref $either ? $either->name : "an unnamed $either";
}
sub speak {
  my $either = shift;
  print $either->generic_name, " goes ", $either->sound, "\n";
}
sub eat {
  my $either = shift;
  my $food = shift;
  print $either->generic_name, " eats $food\n";
}

There. Now it's looking nearly drop-in compatible with the previous definition, except for those friend classes that referenced the attribute names directly in the hash as the initial-cap-keyed versions (such as Color) rather than through the accessors ($self->color).

That brings up the maintenance issue again. The more you can decouple your implementation (hash versus array, names of hash keys, or types of elements) from the interface (method names, parameter lists, or types of return values), the more flexible and maintainable your system becomes.

That flexibility is not free, however. The cost of a method call is higher than the cost of a hash lookup, so it may be acceptable (or even necessary) for a friend class to peer inside. You may have to pay the programmer-time price of development and maintenance so you don't pay the runtime price of an overly flexible system.

On the other hand, don't go overboard in the other direction. Many anecdotes float around about systems where everything was so indirected (to be flexible) that the system ran too slowly to be used.

Previous | Home | Next
11.4. Using AUTOLOAD for Accessors | Book Index | 11.6. Multiple Inheritance
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.6. Multiple Inheritance

How does Perl wander through the @ISA tree? The answer may be simple or complex. If you don't have multiple inheritance (that is, if no @ISA has more than one element), it is simple: Perl simply goes from one @ISA to the next until it finds the ultimate base class whose @ISA is empty.

Multiple inheritance is more complex. It occurs when a class's @ISA has more than one element. For example, suppose someone had given an existing class, called Racer, which has the basic abilities for anything that can race, so that it's ready to be the base class for a runner, a fast car, or a racing turtle. With that, you can make the RaceHorse class as simply as this, maybe:[58]

[58]If there is a conflict among the methods of Horse and Racer, or if their implementations aren't able to work together, the situation can become much more difficult.

{
  package RaceHorse;
  our @ISA = qw{ Horse Racer };
}

Now a RaceHorse can do anything a Horse can do, and anything a Racer can do as well. When Perl searches for a method that's not provided directly by RaceHorse, it first searches through all the capabilities of the Horse (including all its parent classes, such as Animal). When the Horse possibilities are exhausted, Perl turns to see whether Racer (or one of its subclasses) supplies the needed method. On the other hand, if you want Perl to search Racer and its subclasses before searching Horse, put them into @ISA in that order (see Figure 11-1).

Figure 11-1. A class may not need to implement any methods of its own if it inherits everything it needs from its parent classes through multiple inheritance

Previous | Home | Next
11.5. Creating Getters and Setters More Easily | Book Index | 11.7. References to Filehandles
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.7. References to Filehandles

So far, you've seen references to scalars, arrays, hashes, and subroutines. Another important value type in Perl is the filehandle.

However, a filehandle isn't stored in a variable. The filehandle is the handle itself. You can't take a reference directly to a filehandle.[59] However, using the IO::File built-in class, you can create objects that act like filehandles within Perl. Here's a typical use:

[59]You can use the glob, take a reference to the glob, or take a reference to the I/O structure within a glob, but that's still not a reference to the filehandle.

use IO::File;

my $fh = IO::File->open("/etc/passwd")
  or die "constructor failed: $!";

while (<$fh>) {        # $fh acts like any filehandle
  print "a password line is $_";
}

close $fh;             # nearly all built-ins can use IO::File

Here, $fh is constructed using the open class method of IO::File, and then used in places where ordinarily you'd use a traditional (bareword) filehandle. Furthermore, you also get some additional methods:

if ($fh->opened) { ... } # file is open

$fh->blocking(0);       # make I/O be "non-blocking" if supported

The core built-in operations that use filehandles can all use an IO::File objects instead. If the IO::File object is within a simple scalar variable, you can always replace the filehandle with the scalar:

use IO::File;
my $fh = IO::File->new; # create unopened "filehandle" object

open $fh, ">my_new_file" or die "Cannot create: $!";
print $fh "$_\n" for 1..10;
close $fh;

An IO::File object automatically gets closed cleanly when destroyed, so you can simplify the previous code as:

use IO::File;
{
  my $fh = IO::File->open(">my_new_file")
    or die "Cannot create my_new_file: $!";
  print $fh, "$_\n" for 1..10;
}

As $fh goes out of scope, the filehandle is automatically closed. Nice.

If the IO::File object is not named by a simple scalar variable, some operations require a slightly modified syntax to work. For example, copy every file matched by the glob pattern of *.input to a corresponding file whose suffix is .output, but do it in parallel. First, open all the files, both inputs and outputs:

my @handlepairs;
foreach my $file (<*.input>) {
  (my $out = $file) =~ s/\.input$/.output/;
  push @handlepairs, [
    (IO::File->new("<$file") || die),
    (IO::File->new(">$out") || die),
  ];
}

Now you have an array of references to arrays, each element of which is an IO::File object. Let's pump the data:

while (@handlepairs) {
  @handlepairs = grep {
    if (defined(my $line = $_->[0]->getline)) {
      print { $_->[1] } $line;
    } else {
      0;
    }
  } @handlepairs;
}

As long as you have pairs, keep passing the list through the grep structure:

@handlepairs = grep { CONDITION } @handlepairs;

On each pass, only the handle pairs that evaluate as true in the grep CONDITION survive. Inside, you take the first element of each pair and try to read from it. If that's successful, write that line to the second element of the pair (the corresponding output handle). If the print is successful, it returns true, which lets grep know that you want to keep that pair. If either the print fails or the getline returned undef, the grep sees the false value as an indication to discard that pair. Discarding the pair automatically closes both filehandles. Cool!

Note that you can't use the more traditional filehandle read or filehandle print operations because the reading and writing filehandles weren't in a simple scalar variable. Rewrite that loop to see if copying the handles is easier:

while (@handlepairs) {
  @handlepairs = grep {
    my ($IN, $OUT) = @$_;
    if (defined(my $line = <$IN>)) {
      print $OUT $line;
    } else {
      0;
    }
  } @handlepairs;
}

This scenario is arguably better. Most of the time, simply copying the complexly referenced value into a simple scalar is easier on the eyes. In fact, another way to write that loop is to get rid of the ugly if structure:

while (@handlepairs) {
  @handlepairs = grep {
    my ($IN, $OUT) = @$_;
    my $line;
    defined($line = <IN>) and print $OUT $line;
  } @handlepairs;
}

As long as someone understands that and is a partial evaluator and that print returns true when everything is OK, this is a fine replacement. Remember the Perl motto: "There's more than one way to do it" (although not all of them are equally nice or legitimate).

Previous | Home | Next
11.6. Multiple Inheritance | Book Index | 11.8. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


11.8. Exercise

The answers for all exercises can be found in Section A.10.

11.8.1. Exercise [30 min]

The Professor has to read a log file that looks like:

Gilligan: 1 coconut
Skipper: 3 coconuts
Gilligan: 1 banana
Ginger: 2 papayas
Professor: 3 coconuts
MaryAnn: 2 papayas
...

He wants to write a series of files, called gilligan.info, maryann.info, and so on. Each file should contain all the lines that begin with that name. (Names are always delimited by the trailing colon.) At the end, gilligan.info should start with:

Gilligan: 1 coconut
Gilligan: 1 banana

Now the log file is large, and the coconut-powered computer is not very fast, so he wants to process the input file in one pass and write all output files in parallel. How does he do it?

Hint: Use a hash, keyed by the castaway name, holding IO::File objects for each output file. Create them as necessary.

Previous | Home | Next
11.7. References to Filehandles | Book Index | 12. Using Modules
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 12. Using Modules

Contents:

Sample Function-Oriented Interface: File::Basename
Selecting What to Import
Sample Object-Oriented Interface: File::Spec
A More Typical Object-Oriented Module: Math::BigInt
The Differences Between OO and Non-OO Modules
What use Is Doing
Setting the Path at the Right Time
Importing with Exporter
@EXPORT and @EXPORT_OK
Exporting in a Primarily OO Module
Custom Import Routines
Exercise

A module is a building block for your program: a set of related subroutines and variables packaged so it can be reused. This chapter looks at the basics of modules: how to bring in modules that others have written, and how to write modules of your own.

12.1. Sample Function-Oriented Interface: File::Basename

To understand what happens with use, look at one of the many modules included with a normal Perl distribution: File::Basename. This module parses file specifications into useful pieces in a mostly portable manner. The default usage:

use File::Basename;

introduces three subroutines, fileparse, basename, and dirname,[60] into the current package: typically, main in the main part of your program. From this point forward, within this package, you can say: [61]

[60]As well as a utility routine, fileparse_set_fstype.

[61]The new symbols are available for all code compiled in the current package from this point on, whether it's in this same file or not. However, these symbols won't be available in a different package.

my $basename = basename($some_full_path);
my $dirname = dirname($some_full_path);

as if you had written the basename and dirname subroutines yourself, or (nearly) as if they were built-in Perl functions.[62]

[62]These routines pick out the filename and the directory parts of a pathname. For example, if $some_full_path were D:\Projects\Island Rescue\plan 7.rtf (presumably, the program is running on a Windows machine), the basename would be plan 7.rtf and the dirname would be D:\Projects\Island Rescue.

However, suppose you already had a dirname subroutine? You've now overwritten it with the definition provided by File::Basename! If you had turned on warnings, you'd see a message stating that, but otherwise, Perl really doesn't care.

Previous | Home | Next
11.8. Exercise | Book Index | 12.2. Selecting What to Import
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.2. Selecting What to Import

Fortunately, you can tell the use operation to limit its actions. Do this by specifying a list of subroutine names following the module name, called the import list:

use File::Basename ("fileparse", "basename");

Now define the two given subroutines from the module, leaving your own dirname alone. Of course, this is awkward to type, so more often you'll see this written as:

use File::Basename qw( fileparse basename );

In fact, even if there's only one item, you tend to write it with a qw( ) list for consistency and maintenance; often you'll go back to say "give me another one from here," and it's simpler if it's already a qw( ) list.

You've protected the local dirname routine, but what if you still want the functionality provided by File::Basename's dirname? No problem. Just spell it out in full:

my $dirname = File::Basename::dirname($some_path);

The list of names following use doesn't change which subroutine is defined in the module's package (in this case, File::Basename). You can always use the full name regardless of the import list, as in:[63]

[63]You don't need the ampersand in front of any of these subroutine invocations because the subroutine name is already known to the compiler following use.

my $basename = File::Basename::basename($some_path);

In an extreme (but extremely useful) case, you can specify an empty list for the import list, as in:

use File::Basename ( );              # no import
my $base = File::Basename::basename($some_path);

An empty list is different from an absent list. An empty list says "don't give me anything in my current package," while an absent list says "give me the defaults."[64] If the module's author has done her job well, the default will probably be exactly what you want.

[64]As you'll see later in this chapter, the default list comes from the module's @EXPORT array.

Previous | Home | Next
12. Using Modules | Book Index | 12.3. Sample Object-Oriented Interface: File::Spec
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.3. Sample Object-Oriented Interface: File::Spec

Contrast the subroutines imported by File::Basename with what another core (non-CPAN) module has by looking at File::Spec. The File::Spec module is designed to support operations commonly performed on file specifications. (A file specification is usually a file or directory name, but it may be a name of a file that doesn't exist—in which case, it's not really a filename, is it?)

Unlike the File::Basename module, the File::Spec module has a primarily object-oriented interface. Saying:

use File::Spec;

in your program imports no subroutines into the current package. Instead, you're expected to access the functionality of the module using class methods:

my $filespec = File::Spec->catfile( $homedir{gilligan},
      'web_docs', 'photos', 'USS_Minnow.gif' );

This calls the class method catfile of the File::Spec class, building a path appropriate for the local operating system, and returns a single string.[65] This is similar in syntax to the nearly two dozen other operations provided by File::Spec: they're all called as class methods. No instances are ever created.

[65]That string might be something like /home/gilligan/web_docs/photos/USS_Minnow.gif on a Unix system. On a Windows system, it would typically use backslashes as directory separators. As you can see, this module lets you write portable code easily, at least where file specs are concerned.

While it is never stated in the documentation, perhaps the purpose of creating these as class methods rather than as imported subroutines is to free the user of the module from having to worry about namespace collisions (as you saw for dirname in the previous section). The idea of an object class without objects, however, seems a bit off kilter. Perhaps, that's why the module's author also provides a more traditional interface with:

use File::Spec::Functions qw(catfile curdir);

in which two of the File::Spec's many functions are imported as ordinary callable subroutines:

my $filespec = catfile( $homedir{gilligan},
      'web_docs', 'photos', 'USS_Minnow.gif' );
Previous | Home | Next
12.2. Selecting What to Import | Book Index | 12.4. A More Typical Object-Oriented Module: Math::BigInt
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.4. A More Typical Object-Oriented Module: Math::BigInt

So as not to get dismayed about how "un-OO" the File::Spec module might be, let's look at yet another core module, Math::BigInt:

use Math::BigInt;
my $value = Math::BigInt->new(2); # start with 2
$value->bpow(1000);               # take 2**1000
print $value->bstr( ), "\n";       # print it out

Here, nothing is imported. The entire interface calls class methods such as new against the class name to create instances, and then calls instance methods against those instances.

Previous | Home | Next
12.3. Sample Object-Oriented Interface: File::Spec | Book Index | 12.5. The Differences Between OO and Non-OO Modules
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.5. The Differences Between OO and Non-OO Modules

A primarily OO module is distinguished from a primarily non-OO module in two ways:

  • A primarily OO module has functions that are meant to be called as a class methods, possibly returning instances upon which you issue further instance method calls.

  • A primarily non-OO module generally doesn't export any functions at all, making the import list rather irrelevant.

Because methods of the OO module are meant to be called as class methods, they should all set aside their first argument, which is the class name. This class name blesses a new instance but is otherwise ignored. Thus, you should not call OO modules as if they were functional modules, and vice versa. Stick with the design of the module.

Previous | Home | Next
12.4. A More Typical Object-Oriented Module: Math::BigInt | Book Index | 12.6. What use Is Doing
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.6. What use Is Doing

So, just what is that use doing? How does the import list come in to action? Perl interprets the use list as a particular form of BEGIN block wrapped around a require and a method call. For example, the following two operations are equivalent:

use Island::Plotting::Maps qw( load_map scale_map draw_map );

BEGIN {
  require Island::Plotting::Maps;
  Island::Plotting::Maps->import( qw( load_map scale_map draw_map ) );
}

Break this code down piece by piece. First, the require. This require is a package-name require, rather than the string-expression require from earlier chapters. The colons are turned into the native directory separator (such as / for Unix-like systems), and the name is suffixed with .pm (for "perl module"). For this example on a Unix-like system, you end up with:

require "Island/Plotting/Maps.pm";

Recalling the operation of require from earlier, this means you look in the current value of @INC, checking through each directory for a subdirectory named Island that contains a further subdirectory named Plotting that contains the file named Maps.pm.[66]

[66]The .pm portion is defined by the interface and can't be changed. Thus, all module filenames must end in dot-p-m.

If an appropriate file isn't found after looking at all of @INC, the program dies.[67] Otherwise, the first file found is read and evaluated. As always with require, the last expression evaluated must be true (or the program dies),[68] and once a file has been read, it will not be reread if requested again.[69]

[67]Trappable with an eval, of course.

[68]Again trappable with eval.

[69]Thanks to the %INC hash.

In the module interface, the require'd file is expected to define subroutines in the same-named package, not the caller's package. So, for example, a portion of the File::Basename file might look something like this, if you took out all the good stuff:

package File::Basename;
sub dirname { ... }
sub basename { ... }
sub fileparse { ... }
1;

These three subroutines are then defined in the File::Basename package, not the package in which the use occurs. A require'd file must return a true value, so it's traditional to use 1; as the last line of a module's code.

How are these subroutines imported from the module's package to the use r's package? That's the second step inside the BEGIN block. A routine called import in the module's package is called, passing along the entire import list.The module author is responsible for providing an appropriate import routine. It's easier than it sounds, as discussed later in this chapter.

Finally, the whole thing is wrapped in a BEGIN block. This implies that the use operation happens at compile time, rather than runtime, and indeed it does. Thus, subroutines are associated with those defined in the module, prototypes are properly defined, and so on.

Previous | Home | Next
12.5. The Differences Between OO and Non-OO Modules | Book Index | 12.7. Setting the Path at the Right Time
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.7. Setting the Path at the Right Time

The downside of use being executed at compile time is that it also looks at @INC at compile time, which can break your program in hard-to-understand ways unless you take @INC into consideration.

For example, suppose you have your own directory under /home/gilligan/lib, and you place your own Navigation::SeatOfPants module in /home/gilligan/lib/Navigation/SeatOfPants.pm. Simply saying:

use Navigation::SeatOfPants;

is unlikely to do anything useful because only the system directories (and typically the current directory) are considered for @INC. However, even adding:

push @INC, "/home/gilligan/lib";   # broken
use Navigation::SeatOfPants;

doesn't work. Why? Because the push happens at runtime, long after the use was attempted at compile time. One way to fix this is to add a BEGIN block around the push:

BEGIN { push @INC, "/home/gilligan/lib"; }
use Navigation::SeatOfPants;

Now the BEGIN block compiles and executes at compile time, setting up the proper path for the following use.

However, this is noisy and prone to require far more explanation than you might be comfortable with, especially for the maintenance programmer who has to edit your code later. Let's replace all that clutter with a simple pragma:

use lib "/home/gilligan/lib";
use Navigation::SeatOfPants;

Here, the lib pragma takes one or more arguments and adds them at the beginning of the @INC array (think "unshift").[70] It does so because it is processed at compile time, not runtime. Hence, it's ready in time for the use immediately following.

[70]use lib also unshifts an architecture-dependent library below the requested library, making it more valuable than the explicit counterpart presented earlier.

Because a use lib pragma will pretty much always have a site-dependent pathname, it is traditional and encouraged to put it near the top of the file. This makes it easier to find and update when the file needs to move to a new system or when the lib directory's name changes. (Of course, you can eliminate use lib entirely if you can install your modules in a standard @INC locations, but that's not always practical.)

Think of use lib as not "use this library," but rather "use this path to find my libraries (and modules)." Too often, you see code written like:

use lib "/home/gilligan/lib/Navigation/SeatOfPants.pm"; # WRONG

and then the programmer wonders why it didn't pull in the definitions. Be aware that use lib indeed runs at compile time, so this also doesn't work:

my $LIB_DIR = "/home/gilligan/lib";
...
use lib $LIB_DIR;     # BROKEN
use Navigation::SeatOfPants;

Certainly the declaration of $LIB_DIR is established at compile time (so you won't get an error with use strict, although the actual use lib should complain), but the actual initialization to the /home/gilligan/lib/ path happens at runtime. Oops, too late again!

At this point, you need to put something inside a BEGIN block or perhaps rely on yet another compile-time operation: setting a constant with use constant:

use constant LIB_DIR => "/home/gilligan/lib";
...
use lib LIB_DIR;
use Navigation::SeatOfPants;

There. Fixed again. That is, until you need the library to depend on the result of a calculation. (Where will it all end? Somebody stop the madness!) This should handle about 99 percent of your needs.

Previous | Home | Next
12.6. What use Is Doing | Book Index | 12.8. Importing with Exporter
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.8. Importing with Exporter

Earlier we skipped over that "and now magic happens" part where the import routine (defined by the module author) is supposed to take File::Basename::fileparse and somehow alias it into the caller's package so it's callable as fileparse.

Perl provides a lot of introspection capabilities. Specifically, you can look at the symbol table (where all subroutines and most variables are named), see what is defined, and alter those definitions. You saw a bit of that back in the AUTOLOAD mechanism earlier. In fact, as the author of File::Basename, if you simply want to force filename, basename, and fileparse from the current package into the main package, you can write import like this:

sub import {
  no strict 'refs';
  for (qw(filename basename fileparse)) {
    *{"main::$_"} = \&$_;
  }
}

Boy, is that cryptic! And limited. What if you didn't want fileparse? What if you invoked use in a package other than main?

Thankfully, there's a standard import that's available in the Exporter module. As the module author, all you do is add:

use Exporter;
our @ISA = qw(Exporter);

Now the import call to the package will inherit upward to the Exporter class, providing an import routine that knows how to take a list of subroutines[71] and export them to the caller's package.

[71]And variables, although far less common, and arguably the wrong thing to do.

Previous | Home | Next
12.7. Setting the Path at the Right Time | Book Index | 12.9. @EXPORT and @EXPORT_OK
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.9. @EXPORT and @EXPORT_OK

The import provided by Exporter examines the @EXPORT variable in the module's package to determine which variables are exported by default. For example, File::Basename might do something like:

package File::Basename;
our @EXPORT = qw( basename dirname fileparse );
use Exporter;
our @ISA = qw(Exporter);

The @EXPORT list both defines a list of available subroutines for export (the public interface) and provides a default list to be used when no import list is specified. For example, these two calls are equivalent:

use File::Basename;

BEGIN { require File::Basename; File::Basename->import }

No list is passed to import. In that case, the Exporter->import routine looks at @EXPORT and provides everything in the list.[72]

[72]Remember, having no list is not the same as having an empty list. If the list is empty, the module's import method is simply not called at all.

What if you had subroutines you didn't want as part of the default import but would still be available if requested? You can add those subroutines to the @EXPORT_OK list in the module's package. For example, suppose that Gilligan's module provides the guess_direction_toward routine by default but could also provide the ask_the_skipper_about and get_north_from_professor routines, if requested. You can start it like this:

package Navigate::SeatOfPants;
our @EXPORT = qw(guess_direction_toward);
our @EXPORT_OK = qw(ask_the_skipper_about get_north_from_professor);
use Exporter;
our @ISA = qw(Exporter);

The following invocations would then be valid:

use Navigate::SeatOfPants;  # gets guess_direction_toward

use Navigate::SeatOfPants qw(guess_direction_toward); # same

use Navigate::SeatOfPants
  qw(guess_direction_toward ask_the_skipper_about);

use Navigate::SeatOfPants
  qw(ask_the_skipper_about get_north_from_professor);
  ## does NOT import guess_direction_toward!

If any names are specified, they must come from either @EXPORT or @EXPORT_OK, so this request is rejected by Exporter->import:

use Navigate::SeatOfPants qw(according_to_GPS);

because according_to_GPS is in neither @EXPORT nor @EXPORT_OK.[73] Thus, with those two arrays, you have control over your public interface. This does not stop someone from saying Navigate::SeatOfPants::according_to_GPS (if it existed), but at least now it's obvious that they're using something the module author didn't intend to offer them.

[73]This check also catches misspellings and mistaken subroutine names, keeping you from wondering why the get_direction_from_professor routine isn't working.

As described in the Exporter manpage, a few shortcuts are available automatically. You can provide a list that is the same as asking for the default:

use Navigate::SeatOfPants qw(:DEFAULT);

or the default plus some others:

use Navigate::SeatOfPants qw(:DEFAULT get_north_from_professor);

These are rarely seen in practice. Why? The purpose of explicitly providing an import list generally means you want to control the subroutine names you use in your program. Those last examples do not insulate you from future changes to the module, which may import additional subroutines that could collide with your code.[74]

[74]For this reason, it is generally considered a bad idea for an update to a released module to introduce new default imports. If you know that your first release is still missing a function, though, there's no reason why you can't put in a placeholder: sub according_to_GPS { die "not implemented yet" }.

In a few cases, a module may supply dozens or hundreds of possible symbols. These modules can use advanced techniques (described in the Exporter documentation) to make it easy to import batches of related symbols. For example, the core Fcntl module makes the flock constants available as a group with the :flock tag:

use Fcntl qw( :flock );        # import all flock constants
Previous | Home | Next
12.8. Importing with Exporter | Book Index | 12.10. Exporting in a Primarily OO Module
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.10. Exporting in a Primarily OO Module

As seen earlier, the normal means of using an object-oriented module is to call class methods and then methods against instances resulting from constructors of that class. This means that an OO module typically exports nothing, so you'll have:

package My::OOModule::Base;
our @EXPORT = ( ); # you may even omit this line
use Exporter;
our @ISA = qw(Exporter);

As stated in Chapter 8, you can even shorten this down:

package My::OOModule::Base;
use base qw(Exporter);

What if you then derive a class from this base class? The most important thing to remember is that the import method must be defined from the Exporter class, so you add it like so:

package My::OOModule::Derived;
use base qw(Exporter My::OOModule::Base);

However, wouldn't the call to My::OOModule::Derived->import eventually find its way up to Exporter via My::OOModule::Base? Sure it would. So you can leave that out:

package My::OOModule::Derived;
use base qw(My::OOModule::Base);

Only the base classes at the top of the tree need specify Exporter and only when they derive from no other classes.

Please be aware of all the other reserved method names that can't be used by your OO module (as described in the Exporter manpage). At the time of this writing, the list is export_to_level, require_version, and export_fail. Also, you may wish to reserve unimport because that routine will be called by replacing use with no. That use is rare for user-written modules, however.

Even though an OO module typically exports nothing, you might choose to export a named constructor or management routine. This routine typically acts a bit like a class method but is meant to be called as a normal routine.

One example can be found in the LWP library (on the CPAN). The URI::URL module (now deprecated and replaced by the URI module) deals with universal resource identifiers, most commonly seen as URLs such as http://www.gilligan.crew.hut/maps/island.pdf. You can construct a URI::URL object as a traditional object constructor with:

use URI::URL;
my $u = URI::URL->new("http://www.gilligan.crew.hut/maps/island.pdf");

The default import list for URI::URL also imports a url subroutine, which can be used as a constructor as well:

use URI::URL;
my $u = url("http://www.gilligan.crew.hut/maps/island.pdf");

Because this imported routine isn't a class method, you don't use the arrow method call to invoke it. Also, the routine is unlike anything else in the module: no initial class parameter is passed. Even though normal subroutines and method calls are both defined as subroutines in the package, the caller and the author must agree as to which is which.

The url convenience routine was nice, initially. However, it also clashed with the same-name routine in CGI.pm, leading to interesting errors (especially in a mod_perl setting). (The modern interface in the URI module doesn't export such a constructor.) Prior to that, in order to prevent a crash, you had to remember to bring it in as:

use URI::URL ( );        # don't import "url"
my $u = URI::URL->new(...);
Previous | Home | Next
12.9. @EXPORT and @EXPORT_OK | Book Index | 12.11. Custom Import Routines
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.11. Custom Import Routines

Let's use CGI.pm as an example of a custom import routine. Not satisfied with the incredible flexibility of the Exporter's import routine, author Lincoln Stein created a special import for the CGI module.[75] If you've ever gawked at the dizzying array of options that can appear after use CGI, it's all a simple matter of programming.

[75]Some have dubbed this the "Lincoln Loader" out of simultaneous deep respect for Lincoln and the sheer terror of having to deal with something that just doesn't work like anything else they've encountered.

As part of the extension provided by this custom import, you can use the CGI module as an object-oriented module:

use CGI;
my $q = CGI->new;         # create a query object
my $f = $q->param("foo"); # get the foo field

or a function-oriented module:

use CGI qw(param);        # import the param function
my $f = param("foo");     # get the foo field

If you don't want to spell out every possible subfunction, bring them all in:

use CGI qw(:all);         # define "param" and 800-gazillion others
my $f = param("foo");

And then there's pragmata available. For example, if you want to disable the normal sticky field handling, simply add -nosticky into the import list:

use CGI qw(-nosticky :all);

If you want to create the start_table and end_table routines, in addition to the others, it's simply:

use CGI qw(-nosticky :all *table);

Truly a dizzying array of options.

Previous | Home | Next
12.10. Exporting in a Primarily OO Module | Book Index | 12.12. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


12.12. Exercise

The answers for all exercises can be found in Section A.11.

12.12.1. Exercise [15 min]

Take the library you created in Chapter 2 and turn it into a module you can bring in with use. Alter the invoking code so that it uses the imported routines (rather than the full path), and test it.

Previous | Home | Next
12.11. Custom Import Routines | Book Index | 13. Writing a Distribution
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 13. Writing a Distribution

Contents:

Starting with h2xs
Looking at the Templates
The Prototype Module Itself
Embedded Documentation
Controlling the Distribution with Makefile.PL
Alternate Installation Locations (PREFIX=...)
Trivial make test
Trivial make install
Trivial make dist
Using the Alternate Library Location
Exercise

In Chapter 12, you created a fictional Island::Plotting::Maps module, and built the right support for Exporter so that you could include use Island::Plotting::Maps in a program.

While the resulting .pm file is useful, it's not very practical. There's a lot more to building a real module than just creating the .pm file. You'll also need to consider and implement the following questions:

Installation location
How and where is the .pm file installed so a program can find the module in its @INC path?

Documentation
Where is the documentation for the module? How is the documentation installed so the user can read it?

Archive completeness
If there are any accompanying files, where are they? How can the end user know if any missing files are missing?

Testing
What test harnesses can the developer run to verify correct operation, including testing against older known bugs? Can these same tests be run by the installer to ensure proper operation in the target environment?

C-language interfaces
If the module contains C or C++ code (not covered here), how can the developer describe how to compile and link the code in the developer's environment, or the end user environment?

As Roy Scheider uttered in the movie Jaws: "You're gonna need a bigger boat." That "bigger boat" is the difference between a module and a distribution.

13.1. Starting with h2xs

A distribution contains the module (or collection of related modules), plus all the support files required to document, test, ship, and install the module. While you could potentially construct all these files by hand, it's much simpler to use a tool that comes with Perl, awkwardly called h2xs [76]

[76]The name h2xs has an interesting pedigree. Back in the early days of Perl 5, Larry invented the XS language to describe the glue code that Perl needs to talk to C-language functions and libraries. Originally, this code was written entirely by hand, but the h2xs tool was written to scan simple C-include header files (ending in .h) and generate most of the XS directly. Hence, h "2" (to) XS. Over time, more functions were added, including generating template files for the rest of the distribution. Now here we are, about to describe how to use h2xs for things that aren't either h or xs. Amazing.

The h2xs tool creates a series of template files that serve as a starting point for the distribution files. You simply need to say h2xs -XAn, followed by the name of the module—in this case, Island::Plotting::Maps.[77] Here's what the output looks like:[78]

[77]If there's more than one module in the distribution, it should be the name of the most important module. Others can be added later.

[78]The exact behavior and output of h2xs may vary depending upon your version of Perl.

$ h2xs -XAn Island::Plotting::Maps
Defaulting to backwards compatibility with perl 5.8.0
If you intend this module to be compatible with earlier perl versions, please
specify a minimum perl version with the -b option.

Writing Island/Plotting/Maps/Maps.pm
Writing Island/Plotting/Maps/Makefile.PL
Writing Island/Plotting/Maps/README
Writing Island/Plotting/Maps/t/1.t
Writing Island/Plotting/Maps/Changes
Writing Island/Plotting/Maps/MANIFEST
Previous | Home | Next
12.12. Exercise | Book Index | 13.2. Looking at the Templates
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.2. Looking at the Templates

You'll create some subdirectories below the current directory and a bunch of files in the lowest of those directories. Let's look at them to see what they are. First, cd into the directory:

$ cd Island/Plotting/Maps

Now, let's examine the MANIFEST file:

$ cat MANIFEST
Changes
Makefile.PL
MANIFEST
Maps.pm
README
t/1.t

The MANIFEST file resembles a table of contents for the distribution. When you eventually bundle up everything and ship it off to the CPAN or the ultimate recipient, the bundling tool looks at MANIFEST to know what to include, and the unpacking tool verifies that everything in MANIFEST is present at the destination. Of course, MANIFEST lists MANIFEST, but it also lists everything else created by h2xs automatically.

While maintaining a MANIFEST sounds like it might be painful, you can be assured that you won't accidentally include your "notes to self" in the distribution just because the file happened to be in the wrong directory. Specific steps discussed later keep the MANIFEST up to date.

The next, mostly uninteresting, file is README, which is self-describing:

$ cat README
Island/Plotting/Maps version 0.01
=  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==

The README is used to introduce the module and provide instructions on
how to install the module, any machine dependencies it may have (for
example C compilers and installed libraries) and any other information
that should be provided before the module is installed.

A README file is required for CPAN modules since CPAN extracts the
README file from a module distribution so that people browsing the
archive can use it get an idea of the modules uses. It is usually a
good idea to provide version information here so that people can
decide whether fixes for the module are worth downloading.

INSTALLATION

To install this module type the following:

   perl Makefile.PL
   make
   make test
   make install

DEPENDENCIES

This module requires these other modules and libraries:

  blah blah blah

COPYRIGHT AND LICENCE

Put the correct copyright and licence information here.

Copyright (C) 2002 Ginger Grant

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

Obviously, you will want to edit this file to be whatever you want it to be. The phrase "blah blah blah" is often used in the templates to indicate things that must be changed.[79] If you leave unchanged the blah blah blah and other notes from h2xs to you, potential users will suspect that bugs in the code have also escaped your scrutiny, so proofread this stuff (and your code) before you distribute your module.

[79]When you're bored, you might find it amusing to do a search of the current CPAN for all places in which blah blah blah occurs.

Pay special attention to the copyright and license section. (It should have your name in place of Ginger's name, unless your machine is very confused about who is sitting at the keyboard.) Your employer may require you to change the copyright notice to include your company name rather than your name, for example. Or, if you're including someone else's code in your module, you may need to mention their copyright (or lack thereof) as well.

The README file also has a special responsibility: the master CPAN archiving tools pull out the README file as a separate entry automatically, permitting the file to be indexed by search engines on the various worldwide archives, and to be downloaded and read trivially by the CPAN installation tools. In the CPAN.pm shell, for example, you can say:[80]

[80]Well, you would be able to do this, if there were actually a module on CPAN named Island::Plotting::Maps.

$ perl -MCPAN -eshell
cpan> readme Island::Plotting::Maps

and the contents of the README file will be shown without having to download and unpack the entire distribution.

Another file created as a template is Changes:

$ cat Changes
Revision history for Perl extension Island::Plotting::Maps.

0.01  Wed Oct 16 15:53:23 2002
        - original version; created by h2xs 1.22 with options
                -XAn Island::Plotting::Maps

You'll need to maintain this file manually, unless your interactive development environment has automated tools for such maintenance. Most people will expect to be able to look here to see what has been updated in new releases of your module. Try not to disappoint them. One of the main purposes of the Changes file is debugging: if you realize that a certain bug turned up three releases back, you can look here to remind yourself of new features or bug fixes that were introduced in that release.

Previous | Home | Next
13. Writing a Distribution | Book Index | 13.3. The Prototype Module Itself
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.3. The Prototype Module Itself

Now you come to the most important part of the distribution: the module itself. Finally, actual code:

$ cat Maps.pm
package Island::Plotting::Maps;

It looks good so far. The module automatically starts with an appropriate package directive. Following that, you see:

use 5.008;
use strict;
use warnings;

Now you're declaring that the module is compatible with Perl 5.8.0 or later and that the compiler restrictions and warnings are enabled automatically. Good practices are encouraged here. Obviously, you're free to delete or modify anything inappropriate.

Then comes Exporter:

require Exporter;

our @ISA = qw(Exporter);

These lines support the import method call needed to make use work. This is fine for a nonobject-oriented module, but for an object-oriented module inheriting from a parent (base) class, you'll want to replace them with:

use base qw(Our::Parent::Class);

Resulting in more Exporter control:

our %EXPORT_TAGS = ( 'all' => [ qw(

) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(

);

Every symbol you wish to possibly import as a result of the use operation should be placed into the first qw( ) list. This lets you say:

 use OurModule qw(:all)

to get all possible symbols.[81]

[81]Technically, you don't need :all because /^/ (include all symbols that match at least a beginning of string) does the same. Many people are familiar with typing :all, and it's far more self-documenting than /^/ is, so include it if you can.

Every symbol you wish to export by default on a missing import list should go into the last qw( ). (Any symbol in the @EXPORT list is automatically a member of the @EXPORT_OK list, but you'll want to list it again it the first qw( ) list so it comes in via the :all method.)

Recall from Chapter 12 that a typical object-oriented module exports nothing because the interface is entirely through class method calls and instance method calls, neither of which require subroutines in the invoker's package.

Next, you'll see the version number:

our $VERSION = '0.01';

This version number is important for many reasons:

Unique identification
The version number identifies a particular release of a particular module as it floats around the Internet.

Filename generation
The archive of the distribution includes the version number of the primary module by default.

Upgrade indication
Generally, numbers that increase numerically supersede previous versions. For this test, the number is considered a floating-point number, so 2.10 (which is really 2.1) is less than 2.9 (which must be the same as 2.90, by the same logic). To avoid confusion, if you've got two digits after the decimal point in one release, you shouldn't change it in the next without a very good reason.

Interface stability
Generally, numbers that begin with 0 are alpha or beta, with external interfaces that may still be in flux. Also, most people use a major version number change (from 1.x to 2.x, etc.) to indicate a potential break in upward compatibility.

Recognition by the various CPAN tools
The CPAN distribution management tools use the version number to track a particular release, and the CPAN installation tools can determine missing or out-of-date distributions.

Perl's own operators
The use operator can be given a version number in addition to (or instead of) the import list, forcing the use operation to fail if the imported module is not equal or greater to that version:

use Island::Plotting::Maps 1.10 qw{ map_debugger };

Generally, you can start with the 0.01 given by the template and increase it consistently with each new test release. Often, you can coordinate this version number with some source code control system.[82]

[82]The perlmod page includes an example that extracts the CVS/RCS version number for the module's version number.

Now you're past the header information and down to the core of your module. In the template, it is indicated by a simple comment:

# Preloaded methods go here.

What? You didn't think the h2xs tool would even write the module for you, now did you? Anyway, this is where the code goes, usually as a series of subroutines, possibly preceded by some shared module data (using my declarations), and perhaps a few package variables (using our declarations in recent Perl versions). Following the code, you'll find your necessary true value:

1;

so the require (inside the use) doesn't abort.

Previous | Home | Next
13.2. Looking at the Templates | Book Index | 13.4. Embedded Documentation
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.4. Embedded Documentation

Immediately following the mandatory true value in the file, you'll find the _ _END_ _ marker:

_ _END_ _

This marker tells Perl that there's no Perl code anywhere later in the file and that the Perl parser can stop now.[83]

[83]The data immediately following the _ _END_ _ marker is available by reading from the DATA filehandle, which is a great way to include a small amount of constant data with your program. However, that's not why we're doing that here.

Following the _ _END_ _ marker, you'll find the embedded documentation for the module:

# Below is stub documentation for your module. You'd better edit it!

=head1 NAME

Island::Plotting::Maps - Perl extension for blah blah blah

=head1 SYNOPSIS

  use Island::Plotting::Maps;
  blah blah blah

=head1 ABSTRACT

  This should be the abstract for Island::Plotting::Maps.
  The abstract is used when making PPD (Perl Package Description) files.
  If you don't want an ABSTRACT you should also edit Makefile.PL to
  remove the ABSTRACT_FROM option.

=head1 DESCRIPTION

Stub documentation for Island::Plotting::Maps, created by h2xs. It looks like the
author of the extension was negligent enough to leave the stub
unedited.

Blah blah blah.

=head1 EXPORT

None by default.

=head1 SEE ALSO

Mention other useful documentation such as the documentation of
related modules or operating system documentation (such as man pages
in UNIX), or any relevant external documentation such as RFCs or
standards.

If you have a mailing list set up for your module, mention it here.

If you have a web site set up for your module, mention it here.

=head1 AUTHOR

Ginger Grant, <ginger@island.cocoanet>

=head1 COPYRIGHT AND LICENSE

Copyright 2002 by Ginger Grant

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

This documentation is in POD format. The perlpod manpage describes the POD format in detail. Like Perl itself, POD is said to mean various things, such as Perl Online Documentation or Plain Old Documentation, and so on. To most of us, it's just POD.

As the template describes, you're expected to edit portions of this text to fit your particular module. In particular, leaving the blah blah blah is considered bad form.

The POD information is extracted automatically by the installation process to create the native documentation format, such as Unix manpages or HTML. Also, the perldoc command can locate POD in the installed scripts and modules and format it for the screen.

One nice thing about POD is that it can be interspersed with the Perl implementation code it describes. For example, from Chapter 12, you needed three subroutines for the Island::Plotting::Maps module. You can commingle the code and documentation. Each POD directive (a line beginning with an equal sign) switches from Perl mode (lines interpreted as Perl code) to POD mode (lines interpreted as documentation), and each line beginning with =cut switches back. Thus, the resulting file looks something like:

package Island::Plotting::Maps;
[... stuff down to the $VERSION setting above ...]

=head1 NAME

Island::Plotting::Maps - Plot maps on the island

=head1 SYNOPSIS

  use Island::Plotting::Maps;
  load_map("/usr/share/map/hawaii.map");
  scale_map(20, 20);
  draw_map(*STDOUT);

=head1 DESCRIPTION

This module draws maps.  [ more here ]

=over

=item load_map($filename)

This function [ more here ].

=cut

sub load_map {
  my $filename = shift;
  [ rest of subroutine ]
}

=item scale_map($x, $y)

This function [ more here ].

=cut

sub scale_map {
  my ($x, $y) = (shift, shift);
  [ rest of subroutine ]
}

=item draw_map($filehandle)

This function [ more here ].

=cut

sub draw_map {
  my $filehandle = shift;
  [ rest of subroutine ]
}

=back

=head1 SEE ALSO

"Map Reading for Dummies", "First Mates: why they're not the captain",
and be sure to consult with the Professor.

=head1 AUTHOR

Ginger Grant, <ginger@island.cocoanet>

=head1 COPYRIGHT AND LICENSE

Copyright 2002 by Ginger Grant

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;

As you can see, the documentation for the subroutines is now very near the subroutine definition, in hope that as one gets updated, the other will be similarly changed. (Out-of-date documentation is often worse than no documentation at all because at least with no documentation at all, the user is forced to look at the source code.) Many modules in the CPAN do this. The penalty is a very slight increase in compile-time activity because the Perl parser has to skip over the embedded POD directives.

Whether you place your POD at the end of the file (as the template suggests) or intertwined with your code (as presented in the preceding paragraphs) the important thing to remember is always document your code. Even if it's just for you, a few months later, when your brain has been 42,000 other places before you look at the code again, you'll be glad to have those notes. Documentation is important.

Previous | Home | Next
13.3. The Prototype Module Itself | Book Index | 13.5. Controlling the Distribution with Makefile.PL
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.5. Controlling the Distribution with Makefile.PL

The Perl developers have chosen to rely on the standard Unix make utility to build and install Perl itself, and that same mechanism is used for additional modules.[84] If you have a non-Unix system, a make-like utility should also be available. On Windows, for example, you may have dmake or another program. The command perl -V:make will tell you the name of your make utility program; if it says make='nmake', simply use nmake wherever you use make. In any case, you should call the controlling file a Makefile, even though its name may vary as well.

[84]The Module::Build module currently in development may replace all of that some day but is only in a pre-release form at the time of this writing.

However, crafting a Makefile is tricky but repetitive. And what better way to accomplish a tricky but repetitive task than with a program? Since you're talking about Perl add-on modules, you know that Perl is available, so how about a Perl program to generate the Makefile?

That's exactly what happens. The distribution is required to contain a Makefile.PL, which is a Perl program to build a Makefile. Then from there, you use make (or something like it) to control all of the remaining tasks.

The h2xs tool generates a template Makefile.PL that you probably won't even need to touch for single-module distributions:

$ cat Makefile.PL
use 5.008;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    'NAME'                => 'Island::Plotting::Maps',
    'VERSION_FROM'        => 'Maps.pm', # finds $VERSION
    'PREREQ_PM'                => {  }, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM => 'Maps.pm', # retrieve abstract from module
       AUTHOR     => 'Ginger Grant <ginger@island.cocoanet>') : ( )),
);

Yes, this is a Perl program. The WriteMakefile routine is defined by the ExtUtils::MakeMaker module (included with Perl) to generate a Makefile. As the developer of the module, use this makefile to build and test your module and prepare a distribution file:

$ perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Island::Plotting::Maps

The ultimate user of your distribution will execute the identical command at their site. However, the Makefile will most likely be different, reflecting the differences in installation locations, local policies, and even the C compiler and linking instructions appropriate for their architecture. It's a nice system that has worked quite well over the years.

The creation of the Makefile.PL (and resulting Makefile) is quite flexible. For example, you can run code to ask the person installing your module about the locations of other installed libraries or tools, or get options for variations in activity.[85]

[85]Please keep the number of questions to a minimum, however. Most people are irritated when asked a series of questions, especially when they are just upgrading your module. If possible, store the answers in a configuration module that you install so that a later invocation of your installer can pull the previous answers as defaults.

The PREREQ_PM setting is important if your module depends on non-core Perl modules, especially if you plan to upload your code to the CPAN. Proper use of the prerequisites list can make installing your module nearly painless, and your user community will thank you.

Previous | Home | Next
13.4. Embedded Documentation | Book Index | 13.6. Alternate Installation Locations
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.6. Alternate Installation Locations (PREFIX=...)

Speaking of installation locations, the Makefile built by the default invocation of Makefile.PL presumes that the module will be installed in the system-wide Perl directory that all Perl programs can access directly with the built-in @INC path.

However, if you are testing a module, you certainly don't want to install it into the system directories, possibly corrupting a previous version of your module and breaking production programs.

Also, if you're not the system administrator, it's unlikely that you can change those central Perl directories because that would be a great way to insert a trojan horse for privileged users to stumble across.[86]

[86]Even if you weren't the system administrator, you'd soon have all the powers of the system administrator.

Luckily, the Makefile contains provisions for considering an alternate installation location for scripts, manpages, and libraries. The easiest way to specify an alternate location is with a PREFIX value as a parameter on the command line:

$ perl Makefile.PL PREFIX=~/Testing
Checking if your kit is complete...
Looks good
Writing Makefile for Island::Plotting::Maps

Although the messages don't indicate anything different, the Makefile will now install scripts to $PREFIX/bin, manpages below $PREFIX/man, and libraries below $PREFIX/lib/site_perl. In this case, you're selected a subdirectory of your home directory called Testing as the value of $PREFIX.

If you were a project librarian, managing code for a team of developers, you might instead say something like:

$ perl Makefile.PL PREFIX=/path/to/shared/area

which then builds the files into a shared area. Of course, you'd need write privileges to such a directory, and the rest of the team would have to add the bin subdirectory to their PATH, the man subdirectory to their MANPATH, and the lib/site_perl directory to their @INC path, as you'll see shortly.

Previous | Home | Next
13.5. Controlling the Distribution with Makefile.PL | Book Index | 13.7. Trivial make test
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.7. Trivial make test

Testing. Testing. Testing.

Testing is important. First, you should at least ensure that the code you've written even compiles before you install it and start playing with it. That test is free. You can invoke it directly from the newly created Makefile by simply typing make test, as in:

$ make test
cp Maps.pm blib/lib/Island/Plotting/Maps.pm
PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0,
'blib/lib', 'blib/arch')" t/*.t
t/1....ok
All tests successful.
Files=1, Tests=1,  1 wallclock secs ( 0.08 cusr +  0.04 csys =  0.12 CPU)

But what happened there?

First, the .pm file was copied to the testing staging area: the area headed by blib (build library) below the current directory.[87]

[87]Had there been XS files or other more complex build steps, these also would have happened here.

Next, the perl that invoked the Makefile.PL is called upon to run the test harness—a program that manages all test invocations and reports the results at the end.[88]

[88]The perl that invoked the Makefile.PL is used for all configuration decisions. If you have more than one version of Perl installed on your system, be sure to execute the Makefile.PL with the correct one. From there, full paths are always used, so there's no chance of mixing anything else up.

The test harness runs all files in the t subdirectory that end in .t in their natural order. You have only one file (created by h2xs), which looks like this:

$ cat t/1.t
# Before 'make install' is performed this script should be runnable with
# 'make test'. After 'make install' it should work as 'perl 1.t'

#########################

# change 'tests => 1' to 'tests => last_test_to_print';

use Test::More tests => 1;
BEGIN { use_ok('Island::Plotting::Maps') };

#########################

# Insert your test code below, the Test::More module is use( )ed here so read
# its man page ( perldoc Test::More ) for help writing this test script.

It's a simple test program. The test pulls in the Test::More module, described further in Chapter 14. The import list for the module is treated specially; you're declaring that this test file consists of only one "test."

The test is given in the following line and attempts to use the module. If this succeeds, you get an "OK" sign, and the overall test file succeeds. This would fail with bad syntax, or perhaps if you forgot to have that true value at the end of the file.

In this example, the test succeeds, so you get a message for it and a summary of the CPU time used for the test.

Previous | Home | Next
13.6. Alternate Installation Locations | Book Index | 13.8. Trivial make install
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.8. Trivial make install

Since you know the module can at least compile, let's be daring and install it. Of course, you're installing it only into the path specified by the PREFIX in the earlier step, but that's enough to show how it would have worked for the ultimate user's installation.[89]

[89]If you're playing along at home, be sure not to install this pretend module anywhere but a temporary, testing, directory. Although removing an installed module is generally difficult, you'll be able to simply delete the testing directory, along with its contents.

The installation is triggered with make install:

$ make install
Manifying blib/man3/Island::Plotting::Maps.3
Installing /home/ginger/Testing/lib/site_perl/5.8.0/Island/Plotting/Maps.pm
Installing /home/ginger/Testing/man/man3/Island::Plotting::Maps.3
Writing /home/ginger/Testing/lib/site_perl/5.8.0/darwin/auto/Island/Plotting/Maps/.
packlist
Appending installation info to /home/ginger/Testing/lib/site_perl/5.8.0/darwin/
perllocal.pod

Note that you're installing the module below the $PREFIX/lib/site_lib directory (presuming a PREFIX of /home/ginger/Testing from earlier) and a manpage below $PREFIX/man (on Unix machines, in the Section 3 area for subroutines, for example). The manpage comes automatically when you extract the module's POD data and convert it to troff -man code, making it compatible with the Unix man command.[90]

[90]On a non-Unix system, or even a few odd Unix systems, you'll see different behavior, but roughly the same overall result.

Previous | Home | Next
13.7. Trivial make test | Book Index | 13.9. Trivial make dist
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.9. Trivial make dist

After some testing, you may decide it's time to share your work with friends and associates. To do this, make a single distribution file. Many mechanisms are available to do this, but the most common one on most modern Unix platforms is the GNU gzip compressed tar archive, commonly named with a .tar.gz or .tgz extension.

Again, with a simple make invocation (make dist), you end up with the required file:

$ make dist
rm -rf Island-Plotting-Maps-0.01
/usr/local/bin/perl "-MExtUtils::Manifest=manicopy,maniread" \
        -e "manicopy(maniread( ),'Island-Plotting-Maps-0.01', 'best');"
mkdir Island-Plotting-Maps-0.01
mkdir Island-Plotting-Maps-0.01/t
tar cvf Island-Plotting-Maps-0.01.tar Island-Plotting-Maps-0.01
Island-Plotting-Maps-0.01/
Island-Plotting-Maps-0.01/Changes
Island-Plotting-Maps-0.01/Makefile.PL
Island-Plotting-Maps-0.01/MANIFEST
Island-Plotting-Maps-0.01/Maps.pm
Island-Plotting-Maps-0.01/README
Island-Plotting-Maps-0.01/t/
Island-Plotting-Maps-0.01/t/1.t
rm -rf Island-Plotting-Maps-0.01
gzip --best Island-Plotting-Maps-0.01.tar

Now there's a file named Island-Plotting-Maps-0.01.tar.gz in the directory. The version number in the name comes from the module's $VERSION variable.[91]

[91]If there's more than one module, you need to designate the primary module in the Makefile.PL.

Previous | Home | Next
13.8. Trivial make install | Book Index | 13.10. Using the Alternate Library Location
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.10. Using the Alternate Library Location

The libraries are installed relative to the PREFIX specified earlier. If Ginger used a PREFIX of /home/ginger/Testing, you need to add the appropriate directory below it to the search path. The use lib directive of:

use lib "/home/ginger/Testing/lib/site_perl";

does the right thing to find the version-specific directory below it, as well as the architecture-specific directory below it, if needed (usually for architecture-specific files, such as compiled binaries).

You can also specify the include directory on the command line with a -M option:

$ perl -Mlib=/home/ginger/Testing/lib/site_perl myproggy

or a -I option:

$ perl -I /home/ginger/Testing/lib/site_perl myproggy

or even by setting the PERL5LIB environment variable (using sh-like syntax here):

$ PERL5LIB=/home/ginger/Testing/lib/site_perl; export PERL5LIB
$ ./myproggy

However, the downside of any of these methods (other than the use lib method) is that they require you to do something more than just execute the file. If someone (or something) else (such as a coworker or a web server) executes your program, it's unlikely that the proper environment variable or command-line option will be present. Your program will fail because it can't find your locally installed module.

Use use lib, when you can. The other ways are useful mainly for trying out a new version of an old module before replacing the old module (and possibly breaking the programs that use it).

Previous | Home | Next
13.9. Trivial make dist | Book Index | 13.11. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


13.11. Exercise

The answers for all exercises can be found in Section A.12.

13.11.1. Exercise [30 min]

Package up the module from Chapter 12 as a distribution. Be sure to add the proper POD documentation for the subroutine. Test the module, install it locally, and then build a distribution file. If you have time, unpack the distribution into a different directory, pick a new prefix, and install it again to verify that the distribution archive contains everything necessary.

Previous | Home | Next
13.10. Using the Alternate Library Location | Book Index | 14. Essential Testing
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 14. Essential Testing

Contents:

What the Test Harness Does
Writing Tests with Test::Simple
Writing Tests with Test::More
Conditional Tests
More Complex Tests (Multiple Test Scripts)
Testing Things That Write to STDOUT and STDERR
Exercise

As briefly described in Chapter 13, a distribution contains a testing facility invoked from make test. This testing facility permits a module author to write and run tests during development and maintenance and the ultimate module installer to verify that the module works in the new environment.

Why have tests during development? One emerging school of thought states that the tests should be written first, even before the module is created, as a reflection of the module's specification. Of course, the initial test run against the unwritten module will show nearly complete failure. However, as functionality is added, proper functionality is verified immediately. (It's also handy to invoke the tests frequently as you code to make sure you're getting closer to the goal, not breaking more things.)

Certainly, errors may be found in the test suite. However, the defect rate for tests are usually far lower than the defect rate for complex module code; if a test fails, it's usually a good indication that there's more work to be done.

But even when Version 1.0 of the module is finally shipped, there's no need to abandon the test suite. Unless You code the mythical "bug-free module," there will be bug reports. Each bug report can (and should) be turned into a test.[92] While fixing the bug, the remaining tests prevent regression to a less functional version of the code—hence the name regression testing.

[92]If you're reporting a bug in someone else's code, you can generally assume that sending them a test for the bug will be appreciated. A patch would be appreciated even more!

Then there's always the 1.1 or 2.0 releases to think about. When you want to add functionality, start by adding tests.[93] Because the existing tests ensure your upward compatibility, you can be confident that your new release does everything the old release did, and then some.

[93]And writing the documentation at the same time, made easier by Test::Inline, as you'll see later.

Good tests also give small examples of what you meant in your documentation, in case your writing isn't clear.[94] Good tests also give confidence to the installer that this code is portable enough to work on both your system and his system, including all stated and unstated dependencies.

[94]Many modules we've used from the CPAN were documented more by test examples than by the actual POD. Of course, any really good example should be repeated in your module's POD documentation.

Testing is an art. Dozens of how-to-test books have been written and read, and often ignored. Mostly, it's important to remember everything you have ever done wrong while programming (or heard other people do), and then test that you didn't do it again for this project.

Test things that should break (throw exceptions or return false values) as well as things that should work. Test the edges. Test the middle. Test one more or one less than the edge. Test things one at a time. Test many things at once. If something should throw an exception, make sure it didn't also negatively affect the state of the world before it threw the exception. Pass extra parameters. Pass insufficient parameters. Mess up the capitalization on named parameters. Throw far too much data at it. Throw far too little. Test what happens for undef. And so on.

For example, suppose that you want to test Perl's sqrt function, which calculates square roots. It's obvious that you need to make sure it returns the right values when its parameter is 0, 1, 49, or 100. It's nearly as obvious to see that sqrt(0.25) should come out to be 0.5. You should also ensure that multiplying the value for sqrt(7) by itself gives something between 6.99999 and 7.00001.[95] You should make sure that sqrt(-1) yields a fatal error and that sqrt(-100) does too. See what happens when you request sqrt(&test_sub( )), and &test_sub returns a string of "10000". What does sqrt(undef) do? How about sqrt( ) or sqrt(1,1)? Maybe you want to give your function a googol: sqrt( '1' . '0' x 100 ). Because this function is documented to work on $_ by default, you should ensure that it does so. Even a simple function such as sqrt should get a couple of dozen tests; if your code does more complex tasks than sqrt does, expect it to need more tests, too. There are never too many tests.

[95]Remember, floating-point numbers aren't always exact; there's usually a little roundoff. Feel free to write your tests to require more precision than this test implies but don't require more precision than you can get on another machine!

If you write the code and not just the tests, think about how to get every line of your code exercised at least once for full code coverage. (Are you testing the else clause? Are you testing every elsif case?) If you aren't writing the code or aren't sure, use the code coverage facilities.[96]

[96]Basic code coverage tools such as Devel::Cover are found in the CPAN.

Check out other test suites. The Perl distribution itself comes with thousands of tests, designed to verify that Perl compiles correctly on your machine in every possible way. Michael Schwern earned the title of "Perl Test Master" for getting the Perl core completely tested, and, still constantly beats the drum for "test! test! test!" in the community.

In summary, please write tests. Let's see how this is done.

14.1. What the Test Harness Does

Tests are usually invoked (either for the developer or the installer) using make test. The Makefile invokes the test harness, which eventually gets around to using the Test::Harness module to run the tests.

Each test lives in a separate .t file in the t directory at the top level of the distribution. Each test is invoked separately, so an exit or die terminates only that test file, not the whole testing process.

The test file communicates with the test harness through simple messages on standard output. The three most important messages are the test count, a success message, and a failure message.

An individual test file consists of one or more tests. These tests are numbered as small integers starting with one. The first thing a test file must announce to the test harness (on STDOUT) is the expected test number range, as a string 1..n. For example, if there are 17 tests, the first line of output should be:

1..17

followed by a newline. The test harness uses the upper number here to verify that the test file hasn't just terminated early. If the test file is testing optional things and has no testing to do for this particular invocation, the string 1..0 suffices.

After the header, individual successes and failures are indicated by messages of the form ok N and not ok N. For example, here's a test of basic arithmetic. First, print the header:

print "1..4\n"; # the header

Now test that 1 plus 2 is 3:

if (1 + 2 == 3) {
  print "ok 1\n"; # first test is OK
} else {
  print "not ok 1\n"; # first test failed
}

You can also print the not if the test failed.[97]

[97]On some platforms, this may fail unnecessarily. For maximum portability, print the entire string of ok N or not ok N in one print step.

Don't forget the space!

print "not " unless 2 * 4 == 8;
print "ok 2\n";

You could perhaps test that the results are close enough (important when dealing with floating-point values):

my $divide = 5 / 3;
print "not " if abs($divide - 1.666667) > 0.001; # too much error
print "ok 3\n";

Finally, you may want to deal with potential portability problems:

my $subtract = -3 + 3;
print +(($subtract eq "0" or $subtract eq "-0") ? "ok 4" : "not ok 4"), "\n";

As you can see, there are many styles for writing the tests. In ancient Perl development, you saw many examples of each style. Thanks to Michael Schwern and chromatic and the other Perl Testing Cabal members, you can now write these much more simply, using Test::Simple.

Previous | Home | Next
13.11. Exercise | Book Index | 14.2. Writing Tests with Test::Simple
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.2. Writing Tests with Test::Simple

The Test::Simple module is included with the Perl distribution, starting in Perl 5.8.[98]

[98]Older Perl versions back to 5.004_03 can install the same module from the CPAN.

Test::Simple automates the boring task of writing "ok 1", "ok 2", "ok 3", and so on, in your program. Test::Simple exports one subroutine, called (appropriately) ok. It's best illustrated by example. For the earlier code, you can rewrite it as:

use Test::Simple tests => 4;

ok(1 + 2 == 3, '1 + 2 == 3');
ok(2 * 4 == 8, '2 * 4 == 8');
my $divide = 5 / 3;
ok(abs($divide - 1.666667) < 0.001, '5 / 3 == (approx) 1.666667');
my $subtract = -3 + 3;
ok(($subtract eq "0" or $subtract eq "-0"), '-3 + 3 == 0');

Ahh. So much simpler. The use not only pulls the module in but also defines the number of tests. This generates the 1..4 header. Each ok test evaluates its first argument. If the argument is true, it prints the proper ok message. If not, it prints the proper not ok message. For this particular example, the output looks like:[99]

[99]Don't be misled when reading the mathematics of the output. The first number and the dash on each ok line are just labels; Perl isn't telling you that 1 - 1 + 2 == 3!

1..4
ok 1 - 1 + 2 == 3
ok 2 - 2 * 4 == 8
ok 3 - 5 / 3 == (approx) 1.666667
ok 4 - -3 + 3 == 0

The ok N messages are followed with the labels given as the second parameters. This is great for identifying each test, especially because the numbers 1 through 4 don't appear in the original test anymore. The test harness ignores this information, unless you invoke make test with make test TEST_VERBOSE=1, in which case, the information is displayed for each test.

What if a test fails? If you change the first test to 1 + 2 == 4, you get:

1..4
not ok 1 - 1 + 2 == 4
#     Failed test (1.t at line 4)
ok 2 - 2 * 4 == 8
ok 3 - 5 / 3 == (approx) 1.666667
ok 4 - -3 + 3 == 0
# Looks like you failed 1 tests of 4.

The ok 1 became not ok 1. But also notice the extra message indicating the failed test, including its file and line number. Messages preceded by a pound-sign comment marker are merely comments, and are (mostly) ignored by the test harness.

For many people, Test::Simple is simple enough to use for a wide range of tests. However, as your Perl hackery evolves, you'll want to step up to the next level of Perl testing hackery as well, with Test::More.

Previous | Home | Next
14. Essential Testing | Book Index | 14.3. Writing Tests with Test::More
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.3. Writing Tests with Test::More

Like Test::Simple, Test::More is included with the distribution starting with Perl 5.8. The Test::More module is upward-compatible with Test::Simple, so you can simply change the module name to start using it. In this example so far, you can use:

use Test::More tests => 4;

ok(1 + 2 == 3, '1 + 2 == 3');
ok(2 * 4 == 8, '2 * 4 == 8');
my $divide = 5 / 3;
ok(abs($divide - 1.666667) < 0.001, '5 / 3 == (approx) 1.666667');
my $subtract = -3 + 3;
ok(($subtract eq "0" or $subtract eq "-0"), '-3 + 3 == 0');

You get nearly the same output you got with Test::Simple, but there's that nasty little 4 constant in the first line. That's fine once shipping the code, but if you're testing, retesting, and adding more tests, it can be a bit painful to keep the number in sync with the data. You can change that to no_plan,[100] as in:

[100]You can do this with Test::Simple as well.

use Test::More "no_plan";        # during development

ok(1 + 2 == 3, '1 + 2 == 3');
ok(2 * 4 == 8, '2 * 4 == 8');
my $divide = 5 / 3;
ok(abs($divide - 1.666667) < 0.001, '5 / 3 == (approx) 1.666667');
my $subtract = -3 + 3;
ok(($subtract eq "0" or $subtract eq "-0"), '-3 + 3 == 0');

The output is now rearranged:

ok 1 - 1 + 2 == 3
ok 2 - 2 * 4 == 8
ok 3 - 5 / 3 == (approx) 1.666667
ok 4 - -3 + 3 == 0
1..4

Note that the number of tests are now at the end. The test harness knows that if it doesn't see a header, it's expecting a footer. If the number of tests disagree or there's no footer (and no header), it's a broken result. You can use this while developing, but be sure to put the final number of tests in the script before you ship it as real code.

But wait: there's more (to Test::More). Instead of a simple yes/no, you can ask if two values are the same:

use Test::More "no_plan";

is(1 + 2, 3, '1 + 2 is 3');
is(2 * 4, 8, '2 * 4 is 8');

Note that you've gotten rid of numeric equality and instead asked if "this is that." On a successful test, this doesn't give much advantage, but on a failed test, you get much more interesting output. The result of this:

use Test::More "no_plan";

is(1 + 2, 3, '1 + 2 is 3');
is(2 * 4, 6, '2 * 4 is 6');

is the interesting:

ok 1 - 1 + 2 is 3
not ok 2 - 2 * 4 is 6
#     Failed test (1.t at line 4)
#          got: '8'
#     expected: '6'
1..2
# Looks like you failed 1 tests of 2.

Of course, this is an error in the test, but note that the output told you what happened: you got an 8 but were expecting a 6.[101] This is far better than just "something went wrong" as before. There's also a corresponding isnt( ) when you want to compare for inequality rather than equality.

[101]More precisely: you got an '8' but were expecting a '6'. Did you notice that these are strings? The is test checks for string equality. If you don't want that, just build an ok test instead. Or try cmp_ok, coming up in a moment.

What about that third test, where the value had to be less than a tolerance? Well, just use the cmp_ok routine instead:

use Test::More "no_plan";

my $divide = 5 / 3;
cmp_ok(abs($divide - 1.666667), '<' , 0.001,
  '5 / 3 should be (approx) 1.666667');

If the test given in the second argument fails between the first and third arguments, then you get a descriptive error message with both of the values and the comparison, rather than a simple pass/fail value as before.

How about that last test? You wanted to see if the result was a 0 or minus 0 (on the rare systems that give back a minus 0). You can do that with the like function:

use Test::More "no_plan";

my $subtract = -3 + 3;
like($subtract, qr/^-?0$/, '-3 + 3 == 0');

Here, you'll take the string form of the first argument and attempt to match it against the second argument. The second argument is typically a regular expression object (created here with qr) but can also be a simple string, which is converted to a regular expression object. The string form can even be written as if it was (almost) a regular expression:

like($subtract, q/^-?0$/, '-3 + 3 == 0');

The advantage to using the string form is that it is portable back to older Perls.[102]

[102]The qr// form wasn't introduced until Perl 5.005.

If the match succeeds, it's a good test. If not, the original string and the regex are reported along with the test failure. You can change like to unlike if you expect the match to fail instead.

For object-oriented modules, you might want to ensure that object creation has succeeded. For this, isa_ok and can_ok give good interface tests:

use Test::More "no_plan";

use Horse;
my $trigger = Horse->named("Trigger");
isa_ok($trigger, "Horse");
isa_ok($trigger, "Animal");
can_ok($trigger, $_) for qw(eat color);

This results in:

ok 1 - The object isa Horse
ok 2 - The object isa Animal
ok 3 - Horse->can('eat')
ok 4 - Horse->can('color')
1..4

Here you're testing that it's a horse, but also that it's an animal, and that it can both eat and return a color.[103]

[103]Well, you're testing to see that it can('eat') and can('color'). You haven't checked whether it really can use those method calls to do what you want!

You could further test to ensure that each horse has a unique name:

use Test::More "no_plan";

use Horse;

my $trigger = Horse->named("Trigger");
isa_ok($trigger, "Horse");

my $tv_horse = Horse->named("Mr. Ed");
isa_ok($tv_horse, "Horse");

# Did making a second horse affect the name of the first horse?
is($trigger->name, "Trigger", "Trigger's name is correct");
is($tv_horse->name, "Mr. Ed", "Mr. Ed's name is correct");
is(Horse->name, "a generic Horse");

The output of this is:

ok 1 - The object isa Horse
ok 2 - The object isa Horse
ok 3 - Trigger's name is correct
ok 4 - Mr. Ed's name is correct
not ok 5
#     Failed test (1.t at line 13)
#          got: 'an unnamed Horse'
#     expected: 'a generic Horse'
1..5
# Looks like you failed 1 tests of 5.

Oops! Look at that. You wrote a generic Horse, but the string really is an unnamed Horse. That's an error in the test, not in the module, so you should correct that test error and retry. Unless, of course, the module's spec actually called for 'a generic Horse'.

Again, don't be afraid to just write the tests and test the module. If you get either one wrong, the other will generally catch it.

Even the use can be tested by Test::More:

use Test::More "no_plan";

BEGIN { use_ok("Horse") }

my $trigger = Horse->named("Trigger");
isa_ok($trigger, "Horse");
# .. other tests as before ..

The difference between doing this as a test and doing it as a simple use is that the test won't completely abort if the use fails, although many other tests are likely to fail as well. It's also counted as one of the tests, so you get a "test succeeded" for free even if all it does is compile properly to help pad your success numbers for the weekly status report.

The use is placed inside a BEGIN block so any exported subroutines are properly declared for the rest of the program, as recommended by the documentation. For most object-oriented modules, this won't matter because they don't export subroutines.

Previous | Home | Next
14.2. Writing Tests with Test::Simple | Book Index | 14.4. Conditional Tests
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.4. Conditional Tests

If you write tests directly from the specification before you've written the code, the tests are expected to fail. You can include some of your tests inside a TODO block to include them for test count but denote them as unavailable at the same time. For example, suppose you haven't taught your horses how to talk yet:

use Test::More 'no_plan';

use_ok("Horse");
my $tv_horse = Horse->named("Mr. Ed");
TODO: {
  local $TODO = "haven't taught Horses to talk yet";

  can_ok($tv_horse, "talk");  # he can talk!
}
is($tv_horse->name, "Mr. Ed", "I am Mr. Ed!");

Here, the test is inside a TODO block, setting a package $TODO variable with the reason why the items are unfinished:[104]

[104]TODO tests require Test::Harness Version 2.0 or later, which comes with Perl 5.8, but in earlier releases, they have to be installed from the CPAN .

ok 1 - use Horse;
not ok 2 - Horse->can('talk') # TODO haven't taught Horses to talk yet
#     Failed (TODO) test (1.t at line 7)
#     Horse->can('talk') failed
ok 3 - I am Mr. Ed!
1..3

Note that the TODO test counts toward the total number of tests. Also note that the message about why the test is a TODO test is displayed as a comment. The comment has a special form, noted by the test harness, so you will see it during a make test run.

You can have multiple TODO tests in a given block, but only one reason per block, so it's best to group things that are related but use different blocks for different reasons.

Previous | Home | Next
14.3. Writing Tests with Test::More | Book Index | 14.5. More Complex Tests
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.5. More Complex Tests (Multiple Test Scripts)

Initially, the h2xs program gives you a single testing file, t/1.t.[105] You can stick all your tests into this file, but it generally makes more sense to break the tests into logical groups.

[105]As of Perl 5.8, that is. Earlier versions create a test.pl file, which is still run from a test harness during make test, but the output wasn't captured in the same way.

The easiest way to add additional tests is to create t/2.t. That's it—just bump the 1 to a 2. You don't need to change anything in the Makefile.PL or in the test harness: the file is noticed and executed automatically.

You can keep adding files until you get to 9.t, but once you add 10.t, you might notice that it gets executed between 1.t and 2.t. Why? Because the tests are always executed in sorted order. This is a good thing because it lets you ensure that the most fundamental tests are executed before the more exotic tests, simply by controlling the names.

Many people choose to rename the files to reflect a specific ordering and purpose by using names like 01-core.t, 02-basic.t, 03-advanced.t, 04-saving.t, and so on. The first two digits control the testing order, while the rest of the name gives a hint about the general area of testing. Whatever plan you decide to use, stick with it, document it if necessary, and remember that the default order is controlled by the name.

Previous | Home | Next
14.4. Conditional Tests | Book Index | 14.6. Testing Things That Write to STDOUT and STDERR
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.6. Testing Things That Write to STDOUT and STDERR

One advantage to using the ok( ) functions (and friends) is that they don't write to STDOUT directly, but to a filehandle secretly duplicated from STDOUT when your test script begins. If you don't change STDOUT in your program, of course, this is a moot point. But let's say you wanted to write test a routine that writes something to STDOUT, such as making sure a horse eats properly:

use Test::More 'no_plan';
use_ok 'Horse';
isa_ok(my $trigger = Horse->named('Trigger'), 'Horse');

open STDOUT, ">test.out" or die;
$trigger->eat("hay");
close STDOUT;

open T, "test.out" or die;
my @contents = <T>;
close T;
is(join("", @contents), "Trigger eats hay.\n", "Trigger ate properly");

END { unlink "test.out" }  # clean up after the horses

Note that just before you start testing the eat method, you (re-)open STDOUT to your temporary output file. The output from this method ends up in the test.out file. Bring the contents of that file in and give it to the is( ) function. Even though you've closed STDOUT, the is( ) function can still access the original STDOUT, and thus the test harness sees the proper ok or not ok messages.

If you create temporary files like this, please note that your current directory is the same as the test script (even if you're running make test from the parent directory). Also pick fairly safe cross-platform names if you want people to be able to use and test your module portably.

Previous | Home | Next
14.5. More Complex Tests | Book Index | 14.7. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


14.7. Exercise

The answers for all exercises can be found in Section A.12.

14.7.1. Exercise [60 min]

Write a module distribution, starting from the tests first.

Your goal is to create a module My::List::Util that exports two routines on request: sum and shuffle. The sum routine takes a list of values and returns the numeric sum. The shuffle routine takes a list of values and randomly shuffles the ordering, returning the list.

Start with sum. Write the tests, and then add the code. You'll know you're done when the tests pass. Now include tests for shuffle, and then add the implementation for shuffle.

Be sure to update the documentation and MANIFEST file as you go along.

If you can pair up with someone on this exercise, even better. One of you writes the test for sum and the implementation code for shuffle, and the other does the opposite. Swap the t/* files, and see if you can locate any errors!

Previous | Home | Next
14.6. Testing Things That Write to STDOUT and STDERR | Book Index | 15. Contributing to CPAN
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Chapter 15. Contributing to CPAN

Contents:

The Comprehensive Perl Archive Network
Getting Prepared
Preparing Your Distribution
Uploading Your Distribution
Announcing the Module
Testing on Multiple Platforms
Consider Writing an Article or Giving a Talk
Exercise

Besides allowing others in your organization receive the benefits of these wonderful modules and distributions you've created, you may wish to contribute to the Perl community at large. The mechanism for sharing your work is called the Comprehensive Perl Archive Network, or CPAN for short.

15.1. The Comprehensive Perl Archive Network

The CPAN is the result of many volunteers working together, many of whom were originally operating their own little (or big) Perl FTP sites back before that Web thing came along. They got coordinated on their perl-packrats mailing list in late 1993 and decided that disk was getting cheap enough that the same information should be replicated on all sites, rather than having specialization on each site. The idea took about a year to ferment, and Jarkko Hietaniemi established his Finnish FTP site as the CPAN mothership, from which all other mirrors could draw their daily or hourly updates.

Part of the work involved rearranging and organizing the separate archives. Places were established for Perl binaries for non-Unix architectures, scripts, and Perl's source code itself. But the modules portion has come to be the largest and most interesting part of the CPAN.

The modules in the CPAN are organized as a symbolic-link tree in hierarchical functional categories, pointing to author directories where the actual files are located. The modules area also contains indicies that are generally in easy-to-parse-with-Perl formats, such as the Data::Dumper output for the detailed module index. Of course, these indicies are all derived automatically from databases at the master server using Perl programs. (Often, the mirroring of the CPAN from one server to another is done with a now-ancient Perl program called mirror.pl.)

From its small start of a few mirror machines, the CPAN has now grown to over 200 public archives in all corners of the Net, all churning away updating at least daily, sometimes as frequently as hourly. No matter where you are in the world, you can find a nearby CPAN mirror from which to pull the latest goodies.

Previous | Home | Next
14.7. Exercise | Book Index | 15.2. Getting Prepared
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.2. Getting Prepared

To contribute to the CPAN, you need two things:

  • Something to contribute, hopefully already in the shape of a module

  • A Perl Authors Upload Server (PAUSE) ID

The PAUSE ID is your ticket to contributing to the CPAN. You get a PAUSE ID just for the asking. The details are described at http://www.cpan.org/modules/04pause.html. You need to fill out a web form (linked from there) with a few basic details such as your name, home web page, email address, and your preferred PAUSE ID. At the moment, PAUSE IDs must be between four and nine characters. (Some legacy PAUSE IDs are only three characters long.)[106]

[106]Originally, the PAUSE IDs had to be five characters or less, until Randal wanted his MERLYN ID, and the appropriate accommodation was made.

Once you have your PAUSE ID, you need to think globally about your contribution. Because your module will probably be used in programs along with other modules from other authors, you need to ensure that the package names for modules don't collide or confuse. Consult with the module-naming volunteers listening at the modules@perl.org mailing list to get a name or hierarchy of names for your module or related modules.

Before you send your first email to the module czars, it's probably a good idea to do a few things first:

  • Look at the current module list. Get an idea for how things are named. Better yet, are you just reinventing a subset of something that already exists, or can you simply contribute your work as a patch to another module?

  • Visit the list archives (pointers can be found at http://lists.perl.org) to see what the typical conversations look like. That might help you to avoid shock at your response, or better phrase your initial request.

  • Above all, get it in your head that this whole process is run by volunteers who aren't perfect and are doing this in their spare time for the good of the Perl community. Have patience. Have tolerance.

Previous | Home | Next
15. Contributing to CPAN | Book Index | 15.3. Preparing Your Distribution
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.3. Preparing Your Distribution

Once you've gotten your module name settled and you've tested your module with its new name (if needed), you should make sure your distribution is ready for prime time. While this is similar to releasing a distribution inhouse, as described in Chapter 14, you might want to ensure a few additional things about your distribution:

  • Create a README file. This file is automatically extracted to a separate file on the CPAN archives and lets someone view or download just the key facts about your distribution before fetching or unpacking the rest.

  • Make and test your Makefile.PL. Modules without a Makefile.PL are accepted via PAUSE to go into the CPAN but usually get a grimace from those of us who download your stuff because we might have to figure out how to build and install your distribution.

  • Bring your MANIFEST up to date. If you add files that should be part of the distribution, they also need to be in the MANIFEST. One quick trick is to clean things up as you would want them in the distribution, and then invoke make manifest, which updates the MANIFEST file to be exactly what you are holding at the moment.

  • Have a logical distribution version number. The Makefile.PL file should specify either a VERSION value or a VERSION_FROM value. If you have a single module (such as a .pm file) in your distribution, it's usually best to grab the version number from there with VERSION_FROM. If you have multiple files, either designate one of them as the one you'll always update just before a new release or use the VERSION within the Makefile.PL instead. Also keep in mind that your version number must always increase numerically for newer versions of your distribution.

  • Have tests! Reread Chapter 14 if you must. There's nothing that builds more confidence in an installed distribution than at least a few dozen tests that are run during the installation phase.

  • Invoke make disttest, which builds a distribution archive of everything in MANIFEST, unpacks the archive into a separate directory, and then runs the tests on your distribution. If that doesn't work for you, you can't expect it to work for anyone else who downloads your distribution from the CPAN.

Previous | Home | Next
15.2. Getting Prepared | Book Index | 15.4. Uploading Your Distribution
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.4. Uploading Your Distribution

Once you have your distribution ready to share, visit the PAUSE web page at http://pause.perl.org/ and log in using your PAUSE ID and PAUSE password. The menu has many things you can do; there are two processes to complete for your distribution:

  • Upload the distribution archive

  • Edit the module metadata

First is the upload, which you can do using an HTTP upload, a web fetch, or an FTP transfer. The HTTP upload is convenient if the distribution archive is on the same computer as your web browser. Otherwise, if you can move the file into a place where it can be fetched (even a private URL will do), you can use the web fetch. If neither option works, then FTP the file to PAUSE FTP server.

After the file is uploaded, you should edit the metadata. Again, select the appropriate menu item from the PAUSE page and follow the instructions. The metadata helps others decide if you're just releasing an alpha version instead of a final release, and whether or not the module needs additional support, like a C compiler.

Within a short period of time, your upload will appear in the mothership CPAN archive, and then over the following day, will propagate around the world, just waiting for its first download.

Previous | Home | Next
15.3. Preparing Your Distribution | Book Index | 15.5. Announcing the Module
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.5. Announcing the Module

Of course, nobody will know that your module exists until they notice it. Your module gets noticed automatically in many places, such as:

  • The "Recent modules" page of http://search.cpan.org

  • The "new modules" section of http://use.perl.org

  • A daily announcement in the "perl news" mailing list

  • An IRC 'bot on a few of the Perl-related IRC channels announces uploads as soon as they become available

  • An update or an uninstalled module in the CPAN shell, CPAN.pm

For greater visibility, you can also prepare a short notice to be posted to the Usenet comp.lang.perl.announce newsgroup. Just post the notice, and within a day or two, your news posting will be whisking around to news servers all over the globe.

Previous | Home | Next
15.4. Uploading Your Distribution | Book Index | 15.6. Testing on Multiple Platforms
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.6. Testing on Multiple Platforms

Many volunteers have organized a smoke test of your module on many platforms. Simply as a result of uploading your registered module to the CPAN, your module will be downloaded and make test'ed on many different kinds of machines. You can view the results of the tests at http://testers.cpan.org. You should note any failures and consider using the feedback to release a new distribution that works more portably.

Previous | Home | Next
15.5. Announcing the Module | Book Index | 15.7. Consider Writing an Article or Giving a Talk
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.7. Consider Writing an Article or Giving a Talk

Many of the short talks at Perl conferences involve the author of a distribution talking about their own work. After all, who is better qualified to help others use your module than you?

If the idea of proposing a conference talk intimidates you a bit, or you don't want to wait that long, look to your local Perl user group. They're generally looking for speakers (usually for the meeting coming up in the next week or two), and the group size is usually small enough to be a nice casual setting. You can generally find a Perl user group near you by looking on the Perl Mongers web site at http://www.pm.org. If you can't find one, start one!

Previous | Home | Next
15.6. Testing on Multiple Platforms | Book Index | 15.8. Exercise
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


15.8. Exercise

The answers for all exercises can be found in Section A.12.

15.8.1. Exercise

Write a module to solve the halting problem. Release the code to the CPAN. Be sure to include the tests. (Hint: how long will the tests take to run on modern hardware?)

Previous | Home | Next
15.7. Consider Writing an Article or Giving a Talk | Book Index | A. Answers to Exercises
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Appendix A. Answers to Exercises

Contents:

Answers for Chapter 2
Answers for Chapter 3
Answers for Chapter 4
Answers for Chapter 5
Answer for Chapter 6
Answers for Chapter 7
Answers for Chapter 8
Answer for Chapter 9
Answer for Chapter 10
Answer for Chapter 11
Answer for Chapter 12
Answers for Chapters 13-15

This appendix contains the answers to the exercises presented throughout the book.

A.1. Answers for Chapter 2

A.1.1. Exercise 1 (Section 2.10.1)

Here's one way to do it. First, start with the package directive and use strict:

package Oogaboogoo::date;
use strict;

Then define the constant arrays to hold the mappings for day-of-week and month names:

my @day = qw(ark dip wap sen pop sep kir);
my @mon = qw(diz pod bod rod sip wax lin sen kun fiz nap dep);

Next, define the subroutine for day-of-week-number to name. Note that this subroutine will be accessible as Ooogaboogoo::date::day:

sub day {
  my $num = shift @_;
  die "$num is not a valid day number"
    unless $num >= 0 and $num <= 6;
  $day[$num];
}

Similarly, you have the subroutine for the month-of-year-number to name:

sub mon {
  my $num = shift @_;
  die "$num is not a valid month number"
    unless $num >= 0 and $num <= 11;
  $mon[$num];
}

Finally, the mandatory true value at the end of the package:

1;

Name this file date.pl within a directory of Oogaboogoo in one of the directories given in your @INC variable, such as the current directory.

A.1.2. Exercise 2 (Section 2.10.2)

Here's one way to do it. Pull in the .pl file from a place in your @INC path:

use strict;
require 'Oogaboogoo/date.pl';

Then get the information for the current time:

my($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime;

Then use the newly defined subroutines for the conversions:

my $day_name = Oogaboogoo::date::day($wday);
my $mon_name = Oogaboogoo::date::mon($mon);

The year number is offset by 1900 for historical purposes, so you need to fix that:

$year += 1900;

Finally, it's time for the output:

print "Today is $day_name, $mon_name $mday, $year.\n";
Previous | Home | Next
15.8. Exercise | Book Index | A.2. Answers for Chapter 3
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.2. Answers for Chapter 3

A.2.1. Exercise 1 (Section 3.9.1)

They're all referring to the same thing, except for the second one, ${$ginger[2]}[1]. That one is the same as $ginger[2][1], whose base is the array @ginger, rather than the scalar $ginger.

A.2.2. Exercise 2 (Section 3.9.2)

First, construct the hash structure:

my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my %all = (
  "Gilligan" => \@gilligan,
  "Skipper" => \@skipper,
  "Professor" => \@professor,
);

Then pass it to the first subroutine:

check_items_for_all(\%all);

In the subroutine, the first parameter is a hashref, so dereference it to get the keys and the corresponding values:

sub check_items_for_all {
  my $all = shift;
  for my $person (sort keys %$all) {
    check_required_items($person, $all->{$person});
  }
}

From there, call the original subroutine:

sub check_required_items {
  my $who = shift;
  my $items = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  my @missing = ( );
  for my $item (@required) {
    unless (grep $item eq $_, @$items) { # not found in list?
      print "$who is missing $item.\n";
      push @missing, $item;
    }
  }
  if (@missing) {
    print "Adding @missing to @$items for $who.\n";
    push @$items, @missing;
  }
}
Previous | Home | Next
A. Answers to Exercises | Book Index | A.3. Answers for Chapter 4
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.3. Answers for Chapter 4

A.3.1. Exercise 1 (Section 4.9.1)

The curly braces of the anonymous hash constructor make a reference to a hash. That's a scalar (as are all references), so it's not suitable to use alone as the value of a hash. Perhaps this code's author intended to assign to scalar variables (like $passenger_1 and $passenger_2) instead of to hashes. But you can fix the problem simply by changing the two pairs of curly braces to parentheses.

If you tried running this, Perl may have given you a helpful diagnostic message as a warning. If you didn't get the warning, perhaps you didn't have warnings turned on, either with the -w switch or with the use warnings pragma. Even if you don't usually use Perl's warnings, you should enable them during debugging. (How long would it take you to debug this without Perl's warnings to help you? How long would it take to enable Perl's warnings? 'Nuff said.)

What if you got the warning message but couldn't tell what it meant? That's what the perldiag manpage is for. Warning texts need to be concise because they're compiled into the perl binary (the program that runs your Perl code). But perldiag should list all the messages you should ever get from Perl, along with a longer explanation of what each one means, why it's a problem, and how to fix it.

If you want to be ultimately lazy, you can add use diagnostics; at the beginning of your program, and any error message will look itself up in the documentation and display the entire detailed message. Don't leave this in production code, however, unless you like burning a lot of CPU cycles every time your program starts, whether or not an error occurs.

A.3.2. Exercise 2 (Section 4.9.2)

You will be keeping count of how much data has been sent to all machines, so at the start, set the variable $all to a name that will stand in for all of them. It should be a name that will never be used for any real machine, of course. Storing it in a variable is convenient for writing the program and makes it easy to change later.

my $all = "**all machines**";

The input loop is nearly the same as given in the chapter, but it skips comment lines. Also, it keeps a second running total, filed under $all.

my %total_bytes;
while (<>) {
  next if /^#/;
  my ($source, $destination, $bytes) = split;
  $total_bytes{$source}{$destination} += $bytes;
  $total_bytes{$source}{$all} += $bytes;
}

Next, make a sorted list. This holds the names of the source machines in descending order of total transferred bytes. This list is used for the outer for loop. (Rather than using a temporary array, @sources, you might have put the sort directly into the parens of the for loop.)

my @sources =
  sort { $total_bytes{$b}{$all} <=> $total_bytes{$a}{$all} }
  keys %total_bytes;

for my $source (@sources) {
  my @destinations =
    sort { $total_bytes{$source}{$b} <=> $total_bytes{$source}{$a} }
    keys %{ $total_bytes{$source} };
  print "$source: $total_bytes{$source}{$all} total bytes sent\n";
  for my $destination (@destinations) {
    next if $destination eq $all;
    print "  $source => $destination:",
      " $total_bytes{$source}{$destination} bytes\n";
  }
  print "\n";
}

Inside the loop, print out the total number of bytes sent from that source machine, then make sorted list of the destination files (similar to the list in @sources). As you step through that list, use next to skip over the dummy $all item. Because that item will be at the head of the sorted list, why wasn't shift used to discard it, since that would avoid checking repeatedly for $all inside the inner loop? The answer is in this footnote.[107]

[107]Even though the dummy item will sort to the head of the sorted list, it won't necessarily be the first item in the list. If a machine sent data to just one other, that destination machine's total will be equal to the source machine's total output, so that list could sort in either order.

You can simplify this program, perhaps. The subexpression $total_bytes{$source} is used many times in the large output for loop (and twice in the input loop as well). That can be replaced by a simple scalar, initialized at the top of the loop:

for my $source (@sources) {
  my $tb = $total_bytes{$source};
  my @destinations = sort { $tb{$b} <=> $tb{$a} } keys %$tb;
  print "$source: $tb{$all} total bytes sent\n";
  for my $destination (@destinations) {
    next if $destination eq $all;
    print "  $source => $destination: $tb{$destination} bytes\n";
  }
  print "\n";
}

This makes the code shorter and (likely) a bit faster as well. Give yourself extra credit if you thought to do this. Also give yourself extra credit if you thought that it might be too confusing and decided not to make the change.

Previous | Home | Next
A.2. Answers for Chapter 3 | Book Index | A.4. Answers for Chapter 5
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.4. Answers for Chapter 5

A.4.1. Exercise 1 (Section 5.8.1)

use Storable;

my $all = "**all machines**";
my $data_file = "total_bytes.data";

my %total_bytes;
if (-e $data_file) {
  my $data = retrieve $data_file;
  %total_bytes = %$data;
}

while (<>) {
  next if /^#/;
  my ($source, $destination, $bytes) = split;
  $total_bytes{$source}{$destination} += $bytes;
  $total_bytes{$source}{$all} += $bytes;
}

store \%total_bytes, $data_file;

### remainder of program is unchanged

This is similar to what you saw in Chapter 4, but now it uses Storable.

Near the top, put the filename into a variable. You can then retrieve the data but only if the data file already exists.

After reading the data, use Storable again to write it back out to the same disk file.

If you chose to write the hash's data to a file the hard way, by writing your own code and your own file format, you're working too hard. More to the point, unless you're extraordinarily talented or spend way too long on this exercise, you almost certainly have bugs in your serialization routines, or at least flaws in your file format.

A.4.2. Exercise 2 (Section 5.8.2)

There should probably be some checks to ensure that Storable was successful. It will catch some errors (and die), but it will simply return undef for some. See the documentation for Storable. (Of course, if you checked the return values from store and retrieve, you should give yourself extra credit on the previous exercise.)

The program should save the old data file (if any) under a backup filename so that it's easy to revert the latest additions. In fact, it could even keep several backups, such as the last week's worth.

It might also be nice to be able to print the output without having any new input data. As it's written, this can be done by giving an empty file (such as /dev/null) as the input. However there should be an easier way. The output functionality could be separated entirely from the updating, in fact.

Previous | Home | Next
A.3. Answers for Chapter 4 | Book Index | A.5. Answer for Chapter 6
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.5. Answer for Chapter 6

A.5.1. Exercise (Section 6.8.1)

sub gather_mtime_between {
  my($begin, $end) = @_;
  my @files;
  my $gatherer = sub {
    my $timestamp = (stat $_)[9];
    unless (defined $timestamp) {
      warn "Can't stat $File::Find::name: $!, skipping\n";
      return;
    }
    push @files, $File::Find::name if
      $timestamp >= $begin and $timestamp <= $end;
  };
  my $fetcher = sub { @files };
  ($gatherer, $fetcher);
}

This code is pretty straightforward. The main challenge is getting the item names correct. When using stat inside the callback, the filename is $_, but when returning the filename (or reporting it to the user), the name is $File::Find::name.

If the stat fails for some reason, the timestamp will be undef. (That can happen, for example, if it finds a dangling symbolic link.) In that case, the callback simply warns the user and returns early. If you omit that check, you can get warnings of an undefined value during the comparison with $begin and $end.

When you run the completed program with this subroutine, your output should show only file modification dates on the previous Monday (unless you changed the code to use a different day of the week, of course).

Previous | Home | Next
A.4. Answers for Chapter 5 | Book Index | A.6. Answers for Chapter 7
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.6. Answers for Chapter 7

A.6.1. Exercise 1 (Section 7.8.1)

my @sorted =
  map $_->[0],
  sort { $a->[1] <=> $b->[1] }
  map [$_, -s $_],
  glob "/bin/*";

Using the -s operator to determine the file's size is an expensive operation; by caching its value you can save some time. How much? Let's see in the next exercise's answer.

A.6.2. Exercise 2 (Section 7.8.2)

use Benchmark qw(timethese);

timethese( -2, {
  Ordinary => q{
    my @results = sort { -s $a <=> -s $b } glob "/bin/*";
  },
  Schwartzian => q{
    my @sorted =
      map $_->[0],
      sort { $a->[1] <=> $b->[1] }
      map [$_, -s $_],
      glob "/bin/*";
  },
});

On the 33-element /bin on my laptop, I (Randal) was seeing 260 iterations per second of the Ordinary implementation and roughly 500 per second of the Schwartzian implementation, so writing the complex code saved about half of the execution time. On a 74-element /etc, the Schwartzian Transform was nearly three times as fast. In general, the more items sorted, the more expensive the computed function, and the better you can expect the Schwartzian Transform to perform. That doesn't even count the burden on the monkey—er, I mean the operating system.

A.6.3. Exercise 3 (Section 7.8.3)

my @dictionary_sorted =
  map $_->[0],
  sort { $a->[1] cmp $b->[1] }
  map {
    my $string = $_;
    $string =~ tr/A-Z/a-z/;
    $string =~ tr/a-z//cd;
    [ $_, $string ];
  } @input_list;

Inside the second map, which executes first, make a copy of $_. (If you don't, you'll mangle the data.)

A.6.4. Exercise 4 (Section 7.8.4)

sub data_for_path {
  my $path = shift;
  if (-f $path or -l $path) {
    return undef;
  }
  if (-d $path) {
    my %directory;
    opendir PATH, $path or die "Cannot opendir $path: $!";
    my @names = readdir PATH;
    closedir PATH;
    for my $name (@names) {
      next if $name eq "." or $name eq "..";
      $directory{$name} = data_for_path("$path/$name");
    }
    return \%directory;
  }
  warn "$path is neither a file nor a directory\n";
  return undef;
}

sub dump_data_for_path {
  my $path = shift;
  my $data = shift;
  my $prefix = shift || "";
  print "$prefix$path";
  if (not defined $data) { # plain file
    print "\n";
    return;
  }
  my %directory = %$data;
  if (%directory) {
    print ", with contents of:\n";
    for (sort keys %directory) {
      dump_data_for_path($_, $directory{$_}, "$prefix  ");
    }
  } else {
    print ", an empty directory\n";
  }
}
dump_data_for_path(".", data_for_path("."));

By adding a third (prefix) parameter to the dumping subroutine, you can ask it to indent its output. By default, the prefix is empty, of course.

When the subroutine calls itself, it adds two spaces to the end of the prefix. Why the end and not the beginning? Because it's comprised of spaces, either end will work. By using trailing spaces, you can call the subroutine like this:

dump_data_for_path(".", data_for_path("."), ">  ");

This invocation quotes the entire output by prefixing each line with the given string. You can (in some hypothetical future version of this program) use such quoting to denote NFS-mounted directories, or other special items.

Previous | Home | Next
A.5. Answer for Chapter 6 | Book Index | A.7. Answers for Chapter 8
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.7. Answers for Chapter 8

A.7.1. Exercise 1 (Section 8.11.1)

Here's one way to do it. First define the Animal class, with a single method:

use strict;
{ package Animal;
  sub speak {
    my $class = shift;
    print "a $class goes ", $class->sound, "!\n";
  }
}

Now define each subclass with a specific sound:

{ package Cow;
  our @ISA = qw(Animal);
  sub sound { "moooo" }
}
{ package Horse;
  our @ISA = qw(Animal);
  sub sound { "neigh" }
}
{ package Sheep;
  our @ISA = qw(Animal);
  sub sound { "baaaah" }
}

The Mouse package is slightly different because of the extra quietness:

{ package Mouse;
  our @ISA = qw(Animal);
  sub sound { "squeak" }
  sub speak {
    my $class = shift;
    $class->SUPER::speak;
    print "[but you can barely hear it!]\n";
  }
}

Now, enter the interactive part of the program:

my @barnyard = ( );
{
  print "enter an animal (empty to finish): ";
  chomp(my $animal = <STDIN>);
  $animal = ucfirst lc $animal;                # canonicalize
  last unless $animal =~ /^(Cow|Horse|Sheep|Mouse)$/;
  push @barnyard, $animal;
  redo;
}

foreach my $beast (@barnyard) {
  $beast->speak;
}

This code uses a simple check, via a pattern match, to ensure that the user doesn't enter Alpaca or another unavailable animal, because doing so will crash the program. In Chapter 9, you learned about the isa method, which lets you check more simply whether something is an available animal, even allowing for the possibility that it is an animal that was added to the program after the check was written.

A.7.2. Exercise 2 (Section 8.11.2)

Here's one way to do it. First, create the base class of LivingCreature with a single speak method:

use strict;
{ package LivingCreature;
  sub speak {
    my $class = shift;
    if (@_) {                # something to say
      print "a $class goes '@_'\n";
    } else {
      print "a $class goes ", $class->sound, "\n";
    }
  }
}

A person is a living creature, so define the derived class here:

{ package Person;
  our @ISA = qw(LivingCreature);
  sub sound { "hmmmm" }
}

The Animal class comes next, making appropriate sounds, but unable to talk (except to Dr. Doolittle):

{ package Animal;
  our @ISA = qw(LivingCreature);
  sub sound { die "all Animals should define a sound" }
  sub speak {
    my $class = shift;
    die "animals can't talk!" if @_;
    $class->SUPER::speak;
  }
}
{ package Cow;
  our @ISA = qw(Animal);
  sub sound { "moooo" }
}
{ package Horse;
  our @ISA = qw(Animal);
  sub sound { "neigh" }
}
{ package Sheep;
  our @ISA = qw(Animal);
  sub sound { "baaaah" }
}
{ package Mouse;
  our @ISA = qw(Animal);
  sub sound { "squeak" }
  sub speak {
    my $class = shift;
    $class->SUPER::speak;
    print "[but you can barely hear it!]\n";
  }
}

Finally, have the person speak:

Person->speak;                # just hmms
Person->speak("Hello, world!");

Notice that the main speak routine has now moved into the LivingCreature class, which means you don't need to write it again to use it in Person. In Animal, though, you need to check that to ensure an Animal won't try to speak before calling SUPER::speak.

Although it's not the way the assignment was written, you can get a similar result if you choose to make Person a subclass of Animal. (In that case, LivingCreature would presumably be needed as a parent class for an eventual Plant class.) Of course, since an Animal can't speak, how can a Person? The answer is that Person::speak would have to handle its parameters, if any, before or after (or instead of) calling SUPER::speak.

Which would be the better way to implement this? It all depends upon what classes you'll need in the future and how you'll use them. If you expect to add features to Animal that would be needed for Person, it makes sense for Person to inherit from Animal. If the two are nearly completely distinct, and nearly anything that a Person has in common with an Animal is common to all LivingCreature s, it's probably better to avoid the extra inheritance step. The ability to design a suitable inheritance structure is a crucial talent for any OOP programmer.

In fact, you may find that after developing the code one way, you'll want to "refactor" the code a different way. This is common with OOP. However, it's very important to have enough testing in place to ensure that you don't break things while you're moving them around.

Previous | Home | Next
A.6. Answers for Chapter 7 | Book Index | A.8. Answer for Chapter 9
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.8. Answer for Chapter 9

A.8.1. Exercise (Section 9.15.1)

First, start the Animal package:

use strict;
{ package Animal;
  use Carp qw(croak);

And now for the constructor:

## constructors
sub named {
  ref(my $class = shift) and croak "class name needed";
  my $name = shift;
  my $self = { Name => $name, Color => $class->default_color };
  bless $self, $class;
}

Now, for virtual methods: the methods that should be overridden in a subclass. Perl doesn't require virtual methods to be declared in the base class, but it's nice as a documentation item.

## backstops (should be overridden)
sub default_color { "brown" }
sub sound { croak "subclass must define a sound" }

Next comes the methods that work with either a class or an instance:

## class/instance methods
sub speak {
  my $either = shift;
  print $either->name, " goes ", $either->sound, "\n";
}
sub name {
  my $either = shift;
  ref $either
    ? $either->{Name}
    : "an unnamed $either";
}
sub color {
  my $either = shift;
  ref $either
    ? $either->{Color}
    : $either->default_color;
}

Finally, the methods that work only for the particular instance:

## instance-only methods
sub set_name {
  ref(my $self = shift) or croak "instance variable needed";
  $self->{Name} = shift;
}
sub set_color {
  ref(my $self = shift) or croak "instance variable needed";
  $self->{Color} = shift;
}
}

Now that you have your abstract base class, define some concrete classes that can have instances:

{ package Horse;
  our @ISA = qw(Animal);
  sub sound { "neigh" }
}
{ package Sheep;
  our @ISA = qw(Animal);
  sub color { "white" }    # override the default color
  sub sound { "baaaah" }   # no Silence of the Lambs
}

Finally, a few lines of code to test your classes:

my $tv_horse = Horse->named("Mr. Ed");
$tv_horse->set_name("Mister Ed");
$tv_horse->set_color("grey");
print $tv_horse->name, " is ", $tv_horse->color, "\n";
print Sheep->name, " colored ", Sheep->color, " goes ", Sheep->sound, "\n";
Previous | Home | Next
A.7. Answers for Chapter 8 | Book Index | A.9. Answer for Chapter 10
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.9. Answer for Chapter 10

A.9.1. Exercise (Section 10.7.1)

First, start the class:

{ package RaceHorse;
  our @ISA = qw(Horse);

Next, use a simple dbmopen to associate %STANDINGS with permanent storage:

dbmopen (our %STANDINGS, "standings", 0666)
  or die "Cannot access standings dbm: $!";

When a new RaceHorse is named, either pull the existing standings from the database or invent zeroes for everything:

sub named { # class method
  my $self = shift->SUPER::named(@_);
  my $name = $self->name;
  my @standings = split ' ', $STANDINGS{$name} || "0 0 0 0";
  @$self{qw(wins places shows losses)} = @standings;
  $self;
}

When the RaceHorse is destroyed, the standings are updated:

sub DESTROY { # instance method, automatically invoked
  my $self = shift;
  $STANDINGS{$self->name} = "@$self{qw(wins places shows losses)}";
  $self->SUPER::DESTROY;
}

Finally, the instance methods are defined:

## instance methods:
sub won { shift->{wins}++; }
sub placed { shift->{places}++; }
sub showed { shift->{shows}++; }
sub lost { shift->{losses}++; }
sub standings {
  my $self = shift;
  join ", ", map "$self->{$_} $_", qw(wins places shows losses);
}
}
Previous | Home | Next
A.8. Answer for Chapter 9 | Book Index | A.10. Answer for Chapter 11
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.10. Answer for Chapter 11

A.10.1. Exercise (Section 11.8.1)

use IO::File;
my %output_handles;
while (<>) {
  unless (/^(\S+):/) {
    warn "ignoring the line with missing name: $_";
    next;
  }
  my $name = lc $1;
  my $handle = $output_handles{$name} ||=
    IO::File->open(">$name.info") || die "Cannot create $name.info: $!";
  print $handle $_;
}

At the beginning of the while loop, use a pattern to extract the person's name from the data line, issuing a warning if that's not found.

Once you have the name, force it to lowercase so that an entry for "Maryann" will get filed in the same place as one for "MaryAnn." This is also handy for naming the files, as the next statement shows.

The first time through the loop, the filehandle must be created. Let's see how to do that. The || operator has a higher precedence than the assignment, so it is evaluated first; the program will die if the file can't be created. The ||= operator assigns the filehandle to the hash, and the = operator passes it to $handle as well.

The next time you have the same name in $name, the ||= operator kicks in. Remember that $gilligan ||= $anything is effectively like $gilligan = $gilligan || $anything. If the variable on the left is a false value (such as undef), it's replaced by the value on the right, but if it's true (such as a filehandle), the value on the right won't even be evaluated. Thus, since the hash already has a value for that person's name, the hash's value is used and assigned directly to $handle without having to (re-)create the file.

It wasn't necessary to code the castaways' names into this program, because they will be read in as data. This is good because any additional castaway won't require having to rewrite the program. If someone's name is accidentally misspelled, however, it puts some of their data into a new file under the wrong name.

Previous | Home | Next
A.9. Answer for Chapter 10 | Book Index | A.11. Answer for Chapter 12
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.11. Answer for Chapter 12

A.11.1. Exercise (Section 12.12.1)

The module Oogaboogoo/date.pm looks like this:

package Oogaboogoo::date;
use strict;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(day mon);

my @day = qw(ark dip wap sen pop sep kir);
my @mon = qw(diz pod bod rod sip wax lin sen kun fiz nap dep);

sub day {
  my $num = shift @_;
  die "$num is not a valid day number"
    unless $num >= 0 and $num <= 6;
  $day[$num];
}

sub mon {
  my $num = shift @_;
  die "$num is not a valid month number"
    unless $num >= 0 and $num <= 11;
  $mon[$num];
}

1;

The main program now looks like this:

use strict;
use Oogaboogoo::date qw(day mon);

my($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime;
my $day_name = day($wday);
my $mon_name = mon($mon);
$year += 1900;
print "Today is $day_name, $mon_name $mday, $year.\n";
Previous | Home | Next
A.10. Answer for Chapter 11 | Book Index | A.12. Answers for Chapters 13-15
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


A.12. Answers for Chapters 13-15

These complete projects are far too complex to represent completely here. We hope readers of this book will share their solutions with each other on the Internet. Try a search on the Web for the phrase "Perl Alpaca book LPORM answers." You can also use that phrase on the web page where you offer your solutions for downloading. To help anyone who finds your page, include links from your page to any other solutions that look interesting to you.

We search the Web from time to time, and so we may visit your site and look at your results. If we especially like your solution to the halting problem, we'll be sure to let you know.

Previous | Home | Next
A.11. Answer for Chapter 12 | Book Index | Index
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal on the cover of Learning Perl Objects, References, and Modules is an alpaca (Lama pacos). The alpaca is a member of the South American camelid family, which is closely related to the more familiar Asian and African camels. South American camelids also include the llama, the vicuna, and the guanaco. The alpaca is smaller (36 inches at the withers) than a llama, but larger than its other relations. Ninety-nine percent of the world's approximately three million alpacas are found in Peru, Bolivia, and Chile.

The evolution of the wild vicuna into the domestic alpaca began between six and seven thousand years ago. The specialized breeding of alpacas for fiber production wasn't developed until around 500 B.C. The Incas developed the alpaca into the two distinct fleece types, the Huacaya (pronounced wa-kai-ya) and the less common Suri. The main difference between the two types of alpacas is the fiber they produce. The Huacaya fleece has crimp or wave; the Suri fleece is silky and lustrous and has no crimp. Alpacas are prized for their fleece, which is as soft as cashmere and warmer, lighter, and stronger than wool. Alpaca fleece comes in more colors than that of any other fiber-producing animal (approximately 22 basic colors with many variations and blends).

The lifespan of the alpaca is about 20 years. Gestation is 11.5 months, producing one offspring, or cria, every 14 to 15 months. The alpaca is a modified ruminant, not only eating less grass than most other animals but converting it to energy very efficiently. Unlike true ruminants, they have three compartments in their stomach, not four, and can thus survive in areas unsuitable to other domesticated animals. Alpacas are gentle and don't bite or butt. Even if they did, without incisors, horns, hoofs, or claws, they would do little damage.

Mary Anne Weeks Mayo was the production editor and proofreader, and Ann Schirmer was the copyeditor for Learning Perl Objects, References, and Modules. Matt Hutchinson and Claire Cloutier provided quality control. Jamie Peppard provided production assistance. Lucie Haskins wrote the index.

Ellie Volckhausen designed the cover of this book, based on a series design by Edie Freedman. The cover image is a 19th-century engraving from Animate Creations, Volume II. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

David Futato designed the interior layout. This book was converted by Andrew Savikas to FrameMaker 5.5.6 with a format conversion tool created by Erik Ray, Jason McIntosh, Neil Walls, and Mike Sierra that uses Perl and XML technologies. The text font is Linotype Birka; the heading font is Adobe Myriad Condensed; and the code font is LucasFont's TheSans Mono Condensed. The illustrations that appear in the book were produced by Robert Romano and Jessamyn Read using Macromedia FreeHand 9 and Adobe Photoshop 6. This colophon was compiled by Mary Anne Weeks Mayo.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Learning Perl Objects, References & Modules: Index

Learning Perl Objects, References & Modules

Learning Perl Objects, References & Modules
Previous Next

Index

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Symbols & Numbers

@_ array
accessing instance data: 9.3. Accessing the Instance Data
changes reflected: 3.1. Performing the Same Task on Many Arrays
creating: 3.1. Performing the Same Task on Many Arrays
dereferencing and: 3.3. Dereferencing the Array Reference
nested data structures: 3.6. Nested Data Structures
passing uninterrupted: 8.9. What to Do with @_
references and scoping: 4.1. More than One Reference to Data
removing items from: 2.1. The Cure for the Common Code
\ (backslash): 3.2. Taking a Reference to an Array
3.8. References to Hashes
6.1. Referencing a Named Subroutine
: (colon): 2.5.2. Extending @INC with PERL5LIB
, (comma): 4.6. Creating an Anonymous Hash
{} (curly braces)
anonymous hash constructors: 4.6. Creating an Anonymous Hash
arrays and: 3.3. Dereferencing the Array Reference
coderefs and: 6.1. Referencing a Named Subroutine
dereferencing: 3.7. Simplifying Nested Element References with Arrows
dropping: 3.4. Dropping Those Braces
3.4. Dropping Those Braces
hashes and: 3.8. References to Hashes
indirect object syntax and: 10.3. Indirect Object Notation
:: (double colon): 2.7. Packages as Namespace Separators
12.6. What use Is Doing
?: operator: 9.6. Making a Method Work with Either Classes or Instances
( ) (parentheses): 4.5. Creating an Anonymous Array Directly
6.1. Referencing a Named Subroutine
6.8.1. Exercise [30 min]
+ (plus sign): 4.6. Creating an Anonymous Hash
10.1. Nested Object Destruction
# (pound sign): 4.9.2. Exercise 2 [30 min]
14.2. Writing Tests with Test::Simple
; (semicolon): 4.6. Creating an Anonymous Hash
6.4. Closures
[] (square brackets): 4.5. Creating an Anonymous Array Directly
4.5. Creating an Anonymous Array Directly
_ (underscore): 2.7. Packages as Namespace Separators
$@ variable: 2.2. Inserting Code with eval
2.4. Using require
& (ampersand): 6.1. Referencing a Named Subroutine
12.2. Selecting What to Import
<=> (spaceship operator): 7.1. Review of Sorting

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

absent import lists: 12.2. Selecting What to Import
abstract methods: 11.5. Creating Getters and Setters More Easily
accessors
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors
11.4. Using AUTOLOAD for Accessors
Class::MethodMaker module: 11.5. Creating Getters and Setters More Easily
anonymous arrays
complex data and: 5.7. Selecting and Altering Complex Data
creating directly: 4.5. Creating an Anonymous Array Directly
defined: 4.2. What if That Was the Name?
hash references and: 4.6. Creating an Anonymous Hash
square brackets and: 4.5. Creating an Anonymous Array Directly
anonymous hash
creating: 4.6. Creating an Anonymous Hash
filesystem capture example: 7.6. Building Recursively Defined Data
anonymous subroutines: 6.2. Anonymous Subroutines
6.2. Anonymous Subroutines
API (Application Programming Interface): 9.7. Adding Parameters to a Method
archiving: 13. Writing a Distribution
arguments (see parameters)
array reference
anonymous array constructors and: 4.5. Creating an Anonymous Array Directly
4.5. Creating an Anonymous Array Directly
arrows and: 3.7. Simplifying Nested Element References with Arrows
3.7. Simplifying Nested Element References with Arrows
blessing: 10.1. Nested Object Destruction
curly braces and: 3.4. Dropping Those Braces
3.4. Dropping Those Braces
dereferencing: 3.3. Dereferencing the Array Reference
3.3. Dereferencing the Array Reference
3.6. Nested Data Structures
4.2. What if That Was the Name?
efficient sorting example: 7.3. Sorting Efficiently
empty arrays and: 4.7. Autovivification
features: 3.2. Taking a Reference to an Array
3.2. Taking a Reference to an Array
hashes into: 5.7. Selecting and Altering Complex Data
IO::File objects and: 11.7. References to Filehandles
modifying: 3.5. Modifying the Array
3.5. Modifying the Array
nested data structures: 3.6. Nested Data Structures
Schwartzian Transform: 7.4. The Schwartzian Transform
arrays (see also anonymous arrays)
curly braces: 3.3. Dereferencing the Array Reference
dereferencing and: 3.5. Modifying the Array
4.2. What if That Was the Name?
modifying: 3.5. Modifying the Array
3.5. Modifying the Array
nested data structures and: 3.6. Nested Data Structures
ordered lists and: 3. Introduction to References
package names and: 2.7. Packages as Namespace Separators
referencing: 3.2. Taking a Reference to an Array
3.2. Taking a Reference to an Array
3.3. Dereferencing the Array Reference
3.3. Dereferencing the Array Reference
scalars and: 3. Introduction to References
scoping considerations: 4.5. Creating an Anonymous Array Directly
ARRAY(0x1a2b3c): 3.2. Taking a Reference to an Array
arrows
drop arrow rule: 3.7. Simplifying Nested Element References with Arrows
hash references and: 3.8. References to Hashes
3.8. References to Hashes
method invocation arrow: 8.2. Introducing the Method Invocation Arrow
8.2. Introducing the Method Invocation Arrow
8.10. Where We Are So Far...
10.3. Indirect Object Notation
AUTOLOAD method
accessors and: 11.4. Using AUTOLOAD for Accessors
11.4. Using AUTOLOAD for Accessors
functionality: 11.3. AUTOLOAD as a Last Resort
11.3. AUTOLOAD as a Last Resort
inheritance and: 8.5. A Few Notes About @ISA
$AUTOLOAD variable: 11.3. AUTOLOAD as a Last Resort
AutoLoader core module: 11.3. AUTOLOAD as a Last Resort
autovivification
hash references and: 4.8. Autovivification and Hashes
process defined: 4.7. Autovivification

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

backstop method: 9.8. More Interesting Instances
11.1. UNIVERSAL Methods
basename subroutine (File::Basename): 12.1. Sample Function-Oriented Interface: File::Basename
BEGIN block
importing subroutines: 12.6. What use Is Doing
purpose: 6.7. Closure Variables as Static Local Variables
setting constants: 12.7. Setting the Path at the Right Time
setting paths: 12.7. Setting the Path at the Right Time
use list and: 12.6. What use Is Doing
use operation and: 14.3. Writing Tests with Test::More
behavior
classes and: 8.2. Introducing the Method Invocation Arrow
instances and: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
passing as parameter: 6.3. Callbacks
subroutine references and: 6. Subroutine References
testing with isa and can methods: 11.2. Testing Your Objects for Good Behavior
11.2. Testing Your Objects for Good Behavior
blessed references
indirect object syntax and: 10.3. Indirect Object Notation
instances as: 9.2. Invoking an Instance Method
9.2. Invoking an Instance Method
9.8. More Interesting Instances
isa method and: 11.2. Testing Your Objects for Good Behavior
nested object destruction: 10.1. Nested Object Destruction
ref operator and: 9.6. Making a Method Work with Either Classes or Instances
returning: 9.4. How to Build a Horse
block form
grep operator: 5.4. The map and grep Operators
map operator: 5.5. Using map

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

callbacks
accessing variables: 6.4. Closures
6.5. Returning a Subroutine from a Subroutine
find( ) function and: 6.4. Closures
6.4. Closures
invoking subroutines multiple times: 6.5. Returning a Subroutine from a Subroutine
subroutine references and: 6.3. Callbacks
6.3. Callbacks
can method (UNIVERSAL): 11.2. Testing Your Objects for Good Behavior
11.2. Testing Your Objects for Good Behavior
can_ok function (Test::More): 14.3. Writing Tests with Test::More
catfile method (File::Spec): 12.3. Sample Object-Oriented Interface: File::Spec
CGI module: 12.11. Custom Import Routines
Changes file: 13.2. Looking at the Templates
class methods
building instances: 9.4. How to Build a Horse
File::Spec module and: 12.3. Sample Object-Oriented Interface: File::Spec
instance methods and: 9.2. Invoking an Instance Method
OO modules and: 12.5. The Differences Between OO and Non-OO Modules
restricting to: 9.14. Restricting a Method to Class-Only or Instance-Only
class variables: 10.5. Using Class Variables
classes
accessors and: 11.5. Creating Getters and Setters More Easily
defined: 8.2. Introducing the Method Invocation Arrow
instances and: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
methods working with: 9.6. Making a Method Work with Either Classes or Instances
UNIVERSAL class and: 11.1. UNIVERSAL Methods
virtual methods and: A.8.1. Exercise (Section 9.15.1)
Class::MethodMaker module: 11.5. Creating Getters and Setters More Easily
closure variables: 6.7. Closure Variables as Static Local Variables
closures
functionality: 6.4. Closures
lexical variables and: 6.6. Closure Variables as Inputs
persistence and: 6.7. Closure Variables as Static Local Variables
scope and: 6.6. Closure Variables as Inputs
cmp operator: 7.1. Review of Sorting
cmp_ok routine (Test::More): 14.3. Writing Tests with Test::More
code (see also OOP)
decoupling: 3.3. Dereferencing the Array Reference
reusability of: 8.6. Overriding the Methods
12. Using Modules
testing coverage: 14. Essential Testing
ways to share: 2.1. The Cure for the Common Code
code references
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors
overview: 6.1. Referencing a Named Subroutine
collisions, namespace: 2.6. The Problem of Namespace Collisions
12.3. Sample Object-Oriented Interface: File::Spec
comments: 4.9.2. Exercise 2 [30 min]
14.2. Writing Tests with Test::Simple
compile phase
AUTOLOAD and: 11.3. AUTOLOAD as a Last Resort
BEGIN keyword and: 6.7. Closure Variables as Static Local Variables
declarations during: 6.7. Closure Variables as Static Local Variables
use base and: 8.5. A Few Notes About @ISA
complex data structures (see data structures)
composition, inheritance versus: 10.4. Additional Instance Variables in Subclasses
Comprehensive Perl Archive Network (see CPAN)
conditional tests: 14.4. Conditional Tests
constants, setting: 12.7. Setting the Path at the Right Time
constructors
anonymous array: 4.5. Creating an Anonymous Array Directly
4.5. Creating an Anonymous Array Directly
5.7. Selecting and Altering Complex Data
anonymous hash: 4.6. Creating an Anonymous Hash
4.6. Creating an Anonymous Hash
4.6. Creating an Anonymous Hash
creating instances: 9.4. How to Build a Horse
inheriting: 9.5. Inheriting the Constructor
9.5. Inheriting the Constructor
url subroutine: 12.10. Exporting in a Primarily OO Module
copyright notices: 13.2. Looking at the Templates
core modules: 2.7. Packages as Namespace Separators
9.4. How to Build a Horse
11.3. AUTOLOAD as a Last Resort
CPAN (Comprehensive Perl Archive Network)
contributing to: 15. Contributing to CPAN
version numbers and: 13.3. The Prototype Module Itself
current directory
find( ) function and: 6.4. Closures
6.4. Closures
@INC array and: 2.5. require and @INC
search path and: 2.5. require and @INC
6.4. Closures
testing and: 14.6. Testing Things That Write to STDOUT and STDERR

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

data
accessing for instances: 9.3. Accessing the Instance Data
selecting: 5.7. Selecting and Altering Complex Data
5.7. Selecting and Altering Complex Data
storing: 5.3. Storing Complex Data with Storable
6.7. Closure Variables as Static Local Variables
A.9.1. Exercise (Section 10.7.1)
viewing with Data::Dumper: 5.2. Viewing Complex Data with Data::Dumper
5.2. Viewing Complex Data with Data::Dumper
viewing with debugger: 5.1. Using the Debugger to View Complex Data
data structures
looping and: 4.4. When Reference Counting Goes Bad
4.4. When Reference Counting Goes Bad
manipulating: 5. Manipulating Complex Data Structures
nested: 3.6. Nested Data Structures
3.6. Nested Data Structures
4.3. Reference Counting and Nested Data Structures
recursively defined: 7.5. Recursively Defined Data
references to anonymous: 4. References and Scoping
references to subroutines: 6. Subroutine References
Data::Dumper module: 5.2. Viewing Complex Data with Data::Dumper
5.2. Viewing Complex Data with Data::Dumper
7.7. Displaying Recursively Defined Data
daylight savings time (DST): 6.8.1. Exercise [30 min]
dbmopen function: A.9.1. Exercise (Section 10.7.1)
debugging
Changes file and: 13.2. Looking at the Templates
enabling warnings during: A.3.1. Exercise 1 (Section 4.9.1)
viewing complex data: 5.1. Using the Debugger to View Complex Data
x command: 5.1. Using the Debugger to View Complex Data
5.2. Viewing Complex Data with Data::Dumper
delegation: 10.4. Additional Instance Variables in Subclasses
dereferencing
array references: 3.3. Dereferencing the Array Reference
3.3. Dereferencing the Array Reference
3.6. Nested Data Structures
4.2. What if That Was the Name?
coderefs: 6.1. Referencing a Named Subroutine
6.1. Referencing a Named Subroutine
hash references: 3.8. References to Hashes
lexical variables and: 6.4. Closures
DESTROY method
inheritance and: 10.2. Beating a Dead Horse
10.2. Beating a Dead Horse
nested objects: 10.1. Nested Object Destruction
purpose: 10. Object Destruction
10. Object Destruction
destructors
class variables and: 10.6. Weakening the Argument
IO::File objects and: 11.7. References to Filehandles
nested objects example: 10.1. Nested Object Destruction
direct object syntax: 10.3. Indirect Object Notation
10.3. Indirect Object Notation
directories
represented as hashes: 7.6. Building Recursively Defined Data
separating with colon: 2.5.2. Extending @INC with PERL5LIB
t files and: 14.1. What the Test Harness Does
dirname subroutine (File::Basename): 12.1. Sample Function-Oriented Interface: File::Basename
distributions
alternate installation locations: 13.6. Alternate Installation Locations (PREFIX=...)
announcing CPAN modules: 15.5. Announcing the Module
copyrights and licensing: 13.2. Looking at the Templates
embedded documentation: 13.4. Embedded Documentation
Exporter module: 13.3. The Prototype Module Itself
h2xs tool: 13.1. Starting with h2xs
make dist and: 13.9. Trivial make dist
13.9. Trivial make dist
Makefile.PL: 13.5. Controlling the Distribution with Makefile.PL
modules within: 13.3. The Prototype Module Itself
POD format: 13.4. Embedded Documentation
preparing: 15.3. Preparing Your Distribution
15.3. Preparing Your Distribution
qw( ) lists: 13.3. The Prototype Module Itself
template files: 13.2. Looking at the Templates
testing: 13.7. Trivial make test
14. Essential Testing
Test::More module: 14.3. Writing Tests with Test::More
Test::Simple module: 14.2. Writing Tests with Test::Simple
14.2. Writing Tests with Test::Simple
uploading to CPAN: 15.4. Uploading Your Distribution
15.4. Uploading Your Distribution
version numbers: 13.3. The Prototype Module Itself
15.3. Preparing Your Distribution
do operator: 2.3. Using do
documentation
distribution considerations: 13. Writing a Distribution
embedded for distribution: 13.4. Embedded Documentation
testing and: 14. Essential Testing
drop arrow rule: 3.7. Simplifying Nested Element References with Arrows
Dumper subroutine: 5.2. Viewing Complex Data with Data::Dumper

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

empty import lists: 12.2. Selecting What to Import
encapsulation, object: 9.11. Don't Look Inside the Box
END blocks: 10. Object Destruction
_ _END_ _ marker: 13.4. Embedded Documentation
eval function: 2.2. Inserting Code with eval
2.2. Inserting Code with eval
@EXPORT variable: 12.9. @EXPORT and @EXPORT_OK
12.9. @EXPORT and @EXPORT_OK
13.3. The Prototype Module Itself
Exporter module
distributions: 13.3. The Prototype Module Itself
importing with: 12.8. Importing with Exporter
12.8. Importing with Exporter
12.10. Exporting in a Primarily OO Module
package variables: 12.9. @EXPORT and @EXPORT_OK
export_fail method (Exporter): 12.10. Exporting in a Primarily OO Module
exporting
OO modules and: 12.5. The Differences Between OO and Non-OO Modules
12.10. Exporting in a Primarily OO Module
13.3. The Prototype Module Itself
symbols: 13.3. The Prototype Module Itself
@EXPORT_OK variable: 12.9. @EXPORT and @EXPORT_OK
12.9. @EXPORT and @EXPORT_OK
13.3. The Prototype Module Itself
export_to_level method (Exporter): 12.10. Exporting in a Primarily OO Module
expression form
grep operator: 5.4. The map and grep Operators
map operator: 5.5. Using map
extending
class variables: 10.5. Using Class Variables
subroutines: 10.4. Additional Instance Variables in Subclasses
superclass methods: 10.2. Beating a Dead Horse
10.2. Beating a Dead Horse
ExtUtils::MakeMaker module: 13.5. Controlling the Distribution with Makefile.PL

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

File::Basename module: 12.1. Sample Function-Oriented Interface: File::Basename
12.1. Sample Function-Oriented Interface: File::Basename
12.8. Importing with Exporter
File::Find module
features: 6.3. Callbacks
6.4. Closures
returning coderefs: 6.8.1. Exercise [30 min]
filehandles
instance variables: 10.1. Nested Object Destruction
ok function (Test::More) and: 14.6. Testing Things That Write to STDOUT and STDERR
package names and: 2.7. Packages as Namespace Separators
|| operator and: NaN.10.1. Exercise (Section 11.8.1)
references to: 11.7. References to Filehandles
storing in a hash: NaN.10.1. Exercise (Section 11.8.1)
temporary files: 10. Object Destruction
fileparse subroutine (File::Basename): 12.1. Sample Function-Oriented Interface: File::Basename
12.8. Importing with Exporter
files
distribution templates: 13.2. Looking at the Templates
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec
find subroutine: 6.4. Closures
finding timestamps: 6.8.1. Exercise [30 min]
parsing specifications: 12.1. Sample Function-Oriented Interface: File::Basename
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec
filesystems
capturing information about: 7.6. Building Recursively Defined Data
walking through hierarchy: 6.3. Callbacks
6.3. Callbacks
find subroutine (File::Find): 6.3. Callbacks
6.4. Closures
friend classes: 10.4. Additional Instance Variables in Subclasses
11.5. Creating Getters and Setters More Easily

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

garbage collection: 4.4. When Reference Counting Goes Bad
getters
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors
11.4. Using AUTOLOAD for Accessors
creating easily: 11.5. Creating Getters and Setters More Easily
doubling as setters: 9.13. Getters That Double as Setters
9.13. Getters That Double as Setters
encapsulation and: 9.11. Don't Look Inside the Box
optimizing: 9.12. Faster Getters and Setters
glob operator: 7.8.1. Exercise 1 [15 min]
11.4. Using AUTOLOAD for Accessors
11.7. References to Filehandles
global variables
data destruction and: 10. Object Destruction
package variables as: 2.9. Packages and Lexicals
scope and: 6.6. Closure Variables as Inputs
grep operator (see also Schwartzian Transform)
filehandles and: 11.7. References to Filehandles
11.7. References to Filehandles
functionality: 5.4. The map and grep Operators
indices and: 7.2. Sorting with Indices
indirection and: 5.6. Applying a Bit of Indirection
scalar context and: 3.1. Performing the Same Task on Many Arrays
5.4. The map and grep Operators
selecting complex data: 5.7. Selecting and Altering Complex Data

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

hash reference
anonymous hash constructors: 4.6. Creating an Anonymous Hash
autovivification and: 4.8. Autovivification and Hashes
Data::Dumper example: 5.2. Viewing Complex Data with Data::Dumper
debugging example: 5.1. Using the Debugger to View Complex Data
5.1. Using the Debugger to View Complex Data
5.1. Using the Debugger to View Complex Data
dereferencing: 3.8. References to Hashes
features: 3.8. References to Hashes
filesystem capture example: 7.6. Building Recursively Defined Data
object destruction: 10. Object Destruction
as parameters: 3.9.2. Exercise 2 [30 min]
as return values: 7.6. Building Recursively Defined Data
hashes (see also anonymous hash also anonymous hash)
(see also anonymous hash)
directories as: 7.6. Building Recursively Defined Data
instances and: 9.8. More Interesting Instances
map operator and: 5.5. Using map
package names and: 2.7. Packages as Namespace Separators
references and: 3.2. Taking a Reference to an Array
5.7. Selecting and Altering Complex Data
scalars and: 3. Introduction to References
storing filehandles: NaN.10.1. Exercise (Section 11.8.1)
HASH(0x1a2b3c): 3.8. References to Hashes
hexadecimal memory address: 3.2. Taking a Reference to an Array
3.8. References to Hashes
h2xs tool
distributions and: 13.1. Starting with h2xs
Makefile.PL and: 13.5. Controlling the Distribution with Makefile.PL
multiple test scripts and: 14.5. More Complex Tests (Multiple Test Scripts)

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

importing
-nosticky option: 12.11. Custom Import Routines
custom routines: 12.11. Custom Import Routines
Exporter module and: 12.8. Importing with Exporter
12.8. Importing with Exporter
File::Basename module and: 12.2. Selecting What to Import
subroutines: 12.6. What use Is Doing
12.9. @EXPORT and @EXPORT_OK
use operation and: 12.6. What use Is Doing
@INC array
require operator and: 2.5. require and @INC
use operation and: 12.7. Setting the Path at the Right Time
indices, sorting with: 7.2. Sorting with Indices
7.2. Sorting with Indices
indirect object notation: 10.3. Indirect Object Notation
indirection
applying: 5.6. Applying a Bit of Indirection
sorting indices: 7.2. Sorting with Indices
inheritance
code reusability through: 8.6. Overriding the Methods
composition versus: 10.4. Additional Instance Variables in Subclasses
constructors and: 9.5. Inheriting the Constructor
9.5. Inheriting the Constructor
DESTROY method and: 10.2. Beating a Dead Horse
10.2. Beating a Dead Horse
isa method testing: 11.2. Testing Your Objects for Good Behavior
@ISA variable and: 8.5. A Few Notes About @ISA
method invocation and: 8.4. Calling a Second Method to Simplify Things
8.4. Calling a Second Method to Simplify Things
multiple inheritance: 11.6. Multiple Inheritance
installation (of modules)
alternate library locations: 13.10. Using the Alternate Library Location
alternate locations: 13.6. Alternate Installation Locations (PREFIX=...)
distribution considerations: 13. Writing a Distribution
instance methods
APIs and: 9.7. Adding Parameters to a Method
class methods and: 9.2. Invoking an Instance Method
invoking: 9.2. Invoking an Instance Method
9.2. Invoking an Instance Method
Math::BigInt module: 12.4. A More Typical Object-Oriented Module: Math::BigInt
OO modules and: 12.5. The Differences Between OO and Non-OO Modules
parameters and: 9.7. Adding Parameters to a Method
restricting to: 9.14. Restricting a Method to Class-Only or Instance-Only
instance variables
defined: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
filehandles as: 10.1. Nested Object Destruction
hash keys: 9.8. More Interesting Instances
object destruction and: 10. Object Destruction
in subclasses: 10.4. Additional Instance Variables in Subclasses
10.4. Additional Instance Variables in Subclasses
instances
accessors and: 11.5. Creating Getters and Setters More Easily
blessed references and: 9.2. Invoking an Instance Method
9.2. Invoking an Instance Method
building: 9.4. How to Build a Horse
defined: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
9.1. A Horse Is a Horse, of Course of Course--or Is It?
hashes and: 9.8. More Interesting Instances
isa method testing: 11.2. Testing Your Objects for Good Behavior
methods working with: 9.6. Making a Method Work with Either Classes or Instances
interfaces
distribution considerations: 13. Writing a Distribution
File::Basename module: 12.1. Sample Function-Oriented Interface: File::Basename
12.1. Sample Function-Oriented Interface: File::Basename
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec
maintenance considerations: 11.5. Creating Getters and Setters More Easily
version numbers and: 13.3. The Prototype Module Itself
IO::File class: 11.7. References to Filehandles
11.7. References to Filehandles
is function (Test::More): 14.3. Writing Tests with Test::More
14.6. Testing Things That Write to STDOUT and STDERR
@ISA variable
features: 8.5. A Few Notes About @ISA
8.5. A Few Notes About @ISA
inheritance hierarchies and: 11.1. UNIVERSAL Methods
multiple inheritance: 11.6. Multiple Inheritance
isa method (UNIVERSAL): 11.2. Testing Your Objects for Good Behavior
11.2. Testing Your Objects for Good Behavior
isa_ok function (Test::More): 14.3. Writing Tests with Test::More
isnt function (Test::More): 14.3. Writing Tests with Test::More
iteration versus recursion: 7.5. Recursively Defined Data

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

There are no index entries for this letter.

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

key/value pairs: 4.6. Creating an Anonymous Hash

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

lexical variables
closures and: 6.4. Closures
6.6. Closure Variables as Inputs
data destruction and: 10. Object Destruction
defined: 2.3. Using do
@ISA and: 8.5. A Few Notes About @ISA
packages and: 2.9. Packages and Lexicals
2.9. Packages and Lexicals
reference longevity: 4.1. More than One Reference to Data
subroutine references: 6.4. Closures
6.5. Returning a Subroutine from a Subroutine
6.7. Closure Variables as Static Local Variables
libraries
alternate installation locations: 13.6. Alternate Installation Locations (PREFIX=...)
13.10. Using the Alternate Library Location
loading only once: 2.4. Using require
search path for: 2.5. require and @INC
licensing: 13.2. Looking at the Templates
like function (Test::More): 14.3. Writing Tests with Test::More
lists
absent import lists: 12.2. Selecting What to Import
qw( ) list: 12.2. Selecting What to Import
13.3. The Prototype Module Itself
sorted list: A.3.2. Exercise 2 (Section 4.9.2)
looping (code structure): 5.1. Using the Debugger to View Complex Data
6.7. Closure Variables as Static Local Variables
looping (data structure): 4.4. When Reference Counting Goes Bad
4.4. When Reference Counting Goes Bad

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

maintenance considerations: 11.5. Creating Getters and Setters More Easily
make dist: 13.9. Trivial make dist
13.9. Trivial make dist
make install: 13.8. Trivial make install
make test: 13.7. Trivial make test
14. Essential Testing
14.2. Writing Tests with Test::Simple
Makefile.PL
controlling distribution: 13.5. Controlling the Distribution with Makefile.PL
PREFIX=option: 13.6. Alternate Installation Locations (PREFIX=...)
13.10. Using the Alternate Library Location
test harness: 13.7. Trivial make test
14.1. What the Test Harness Does
14.1. What the Test Harness Does
14.3. Writing Tests with Test::More
testing and: 15.3. Preparing Your Distribution
MANIFEST file: 13.2. Looking at the Templates
13.2. Looking at the Templates
15.3. Preparing Your Distribution
map operator (see also Schwartzian Transform)
functionality: 5.4. The map and grep Operators
indirection and: 5.6. Applying a Bit of Indirection
scalar context: 5.5. Using map
selecting complex data: 5.7. Selecting and Altering Complex Data
Math::BigInt module: 12.4. A More Typical Object-Oriented Module: Math::BigInt
12.4. A More Typical Object-Oriented Module: Math::BigInt
member variables: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
9.8. More Interesting Instances
memory addresses: 3.2. Taking a Reference to an Array
3.8. References to Hashes
memory management: 4.4. When Reference Counting Goes Bad
10.6. Weakening the Argument
meta-variables: 10.5. Using Class Variables
methods (see also class methods, instance methods)
abstract methods: 11.5. Creating Getters and Setters More Easily
getters doubling as setters: 9.13. Getters That Double as Setters
inheritance and: 8.4. Calling a Second Method to Simplify Things
8.4. Calling a Second Method to Simplify Things
instances and: 9.2. Invoking an Instance Method
9.2. Invoking an Instance Method
invocation arrow: 8.2. Introducing the Method Invocation Arrow
8.2. Introducing the Method Invocation Arrow
8.10. Where We Are So Far...
10.3. Indirect Object Notation
overriding: 8.6. Overriding the Methods
parameters and: 8.3. The Extra Parameter of Method Invocation
8.3. The Extra Parameter of Method Invocation
9.7. Adding Parameters to a Method
9.7. Adding Parameters to a Method
restricting: 9.14. Restricting a Method to Class-Only or Instance-Only
superclasses: 10.2. Beating a Dead Horse
10.2. Beating a Dead Horse
UNIVERSAL class and: 11.1. UNIVERSAL Methods
working with classes: 9.6. Making a Method Work with Either Classes or Instances
modules (see also packages)
announcing: 15.5. Announcing the Module
core modules: 2.7. Packages as Namespace Separators
9.4. How to Build a Horse
11.3. AUTOLOAD as a Last Resort
distributions and: 13.1. Starting with h2xs
13.3. The Prototype Module Itself
overview: 12. Using Modules
my variables: 2.3. Using do
2.8. Scope of a Package Directive

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

namespaces
packages as separators: 2.7. Packages as Namespace Separators
problems with collisions: 2.6. The Problem of Namespace Collisions
12.3. Sample Object-Oriented Interface: File::Spec
nested entities
data structures: 3.6. Nested Data Structures
3.6. Nested Data Structures
4.3. Reference Counting and Nested Data Structures
element references: 3.7. Simplifying Nested Element References with Arrows
object destruction: 10.1. Nested Object Destruction
new method
creating objects: 9.4. How to Build a Horse
indirect object notation: 10.3. Indirect Object Notation
Math::BigInt module: 12.4. A More Typical Object-Oriented Module: Math::BigInt
numbers
sorting: 7.1. Review of Sorting
7.1. Review of Sorting
testing equality: 14.3. Writing Tests with Test::More

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

object-oriented programming (see OOP)
objects
bless operator and: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
as blessed references: 9.8. More Interesting Instances
creating: 9.4. How to Build a Horse
destruction of: 10. Object Destruction
encapsulation of: 9.11. Don't Look Inside the Box
filehandles and: 11.7. References to Filehandles
instances and: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
structure considerations: 9.8. More Interesting Instances
testing with isa and can methods: 11.2. Testing Your Objects for Good Behavior
11.2. Testing Your Objects for Good Behavior
ok function (Test::Simple): 14.2. Writing Tests with Test::Simple
14.6. Testing Things That Write to STDOUT and STDERR
OO (object-oriented) modules
exporting: 13.3. The Prototype Module Itself
exporting and: 12.10. Exporting in a Primarily OO Module
non-OO versus: 12.5. The Differences Between OO and Non-OO Modules
Test::More module: 14.3. Writing Tests with Test::More
OOP (object-oriented programming)
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec
inheritance structures and: A.7.2. Exercise 2 (Section 8.11.2)
overview: 8. Introduction to Objects
versus non-OOP: 12.5. The Differences Between OO and Non-OO Modules
ordered lists: 3. Introduction to References
our variables: 8.5. A Few Notes About @ISA
overriding
methods: 8.6. Overriding the Methods
superclass methods: 10.2. Beating a Dead Horse
10.2. Beating a Dead Horse
UNIVERSAL class methods: 11.1. UNIVERSAL Methods

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

packages (see also modules)
global variables: 2.9. Packages and Lexicals
6.6. Closure Variables as Inputs
@ISA variable and: 8.5. A Few Notes About @ISA
8.5. A Few Notes About @ISA
lexicals and: 2.9. Packages and Lexicals
2.9. Packages and Lexicals
main program in: 2.7. Packages as Namespace Separators
as namespace separators: 2.7. Packages as Namespace Separators
naming considerations: 2.7. Packages as Namespace Separators
8.2. Introducing the Method Invocation Arrow
scope of directives: 2.8. Scope of a Package Directive
2.8. Scope of a Package Directive
parameters (see also return values)
@_: 8.9. What to Do with @_
adding to methods: 9.7. Adding Parameters to a Method
9.7. Adding Parameters to a Method
callbacks and: 6.5. Returning a Subroutine from a Subroutine
6.5. Returning a Subroutine from a Subroutine
hash references as: 3.9.2. Exercise 2 [30 min]
instance methods and: 9.2. Invoking an Instance Method
instances as: 9.2. Invoking an Instance Method
method invocation and: 8.3. The Extra Parameter of Method Invocation
8.3. The Extra Parameter of Method Invocation
passing to superclasses: 10.4. Additional Instance Variables in Subclasses
returning updated values: 9.10. Getting Your Deposit Back
shifting: 8.4. Calling a Second Method to Simplify Things
8.9. What to Do with @_
parent-child relationships: 10.6. Weakening the Argument
parsing
file specifications: 12.1. Sample Function-Oriented Interface: File::Basename
shifting style: 2.1. The Cure for the Common Code
3.1. Performing the Same Task on Many Arrays
passing by reference (see references)
PATH environment variable: 2.5. require and @INC
paths, searching for installed modules/libraries: 12.7. Setting the Path at the Right Time
12.7. Setting the Path at the Right Time
PAUSE (Perl Authors Upload Server) ID: 15.2. Getting Prepared
15.4. Uploading Your Distribution
perl command
-d option: 5.1. Using the Debugger to View Complex Data
-I option: 2.5.3. Extending @INC with -I
13.10. Using the Alternate Library Location
-M option: 13.10. Using the Alternate Library Location
-V command line option: 2.5. require and @INC
-V:make: 13.5. Controlling the Distribution with Makefile.PL
-w option: 10.3. Indirect Object Notation
A.3.1. Exercise 1 (Section 4.9.1)
PREFIX= option (Makefile.PL): 13.6. Alternate Installation Locations (PREFIX=...)
13.10. Using the Alternate Library Location
perl-packrats mailing list: 15.1. The Comprehensive Perl Archive Network
PERL5LIB environment variable: 2.5.2. Extending @INC with PERL5LIB
.pl (Perl Library) extension: 2.3. Using do
.plx (Perl Executable) extension: 2.3. Using do
.pm (Perl Module) extension: 12.6. What use Is Doing
POD format: 13.4. Embedded Documentation
prefixes, explicit: 2.6. The Problem of Namespace Collisions
PREREQ_PM setting (Makefiles): 13.5. Controlling the Distribution with Makefile.PL
programs (see also OOP)
behaviors of: 6. Subroutine References
compile phase: 6.7. Closure Variables as Static Local Variables
object destruction and: 10. Object Destruction
run phase: 6.7. Closure Variables as Static Local Variables
sharing code: 2.1. The Cure for the Common Code
whitespace: 3.3. Dereferencing the Array Reference
4.7. Autovivification
properties, instances and: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
push function: 2.5.1. Extending @INC

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

qw( ) list: 12.2. Selecting What to Import
13.3. The Prototype Module Itself

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

README file: 13.2. Looking at the Templates
13.2. Looking at the Templates
15.3. Preparing Your Distribution
recursively defined data: 7.6. Building Recursively Defined Data
ref operator: 9.6. Making a Method Work with Either Classes or Instances
9.14. Restricting a Method to Class-Only or Instance-Only
reference counting
closures and: 6.5. Returning a Subroutine from a Subroutine
defined: 4.1. More than One Reference to Data
garbage collection and: 4.4. When Reference Counting Goes Bad
memory management and: 4.4. When Reference Counting Goes Bad
nested data structures and: 4.3. Reference Counting and Nested Data Structures
subroutine reference example: 6.5. Returning a Subroutine from a Subroutine
weak references and: 10.6. Weakening the Argument
references (see also array reference, blessed references, dereferencing hash references)
to filehandles: 11.7. References to Filehandles
bless operator: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
destruction and: 10.6. Weakening the Argument
hierarchical data and: 7.5. Recursively Defined Data
instances and: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
9.5. Inheriting the Constructor
9.8. More Interesting Instances
named subroutines: 6.1. Referencing a Named Subroutine
object destruction and: 10. Object Destruction
overview: 3. Introduction to References
return values: 9.4. How to Build a Horse
as scalars: A.3.1. Exercise 1 (Section 4.9.1)
scoping and: 4. References and Scoping
weak references: 10.6. Weakening the Argument
require operator
functionality: 2.4. Using require
2.4. Using require
@INC and: 2.5. require and @INC
syntax errors and: 2.4. Using require
use operation and: 12.6. What use Is Doing
12.6. What use Is Doing
require_version method (Exporter): 12.10. Exporting in a Primarily OO Module
return values (see also parameters)
bless operator and: 9.4. How to Build a Horse
coderefs as: 6.8.1. Exercise [30 min]
hash references: 7.6. Building Recursively Defined Data
required files: 12.6. What use Is Doing
subroutine references: 6.5. Returning a Subroutine from a Subroutine
undef example: 7.6. Building Recursively Defined Data
updated parameters: 9.10. Getting Your Deposit Back
run phase
BEGIN keyword and: 6.7. Closure Variables as Static Local Variables
storage allocation: 6.7. Closure Variables as Static Local Variables

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

s command (debugger): 5.1. Using the Debugger to View Complex Data
scalars
anonymous: 6.4. Closures
curly braces and: 6.1. Referencing a Named Subroutine
filehandles and: 11.7. References to Filehandles
hash references and: 4.6. Creating an Anonymous Hash
indirect object syntax: 10.3. Indirect Object Notation
isa method and: 11.2. Testing Your Objects for Good Behavior
package names and: 2.7. Packages as Namespace Separators
references and: 3.2. Taking a Reference to an Array
A.3.1. Exercise 1 (Section 4.9.1)
single values and: 3. Introduction to References
Schwartzian Transform
dictionary order: 7.8.3. Exercise 3 [10 min]
performance: A.6.2. Exercise 2 (Section 7.8.2)
sorting and: 7.4. The Schwartzian Transform
scope
do operator and: 2.3. Using do
global variables and: 6.6. Closure Variables as Inputs
references and: 4. References and Scoping
scripts
alternate installation locations: 13.6. Alternate Installation Locations (PREFIX=...)
complex tests: 14.5. More Complex Tests (Multiple Test Scripts)
search path: 2.5. require and @INC
6.4. Closures
SelfLoader core module: 11.3. AUTOLOAD as a Last Resort
setters
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors
11.4. Using AUTOLOAD for Accessors
creating: 9.10. Getting Your Deposit Back
11.5. Creating Getters and Setters More Easily
encapsulation and: 9.11. Don't Look Inside the Box
getters doubling as: 9.13. Getters That Double as Setters
9.13. Getters That Double as Setters
optimizing: 9.12. Faster Getters and Setters
9.13. Getters That Double as Setters
restricting methods: 9.13. Getters That Double as Setters
shifting
@_ array: 3.1. Performing the Same Task on Many Arrays
argument parsing: 2.1. The Cure for the Common Code
3.1. Performing the Same Task on Many Arrays
arguments: 8.4. Calling a Second Method to Simplify Things
8.9. What to Do with @_
closure variables: 6.6. Closure Variables as Inputs
example eliminating: 3.3. Dereferencing the Array Reference
smoke tests: 15.6. Testing on Multiple Platforms
sorting
dictionary order: 7.8.3. Exercise 3 [10 min]
efficient: 7.3. Sorting Efficiently
glob operator: 7.8.1. Exercise 1 [15 min]
with indices: 7.2. Sorting with Indices
7.2. Sorting with Indices
review of: 7.1. Review of Sorting
7.1. Review of Sorting
Schwartzian Transform: 7.4. The Schwartzian Transform
sort blocks: 7.1. Review of Sorting
sorted list: A.3.2. Exercise 2 (Section 4.9.2)
spaceship operator: 7.1. Review of Sorting
sqrt function: 14. Essential Testing
static local variables: 6.7. Closure Variables as Static Local Variables
STDERR filehandle: 14.6. Testing Things That Write to STDOUT and STDERR
STDOUT filehandle: 14.6. Testing Things That Write to STDOUT and STDERR
Storable module: 5.3. Storing Complex Data with Storable
storing data: 5.3. Storing Complex Data with Storable
6.7. Closure Variables as Static Local Variables
A.9.1. Exercise (Section 10.7.1)
strings (see text strings)
subclasses
abstract methods and: 11.5. Creating Getters and Setters More Easily
instance variables in: 10.4. Additional Instance Variables in Subclasses
10.4. Additional Instance Variables in Subclasses
subroutine references: 6.1. Referencing a Named Subroutine
subroutines (see also closures)
custom import routines: 12.11. Custom Import Routines
extending: 10.4. Additional Instance Variables in Subclasses
importing: 12.6. What use Is Doing
12.9. @EXPORT and @EXPORT_OK
isa called as: 11.2. Testing Your Objects for Good Behavior
modules and: 12. Using Modules
out of scope variables and: 6.7. Closure Variables as Static Local Variables
package names and: 2.7. Packages as Namespace Separators
referencing: 6.1. Referencing a Named Subroutine
syntax errors and: 2.2. Inserting Code with eval
SUPER pseudo-class: 8.8. The SUPER Way of Doing Things
superclasses: 8.8. The SUPER Way of Doing Things
10.2. Beating a Dead Horse
10.2. Beating a Dead Horse
10.4. Additional Instance Variables in Subclasses
symbols: 12.8. Importing with Exporter
13.3. The Prototype Module Itself
syntax errors: 2.2. Inserting Code with eval
2.4. Using require
system performance: 11.5. Creating Getters and Setters More Easily

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

t directory: 14.1. What the Test Harness Does
"take a reference to" operator: 3.2. Taking a Reference to an Array
3.8. References to Hashes
6.1. Referencing a Named Subroutine
template files: 13.2. Looking at the Templates
temporary files
data destruction and: 10. Object Destruction
10.1. Nested Object Destruction
10.1. Nested Object Destruction
STDOUT and: 14.6. Testing Things That Write to STDOUT and STDERR
testing
code coverage: 14. Essential Testing
conditional tests: 14.4. Conditional Tests
distributions and: 13. Writing a Distribution
13.7. Trivial make test
inequality: 14.3. Writing Tests with Test::More
isa and can methods: 11.2. Testing Your Objects for Good Behavior
11.2. Testing Your Objects for Good Behavior
Makefile.PL and: 15.3. Preparing Your Distribution
multiple test scripts: 14.5. More Complex Tests (Multiple Test Scripts)
numeric equality: 14.3. Writing Tests with Test::More
pound-sign comments and: 14.2. Writing Tests with Test::Simple
smoke tests: 15.6. Testing on Multiple Platforms
sqrt function: 14. Essential Testing
test harness: 13.7. Trivial make test
14.1. What the Test Harness Does
14.1. What the Test Harness Does
14.3. Writing Tests with Test::More
use operation: 14.3. Writing Tests with Test::More
writing to STDOUT and STDERR: 14.6. Testing Things That Write to STDOUT and STDERR
testing expression (of map or grep): 5.4. The map and grep Operators
5.5. Using map
Test::More module: 14.3. Writing Tests with Test::More
14.6. Testing Things That Write to STDOUT and STDERR
Test::Simple module: 14.2. Writing Tests with Test::Simple
14.2. Writing Tests with Test::Simple
TEST_VERBOSE option (make test): 14.2. Writing Tests with Test::Simple
text strings
cmp operator: 7.1. Review of Sorting
like function: 14.3. Writing Tests with Test::More
ref operator and: 9.6. Making a Method Work with Either Classes or Instances
sorting: 7.1. Review of Sorting
timestamps: 6.8.1. Exercise [30 min]
TODO blocks: 14.4. Conditional Tests
$TODO variable: 14.4. Conditional Tests

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

undef (value)
autovivification and: 4.7. Autovivification
filesystem capture example: 7.6. Building Recursively Defined Data
ref operator and: 9.6. Making a Method Work with Either Classes or Instances
variables with value of: 6.7. Closure Variables as Static Local Variables
weak references and: 10.6. Weakening the Argument
unimport method (Exporter): 12.10. Exporting in a Primarily OO Module
UNIVERSAL class
inheritance and: 8.5. A Few Notes About @ISA
purpose of: 11.1. UNIVERSAL Methods
utility methods: 11.2. Testing Your Objects for Good Behavior
11.2. Testing Your Objects for Good Behavior
unshift function: 2.5.1. Extending @INC
12.7. Setting the Path at the Right Time
URIs (universal resource identifiers): 12.10. Exporting in a Primarily OO Module
URI::URL module: 12.10. Exporting in a Primarily OO Module
url subroutine (URI::URL): 12.10. Exporting in a Primarily OO Module
use base: 8.5. A Few Notes About @ISA
use CGI: 12.11. Custom Import Routines
use lib: 12.7. Setting the Path at the Right Time
12.7. Setting the Path at the Right Time
13.10. Using the Alternate Library Location
use operation: 12.6. What use Is Doing
13.3. The Prototype Module Itself
14.3. Writing Tests with Test::More
14.3. Writing Tests with Test::More
use strict: 8.1. If We Could Talk to the Animals...
8.5. A Few Notes About @ISA

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

variables (see also instance variables, lexical variables)
bless operator: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
callbacks and: 6.4. Closures
6.5. Returning a Subroutine from a Subroutine
class variables: 10.5. Using Class Variables
closure variables: 6.7. Closure Variables as Static Local Variables
filehandles and: 11.7. References to Filehandles
global variables: 2.9. Packages and Lexicals
6.6. Closure Variables as Inputs
10. Object Destruction
member variables: 9.1. A Horse Is a Horse, of Course of Course--or Is It?
9.8. More Interesting Instances
memory addresses of: 3.2. Taking a Reference to an Array
meta-variables: 10.5. Using Class Variables
modules and: 12. Using Modules
my variables: 2.3. Using do
2.8. Scope of a Package Directive
our variables: 8.5. A Few Notes About @ISA
out of scope: 6.4. Closures
6.4. Closures
6.5. Returning a Subroutine from a Subroutine
6.5. Returning a Subroutine from a Subroutine
6.6. Closure Variables as Inputs
6.7. Closure Variables as Static Local Variables
package names: 8.2. Introducing the Method Invocation Arrow
reference removal and: 4.2. What if That Was the Name?
4.2. What if That Was the Name?
as repository of values: 6. Subroutine References
static local: 6.7. Closure Variables as Static Local Variables
version numbers: 13.3. The Prototype Module Itself
15.3. Preparing Your Distribution
$VERSION variable: 13.9. Trivial make dist
viewing data
Data::Dumper: 5.2. Viewing Complex Data with Data::Dumper
5.2. Viewing Complex Data with Data::Dumper
with debugger: 5.1. Using the Debugger to View Complex Data
void context: 9.10. Getting Your Deposit Back

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

wantarray function: 9.10. Getting Your Deposit Back
9.10. Getting Your Deposit Back
warnings, enabling: 2.4. Using require
A.3.1. Exercise 1 (Section 4.9.1)
weak references: 10.6. Weakening the Argument
WeakRef module: 10.6. Weakening the Argument
whitespace: 3.3. Dereferencing the Array Reference
4.7. Autovivification
working directory (see current directory)
WriteMakefile subroutine (ExtUtils::MakeMaker): 13.5. Controlling the Distribution with Makefile.PL
writing distributions: 13. Writing a Distribution

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x command (debugger): 5.1. Using the Debugger to View Complex Data
5.2. Viewing Complex Data with Data::Dumper

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

There are no index entries for this letter.

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

There are no index entries for this letter.

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2003 O'Reilly & Associates, Inc. All Rights Reserved.


Mastering Regular Expressions, 2nd Edition

 Mastering Regular Expressions, 2nd Ed.

By Jeffrey Friedl
ISBN 0-596-00272-6
Second edition, published July 2002.
(See the catalog page for this book.)

This bonus book is in Adobe PDF format. It is searchable from within the Adobe Reader, but not as a part of the overall Perl CD Bookshelf html collection. The author maintains a website for this book at www.regex.info, which contains regular expression links, some code snippets from the book, a searchable index, errata, and more.

Go to Mastering Regular Expressions

Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.


Related Articles from the O'Reilly Network

O'Reilly Network

Related Articles from
the O'Reilly Network
Optimizing Your Perl
Using CGI::Application
Class::DBI
The Many Dates and Times of Perl
How to Avoid Writing Code
Parse::RecDescent Tutorial
Stopping Spam with SpamAssassin
Choosing a Templating System
An Introduction to Testing
Testing mod_perl 2.0
Hidden Treasures of the Perl Core
Hidden Treasures of the Perl Core, Part II

Trouble Printing Code Examples?

The Perl CD Bookshelf, Version 4.0, is Copyright © 2004 by O'Reilly & Associates, Inc. All rights reserved.
Questions, comments, and suggestions to bookquestions@oreilly.com.


Perl.com: Optimizing Your Perl

Published on Perl.com
http://www.perl.com/pub/a/2002/02/12/bigo.html
See this if you're having trouble printing code examples

Optimizing Your Perl
By Robert Spier

Is your Perl program taking too long to run? This might be because you've chosen a data structure or algorithm that takes a long time to run. By rethinking how you've implemented a function, you might be able to realize huge gains in speed.

Some Simple Complexity Theory

Before we can talk about speeding up something, we need a way to describe how long something takes. Because we're talking about algorithms that may have varying amounts of input, the actual "time" to do something isn't conclusive. Computer scientists and mathematicians use a system called big-O notation to describe the order of magnitude of how long something will take. Big-O notation represents a worst-case analysis. There are other notations to represent the magnitude of minimum and actual runtimes.

Don't let the talk of computer scientists and mathematicians scare you. The next few paragraphs talk about a way to describe the difference between orders of magnitude such as a second, minute, hour or day. Or 1, 10, 100 and 1,000. You don't need to know any fancy or scary math to understand it.

It's simple. If the runtime of a function is constant, then this is written as O(1). (Note the capital or "big" O.) Constant means that no matter how much data is processed, (i.e., how much input there is) the time doesn't change.

If the runtime is directly related to the amount of input (a.k.a. linear), then this is O(n). If there is twice as much input, then the algorithm will take twice as long to run. Some functions are O(n^2) (quadratic) or O(n^3) (cubic) or even worse.

Because we are only looking at orders of magnitude (is the operation going to take one minute or one hour) we can ignore constant factors and smaller terms. O(2n) and O(n) are equivalent. As are O(n+1) and O(n) or O(n^2+n) and O(n^2). The smaller term is insignificant compared to the larger.

There are rules for analyzing code and determining its big-O, but the simplest way is to look at how many times you iterate over the data. if you don't iterate, then it's O(1). If you iterate over it once, then it's O(n). If you have two nested loops, then it's probably O(n^2).

Example #1: Graphing

I developed a new graph module for a project at my day job, because the existing one was overkill, yet did not support a feature I needed. It was easy to implement and worked very well, until the graph got very big. I needed flattened subgraphs to do dependency checks, but it was taking more than two minutes to compute (on a 1Ghz P3) for a 1,000 node graph. I needed the computation to be much faster, or my users would get mad.

My initial Graph module looked like this. (Simplified to only show relevant parts.)

 package Graph; # for Directed Graphs
 use strict;
 sub new {
  my $this = { edges => [],
               vertices => {} };
  bless $this, "Graph";
 }
 sub add_edge { # from x to y
  my ($this,$x,$y) = @_;
  $this->{vertices}{$x}++;
  $this->{vertices}{$y}++;
  push @{$this->{edges}},[$x=>$y];
 }
 sub in_edges {
  my ($this,$v) = @_;
  grep { $_->[1] eq $v } @{$this->{edges}};
 }

The add_edge method is O(1) because it will always take the same amount of time no matter how many nodes/edges are in the graph. The in_edges method is O(n) because it has to iterate over each edge in the graph. (The iteration is "inside" the grep.)

The problematic section of the code looked like this:

 sub flat_subgraph {
    my ($graph,$start) = @_;
    my %seen;
    my @worklist = ($start);
    while (@worklist) {
      my $x = shift @worklist;
      push @worklist, $graph->in_edges($x)
         unless $seen{$x}++;
    }
    return keys %seen;
 }

And I actually needed to do that for multiple vertices;

  my %dependencies;
  for (keys %{$graph->{vertices}}) {
   $dependencies{$_} = [ flat_subgraph( $graph, $_ ) ];
  }

This would make the entire flattening operation O(n^3). ( The dependency loop is O(n), flat_subgraph is effectively O(n), and in_edges is O(n)). That means that it takes much longer to compute as the Graph becomes bigger. (Imagine a curve with the following values: 1,8,27,64..., that's the curve of relative times.)

Caching

With my users expecting instant feedback, something had to be done. The first thing I tried was to cache the in_edges computation.

 sub in_edges {
  my ($this,$v) = @_;
  if (exists $this->{cache}{in_edges}{$v}) {
      return @{$this->{cache}{in_edges}{$v}};
  } else {
    my @t = grep { $_->[1] eq $v } @{$this->{edges}};
    $this->{cache}{in_edges}{$v} = [@t];
    return @t;
   }
 }

This helped, but not as much as I had hoped. The in_edges calculation was still expensive when it wasn't cached. It's still O(n) in the worst case, but becomes O(1) when cached. On average, that means the entire flattening operation is somewhere between O(n^2) and O(n^3), which is still potentially slow.

In situations where the same functions are called with the same arguments, caching can be useful. Mark-Jason Dominus has written a module called Memoize, which makes it easy to write caching functions. See his Web site http://perl.plover.com/MiniMemoize/ for more information.

Change the Structure

The next thing I tried was to change the Graph data structure. When I originally designed it, my goal was simplicity, not necessarily speed. Now speed was becoming important and I had to make changes.

I modified graph so that in_edges were calculated when the new edge was being added.

 package Graph; # for Directed Graphs
 use strict;
 sub new {
  my $this = { edges => [],
               vertices => {},
               in_edges => {} };
  bless $this, "Graph";
 }
 sub add_edge { # from x to y
  my ($this,$x,$y) = @_;
  $this->{vertices}{$x}++;
  $this->{vertices}{$y}++;
  push @{$this->{in_edges}{$y}}, $x;
  push @{$this->{edges}},[$x=>$y];
 }
 sub in_edges {
  my ($this,$v) = @_;
  return @{$this->{in_edges}{$v}};
 }

add_edge remains O(1) - it still executes in a constant time. in_edges is O(1) as well now; its runtime will not vary based on the number of edges.

This was the solution I needed, getting a full flattening down from more than four minutes to only six seconds.

The Importance of Good Interfaces

One of the things that made this fiddling possible was a good design for the Graph module's interface. The interface hid all the details of the internals from me, so that different implementations could be plugged in. (This is actually how I did the testing, I had a regular Graph, a Graph::Cached, and a Graph::Fast. Once I decided that I liked Graph::Fast the best, I renamed it to just Graph.)

I'm glad I designed Graph the way I did. I put simplicity and design first. There is a phrase you might have heard: "Premature optimization is the root of all evil." If I had optimized the Graph module first, then I might have ended up with more complicated code that didn't work in all cases. My initial cut of Graph was slow, but worked consistently. Optimization happened later, after I had a baseline I could return to, to guarantee proper operation.

Example #2: Duplicate Message Filter

You don't always need to try and optimize code to the fullest extent. Optimizing code takes your time and energy, and it isn't always worth it. If you spend two days to shave two seconds off a program, then it's probably not worth it. (Unless of course, that program is running hundreds of times each day.) If a program is "fast enough", then making it faster isn't worth it.

Our second example is a duplicate message filter for e-mail. This filter is useful when you receive cc's of messages also sent to mailing lists you are on, but you don't want to see both.

The general idea behind this filter is simple.

  skip $message if seen $message->id;

It's only the seen function that interests us. It searches some form of cache of id's. How we implement it can have a large effect on the speed of our mailfilter. (For more information on filtering mail with perl, take a look at Mail::Audit.)

The two most obvious methods that come to mind for implementing seen are a simple linear search (O(n)) or the use of a persistent database/hash table to do the lookup. O(1). I'll ignore the cost of maintaining the database, eliminating old Message-Id's, etc.

A linear approach writes out the message id's with some sort of separator. Some programs use null bytes, others use newlines.

The database/hash method stores the message id's in a binary database like a DBM or Berkeley DB file. At the expense of using more disk space, lookups are generally faster.

But - there's one more factor to take into account - overhead. The linear search has little overhead, while the DB file has a large overhead. (Overhead here means time to open the file and initialize the appropriate data structures.)

 TABLE: Comparison

  Records | Comment
  -----------------
    100   | linear is 415% faster
    250   | linear is 430% faster
    500   | hash is 350% faster
   1000   | hash is 690% faster

I performed a set of timings with a rough example implementation on my P2/400, and received the above results. The hash lookup speeds remained constant, while the linear lookup dropped off rapidly after 250 items in the cache.

Returning to the big picture, we need to take our message-id cache size into account when determining the method to use. For this kind of cache, there's usually not a reason to keep a huge amount of entries around, only two or three days worth should catch most duplicate messages. (And probably even one day's worth in most cases.)

For this problem, an O(1) solution is possible, but the constant time it takes might be higher than an O(n) solution. Both cases are trivial to implement, but in some situations it will be difficult to implement O(1) - and not worth it either.

Conclusion

Perl is a powerful language, but it doesn't prevent the programmer from making poor decisions and shooting him/herself in the foot. One mistake is to choose the wrong data structure or algorithm for the job. By using a little bit of complexity theory, it's possible to optimize your code and get huge speed gains.

I've only touched the surface of big-O notation and complexity theory. It's a highly researched topic that delves into the deep dark corners of math and computers. But, hopefully there's enough here to give you a basic tool set.

As the second example showed, you don't necessarily want to spend too much time thinking about optimization. Over-optimization isn't always worth it.

For More Information

Google
 http://www.google.com/search?q=big-O+complexity
Introduction to the Theory of Computation
Part Three of Sipser, Michael. "Introduction to the Theory of Computation". PWS Publishing Company. Boston, MA. 1997.

Algorithms and Complexity, Internet Edition
http://www.cis.upenn.edu/~wilf/AlgComp2.html

Special Thanks

Walt Mankowski

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Using CGI::Application

Published on Perl.com
http://www.perl.com/pub/a/2001/06/05/cgi.html
See this if you're having trouble printing code examples

Using CGI::Application
By Jesse Erlbaum

Why CGI::Application?

Table of Contents

•Why CGI::Application?

•Understanding CGI::Application

•Putting It All Together

•Conclusions & Advanced Concepts: Where to Go From Here

•Resources

The Common Gateway Interface (CGI) may be viewed by some as "less than glamorous", but it is the workhorse of Web-based application development. For what CGI lacks in buzzword compliance, it more than makes up for in reliability, flexibility, portability, and (perhaps most important of all) familiarity!

CGI::Application builds upon the bedrock of CGI, adding a structure for writing truly reusable Web-applications. CGI::Application takes what works about CGI and simply provides a structure to negate some of the more onerous programming techniques that have cast an unfavorable light upon it.

CGI::Application code is so universal and non-proprietary that it works exceedingly well on any operating system and Web server that supports Perl and CGI. As you shall see, the CGI::Application structure even makes it possible for authors to distribute, for the first time, fully functional and sophisticated Web-applications via CPAN.

Understanding CGI::Application

Run-Modes

The most significant contribution of CGI::Application is the formal structure of "run-modes." A run-mode generally refers to a single screen of an application. All sophisticated Web applications feature multiple screens (or "pages"). For instance, an application to search through a database might feature a search form, a list of results and a detail of a single record. Each one of these three screens is part of a whole application.

Different programmers have devised different systems for managing these run-modes. Too many Web applications still look like huge IF-THEN-ELSE blocks, containing each run-mode in the enclosure of one conditional state. Often, these conditionals try to divide the application state by looking for the presence of various form variables. For instance, if a search field is present, show the list of results - otherwise, show the search form:

     my $query = CGI->new();
     print $query->header();
     if (my $search_term = $query->param("search_term")) {
          # ...30 lines of code to run a search
          # and print the results as HTML
     } else {
          # ...15 lines of code to display
          # the search form
     }

It is code such as this that has given CGI a bad name! It is barely structured and easily broken by even small changes in functionality.

The most savvy programmers quickly realized that run-modes are a specific thing that must be directly managed, and the most succinct way to determine the run-mode is to explicitly set it. Some systems, such as ASP, HTML::Mason, Cold Fusion and JSP attempt to manage these run-modes by having one physical document for each run-mode. This has the effect of spreading the code for a single application over at least as many files as there are run-modes! Taking the run-modes out of context by breaking them into separate files solves the state management problem at the cost of creating all sorts of new problems, not the least of which is the management of code assets. These run-modes are, after all, all part of the same application.

Application Modules

CGI::Application provides another solution to the run-mode management problem by providing two core facilities. First, CGI::Application designates a single specific HTML form input as a "Mode Parameter". This Mode Parameter is used to store (and retrieve) the current run-mode of your application. The value of a run-mode is a simple text scalar. CGI::Application reads the value of this Mode Parameter and acts as a traffic cop, directing the application operation accordingly.

Second, CGI::Application maps each run-mode to a specific Perl subroutine. Each subroutine, referred to as a "Run-Mode Method", implements the behavior of a single run-mode. All of your code, including all your run-mode methods and the mapping table between run-modes and subroutines, is stored in a single file. This file is a Perl module, referred to as your "Application Module".

Your Application Module is a sub-class of CGI::Application. In fact, CGI::Application is never intended to be used directly. CGI::Application is referred to by object-oriented enthusiasts as an "abstract class", and is only used via inheritance. To implement inheritance from CGI::Application, put the following code at the top of your Application Module:

     package Your::Web::Application;
     use base 'CGI::Application';

This code gives a name to your application (in this case, "Your::Web::Application"), and causes CGI::Application to be designated as the parent class. This parent class implements a number of methods that will provide the necessary infrastructure for your application. Some of the methods are expected to be called by your code to perform functions or set properties. Other inherited methods are expected to be implemented in your code, to provide the functionality specific to your application.

Defining Your Run-Mode Map

The map between run-modes and run-mode methods is defined in the setup() method. The setup() method is a method that you are expected to override in your Application Module by implementing a setup() subroutine. It is in your setup() subroutine that you define the map between run-modes and run-mode methods. Think of this map as the definitive list of things your application can do. If you ever add a function to your Web application, then you will amend this map to include your new run mode.

This run mode map is defined in your setup() method by using the run_modes() method provided by CGI::Application. The run_modes() method is an instance method that takes, as arguments, an associative array of run-modes as keys and run-mode method names as values (Note: CGI::Application version 1.3 is used in all our examples). To set up our prototypical database search application with three run-modes, this is how our code might look:

     package WidgetView;
     use base 'CGI::Application';
     sub setup {
          my $self = shift;
          $self->run_modes(
               'mode_1' => 'show_search_form',
               'mode_2' => 'show_results_list',
               'mode_3' => 'show_widget_detail'
           );
           $self->start_mode('mode_1');
           $self->mode_param('rm');
     }

That's it! The setup method receives an instance of your application class ($self) as an argument. When you call run_modes() you are setting the run-modes for this instance, so you use the object-oriented indirect ("->") operator. The inherited start_mode() method tells CGI::Application which mode to default to, if no mode is specified (as is the case when the application is first called). The inherited mode_param() method specifies the name of the HTML form parameter that will hold the run-mode state of the application from request to request.

What we have done here is set up an application called "WidgetView" with three run-modes, creatively named "mode_1", "mode_2" and "mode_3". These run-modes map to three as-yet-unwritten subroutines, respectively show_search_form(), show_results_list() and show_widget_detail(). The mode parameter is set to "rm" (the default), and the first mode of operation will be "mode_1".

Creating Run-Mode Methods

The run-mode method subroutines will contain the bulk of your code. These run-mode methods each implement the functionality for a particular run-mode. As we mentioned earlier, run-modes loosely translate into screens. As such, your run-mode methods will be responsible for setting up the HTTP and HTML output to be sent back to the requesting Web browser.

The most critical thing to remember about run-mode methods is that they should never print() anything to STDOUT. The inherited CGI::Application run() method is singularly responsible for actually sending all HTTP headers and HTML content to the Web browser. Your run-mode method is called by the run() method, and your code is expected to return a scalar containing all your HTML content. If you send anything to STDOUT, it will cause your application to malfunction. Symptoms of this type of mistake are typically content preceding HTTP headers, or HTTP headers appearing more than once in the output. If you see this, then you have probably tried sending output to STDOUT.

Your run-mode method will invariably need to interact with the CGI query to retrieve (and set) form parameters. CGI::Application does not attempt to provide this basic functionality. Instead, CGI::Application utilizes Lincoln D. Stein's superb CGI.pm module for all interactions with the CGI query. Becoming expert in CGI.pm will greatly enhance your mastery of CGI::Application. CGI::Application gives you access to the CGI.pm query object by way of the inherited query() method. Once you retrieve the CGI.pm query object via the query() method, you may interact with it as required.

For our first run-mode ("mode_1") we have specified what the run-mode method show_search_form() should be called. The purpose of this run-mode is to display the search form when the user first enters the application. Our run-mode method might look something like this:

     sub show_search_form {
          my $self = shift;
          # Get the CGI.pm query object
          my $q = $self->query();
          my $output = "";
          $output .= $q->start_html(-title => "Search Form");
          $output .= $q->start_form();

          # Build up our HTML form
          $output .= "Search for Widgets: ";
          $output .= $q->textfield(-name => 'search_term');
          $output .= $q->submit();

          # Set the new run-mode, when the user hits "submit"
          $output .= $q->hidden(-name => 'rm', -value => 'mode_2');
          $output .= $q->end_form();
          $output .= $q->end_html();

          return $output;
       }

As you can see, this subroutine is straight-forward. The specified run-mode method is called in an object-oriented context ($self). We retrieve the CGI.pm query object via our Application Module's query() method (inherited from CGI::Application). The HTML form we create should be familiar to anybody who has used CGI.pm. When we have completely built up our $output, we return it (as opposed to printing it to STDOUT).

There is only one bit of "magic" going on here, and that is our hidden form variable "rm". This is the method by which a CGI::Application gets from one run-mode to another. In the case of this run-mode (based on the desired functionality of our application), there is only one place we can go, and that is to "mode_2" - the list of matching results. If the "mode_1" run-mode allowed us to do more than one thing (for instance, to add a new Widget), then we would have to have two buttons on this screen with each set having a different value for the form variable, "rm".

How you go about setting that variable is up to you. For instance, you could have multiple HTML forms, or you could use JavaScript. CGI::Application imposes no restrictions on how the run-mode parameter gets set. It only cares that it is set, and leaves the logistics up to the application developer. Once the run-mode parameter is set, CGI::Application provides all the run-mode state management necessary to direct your application to the proper subroutine.

HTTP Headers

CGI::Application, by default, will return all content as MIME type "text/html". This is set by the HTTP headers. If you wish to set a different MIME type, manipulate a cookie or perform a HTTP redirect, then you will need to change the default HTTP headers. This is done by using two inherited CGI::Application methods: header_type() and header_props(). Refer to CGI::Application's perldoc for details on their usage.

Instance Scripts

There is one final piece in the CGI::Application architecture, and that is the "Instance Script". So far, we have talked extensively about the Application Module, but we have not yet explained exactly how the Application Module gets used! This is where the Instance Script comes in.

In traditional CGI programming, we might have a file, myapp.cgi, which is requested by a Web browser. The Web server (based on its configuration) will treat this file as a program, and return the output of its execution (as opposed to its content). In traditional CGI, this file would contain all your application code, and it would be quite lengthy. Using CGI::Application, we have put all our code in our Application Module, instead. This means that the actual file executed by the Web server can be completely empty of application-specific code! As a matter of fact, for our prototypical "WidgetView" application, what follows is the entirety of widgetview.cgi:

     #!/usr/bin/perl -w
     use WidgetView;
     my $app = WidgetView->new();
     $app->run();

It is that simple! The file, widgetview.cgi, is referred to as an "Instance Script" because it manages a single "instance" of your Application Module. As long as WidgetView.pm is in Perl's search path (@INC), this Instance Script will run your entire Web application.

Putting It All Together

In our prototypical WidgetView application, we have all the essential components of a complete CGI::Application.

Our Application Module, WidgetView.pm, may reside anywhere in the server's file system, provided it is within Perl's search path. It is recommended that your Application Module be placed outside the Web server's public document space, so that its contents are not accessible directly via the Web server.

The Application Module in our example contains four subroutines:

setup()
Configures our run-mode map, and other application settings.
show_search_form()
Run-mode "mode_1". Returns the HTML search form.
show_results_list()
Run-mode "mode_2". Based on the contents of the search form, it finds matching items in the database. The results are formatted in HTML and returned. A button is provided for each matching item, allowing the Web user to select one item by clicking on it. Clicking on an item sets the value of form parameter "rm" to "mode_3" and sets the value of another form parameter (e.g.: "item_id") to the unique identifier for the selected item.
show_widget_detail()
Run-mode "mode_3". Based on the value of the form parameter "item_id", this method retrieves all the details about the specified item from the database. These details are formatted as HTML and returned by this run-mode method.

A more complete source listing of the WidgetView application can be found here.

Our Instance Script, widgetview.cgi, resides within the Web server's public document space. It is configured to be treated as a CGI application. As long as your Web server supports CGI and Perl, your Web application based on CGI::Application will operate as you expect. WidgetView.pm does not require an Apache Web server - in fact, it will run equally well on any CGI-compatible server, including Microsoft's "IIS" or Netscape's "iPlanet" server, regardless of operating system.

Naturally, WidgetView will run exceedingly well on Apache/mod_perl servers, as CGI::Application adheres to very clean Perl programming standards. CGI::Application was designed, from the ground up, to run in full strict mode without throwing any warnings.

Conclusions & Advanced Concepts: Where to Go From Here

The concepts presented in this article should provide you with a starting point for using CGI::Application as the foundation of your Web application development. There are many advanced concepts that complete the CGI::Application picture, a few of which I will endeavor to summarize here.

Code Reuse

A tremendous potential for reusability is created through the structure of Instance Scripts. A single Application Module can be used by multiple Instance Scripts. Consider the potential for writing a Perl module and using it multiple times within a single project, across projects or even across organizations! For the first time, high-level functionality for the Web can be encapsulated in a single Perl module and distributed. If you are a CPAN author (or interested in becoming one), you could create a Web application and distribute it via CPAN in the same way CGI::Application, itself, is distributed!

Instance Scripts also have the capability to set instance-specific properties. As a result, the Instance Script becomes a sort of "configuration file" for your Application Module. The new() method (inherited from CGI::Application) has the capability to allow you to set variables that you may utilize in your Application Modules, via the inherited param() method. As a simple example, you could write a mail-form application that takes instance parameters such as the address to which the form contents should be e-mailed. Multiple Instance Scripts, all referring to the same Application Module, could each specify a different e-mail recipient or a different form. Refer to the CGI::Application perldoc for the usage details on the new() and param() methods.

CGI::Application is designed to support code reuse via inheritance. Application Modules could be devised to provide project-wide functionality. Specific applications could then inherit from your custom parent class instead of directly from CGI::Application. For example, consider the possibility of having each of your applications load configuration data from a database, or set specific run-time properties. Your parent class Application Module might implement a cgiapp_init() method, which would allow for these types of inherited behaviors. Refer to CGI::Application's perldoc for specific usage of the cgiapp_init() method.

Separating the HTML GUI From Application Code Using HTML::Template

At my company, Vanguard Media, CGI::Application is one part of a larger development strategy. One of the principle guiding forces of our application strategy is the maximum separation of the HTML GUI (Graphic User Interface) from the underlying application code. We have found that the best Perl programmers are rarely the best HTML designers, and the best HTML designers are rarely the best Perl programmers. It is for this reason that the separation of these two elements is arguably the most beneficial design decision you can make when devising an application architecture.

To this end, Sam Tregar's excellent HTML::Template module is utilized. HTML::Template allows external "template files" to be created for each screen in our applications. These template files contain 99 percent pure HTML, with a very small additional syntax for including scalar variables, loops and conditional blocks of data, set by the calling Run-Mode Method.

HTML::Template is so fundamental to our development strategy that special hooks have been built into CGI::Application to support its use! Refer to the CGI::Application perldoc for usage details of the inherited tmpl_path() and load_tmpl() methods.

Thoughts on Sessions and Security

A question that frequently comes up on the CGI::Application mailing list is how best to implement login security and session management. Experience has taught me that these are elements that are best excluded from your application code, and pushed into a lower layer of your Web server.

If you are using the Apache Web server, and are interested in implementing login security and session management, I encourage you to check out the various Apache::Auth* modules on CPAN. These modules tie into the "Authentication" and "Authorization" phases of the request. This code runs long before your CGI applications are called.

There are two primary advantages in placing your sessions and security code in this layer. First, your security will work for all documents, not just Perl applications. Even static HTML documents will be protected by this system. Second, putting sessions and security in this layer will avoid an architecture where programmers have to include special code at the start of their applications to participate in the sessions and security system.

Resources

I hope you enjoyed reading this article. The following references should help you further explore the use of CGI::Application:

Download CGI::Application
http://www.cpan.org/authors/id/J/JE/JERLBAUM/
CGI Application Mailing List
Send email to: cgiapp-subscribe@lists.vm.com
CGI.pm
http://stein.cshl.org/WWW/software/CGI/cgi_docs.html
HTML::Template
Apache/mod_perl
http://perl.apache.org/

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Class::DBI

Published on Perl.com
http://www.perl.com/pub/a/2002/11/27/classdbi.html
See this if you're having trouble printing code examples

Class::DBI
By Tony Bowden

Several articles on Perl.com, including the recent Phrasebook Design Pattern, have discussed the problems faced when writing Perl code that interacts with a database. Terrence Brannon's DBIx::Recordset article attempted to show how code dealing with databases can be made simpler, and more maintainable. In this article, I will try to show how Class::DBI can make this easier still.

Class::DBI prizes laziness and simplicity. Its goal is to make simple database interactions trivial, while leaving the hard ones possible. For many simple applications, it replaces the need for writing SQL entirely. On the other hand, it doesn't force you to build complex data structures to specify a complex query; if you really need the power or expressiveness of raw SQL, then it gets out of your way and lets you drop back to that.

The easiest way to see Class::DBI in action is to build a simple application with it. In this article, I'll build a tool for performing analysis on my telephone bill.

Data::BT::PhoneBill (available from CPAN), provides a simple interface to a phone bill downloaded from the BT Web site. So, armed with this module, and a few recent phonebills, let's store these details in a database, and see how to extract useful information from them.

Class::DBI works on the basis that each table in your database has a corresponding class. Although each class could set up its own connection information, it's a better idea to encapsulate that connection in one class, and have all the others inherit from that. So, we set up our database, and create the base class for our application:

  package My::PhoneBill::DBI;

  use base 'Class::DBI';

  __PACKAGE__->set_db('Main', 'dbi:mysql:phonebill', 'u/n', 'p/w');

  1;

We simply inherit from Class::DBI and use the 'set_db' method to set up the connection information for our database. That's all we need in this class for now, so next we set up our table for storing the phone call information:

  CREATE TABLE call (
    callid      MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    number      VARCHAR(20) NOT NULL,
    destination VARCHAR(255) NOT NULL,
    calldate    DATE NOT NULL,
    calltime    TIME NOT NULL,
    type        VARCHAR(50) NOT NULL,
    duration    SMALLINT UNSIGNED NOT NULL,
    cost        FLOAT(8,1)
  );

For this, we set up a corresponding class:

  package My::PhoneBill::Call;

  use base 'My::PhoneBill::DBI';

  __PACKAGE__->table('call');
  __PACKAGE__->columns(All   =>
    qw/callid number destination calldate calltime type duration cost/);

  1;

We inherit our connection information from our base class, and then specify what table we're dealing with, and what its columns are. Now we have enough to populate the table.

So, we create a simple, "populate_phone_bill" script:

  #!/usr/bin/perl

  use Data::BT::PhoneBill;
  use My::PhoneBill::Call;

  my $file = shift or die "Need a phone bill file";
  my $bill = Data::BT::PhoneBill->new($file) or die "Can't parse bill";

  while (my $call = $bill->next_call) {
    My::PhoneBill::Call->create({
      number      => $call->number,
      calldate    => $call->date,
      calltime    => $call->time,
      destination => $call->destination,
      duration    => $call->duration,
      type        => $call->type,
      cost        => $call->cost,
    });
  }

The create() call runs the SQL to INSERT the row for each call. As we're using Class::DBI, and have defined our primary key column to be AUTO_INCREMENT, we don't need to specify a value for that column. On databases that support sequences, we could also inform Class::DBI what sequence should be used to provide the primary key.

Now that we have a table populated with calls, we can begin to run queries against it. Let's write a simple script that reports on all the calls to a specified number:

  #!/usr/bin/perl

  use My::PhoneBill::Call;

  my $number = shift or die "Usage: $0 <number>";

  my @calls = My::PhoneBill::Call->search(number => $number);
  my $total_cost = 0;

  foreach my $call (@calls) {
    $total_cost += $call->cost;
    printf "%s %s - %d secs, %.1f pence\n",
      $call->calldate, $call->calltime, $call->duration, $call->cost;
  }
  printf "Total: %d calls, %d pence\n", scalar @calls, $total_cost;

Here we can see that Class::DBI provides a 'search' method for us to use. We supply a hash of column/value pairs, and we get back all the records that matched. Each result is an instance of the Call class, and each has an accessor method corresponding to each column. (It's also a mutator method, so we can update that record, but we're only reporting at this stage).

So, if we want to see how often we're calling the Speaking Clock, then we run

  > perl calls_to 123
  2002-09-17 11:06:00 - 5 secs, 8.5 pence
  2002-10-19 21:20:00 - 8 secs, 8.5 pence
  Total: 2 calls, 17 pence

Similarly, if we want to see all the calls on a given date, then we could have a 'calls_on' script:

  #!/usr/bin/perl

  use My::PhoneBill::Call;

  my $date = shift or die "Usage: $0 <date>";

  my @calls = My::PhoneBill::Call->search(calldate => $date);
  my $total_cost = 0;

  foreach my $call (@calls) {
    $total_cost += $call->cost;
    printf "%s) %s - %d secs, %.1f pence\n",
      $call->calltime, $call->number, $call->duration, $call->cost;
  }
  printf "Total: %d calls, %d pence\n", scalar @calls, $total_cost;

Running it gives:

  > perl calls_on 2002-10-19
  ...
  18:36:00) 028 9024 4222 - 41 secs, 4.2 pence
  21:20:00) 123 - 8 secs, 8.5 pence
  ...
  Total: 7 calls, 92 pence

As promised, we've written a database application without writing any SQL. OK, so we haven't really done anything very complicated yet, but even for this simplistic use Class::DBI makes our life much easier.

Building a Phone Book

I used to have a good memory for phone numbers. But Nokia, Ericsson, et al, have conspired against me. By giving my cell phone a built-in address book, they ensured that the part of my brain responsible for remembering 10 or 11 digit numbers would gradually atrophy. Now, when I look at the output of 'calls_on', I have no idea who "028 9024 4222" represents. So, let's build an address book that can store this information, and then change our reports to use it.

The first thing we should do is arrange our information a little better. We'll take the number and destination columns, and move them to a "recipient" table, to which we'll add a name column. "Destination" doesn't make as much sense when associated with the number, rather than the call, so we'll rename it to "location".

  CREATE TABLE recipient (
    recipid  MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    number   VARCHAR(20) NOT NULL,
    location VARCHAR(255) NOT NULL,
    name     VARCHAR(255),
    KEY (number)
  );

And then we create the relevant class for this table:

  package My::PhoneBill::Recipient;

  use base 'My::PhoneBill::DBI';

  __PACKAGE__->table('recipient');
  __PACKAGE__->columns(All => qw/recipid number location name/);

  1;

We also need to modify the Call table:

  CREATE TABLE call (
    callid    MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
 *  recipient MEDIUMINT UNSIGNED NOT NULL,
    calldate  DATE NOT NULL,
    calltime  TIME NOT NULL,
    type      VARCHAR(50) NOT NULL,
    duration  SMALLINT UNSIGNED NOT NULL,
    cost      FLOAT(8,1),
 *  KEY (recipient)
  );

and its associated class:

  package My::PhoneBill::Call;

  use base 'My::PhoneBill::DBI';

  __PACKAGE__->table('call');
  __PACKAGE__->columns(All   =>
 *  qw/callid recipient calldate calltime type duration cost/);

  1;

Then we can modify our script that populates the database:

  #!/usr/bin/perl

  use Data::BT::PhoneBill;
  use My::PhoneBill::Call;
 *use My::PhoneBill::Recipient;

  my $file = shift or die "Need a phone bill file";
  my $bill = Data::BT::PhoneBill->new($file) or die "Can't parse bill";

 *while (my $call = $bill->next_call) {
 *  my $recipient = My::PhoneBill::Recipient->find_or_create({
 *    number      => $call->number,
 *    location    => $call->destination,
 *  });
 *  My::PhoneBill::Call->create({
 *    recipient   => $recipient->id,
      calldate    => $call->date,
      calltime    => $call->time,
      duration    => $call->duration,
      type        => $call->type,
      cost        => $call->cost,
    });
  }

This time we need to create the Recipient first, so we can link to it from the Call. But we don't want to create a new Recipient for each call - if we've ever rang this person before, there'll already be an entry in the recipient table: so we use find_or_create to give us back the existing entry if it's there, or else create a new one.

With the table repopulated we can return to our reporting scripts.

Our calls_on script now fails as we can can't ask a call for its 'number'. So, we change it to:

  #!/usr/bin/perl

  use My::PhoneBill::Call;

  my $date = shift or die "Usage: $0 <date>";

  my @calls = My::PhoneBill::Call->search(calldate => $date);
  my $total_cost = 0;

  foreach my $call (@calls) {
    $total_cost += $call->cost;
    printf "%s) %s - %d secs, %.1f pence\n",
 *    $call->calltime, $call->recipient, $call->duration, $call->cost;
  }
  printf "Total: %d calls, %d pence\n", scalar @calls, $total_cost;

However, running it doesn't really give us what we want:

  > perl calls_on 2002-10-19
  ...
  18:36:00) 67 - 41 secs, 4.2 pence
  21:20:00) 47 - 8 secs, 8.5 pence
  ...
  Total: 7 calls, 92 pence

Instead of getting the phone number, we now get the ID from the recipient table, which is just an auto-incrementing value.

To turn this into a sensible value, we add the following line to the Call class:

  __PACKAGE__->has_a(recipient => 'My::PhoneBill::Recipient');

This tells it that the recipient method doesn't just return a simple value, but that that value should be automatically turned into an instance of the Recipient class.

Of course, calls_on still won't be correct:

  > perl calls_on 2002-10-19
  ...
  18:36:00) My::PhoneBill::Recipient=HASH(0x835b6b8) - 41 secs, 4.2 pence
  21:20:00) My::PhoneBill::Recipient=HASH(0x835a210) - 8 secs, 8.5 pence
  ...
  Total: 7 calls, 92 pence

But now all it takes is a small tweak to the script:

    printf "%s) %s - %d secs, %.1f pence\n",
      $call->calltime, $call->recipient->number, $call->duration, $call->cost;

And now everything is working perfectly again:

  > perl calls_on 2002-10-19
  ...
  18:36:00) 028 9024 4222 - 41 secs, 4.2 pence
  21:20:00) 123 - 8 secs, 8.5 pence
  ...
  Total: 7 calls, 92 pence

The calls_to script is slightly trickier, as the initial search is now on the recipient rather than the call.

So, we change the initial search to:

  my ($recipient) = My::PhoneBill::Recipient->search(number => $number)
    or die "No calls to $number\n";

Then we need to get all the calls to that recipient. For this, we need to inform Recipient of the relationship with calls. Unlike the has_a we just set up in the Call class, the recipient table doesn't store any value concerned with the call table that could be inflated on demand. Instead we need to add a has_many declaration to Recipient:

  __PACKAGE__->has_many(calls => 'My::PhoneBill::Call');

This creates a new method calls for each Recipient object, returning a list of Call objects whose recipient method is our primary key.

So, having found our recipient in the calls_to script, we can simply ask:

  my @calls = $recipient->calls;

And now the script works just as before:

  #!/usr/bin/perl

  use My::PhoneBill::Recipient;

  my $number = shift or die "Usage: $0 <number>";

  my ($recipient) = My::PhoneBill::Recipient->search(number => $number)
    or die "No calls to $number\n";
  my @calls = $recipient->calls;

  my $total_cost = 0;

  foreach my $call (@calls) {
    $total_cost += $call->cost;
    printf "%s %s - %d secs, %.1f pence\n",
      $call->calldate, $call->calltime, $call->duration, $call->cost;
  }
  printf "Total: %d calls, %d pence\n", scalar @calls, $total_cost;

And now we can get the old results again:

  > perl calls_to 123
  2002-09-17 11:06:00 - 5 secs, 8.5 pence
  2002-10-19 21:20:00 - 8 secs, 8.5 pence
  Total: 2 calls, 17 pence

Next we need a script to give a name to a number in our address book:

  #!/usr/bin/perl

  use My::PhoneBill::Recipient;

  my($number, $name) = @ARGV;
  die "Usage $0 <number> <name>\n" unless $number and $name;

  my $recip = My::PhoneBill::Recipient->find_or_create({number => $number});
  my $old_name = $recip->name;
  $recip->name($name);
  $recip->commit;

  if ($old_name) {
    print "OK. $number changed from $old_name to $name\n";
  } else {
    print "OK. $number is $name\n";
  }

This lets us associate a number to a name:

  > perl add_phone_number 123 "Speaking Clock"
  OK. 123 is Speaking Clock

And now with a tiny change to our calls_on script we can output the name where known:

    printf "%s) %s - %d secs, %.1f pence\n",
      $call->calltime, $call->recipient->name || $call->recipient->number,
      $call->duration, $call->cost;

  > perl calls_on 2002-10-19
  ...
  18:36:00) 028 9024 4222 - 41 secs, 4.2 pence
  21:20:00) Speaking Clock - 8 secs, 8.5 pence
  ...
  Total: 7 calls, 92 pence

To allow the calls_to script to work if we give it either a name or a number, we can use:

  my $recipient = My::PhoneBill::Recipient->search(name => $number)
               || My::PhoneBill::Recipient->search(number => $number)
               || die "No calls to $number\n";

However, as we've called search in scalar context, rather than the normal list context, we get back an interator rather than an individual Recipient object. As one name may map to multiple numbers, we need to iterate over each of these in turn:

    my @calls;
    while (my $recip = $recipient->next) {
      push @calls, $recip->calls;
    }

(Printing individual totals for each number is left as an exercise for the reader.)

  > perl calls_to "Speaking Clock"
  2002-09-17 11:06:00 - 5 secs, 8.5 pence
  2002-10-19 21:20:00 - 8 secs, 8.5 pence
  Total: 2 calls, 17 pence

Working With Other Modules

Sometimes the information we store in the database can be used to work with non-Class::DBI modules. For example, if we wanted to format the dates of our calls differently, we might like to turn them into Date::Simple objects. Again, Class::DBI makes this easy.

In the Call class, we again use has_a to declare this relationship:

  __PACKAGE__->has_a(recipient => 'My::PhoneBill::Recipient');
 *__PACKAGE__->has_a(calldate  => 'Date::Simple');

Now, when we fetch the calldate it is automatically inflated to a Date::Simple object. So, we can change the output of calls_to to print the date in a nicer format:

  printf "%s %s - %d secs, %.1f pence\n",
    $call->calldate->format("%d %b"), $call->calltime,
    $call->duration, $call->cost;

  > perl calls_to "Speaking Clock"
  17 Sep 11:06:00 - 5 secs, 8.5 pence
  19 Oct 21:20:00 - 8 secs, 8.5 pence
  Total: 2 calls, 17 pence

Class::DBI assumes that any non-Class::DBI class is inflated through a new method, and can be deflated through stringification. As both of these are true for Date::Simple, we didn't need to do anything more. If this is not the case - for example, if you wanted to use Time::Piece instead of Date::Simple - you need to tell Class::DBI how to do the inflating and deflating as the value goes in and comes out of the database.

  __PACKAGE__->has_a(calldate => 'Time::Piece',
    inflate => sub { Time::Piece->strptime(shift, "%Y-%m-%d") },
    deflate => 'ymd'
  );

Deflating a Time::Piece object back to an ISO date string suitable for MySQL is quite simple: you can just call its ymd() method. Thus we can specify this as a string. Inflating is more difficult, as it requires a two argument call to strptime(). Thus we need to specify this as a subroutine reference. When inflating, this is called with the value from the database as its one and only argument. Thus, we can pass that to Time::Piece's strptime method, specifying the format to instantiate from.

Using Time::Piece instead of Date::Time requires one further change to to our output script:

  printf "%s %s - %d secs, %.1f pence\n",
 *  $call->calldate->strftime("%d %b"), $call->calltime,
    $call->duration, $call->cost;

MOST CALLED NUMBERS

BT provide a service that allows you to save money on 10 numbers of your choice. So it would be useful if we were able to find out which numbers we spend the most money calling. We'll assume that any number we've only ever called once isn't worth adding to our list, as it was probably a one-off call. Thus we want the 10 numbers with the highest spend that have had more than one call.

As we said earlier, Class::DBI doesn't attempt to provide a syntax to express any arbitrary SQL, so there's no way of asking directly for this information. Instead, we'll try a simple approach.

Firstly we'll add a method to the Recipient class to tell us the total we've spent on calls to that number:

  use List::Util 'sum';

  sub total_spend {
    my $self = shift;
    return sum map $_->cost, $self->calls;
  }

Then we can create a top_ten script:

  #!/usr/bin/perl

  use My::PhoneBill::Recipient;

  my @recipients = My::PhoneBill::Recipient->retrieve_all;
  my @regulars = grep $_->calls > 1, @recipients;
  my @sorted = sort { $b->total_spend <=> $a->total_spend } @regulars;

  foreach my $recip (@sorted[0 .. 9]) {
    printf "%s - %d calls = %d pence\n",
      $recip->name || $recip->number,
      scalar $recip->calls,
      $recip->total_spend;
  }

This is very slow, however, once you have more than a few hundred calls stored in your database. This is mainly because we're sorting based on a method call. Replacing the sort above with a Schwartzian Transform speeds everything up significantly:

  my @sorted = map $_->[0],
    sort { $b->[1] <=> $a->[1] }
    map [ $_, $_->total_spend ], @regulars;

Now, until the database gets significantly bigger, this is probably fast enough - especially as you probably won't be running the script very often.

However, if this isn't enough, then we can always drop back to SQL. Of course, when we need to optimize for speed, we usually lose something else - in this case, portability. In this example, we're using MySQL, so I would add the relevant MySQL-specific query to Recipient.pm:

  __PACKAGE__->set_sql(top_ten => qq{
    SELECT recipient.recipid,
           SUM(call.cost) AS spend,
           COUNT(call.callid) AS calls
      FROM recipient, call
     WHERE recipient.recipid = call.recipient
     GROUP BY recipient.recipid
    HAVING calls > 1
     ORDER BY spend DESC
     LIMIT 10
  });

Then we can set up a method that returns the relevant objects for these:

  sub top_ten {
    my $class = shift;
    my $sth = $class->sql_top_ten;
       $sth->execute;
    return $class->sth_to_objects($sth);
  }

Any SQL set up using set_sql can be retrieved as a readily prepared DBI statement handle by prepending its name with sql_ - thus we fetch back this top_ten using my $sth = $class->sql_top_ten;

Although we could happily execute this and then call any of the traditional DBI commands (fetchrow_array etc.), we can also take a shortcut. As one of the columns being returned from our query is the primary key of the Recipient, we can simply feed the results into the underlying method in Class::DBI that allows searches to return a list of objects, sth_to_objects.

So, our script becomes simply:

  foreach my $recip (My::PhoneBill::Recipient->top_ten) {
    printf "%s - %d calls = %d pence\n",
      $recip->name || $recip->number,
      scalar $recip->calls,
      $recip->total_spend;
  }

As we have seen, Class::DBI makes it possible to perform many of the common database tasks completely trivially - without writing a single line of SQL. But, when you really need it, it's fairly easy to write the SQL that you need and execute it.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: The Many Dates and Times of Perl

Published on Perl.com
http://www.perl.com/pub/a/2003/03/13/datetime.html
See this if you're having trouble printing code examples

The Many Dates and Times of Perl
By Dave Rolsky

Some Basic Concepts

In order to understand what you might want to do with dates and times, it's good to have a handle on some basic concepts. Here are some terms that I'll be using in this article:

  • datetime
    • This is not a word, but I will use it as a convenient shorthand to refer to a date and time together, because they are basically the same thing. Adding time to a date simply increases its granularity.
  • UTC (also GMT and Zulu)
    UTC stands for "Coordinated Universal Time". It is an international standard which is kept using atomic clocks, and is kept to within 0.9 seconds of the rotation of the earth on its axis in order to work well with traditional standards of time-keeping. UTC time is measured at the prime meridian (O degrees longitude).

    Time zones around the world are specified as an offset from UTC. The widely used term GMT (Greenwich Mean Time) refers to a time zone that is equivalent to UTC. In other words, it has no offset.

    The US military has a set of terms used for time zones around the world based on the alphabet (A-Z). In this system UTC is Z, sometimes called "Zulu".

    UTC is a good standard for the internal representation of dates and times, as it makes comparing datetimes or doing datetime math much easier.

  • Time zones and Daylight Saving Time

    Time zones, as mentioned above, are defined as an offset from UTC. Most, but not all, time zones are in offsets of whole hours. Adelaide, Australia has an offset of nine and a half hours ahead of UTC, and Nepal has an offset five hours and forty-five minutes ahead of UTC.

    Time zones are complicated by the use of Daylight Saving Time, which changes the actual offset of a given location to vary over the course of the year. The eastern US has an offset of -0500 from UTC, five hours ahead of UTC. This means that 12:00 (noon) UTC becomes 07:00 (AM). However, when Daylight Saving Time is in effect, the offset becomes -0400, four hours ahead of UTC. Because time zones are determined by governments, use of Daylight Saving Time, and the base offsets, have changed over time, and may change again in the future.

    This greatly complicates math when dealing with non-UTC datetimes. If If I have a local datetime for the Eastern US of 2002-10-25 14:15:00 and I add six months to that datetime, then I will have crossed a DST change.

    The upshot of all this is that any code that represents time zones as fixed offset will probably start producing errors once date math gets involved.

    The definitive source of time zone offsets and rules is the Olson time zone database. It defines zones according to names like "America/New_York", as opposed to "EST". The latter shorthand is commonly used, but it should probably be avoided because these short names are not unique or definitive. For example, there is an "EST" at -0500 and +1000.

  • Local time

    The local time is UTC plus the local time zone offset. While UTC is great for internal use, most people want to see datetimes in terms of their location. In a sense, local time is the display format, while UTC is the storage format.

  • The epoch

    Epoch is a generic term referring to the "start" of any particular system. For example, the Gregorian calendar's epoch is January 1, 1 CE.

    The epoch system, as used most operating systems, represents a datetime as the number of seconds after a specific date and time. For Unix systems, the epoch began on January 1, 1970 at midnight GMT (UTC). Other systems have different epochs. Because of this, you cannot assume that an epoch time of 2,003,131 means the same thing from system to system, because different systems have a different "second 0". Storing a datetime as its epoch is not portable.

    Even worse, on most current systems, epochs are represented by a 32 bit signed integer, which only lets you represent datetimes with a range of about 136 years. On most UNIX systems currently in use, this means that the latest date you can represent right now is sometime in the year 2038, and the earliest is around 1902. This doesn't work very well if you're trying to represent the birth date of your great-great-grandmother.

    The upshot of all this is I would strongly recommend not using epochs except when you have no other choice. Of course, you'll often have no choice, so it's important to know how this system works.

  • The Gregorian Calendar

    There have been many different calendar systems in use throughout history. The Gregorian calendar is the current generally agreed upon international standard for representing dates, and is what you are using when you say "August 8, 1999". Other calendars that are still in use include the Hebrew calendar, the Islamic calendar, and the Chinese calendar.

    Even though the Gregorian calendar wasn't created until 1582, and it wasn't adopted world wide until this century, we can still extrapolate backwards in time using the Gregorian calendar.

What Needs Doing with Dates and Times?

There are a lot of things you can do with dates and times, and different modules/distributions provide different types of functionality. Broadly speaking, we can consider the following areas of functionality:

  • Parsing/Formatting

    There are more datetime formats in use in the computing world than you can shake a stick at. You'll often have to parse a datetime in one format in order to turn it into something you can work with internally, like a bunch of integers or an epoch time.

    On the flip side, you'll often have to take some standard representation, like an epoch, and convert it to some other format.

  • Basic representation

    A nice datetime object can be quite handy. These range from lightweight wrappers around Perl's localtime() to objects that try to provide methods for all possible datetime operations.

  • Math and calculations

    You'll often want to answer questions like "what day is seven days after today" or "how much time is there between now and midnight?" This is closely related to the task of figuring out the date Easter falls on in a given year, or what day of the week Martin Luther King's birthday falls on.

There are plenty of other things we can do with datetimes, but these are largely elaborations of the above areas of functionality.

Perl's Built-in Date/Time Functionality

Perl has some built-in functionality for handling dates and times. This functionality includes:

  • time()

    A function that returns the current epoch time.

  • localtime() and gmtime()

    These functions convert an epoch time into a set of components representing the local time. They both return arrays containing things like the hour, minute, month, etc., though some of the values returned are awkward to use. For example, the year is the actual year minus 1900.

    The localtime() function returns the datetime of your current location, based on your system's time zone setting, while the gmtime function returns the current UTC datetime.

    The Time::localtime and Time::gmtime modules provide a thin object layer around gmtime() and localtime() respectively, so you can do things like print gmtime()->year. Of course, that still prints the year minus 1900.

  • Time::Local

    This core module provide functions that translate from the array of components returned by localtime() or gmtime() back to an epoch time.

  • POSIX.pm

    The POSIX module included with Perl provides interfaces to several common C library functions for datetimes, such as strftime(). I consider this the last refuge for the desperate, because the POSIX.pm module is a memory hog, and the C library interface is rather un-Perlish.

The Big Stars

These are the modules that have the longest history, and are the most widely used.

  • TimeDate distribution

    This distribution, maintained and mostly written by Graham Barr, includes three modules. Date::Format module provides a few functions for formatting datetime output, including a strftime() similar to the one in the standard C library. It can work with either epoch times, or the array of components returned by Perl's localtime() function.

    Date::Parse parses a limited set of common datetime formats, returning either an epoch time or an array of components.

    The distribution also includes a number of language modules which can be used to localize both parsing and formatting.

    Finally, Time::Zone provides an interface to time zone offsets, based on short time zone names like "EST" or "GMT". As was mentioned before, these names are not official or standardized, so they are of limited usefulness.

    All of these modules are limited by their use of epoch time internally, but they are fairly quick and light weight. For complex datetime problems, these modules probably don't automate enough of the dirty work.

  • Time::Piece

    Written and maintained by Matt Sergeant, this module is based on an interface designed by Larry Wall. It provides a convenient object API for datetimes, though the API is a bit confusing. For example, $time->mon returns the month number (1-12) while $time->month returns the abbreviated name of the month.

    It also implements basic parsing and formatting via the use of the C-level strptime() and strftime() functions. The included Time::Seconds module allows for basic date math, such as $tomorrow = $time + ONE_DAY.

    The implementation is fairly lightweight, but is limited by its use of epoch time as the internal representation. It is certainly useful, but like the TimeDate modules, it doesn't go far enough for more complex uses.

    As of this writing, Matt Sergeant has released an experimental version of Time::Piece based on my DateTime.pm module. This leaves the Time::Piece API unchanged, but allows it to handle dates that cannot be represented by a given system's epoch.

  • Date::Manip

    Sullivan Beck's Date::Manip is really huge, weighing in at about 3,000 lines of code. As might be expected of that much code, there is something for everyone here. It handles parsing, formatting, date math, as well as more esoteric things like recurring datetimes and business day calculations. It should be noted that it's time zone support is pretty much the same that provided by Time::Zone.

    This module's most unique feature is its very flexible parser, which is capable of handling things like "3 weeks ago Monday" or "next Sunday". It also provides some parsing for specifying recurrences, like "every 3rd Monday in 2003".

    Unlike everything else we've covered so far, this module is not limited to epoch times. It has an entirely functional interface, and in my opinion the API could be cleaner. I dislike the fact that some functions do many different things, with the output depending either on the argument type(s), explicit flags, or both.

    But the biggest problem with this module, which is acknowledged by its author, is its size. It uses lots of memory (about 3MB on my system), and is fairly slow to load. The former makes it problematic for mod_perl, and the latter causes problems with CGI scripts. You can find most of its features elsewhere, in slimmer modules, but if size and speed are not an issue, this module almost certainly does everything you want.

  • Date::Calc

    Steffen Beyer's Date::Calc distribution is where you go when you need functionality combined with speed. This modules offers much of the functionality provided by Date::Manip, but the core Date::Calc module has a much smaller memory footprint than Date::Manip (about 1MB on my box), and much greater speed. This is based its core implementation is in C.

    This module provides functions for calculating all sorts of date-related information, as well some minimal parsing and formatting operations. The interface requires some hand-holding to use, as every function returns one or more elements, never a data structure such as a hash, so you have to constantly deal with passing and receiving arrays of values.

    The distribution also includes a class called Date::Calc::Object, which can represent either a datetime or a "delta", the difference between two datetimes. This dual nature is odd, since many of the methods applicable to one will not work for the other. The class supports overloading for date math and comparison, so you can do things like $date + [1, 2, 3], which adds one year, two months, and three days to the given date.

    Finally, there is a Date::Calendar object, which can be used to set up a calendar "profile" defining holidays, work days, and partial work days in a variety of ways. This is quite useful if you need to calculate a day X business days in the future, while taking account of a particular organization's holidays.

    None of the modules in this distribution rely on epoch time, though they only support positive-numbered years. Time zone support is extremely minimal, and is done only as offsets, without support for daylight saving rules. Localization for a variety of languages is implemented for parsing and formatting.

And a Cast of Thousands ...

It wouldn't be Perl if there weren't at least a dozen other modules with overlapping functionality, right? In this case, there's more than two dozen! For sanity's sake, I've excluded more than a few modules, in particular those that either appeared to be unmaintained, or those without enough comprehensible documentation for me to figure out what the heck they do. In alphabetical order, those remaining are:

  • Astro::Sunrise - Ron Hill

    This module provides sunrise and sunset times, given a specific date and place.

  • Astro::Time - Chris Phillips

    Contains a number of functions useful when dealing with datetimes as they are used in astronomy.

  • Class::Date - Bal&0xE1;zs Szab&0xF3;

    This is basically the Time::Piece API plus more stuff. It appears to provide complete time zone support based on the Olson database, by way of POSIX.pm. It is epoch-limited.

  • Date::Business - Richard DeSimine

    A simple interface for doing date math with business dates. In other words, weekends don't count, and you can define your own holidays. This module is epoch-limited.

  • Date::Convert - Mordechai Abzug

    Converts dates between the Gregorian, Hebrew, and Julian calendars.

  • Date::Convert::French_Rev - Jean Forget

    Converts to and from the French Revolutionary calendar.

  • Date::Day - John Von Essen

    Tells you the day of the week for a given date.

  • Date::DayofWeek - Rich Bowen

    Does exactly the same thing as Date::Day but only for years 1500-2699. On the flip side, it uses a cuter algorithm.

  • Date::Decade - Michael Diekmann

    Provides three decade calculation functions with an API similar to that of Date::Calc.

  • Date::Discordian - Rich Bowen

    Converts to and from the Discordian calendar.

  • Date::Easter - Rich Bowen

    Calculates the date Easter falls on in a given year.

  • Date::Handler - Benoit Beausejour

    A date object comparable to Time::Piece, but with a more consistent interface. It implements localization, a variety of date math operations, and includes an object for representing datetime spans. It provides time zone support based on the native OS implementation, which on some systems means support for the Olson database. It is epoch-limited.

  • Date::ICal - Rich Bowen

    A date object that provides a simple API, date math, and iCal formatting and parsing (see RFC 2445). It only support time zones as offsets, but it is not epoch-limited.

  • Date::ISO - Rich Bowen

    A subclass of Date::ICal that adds ISO 8601 format parsing and formatting.

  • Date::Japanese::Era - Tatsuhiko Miyagawa
    C

    onverts to and from Japanese Era dates.

  • Date::Japanese::Holiday - Tomohiro Ikebe

    Tells you whether or not a given date is a Japanese holiday.

  • Date::Leapsecond - Fl&0xE1;vio Soibelmann Glock

    Converts between UT1 and UTC times.

  • Date::Leapyear - Rich Bowen

    One function to tell you whether or not a given year is a leap year.

  • Date::Maya - Abigail

    Converts between Julian days and the Mayan calendar.

  • Date::Passover - Rich Bowen

    Calculates the dates of Passover and Rosh Hashanah for a given year.

  • Date::PeriodParser - Simon Cozens

    Parses English descriptions of time periods like "this morning" or "around two weeks ago" and turns them into pairs of epoch times representing the beginning and end of the period.

  • Date::Range - Tony Bowden

    An object for representing a range of dates. Lets you figure out whether two ranges overlap, whether a date is included in a given range, and a few other useful things.

  • Date::Roman - Leo Cacciari

    An object for representing dates according to the Roman calendar.

  • Date::Set - Fl&0xE1;vio Soibelmann Glock

    An object that represents sets of datetimes. A set can be either a datetime span, a recurring set of dates, or a fixed set of specific datetimes. It provides set math operations for all of these, as well as allowing you to iterate across the members of the set. Also see Date::Set::Timezone.

  • Date::Simple - John Tobey
    A date object that represents dates only, without a time component. It provides date math. It is not epoch-limited.
  • Date::Tie - Fl&0xE1;vio Soibelmann Glock

    A basic date object with date math. Its functionality is implemented via a tied hash interface. It supports fixed offset time zones, and it is epoch-limited.

  • HTTP::Date - Gisle Aas

    This module is part of the LWP distribution. It parses many common datetime formats, including all of those that are used by the HTTP protocol. If Date::Parse doesn't understand all the formats you need to deal with, this module provides a good alternative.

  • Time::Duration - Sean Burke

    Given a number of seconds, this module return a human language description of the duration. For example, 3660 seconds would be "1 hour and 1 minute".

  • Time::Human - Simon Cozens

    Given an epoch time, this module can return a string describing that time in colloquial terms, such as "half past nine". It has hooks for localization.

  • Time::Unix - Nathan Wiger

    Loading this module forces Perl's time() function to use the Unix epoch system, regardless of the OS on which the code is running.

  • Time modules - David Muir Sharnoff

    This distribution includes Time::CTime, Time::ParseDate, and Time::Timezone, which are slightly more powerful versions of Graham Barr's Date::Format, Date::Parse, and Time::Zone.

But Wait, There's More!

Not content to leave well enough alone, I've recently started a project to fix what I see as the fundamental problem with the state of Perl datetime modules. That fundamental problem is that despite the fact that almost all the possible functionality you could want exists, it is scattered over a large number of incompatible modules.

For example, Date::Calc provides good functionality for various datetime calculations and date math, but the values it returns are not well suited for being passed to Date::Format. And while Date::Manip has powerful parsing, the return value from its parsing routine cannot be passed to any other module without further massaging. And so and so on.

For example, if I wanted to parse a date with Date::Parse and then calculate the date one week later with Date::Calc, and then format it with Date::Format, I'd have to do the following:

my $time1 = str2time($date_string); # Date::Parse

# Today() from Date::Calc returns
# date information for an epoch time
my ($y1, $m1, $d1) = Today($time);

my ($y2, $m2, $d2) = Add_Delta_Days($y1, $m1, $d1, 7);

my $time2 = Date_to_Time($y2, $m2, $d2);

print strftime('%B %d, %Y', $time2);

Of course, I didn't have to use the strftime() function for formatting a date. I could have done it with just Date::Calc as:

print sprintf('%s %02d %04d',
Month_to_Text($m2), $d2, $y2);

But I want convenience. If I'm dealing with many datetimes and I need to parse various inputs, generate different formats, and do lots of calculations, then a convenient and uniform API can go a long way towards code maintainability. The extra glue code needed to make different modules cooperate can quickly obscure the actual intent of the program.

Efforts in the past to herd all the existing module authors towards a common API have failed, so rather than try that again, I decided to just write even more datetime code. As we all know, the best way to put out a fire is to pour copious amounts of gasoline on it. In order to make my project sound cool, I'm calling it the "Perl DateTime Suite", which sounds much better than "more date and time modules".

The goal for this project is to produce a suite of datetime modules that do everything you'd ever need related to dates and times. The modules in this suite will cooperate with each other, which means that a module that parses datetimes will return a standard object, and a module for formatting datetimes will accept that standard object.

So far, this project has attracted interest from a number of people, and discussions on the datetime@perl.org list have gone well. Recently, I released alpha versions of the core object, DateTime.pm, as well as DateTime::TimeZone, which provides complete time zone support based on the Olson database. There is also an alpha of DateTime::Format::ICal on CPAN, a module for parsing and formatting iCal datetimes and durations. In the future, look for more modules in the suite, all of which will begin with "DateTime::".

Further Resources and Reading

Some excellent online resources include Claus Tondering's Calendar FAQ at http://www.tondering.dk/claus/calendar.html as well as the US Naval Observatory Time Service site at http://tycho.usno.navy.mil/. For more information on time zones and the Olson database, see http://www.twinsun.com/tz/tz-link.htm.

If you're interested in discussing anything related to Perl and datetimes, check out the datetime@perl.org list. You can subscribe by sending a message to datetime-subscribe@perl.org.

Thanks

Thanks to Jonathan Scott Duff, Nick Tonkin, and Iain Truskett for reviewing this article before publication.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Simple, Small Classes

Published on Perl.com
http://www.perl.com/pub/a/2003/07/15/nocode.html
See this if you're having trouble printing code examples

How to Avoid Writing Code
By Kake Pugh

One of the most boring programming tasks in the world has to be pulling data out of a database and displaying it on a web site. Yet it's also one of the most ubiquitous. Perl programmers being lazy, there are tools to help make boring programming tasks less painful, and two of these tools, Class::DBI and the Template Toolkit, create a whole which is far more drudgery-destroying than its parts.

Both these tools can do more complicated stuff than that described in this article, but my aim is to motivate people who may not have tried them out to give them a go and see how much work they can save you for even simple tasks.

I've assumed that you know the basics of designing a database--why you have several tables and JOIN them rather than putting everything in the same table. I've also assumed that you're not allergic to reading documentation, so I'm going to spend more space on saying why I use particular features of the modules rather than explaining exactly how they work.

Synergy

The reason that Class::DBI and the Template Toolkit work so well together is simple. Template Toolkit templates can call methods on objects passed to them--so there's no need to explicitly pull every column out of the database before you process the template--and Class::DBI saves you the bother of writing methods to retrieve database columns. You're essentially going straight from the database to HTML with only a very small amount of Perl in the middle.

Suppose you're writing a web application to store details of books and their authors, and reviews of the books by users of the site. You'd like to have a page that displays all the books in your database and, for each book, offers links to all the reviews already written. With suitably set-up classes you can write a couple of lines of Perl:

  #!/usr/bin/perl -w
  use strict;

  use Bookworms::Book;
  use Bookworms::Template;

  my @books = Bookworms::Book->retrieve_all;
  @books = sort { $a->title cmp $b->title } @books;
  print Bookworms::Template->output( template => "book_list.tt",
                                     vars     => { books => \@books } );

hand your designer a simple template to pretty up:

  [% page_title = "List all books" %]
  [% INCLUDE header.tt %]

    <ul>
      [% FOREACH book = books %]
        <li>[% book.title %] ([% book.author.name %])
            [% FOREACH review = book.reviews %]
              (<a href="review.cgi?review=[% review.uid %]">Read review
              by [% review.reviewer.name %]</a>)
            [% END %]
        </li>
      [% END %]
    </ul>

  [% INCLUDE footer.tt %]

and your task is done. You don't have to explicitly select the reviews; you don't have to then cross-reference to another table to find out the reviewer's name; you don't have to mess with HERE-documents or fill your program with print statements. You hardly have to do anything.

Except of course, write the Bookworm::* classes in the first place, but that's easy.

Simple, Small Classes

For convenience, we write a class containing all the SQL needed to set up our database schema. This is very useful for running tests as well as for deploying a new install of the application.

  package Bookworm::Setup;
  use strict;
  use DBI;

  # Hash for table creation SQL - keys are the names of the tables,
  # values are SQL statements to create the corresponding tables.
  my %sql = (
      author => qq {
          CREATE TABLE author (
              uid   int(10) unsigned NOT NULL auto_increment,
              name  varchar(200),
              PRIMARY KEY (uid)
          )
      },
      book => qq{
          CREATE TABLE book (
              uid           int(10) unsigned NOT NULL auto_increment,
              title         varchar(200),
              first_name    varchar(200),
              author        int(10) unsigned, # references author.uid
              PRIMARY KEY (uid)
          )
      },
      review => qq{
          CREATE TABLE review (
              uid       int(10) unsigned NOT NULL auto_increment,
              book      int(10) unsigned, # references book.uid
              reviewer  int(10) unsigned, # references reviewer.uid
              PRIMARY KEY (uid)
          )
      },
      reviewer => qq{
          CREATE TABLE review (
              uid   int(10) unsigned NOT NULL auto_increment,
              name  varchar(200),
              PRIMARY KEY (uid)
          )
      }
  );
This class has a single method that sets up a database conforming to the schema above. Here's the rendered POD for it; the implementation is pretty simple. The "force_clear" option is very useful for testing.
    setup_db( dbname      => 'bookworms',
              dbuser      => 'username',
              dbpass      => 'password',
              force_clear => 0            # optional, defaults to 0
            );

  Sets up the tables. Unless "force_clear" is supplied and set to a
  true value, any existing tables with the same names as we want to
  create will be left alone, whether or not they have the right
  columns etc. If "force_clear" is true, then any tables that are "in
  the way" will be removed. _Note that this option will nuke all your
  existing data._

  The database user "dbuser" must be able to create and drop tables in
  the database "dbname".

  Croaks on error, returns true if all OK.

Now, another class to wrap around the Template Toolkit; we want to grab global variables like the name of the site, and so on, from a config class. (There are plenty of config modules on CPAN; you're bound to find one you like. I quite like Config::Tiny; other people swear by AppConfig--and since the latter is a prerequisite of the Template Toolkit, you'll have it installed already.) Bookworms::Config is just a little wrapper class around Config::Tiny, so if I change to a different config method later I don't have to rewrite lots of code.

  package Bookworms::Template;
  use strict;
  use Bookworms::Config;
  use CGI;
  use Template;

  # We have one method, which returns everything you need to send to
  # STDOUT, including the Content-Type: header.

  sub output {
      my ($class, %args) = @_;

      my $config = Bookworms::Config->new;
      my $template_path = $config->get_var( "template_path" );
      my $tt = Template->new( { INCLUDE_PATH => $template_path } );

      my $tt_vars = $args{vars} || {};
      $tt_vars->{site_name} = $config->get_var( "site_name" );

      my $header = CGI::header;

      my $output;
      $tt->process( $args{template}, $tt_vars, \$output)
          or croak $tt->error;
      return $header . $output;
  }

Now we can start writing the classes to manage our database tables. Here's the class to handle book objects:

  package Bookworms::Book;
  use base 'Bookworms::DBI';
  use strict;

  __PACKAGE__->set_up_table( "book" );
  __PACKAGE__->has_a( author => "Bookworms::Author" );
  __PACKAGE__->has_many( "reviews",
                         "Bookworms::Review" => "book" );

  1;

Yes, that's all you need. This simple class, by its ultimate inheritance from Class::DBI, has auto-created constructors and accessors for every aspect of a book as defined in our database schema. And moreover, because we've told it (using has_a) that the author column in the book table is actually a foreign key for the primary key of the table modeled by Bookworms::Author, when we use the ->author accessor we actually get a Bookworms::Author object, which we can then call methods on:

  my $hobbit = Bookworms::Book->search( title => "The Hobbit" );
  print "The Hobbit was written by " . $hobbit->author->name;

There are a couple of supporting classes that we need to write, but they're not complicated either.

First a base class, as with all Class::DBI applications, to set the database details:

  package Bookworms::DBI;
  use base "Class::DBI::mysql";

  __PACKAGE__->set_db( "Main", "dbi:mysql:bookworms",
    "username", "password" );

  1;

Our base class inherits from Class::DBI::mysql instead of plain Class::DBI, so we can save ourselves the trouble of directly specifying the table columns for each of our database tables--the database-specific base classes will auto-create a set_up_table method to handle all this for you.

At the time of writing, base classes for MySQL, PostgreSQL, Oracle, and SQLite are available on CPAN. There's also Class::DBI::BaseDSN, which allows you to specify the database type at runtime.

We'll also want a class for each of the author, review, and reviewer tables, but these are even simpler than the Book class. For example, the author class could be as trivial as:

  package Bookworms::Author;
  use base 'Bookworms::DBI';
  use strict;

  __PACKAGE__->set_up_table( "author" );

  1;

If we wanted to be able to access all the books by a given author, we could add the single line

  __PACKAGE__->has_many( "books",
                         "Bookworms::Book" => "author" );

and an accessor to return an array of Bookworms::Book objects would be automatically created, to be used like so:

  my $author = Bookworms::Author->search( name => "J K Rowling" );
  my @books = $author->books;

Or indeed:

  <h1>[% author.name %]</h1>

  <ul>
    [% FOREACH book = author.books %]
      <li>[% book.title %]</li>
    [% END %]
  </ul>

Simple, small, almost trivial classes, taking a minute or two each to write.

What Does This Get Me?

The immediate benefits of all this are obvious:

  • You don't have to mess about with HTML, since the very simplistic use of the Template Toolkit means that templates are comprehensible to competent web designers.
  • You don't have to maintain classes full of copy-and-paste code, since the repetitive programming tasks like creating constructors and simple accessors are done for you.

A large hidden benefit is testing. Since the actual CGI scripts--which can be a pain to test--are so simple, you can concentrate most of your energy on testing the underlying modules.

It's probably worth writing a couple of simple tests to make sure that you've set up your classes the way you intended to, particularly in your first couple of forays into Class::DBI.

  use Test::More tests => 5;
  use strict;

  use_ok( "Bookworms::Author" );
  use_ok( "Bookworms::Book" );
  my $author = Bookworms::Author->create({ name => "Isaac Asimov" });
  isa_ok( $author, "Bookworms::Author" );
  my $book = Bookworms::Book->create({ title  => "Foundation",
                                       author => $author });
  isa_ok( $book, "Bookworms::Book" );
  is( $book->author->name, "Isaac Asimov", "right author" );

However, the big testing win with this technique of separating out the heavy lifting from the CGI scripts into modules is when you'd like to add something more complicated. Say, for example, fuzzy matching. It's well known that people can't spell, and you'd like someone typing in "Isaac Assimov" to find the author they're looking for. So, let's process the author names as we create the author objects, and store some kind of canonicalized form in the database.

Class::DBI allows you to define "triggers"--methods that are called at given points during the lifetime of an object. We'll want to use an after_create trigger, which is called after an object has been created and stored in the database. We use this in preference to a before_create trigger, since we want to know the uid of the object, and this is only created (via the auto_increment primary key) once the object has been written to the database.

We use Search::InvertedIndex to store the canonicalized names, for quick access. We start with a very simple canonicalization--stripping out vowels and collapsing repeated letters. (I've found that this can pick up about half of name misspellings found in the wild, which is pretty impressive.)

We'll write a couple of tests before we move on to code. Here are some that check that our class is doing what we told it to--removing vowels and collapsing repeated consonants.

  use Test::More tests => 2;
  use strict;

  use Bookworms::Author;

  my $author = Bookworms::Author->create({ name => "Isaac Asimov" });
  my @matches = Bookworms::Author->fuzzy_match( name => "asemov" );
  is_deeply( \@matches, [ $author ],
    "fuzzy matching catches wrong vowels" );
  @matches = Bookworms::Author->fuzzy_match(
    name => "assimov" );
  is_deeply( \@matches, [ $author ],
    "fuzzy matching catches repeated letters" );

We should also write some other tests to run our algorithms over various misspellings that we've captured from actual users, to give an idea of whether "what we told our class to do" is the right thing.

Here's the first addition to the Bookworms::Author class, to store the indexed data:

  use Search::InvertedIndex;

  my $database = Search::InvertedIndex::DB::Mysql->new(
                     -db_name    => "bookworms",
                     -username   => "username",
                     -password   => "password",
                     -hostname   => "",
                     -table_name => "sii_author",
                     -lock_mode  => "EX"
    ) or die "Couldn't set up db";

  my $map = Search::InvertedIndex->new( -database => $database )
    or die "Couldn't set up map";
  $map->add_group( -group => "author_name" );

  __PACKAGE__->add_trigger( after_create => sub {
      my $self = shift;
      my $update = Search::InvertedIndex::Update->new(
          -group => "author_name",
          -index => $self->uid,
          -data  => $self->name,
           -keys  => { map { $self->_canonicalise($_) => 1 }
                       split(/\s+/, $self->name)
                     }
          );
          $map->update( -update => $update );
      }
  } );

  sub _canonicalise {
      my ($class, $word) = @_;
      return "" unless $word;
      $word = lc($word);
      $word =~ s/[aeiou]//g;    # remove vowels
      $word =~ s/(\w)\1+/$1/eg; # collapse doubled
                                # (or tripled, etc) letters
      return $word;
  }

(We'll also want similar triggers for after_update and after_delete, in order that our indexing is kept up to date with our data.)

Then we can write the fuzzy_matching method:

  sub fuzzy_match {
      my ($class, %args) = @_;
      return () unless $args{name};
      my @terms = map { $class->_canonicalise($_) => 1 }
                        split(/\s+/, $args{name});
      my @leaves;
      foreach my $term (@terms) {
          push @leaves, Search::InvertedIndex::Query::Leaf->new(
              -key   => $term,
              -group => "author_name" );
      }

      my $query = Search::InvertedIndex::Query->new( -logic => 'and',
                                                     -leafs => \@leaves );
      my $result = $map->search( -query => $query );

      my @matches;
      my $num_results = $result->number_of_index_entries || 0;
      if ( $num_results ) {
          for my $i ( 1 .. $num_results ) {
              my ($index, $data) = $result->entry( -number => $i - 1 );
              push @matches, $data;
          }
      }

      return @matches;
  }

(The matching method can be improved. I've found that neither Text::Soundex nor Text::Metaphone are much of an improvement over the simple approach already detailed, but Text::DoubleMetaphone is definitely worth plugging in, to catch misspellings such as Nicolas/Nicholas and Asimov/Azimof.)

There are plenty of other features that our little web application would benefit from, but I shall leave those as an exercise for the reader. I hope I've given you some insight into my current preferred web development techniques--and I'd love to see a finished Bookworms application if it does scratch anyone's itch.

See Also

  • Class::DBI
  • The Template Toolkit
  • Search::InvertedIndex
  • Text::DoubleMetaphone

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Parse::RecDescent Tutorial

Published on Perl.com
http://www.perl.com/pub/a/2001/06/13/recdecent.html
See this if you're having trouble printing code examples

Parse::RecDescent Tutorial
By Jeffrey Goff

The Basics

Parse::RecDescent is a combination compiler and interpreter. The language it uses can be thought of roughly as a macro language like CPP's, but the macros take no parameters. This may seem limiting, but the technique is very powerful nonetheless. Our macro language looks like this:

  macro_name : macro_body

A colon separates the macro's name and body, and the body can have any combination of explicit strings ("string, with optional spaces"), a regular expression (/typical (?=perl) expression/), or another macro that's defined somewhere in the source file. It can also have alternations. So, a sample source file could look like:

  startrule : day  month /\d+/ # Match strings of the form "Sat Jun 15"

  day : "Sat" | "Sun" | "Mon" | "Tue" | "Wed" | "Thu" | "Fri"

  month : "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" |
          "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"

Three macros make up this source file: startrule, dayrule and monthrule. The compiler will turn these rules into its internal representation and pass it along to the interpreter. The interpreter then takes a data file and attempts to expand the macros in startrule to match the contents of the data file.

The interpreter takes a string like "Sat Jun 15" and attempts to expand the startrule macro to match it. If it matches, the interpreter returns a true value. Otherwise, it returns undef;. Some sample source may be welcome at this point:

  #!/usr/bin/perl

  use Parse::RecDescent;

  # Create and compile the source file
  $parser = Parse::RecDescent->new(q(
    startrule : day  month /\d+/

    day : "Sat" | "Sun" | "Mon" | "Tue" | "Wed" | "Thu" | "Fri"

    month : "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" |
            "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"
  ));

  # Test it on sample data
  print "Valid date\n" if $parser->startrule("Thu Mar 31");
  print "Invalid date\n" unless $parser->startrule("Jun 31 2000");

Creating a new Parse::RecDescent instance is done just like any other OO module. The only parameter is a string containing the source file, or grammar. Once the compiler has done its work, the interpreter can run as many times as necessary. The sample source tests the interpreter on valid and invalid data.

By the way, just because the parser knows that the string "Sat Jun 15" is valid, it has no way of knowing if the 15th of June was indeed a Saturday. In fact, the sample grammar would also match "Sat Feb 135". The grammar describes form, not content.

Getting Data

Now, this is quite a bit of work to go to simply to match a string. However, much, much more can be done. One element missing from this picture is capturing data. So far the sample grammar can tell if a string matches a regular expression, but it can't tell us what the data it's parsed is. Well, these macros can be told to run perl code when encountered.

Perl code goes after the end of a rule, enclosed in braces. When the interpreter recognizes a macro such as startrule, the text matched is saved and passed to the perl code embedded in the grammar.

Each word or term of the macro ('day', 'month'...) is saved by the interpreter. dayrule gets saved into the $item{day} hash entry, as does monthrule. The /\d+/ term doesn't have a corresponding name, so its data comes from the @item array. $item[0] is always the rule name, so /\d+/ gets saved into $item[3]. So, code to print the parsed output from our sample startrule rule looks like this:

  startrule : day month /\d+/
            { print "Day: $item{day} Month: $item{month} Date: $item[3]\n"; }

Everything in the parser is run as if it was in the Parse::RecDescent package, so when calling subroutines outside Parse::RecDescent, either qualify them as Package::Name->my_sub() or subclass Parse::RecDescent.

A Mini-Language

All of the pieces are now in place to create a miniature language, compile, and run code in it. To make matters simple, the language will only have two types of instruction: Assign and Print. A sample 'Assign' instruction could look like foo = 3 + a. The 'Print' statement will look like print foo / 2. Add the fact that 3 + a can be arbitrarily long (temp = 3+a/2*4), and now you've got a non-trivial parsing problem.

The easiest instruction to implement is the 'Print' instruction. Assuming for the moment that the right-hand side of the statement (the foo / 2 part of print foo / 2) already has a rule associated with it (called 'expression'), the 'Print' instruction is very simple:

  print_instruction : /print/i expression
                    { print $item{expression}."\n" }

The 'Assign' instruction is a little harder to do, because we need to implement variables. We'll do this in a straightforward fashion, storing variable names in a hash. This will live in the main package, and for the sake of exposition we'll call it %VARIABLE. One caveat to remember is that the perl code runs inside the Parse::RecDescent package, so we'll explicitly specify the main package when writing the code.

More complex than the 'Print' instruction, the 'Assign' instruction has three parts: the variable to assign to, an "=" sign, and the expression that gets assigned to the variable. So, the instruction looks roughly like this:

  assign_instruction : VARIABLE "=" expression
                     { $main::VARIABLE{$item{VARIABLE}} = $item{expression} }

Much like we did with the dayrule rule in the last section, we'll combine the print_instruction and assign_instruction into one instruction rule. The syntax for this should be fairly simple to remember, as it's the same as a Perl regular expression.

  instruction : print_instruction
              | assign_instruction

In order to make the startrule expand to the instruction rule, we'd ordinarily use a rule like startrule : instruction. However, most languages let you enter more than one instruction in a source file. One way to do this would be to create a recursive rule that would look like this:

  instructions : instruction ";" instructions
               | instruction
  startrule : instructions

[[JMG: I'm sorely tempted to rewrite this chunk, if only 'cause there's a lot of info here in just one paragraph]]

Input text like "print 32" expands as follows: startrule expands to instructions. instructions expands to instruction, which expands to print_instruction. Longer input text like "a = 5; b = a + 5; print a" expands like so: startrule expands to instructions. The interpreter looks ahead and chooses the alternative with the semicolon, and parses "a = 5" into its first instruction. "b = a + 5; print a" is left in instructions. This process gets repeated twice until each bit has been parsed into a separate instruction.

If the above seemed complex, Parse::RecDescent has a shortcut available. The above instructions rule can be collapsed into startrule : instruction(s). The (s) part can simply be interpreted as "One or more instructions". By itself this assumes only whitespace exists between the different instructionrule;s, but here again, Parse::RecDescent comes to the rescue, by allowing the user to specify a separator regular expression, like (s /;/). So, the startrule actually will use the (s /;/) syntax.

  startrule : instruction(s /;/)

The Expression Rule

Expressions can be anything from '0' all the way through 'a+bar*foo/300-75'. Ths range may seem intimidating, but we'll try to break it down into easy-to-digest pieces. Starting simply, an expression can be as simple as a single variable or integer. This would look like:

  expression : INTEGER
             | VARIABLE
             { return $main::VARIABLE{$item{VARIABLE}} }

The VARIABLE rule has one minor quirk. In order to compute the value of the expression, variables have to be given a value. In order to modify the text parsed, simply have the code return the modified text. In this case, the perl code looks up the variable in %main::VARIABLE and returns the value of the variable rather than the text.

Those two lines take care of the case of an expression with a single term. Multiple-term expressions (such as 7+5 and foo+bar/2) are a little harder to deal with. The rules for a single expression like a+7 would look roughly like:

  expression : INTEGER OP INTEGER
             | VARIABLE OP INTEGER
             | INTEGER OP VARIABLE
             | VARIABLE OP VARIABLE
  OP : /[-+*/%]/

This introduces one new term, OP. This rule simply contains the binary operators /[-+*/%]/. The above approach works for two terms, and can be extended to three terms or more, but is terribly unwieldy. If you'll remember, the expression rule already is defined as INTEGER | VARIABLE, so we can replace the right-hand term with expression. Replacing the right-hand term with expression and getting rid of redundant lines results in this:

  expression : INTEGER OP expression
             | VARIABLE OP expression

We'll hand off the final evaluation to a function outside the Parse::RecDescent package. This function will simply take the @item list from the interpreter and evaluate the expression. Since the array will look like (3,'+',5). we can't simply say $item[1] $item[2] $item[3], since $item[2] is a scalar variable, not an operator. Instead we'll take the string "$item[1] $item[2] $item[3]" and evaluate that. This will evaluate the string and return the result. This then gets passed back, and becomes the value of the expression.

  expression : INTEGER OP expression
             { return main::expression(@item) }
             | VARIABLE OP expression
             { return main::expression(@item) }

  sub expression {
    shift;
    my ($lhs,$op,$rhs) = @_;
    return eval "$lhs $op $rhs";
  }

That completes our grammar. Testing is fairly simple. Write some code in the new language, like "a = 3 + 5; b = a + 2; print a; print b", and pass it to the $parser->startrule() method to interpret the string.

The file included with this article comes with several test samples. The grammar in the tutorial is very simple, so plenty of room to experiment remains. One simple modification is to change the INTEGER rule to account for floating point numbers. Unary operators (single-term such as sin()) can be added to the expression rule, and statements other than 'print' and 'assign' can be added easily.

Other modifications might include adding strings (some experimental extensions such as '<perl_quotelike>' may help). Changing the grammar to include parentheses and proper precedence are other possible projects.

Closing

Parse::RecDescent is a powerful but difficult-to-undertstand module. Most of this is because parsing a language can be difficult to understand. However, as long as the language has a fairly consistent grammar (or one can be written), it's generally possible to translate it into a grammar that Parse::RecDescent can handle.

Many languages have their grammars available on the Internet. Grammars can usually be found in search engines under the keyword 'BNF', standing for 'Backus-Naur Form'. These grammars aren't quite in the form Parse::RecDescent prefers, but can usually be modified to suit.

When writing your own grammars for Parse::RecDescent, one important rule to keep in mind is that a rule can never have itself as the first term. This makes rules such as statement : statement ";" statements illegal. This sort of grammar is called "left-recursive" because a rule in the grammar expands to its left side.

Left-recursive grammars can usually be rewritten to right-recursive, which will parse cleanly under Parse::RecDescent, but there are classes of grammars thatcant be rewritten to be right-recursive. If a grammar can't be done in Parse::RecDescent, then something like Parse::Yapp may be more appropriate. It's also possible to coerce yacc into generating a perl skeleton, supposedly.

Hopefully some of the shroud of mystery over Parse::RecDescent has been lifted, and more people will use this incredibly powerful module.

 #!/usr/bin/perl -w

 use strict;
 use Parse::RecDescent;
 use Data::Dumper;

 use vars qw(%VARIABLE);

 # Enable warnings within the Parse::RecDescent module.

 $::RD_ERRORS = 1; # Make sure the parser dies when it encounters an error
 $::RD_WARN   = 1; # Enable warnings. This will warn on unused rules &c.
 $::RD_HINT   = 1; # Give out hints to help fix problems.

 my $grammar = <<'_EOGRAMMAR_';

   # Terminals (macros that can't expand further)
   #

   OP       : m([-+*/%])      # Mathematical operators
   INTEGER  : /[-+]?\d+/      # Signed integers
   VARIABLE : /\w[a-z0-9_]*/i # Variable

   expression : INTEGER OP expression
              { return main::expression(@item) }
              | VARIABLE OP expression
              { return main::expression(@item) }
              | INTEGER
              | VARIABLE
              { return $main::VARIABLE{$item{VARIABLE}} }

   print_instruction  : /print/i expression
                      { print $item{expression}."\n" }
   assign_instruction : VARIABLE "=" expression
                      { $main::VARIABLE{$item{VARIABLE}} = $item{expression} }

   instruction : print_instruction
               | assign_instruction

   startrule: instruction(s /;/)

 _EOGRAMMAR_

 sub expression {
   shift;
   my ($lhs,$op,$rhs) = @_;
   $lhs = $VARIABLE{$lhs} if $lhs=~/[^-+0-9]/;
   return eval "$lhs $op $rhs";
 }

 my $parser = Parse::RecDescent->new($grammar);

 print "a=2\n";             $parser->startrule("a=2");
 print "a=1+3\n";           $parser->startrule("a=1+3");
 print "print 5*7\n";       $parser->startrule("print 5*7");
 print "print 2/4\n";       $parser->startrule("print 2/4");
 print "print 2+2/4\n";     $parser->startrule("print 2+2/4");
 print "print 2+-2/4\n";    $parser->startrule("print 2+-2/4");
 print "a = 5 ; print a\n"; $parser->startrule("a = 5 ; print a");

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Stopping Spam with SpamAssassin

Published on Perl.com
http://www.perl.com/pub/a/2002/03/06/spam.html
See this if you're having trouble printing code examples

Stopping Spam with SpamAssassin
By Simon Cozens

I receive a lot of spam; an absolute massive bucket load of spam. I received more than 100 pieces of spam in the first three days of this month. I receive so much spam that Hormel Foods sends trucks to take it away. And I'm convinced that things are getting worse. We're all being bombarded with junk mail more than ever these days.

Well, a couple of days ago, I reached my breaking point, and decided that the simple mail filtering I had in place up until now just wasn't up to the job. It was time to call in an assassin.

SpamAssassin

SpamAssassin is a rule-based spam identification tool. It's written in Perl, and there are several ways of using it: You can call a client program, spamassassin, and have it determine whether a given message is likely to be spam; you can do essentially the same thing but use a client/server approach so that your client isn't always loading and parsing the rules each time mail comes; or, finally, you can use a Perl module interface to filter spam from a Perl program.

SpamAssassin is extremely configurable; you can select which rules you want to use, change the way the rules contribute to a piece of mail's "spam score," and add your own rules. We'll look at some of these features later in the article. First, how do we get SpamAssassin installed and start using it?

If you're using Debian Linux or one of the BSDs, then this couldn't be easier: just install the appropriate package using apt or the ports tree respectively. (The BSD port is called p5-Mail-SpamAssassin)

Those less fortunate will have to download the latest version of SpamAssassin, and install it themselves.

Vipul's Razor

SpamAssassin uses a variety of ways for testing whether an e-mail is spam, ranging from simple textual checks on the headers or body and detecting missing or misleading headers to network-based checks and an interesting distributed system called Vipul's Razor.

Vipul's Razor takes advantage of the fact that spam is, by its nature, distributed in bulk. Hence, a lot of the spam that you see, I'm also going to see at some point. If there were a big clearing-house where you could report spam and I could see if my incoming mail matches what you've already reported, then I could have a guaranteed way of determining whether a given mail is spam. Vipul's Razor is that clearing-house.

Why is it a Razor? Because it's a collaborative system, its strength is directly derived from the quality of its database, which comes back to the way it's used by the likes of you and me. If end-users report lots of real spam, the Razor gets better; if the database gets "poisoned" by lots of false or misleading reports, then the efficiency of the whole system drops.

Just like any other spam detection mechanism, Razor isn't perfect. There are two points particularly worth noting. First, while it tries to completely avoid false positives (saying something's spam when it isn't) by requiring that spam be reported, it doesn't do anything about false negatives (saying something's not spam when it is) because it only knows about the mail in its database.

Second, spammers, like all other primitive organisms, are constantly evolving. Vipul's Razor only works for spam that is delivered in bulk without modification. Spam that is "personalized" by the addition of random spaces, letters or the name of the recipient, will produce a different signature that won't match similar spam messages in the Razor database.

Nevertheless, the Razor is an excellent addition to the spam fighter's arsenal, since when it marks something as spam, you can be almost positive it's correct. And just like SpamAssassin, it's all pure Perl. Mail::Audit has long supported a Razor plugin, but now we can move to calling Razor as part of a more comprehensive mail filtering system based on SpamAssasin and Mail::Audit

Installing Vipul's Razor is similar to installing SpamAssassin. Debian and BSD users have packages called "razor" and "razor-clients," respectively; and the rest of the world can download and install from the home page. SpamAssassin will detect whether Razor is available and, by default, use it if so.

Assassinating Spam With Mail::Audit : The Easy Way

So this is the part you've all been waiting for. How do we use these things to trap spam? For those of you who aren't familiar with Mail::Audit, the idea is simple: just like with procmail, you write recipes that determine what happens to your mail. However, in the case of Mail::Audit, you specify the recipe in Perl. For instance, here's a recipe to move all mail sent to perl5-porters@perl.org to another folder:

    use Mail::Audit;
    my $mail = Mail::Audit->new();
    if ($mail->from =~ /perl5-porters\@perl.org/) {
        $mail->accept("p5p");
    }
    $mail->accept();
For more details on how to construct mail filters with Mail::Audit, see my previous article.

Plugging SpamAssassin into your filters couldn't be simpler. First of all, you absolutely need the latest version of Mail::Audit, version 2.1 from CPAN. Nothing earlier will do! Now write a filter like this:

    use Mail::Audit;
    use Mail::SpamAssassin;
    my $mail = Mail::Audit->new();

    ... the rest of your rules here ...

    my $spamtest = Mail::SpamAssassin->new();
    my $status = $spamtest->check($mail);

    if ($status->is_spam ()) {
        $status->rewrite_mail() };
        $mail->accept("spam");
    }
    $mail->accept();
As you might be able to guess, the important thing here is the calls to check and is_spam. check produces a "status object" that we can query and use to manipulate the e-mail. is_spam tells us whether the mail has exceeded the number of "spam points" required to flag an e-mail as spam.

The rewrite_mail method adds some headers and rewrites the subject line to include the distinctive string "*****SPAM******". The additional headers explain why the e-mail was flagged as spam. For instance:

X-Spam-Status: Yes, hits=6.1 required=5.0
tests=SUBJ_HAS_Q_MARK,REPLY_TO_EMPTY,SUBJ_ENDS_IN_Q_MARK version=2.1
This message had a question mark in the subject, an empty reply-to, and the subject ended in a question mark. The mail wasn't actually spam, but this goes to prove that the technique isn't perfect. Nevertheless, since installing the spam filter, I've only seen about 10 false positives, and zero false negatives. I'm happy enough with this solution.

One important point to remember, however, is where in the course of your filtering you should call SpamAssassin's checks. For instance, you want to do so after your mailing list filtering, because mail sent to mailing lists may have munged headers that might confuse SpamAssassin. However, this means that spam sent to mailing lists might slip through the net. Experiment, and find the best solution for your own e-mail patterns.

Assassinating Spam Without Mail::Audit

Of course, there are times when it might not be suitable to use Mail::Audit or you may not want to. Since SpamAssassin is provided as a command line tool as well as a set of Perl modules, it's easy enough to integrate it in whatever mail filtering solution you use.

For instance, here's a procmail recipe that calls out to spamassassin to filter out spam:

:0fw
| spamassassin -P

:0:
* ^X-Spam-Status: Yes
spambox
For the speed-conscious, you can run the spamd daemon and replace calls to spamassassin with spamc; be aware that this is a TCP/IP daemon that you may want to firewall from the rest of the world.

Another approach is to call spamassassin in your mail transport agent, meaning that spam is filtered out before it even attempts to be delivered to you. There's a Sendmail milter library available that allows you to use SpamAssassin, and similar tricks for Exim and other MTAs are available.

Assassinating Spam With Mail::Audit : More Complex Operations

The Mail::SpamAssassin module has many other methods you can use to manipulate e-mail. For instance, if you've identified something as definitely being spam, then you can use

    $spamtest->report_as_spam($mail);
to report it to Vipul's Razor. (Take note of this: As we've mentioned above, the efficiency of the Razor database comes from the fact that e-mails in it are confirmed as spam by a human. Adding false positives to the database would degrade its usefulness for everyone. Only submit mail that you've confirmed personally.)

If you're finding that mail checking is taking too long because SpamAssassin is having to contact the various network-based blacklists and databases, then you can instruct it to only perform "local" checking:

    $spamtest = Mail::SpamAssassin->new({local_tests_only => 1});

There is a wealth of other options available. See the Mail::SpamAssassin documentation for more details, and happy assassinating!

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Choosing a Templating System

Published on Perl.com
http://www.perl.com/pub/a/2001/08/21/templating.html
See this if you're having trouble printing code examples

Choosing a Templating System
By Perrin Harkins

Introduction

Go on, admit it: You've written a templating system. It's OK, nearly everyone has at some point. You start with something beautifully simple like $HTML =~ s/\$(\w+)/${$1}/g and end up adding conditionals, loops and includes until you've created your own unmaintainable monster.

Luckily for you, you are not the first to think it might be nice to get the HTML out of your code. Many have come before, and more than a few have put their contributions up on CPAN. At this time, there are so many templating modules on CPAN that it's almost certain you can find one that meets your needs. This document aims to be your guide to those modules, leading you down the path to the templating system of your dreams.

And, if you just went straight to CPAN in the first place and never bothered to write your own, congratulations: You're one step ahead of the rest of us.

On a Personal Note

Nothing can start an argument faster on the mod_perl mailing list than a claim that one approach to templating is better than another. People get attached to the tools they've chosen. Therefore, let me say up front that I am biased. I've been at this for a while and I have opinions about what works best. I've tried to present a balanced appraisal of the features of various systems in this document, but it probably won't take you long to figure out what I like. Besides, attempts to be completely unbiased lead to useless documents that don't contain any real information. So take it all with a pound of salt and if you think I've been unfair to a particular tool through a factual error or omission, let me know.

Why Use Templates?

Why bother using templates at all? Print statements and CGI.pm were good enough for grandpa, so why should you bother learning a new way to do things?

Consistency of Appearance

It doesn't take a genius to see that making one navigation bar template and using it in all of your pages is easier to manage than hard-coding it everywhere. If you build your whole site like this, it's much easier to make site-wide changes in the look and feel.

Reusability

Along the same lines, building a set of commonly used components makes it easier to create new pages.

Better Isolation From Changes

Which one changes more often: the logic of your application or the HTML used to display it? Actually the answer doesn't matter, as long as it's one of them. Templates can be a great abstraction layer between the application logic and the display logic, allowing one to be updated without touching the other.

Division of Labor

Separating your Perl code from your HTML means that when your marketing department decides everything should be green instead of blue, you don't have to lift a finger. Just send them to the HTML coder down the hall. It's a beautiful thing, getting out of the HTML business.

Even if the same people in your organization write the Perl code and the HTML, you at last have the opportunity for more people to be working on the project in parallel.

What Are the Differences?

Before we look at the available options, let's go through an explanation of some of the things that make them different.

Execution Models

Although some try to be flexible about it, most templating systems expect you to use some variation of the two basic execution models, which I will refer to as ``pipeline'' and ``callback.'' In the callback style, you let the template take over and it has the application's control flow coded into it. It uses callbacks to modules or snippets of in-line Perl code to retrieve data for display or perform actions such as user authentication. Some popular examples of systems using this model include Mason, Embperl and Apache::ASP.

The pipeline style does all the work up front in a standard CGI or mod_perl handler, then decides which template to run and passes some data to it. The template has no control flow logic in it, just presentation logic, e.g. show this graphic if this item is on sale. Popular systems supporting this approach include HTML::Template and Template Toolkit.

The callback model works well for publishing-oriented sites where the pages are essentially mix and match sets of articles and lists. Ideally, a site can be broken down into visual ``components'' or pieces of pages that are general enough for an HTML coder to recombine them into entirely new kinds of pages without any help from a programmer.

The callback model can get a bit hairy when you have to code logic that can result in totally different content being returned. For example, if you have a system that processes some form input and takes the user to different pages depending on the data submitted. In these situations, it's easy to end up coding a spaghetti of includes and redirects, or putting what are really multiple pages in the same file.

On the other hand, a callback approach can result in fewer files (if the Perl code is in the HTML file), and feels easier and more intuitive to many developers. It's a simple step from static files to static files with a few in-line snippets of code in them. This is part of why PHP is so popular with new developers.

The pipeline model is more like a traditional model-view-controller design. Working this way can provide additional performance tuning opportunities over an approach where you don't know what data will be needed at the beginning of the request. You can aggregate database queries, make smarter choices about caching, etc. It can also promote a cleaner separation of application logic and presentation. However, this approach takes longer to get started with since it's a bigger conceptual hurdle and always involves at least two files: one for the Perl code and one for the template.

Keep in mind, many systems offer significant flexibility for customizing their execution models. For example, Mason users could write separate components for application logic and display, letting the logic components choose which display component to run after fetching their data. This allows it to be used in a pipeline style. A Template Toolkit application could be written to use a simple generic handler (like the Apache::Template module included in the distribution) with all the application logic placed in the template using object calls or in-line Perl. This would be using it in a callback style.

HTML::Template and some of the AxKit XML processors are fairly rigid about insisting on a pipeline approach. Neither provide methods for calling back into Perl code during the HTML formatting stage; you have to do the work before running the template. The authors of these tools consider this a feature since it prevents developers from cheating on the separation of application code and presentation.

Languages

Here's the big issue with templating systems. This is the one that always cranks up the flame on Web development mailing lists.

Some systems use in-line Perl statements. They may provide some extra semantics, like Embperl's operators for specifying whether the code's output should be displayed or Mason's <%init> sections for specifying when the code gets run, but at the end of the day your templates are written in Perl.

Other systems provide a specialized mini-language instead of (or in addition to) in-line Perl. These will typically have just enough syntax to handle variable substitution, conditionals and looping. HTML::Template and Template Toolkit are popular systems using this approach. AxKit straddles the fence, providing both a (not-so-) mini-language - XSLT - and an in-line Perl approach - XPathScript.

Here's how a typical discussion of the merits of these approaches might go:

IN-LINE: Mini-languages are stupid. I already know Perl and it's easy enough. Why would you want to use something different?

MINI-LANG: Because my HTML coder doesn't know Perl, and this is easier for him.

IN-LINE: Maybe he should learn some Perl. He'd get paid more.

MINI-LANG: Whatever. You just want to use in-line Perl so you can handle change requests by putting little hacks in the template instead of changing your modules. That's sloppy coding.

IN-LINE: That's efficient coding. I can knock out data editing screens in half the time it takes you, and then I can go back through, putting all the in-line code into modules and just have the templates call them.

MINI-LANG: You could, but you won't.

IN-LINE: Is it chilly up there in that ivory tower?

MINI-LANG: Go write some VBScript, weenie.

etc.

Most people pick a side in this war and stay there. If you are one of the few who hasn't decided yet, you should take a moment to think about who will be building and maintaining your templates, what skills those people have and what will allow them to work most efficiently.

Here's an example of a simple chunk of template using first an in-line style (Apache::ASP in this case) and then a mini-language style (Template Toolkit). This code fetches an object and displays some properties of it. The data structures used are identical in both examples. First Apache::ASP:

  <% my $product = Product->load('sku' => 'bar1234'); %>

  <% if ($product->isbn) { %>
    It's a book!
  <% } else { %>
    It's NOT a book!
  <% } %>

  <% foreach my $item (@{$product->related}) { %>
    You might also enjoy <% $item->name %>.
  <% } %>

And now Template Toolkit:

  [% USE product(sku=bar1234) %]

  [% IF product.isbn %]
    It's a book!
  [% ELSE %]
    It's NOT a book!
  [% END %]

  [% FOREACH item = product.related %]
    You might also enjoy [% item.name %].
  [% END %]

There is a third approach, based on parsing an HTML document into a DOM tree and then manipulating the contents of the nodes. The only module using this approach is HTML_Tree. The idea is similar to using a mini-language, but it doesn't require any non-standard HTML tags and it doesn't embed any logic about loops or conditionals in the template itself. This is nice because it means your templates are valid HTML documents that can be viewed in a browser and worked with in most standard HTML tools. It also means people working with the templates can put placeholder data in them for testing and it will simply be replaced when the template is used. This preview ability only breaks down when you need an if/else type construct in the template. In that situation, both the ``if'' and ``else'' chunks of HTML would show up when previewing.

Parsers and Caching

The parsers for these templating systems are implemented in one of three ways: They parse the template every time (``repeated parse''), they parse it and cache the resulting parse tree (``cached parse tree''), or they parse it, convert it to Perl code and compile it (``compiled'').

Systems that compile templates to Perl take advantage of Perl's powerful run-time code evaluation capabilities. They examine the template, generate a chunk of Perl code from it and eval the generated code. After that, subsequent requests for the template can be handled by running the compiled bytecode in memory. The complexity of the parsing and code generation steps varies based on the number of bells and whistles the system provides beyond straight in-line Perl statements.

Compiling to Perl and then to Perl bytecode is slow on the first hit but provides excellent performance once the template has been compiled, since the template becomes a Perl subroutine call. This is the same approach used by systems like JSP (Java ServerPages). It is most effective in environments with a long-running Perl interpreter, like mod_perl.

HTML::Template, HTML_Tree, and the 2.0 beta release of Embperl all use a cached parse tree approach. They parse templates into their respective internal data structures and then keep the parsed structure for each processed template in memory. This is similar to the compiled Perl approach in terms of performance and memory requirements, but does not actually involve Perl code generation and thus doesn't require an eval step. Which way is faster: caching the parse tree or compiling? It's hard to objectively measure, but anecdotal evidence seems to support compilation. Template Toolkit used a cached parse tree approach for version 1, but switched to a compilation approach for version 2 after tests showed it to offer a significant speed increase. However, as will be discussed later, either approach is more than fast enough.

In contrast to this, a repeated parse approach may sound slow. However, it can be pretty fast if the tokens being parsed for are simple enough. Systems using this approach generally use simple tokens, which allows them to use fast and simple parsers.

Why would you ever use a system with this approach if compilation has better performance? Well, in an environment without a persistent Perl interpreter like vanilla CGI this can actually be faster than a compiled approach since the startup cost is lower. The caching of Perl bytecode done by compilation systems is useless when the Perl interpreter doesn't stick around for more than one request.

There are other reasons, too. Compiled Perl code takes up a lot of memory. If you have many unique templates, they can add up fast. Imagine how much RAM it would take up if each page that used server-side includes (SSI) had to stay in memory after they had been accessed. (Don't worry, the Apache::SSI module doesn't use compilation so it doesn't have this problem.)

Application Frameworks vs. Just Templates

Some of the templating tools try to offer a comprehensive solution to the problems of Web development. Others offer just a templating solution and assume you will fit this together with other modules to build a complete system.

Some common features offered in the frameworks include:

URL Mapping

All of the frameworks offer a way to map a URL to a template file. In addition to simple mappings similar to the handling of static documents, some offer ways to intercept all requests within a certain directory for pre-processing, or to create an object inheritance scheme out of the directory structure of a site.

Session Tracking

Most interactive sites need to use some kind of session tracking to associate application state data with a user. Some tools make this simple by handling all the cookies or URL-munging for you and allowing you simply to read and write from an object or hash that contains the current user's session data. A common approach is to use the Apache::Session module for storage.

Output Caching

Caching is the key to good performance in many Web systems, and some of these tools provide user-controlled caching of output. This is one of the major features of both Mason and AxKit. AxKit can cache at the page level, while Mason also offers fine-grained caching of components within the page.

Form Handling

How will you live without CGI.pm to parse incoming form data? Many of these tools will do it for you, making it available in a convenient data structure. Some also validate form input, and even provide ``sticky'' form widgets that keep their selected values when re-displayed or set up default values based on data you provide.

Debugging

Everyone knows how painful it can be to debug a CGI script. Templating systems can make it worse, by screwing up Perl's line numbers with generated code. To help fix the problem they've created, some offer built-in debugging support, including extra logging, or integration with the Perl debugger.

If you want to use a system that just does templates but you need some of these other features and don't feel like implementing them yourself, there are some tools on CPAN that provide a framework you can build upon. The libservlet distribution, which provides an interface similar to the Java servlet API, is independent of any particular templating system. Apache::PageKit and CGI::Application are other options in this vein, but both of these are currently tied to HTML::Template. OpenInteract is another framework, this time tied to Template Toolkit. All of these could be adapted for the ``just templates'' module of your choice with fairly minimal effort.

The Contenders

OK, now that you know something about what separates these tools from one another, let's take a look at the top choices for Perl templating systems. This is not an exhaustive list: I've only included systems that are currently maintained, well-documented and have managed to build up a significant user community. In short, I've left out about dozen less-popular systems. At the end of this section, I'll mention a few systems that aren't as commonly used but may be worth a look.

SSI

SSI is the granddaddy of templating systems, and the first one that many people used since it comes as a standard part of most Web servers. With mod_perl installed, mod_include gains some additional power. Specifically, it is able to take a new #perl directive that allows for in-line subroutine calls. It can also efficiently include the output of Apache::Registry scripts by using the Apache::Include module.

The Apache::SSI module implements the functionality of mod_include entirely in Perl, including the additional #perl directive. The main reasons to use it are to post-process the output of another handler (with Apache::Filter) or to add your own directives. Adding directives is easy through subclassing. You might be tempted to implement a complete template processor in this way, by adding loops and other constructs, but it's probably not worth the trouble with so many other tools out there.

SSI follows the callback model and is mostly a mini-language, although you can sneak in bits of Perl code as anonymous subs in #perl directives. Because SSI uses a repeated parse implementation, it is safe to use it on large numbers of files without worrying about memory bloat.

SSI is a great choice for sites with fairly simple templating needs, especially ones that just want to share some standard headers and footers between pages. However, you should consider whether your site will eventually need to grow into something with more flexibility and power before settling on this simple approach.

HTML::Mason

http://www.masonhq.com/

Mason has been around for a few years, and has built a loyal following. It was originally created as a Perl clone of some of the most interesting features from Vignette StoryServer, but has since become its own unique animal. It comes from a publishing background, and includes features oriented toward splitting pages into re-useable chunks, or ``components.''

Mason uses in-line Perl with a compilation approach, but has a feature to help keep the Perl code out of the HTML coder's way. Components (templates) can include a section of Perl at the end of the file that is wrapped inside a special tag indicating that it should be run first, before the rest of the template. This allows programmers to put all the logic for a component down at the bottom away from the HTML, and then use short in-line Perl snippets in the HTML to insert values, loop through lists, etc.

Mason is a site development framework, not just a templating tool. It includes a handy caching feature that can be used for capturing the output of components or simply storing data that is expensive to compute. It is currently the only tool that offers this sort of caching as a built-in. It also implements an argument parsing scheme that allows a component to specify the names, types and default values that it expects to be passed, either from another component or from the values passed in the URI query string.

While the documentation mostly demonstrates a callback execution model, it is possible to use Mason in a pipeline style. This can be accomplished in various ways, including building special components called ``autohandlers,'' which run before anything else for requests within a certain directory tree. An autohandler could do some processing and set up data for a display template that includes only minimal in-line Perl. There is also support for an object-oriented site approach, applying concepts such as inheritance to the site directory structure. For example, the autohandler component at /store/book/ might inherit a standard layout from the autohandler at /store/, but override the background color and navigation bar. Then /store/music/ can do the same, with a different color. This can be a powerful paradigm for developing large sites. Note that this inheritance is only supported at the level of methods defined in autohandler components. You can't override the component /store/foo.html with another one at /store/book/foo.html.

Mason's approach to debugging is to create ``debug files'' that run Mason outside of a Web server environment, providing a fake Web request and activating the debugger. This can be helpful if you're having trouble getting Apache::DB to behave under mod_perl, or using an execution environment that doesn't provide built-in debugger support.

Another unique feature is the ability to leave the static text parts of a large template on disk, and pull them in with a file seek when needed rather than keeping them in RAM. This exchanges some speed for a significant savings in memory when dealing with templates that are mostly static text.

There are many other features in this package, including filtering of HTML output and a page previewing utility. Session support is not built-in, but a simple example showing how to integrate with Apache::Session is included. Mason's feature set can be a bit overwhelming for newbies, but the high-quality documentation and helpful user community go a long way.

HTML::Embperl

http://perl.apache.org/embperl/

Embperl makes its language choice known up front: embedded perl. It is one of the most popular in-line Perl templating tools and has been around longer than most of the others. It has a solid reputation for speed and ease of use.

It is commonly used in a callback style, with Embperl intercepting URIs and processing the requested file. However, it can optionally be invoked through a subroutine call from another program, allowing it to be used in a pipeline style. Templates are compiled to Perl bytecode and cached.

Embperl has been around long enough to build an impressive list of features. It has the ability to run code inside a Safe compartment, support for automatically cleaning globals to make mod_perl coding easier, and extensive debugging tools including the ability to e-mail errors to an administrator.

The main thing that sets Embperl apart from other in-line Perl systems is its tight HTML integration. It can recognize TABLE tags and automatically iterate over them for the length of an array. It automatically provides sticky form widgets. An array or hash reference placed at the end of a query string in an HREF or SRC attribute will be automatically expanded into query string ``name=value'' format. META HTTP-EQUIV tags are turned into true HTTP headers.

Another reason people like Embperl is that it makes some of the common tasks of Web application coding so simple. For example, all form data is always available just by reading the magic variable %fdat. Sessions are supported just as easily, by reading and writing to the magic %udat hash. There is also a hash for storing persistent application state. HTML-escaping is automatic (though it can be toggled on and off).

Embperl includes something called EmbperlObject, which allows you to apply OO concepts to your site hierarchy in a similar way to the autohandler and inheritance features of Mason, mentioned above. This is a convenient way to code sites with styles that vary by area, and is worth checking out. EmbperlObject includes the ability to do overrides on a file level. This means that you can have a directory like /store/music that overrides specific templates and inherits the rest from a parent directory.

One drawback of older versions of Embperl was the necessity to use built-in replacements for most of Perl's control structures like ``if'' and ``foreach'' when they are being wrapped around non-Perl sections. For example:

  [$ if ($foo) $]
    Looks like a foo!
  [$ else $]
    Nope, it's a bar.
  [$ endif $]

These may seem out of place in a system based around in-line Perl. As of version 1.2b2, it is possible to use Perl's standard syntax instead:

  [$ if ($foo) { $]
    Looks like a foo!
  [$ } else { $]
    Nope, it's a bar.
  [$ } $]

At the time of this writing, a new 2.x branch of Embperl is in beta testing. This includes some interesting features such as a more flexible parsing scheme that can be modified to users' tastes. It also supports direct use of the Perl debugger on Embperl templates and provides performance improvements.

Apache::AxKit

http://axkit.org/

AxKit is the first mod_perl page generation system to be built from the ground up around XML. Technically, AxKit is not a templating tool but rather a framework for stringing together different modules that generate and transform XML data. In fact, it can optionally use Template Toolkit as an XML transformation language. However, it deserves coverage here since it is also the home of some templating tools that are not represented elsewhere.

In its simplest form, AxKit maps XML files to XSL stylesheets that it can process using commonly available XSLT modules like XML::XSLT or XML::Sablotron. The rules for mapping a stylesheet to a request are flexible, and they can incorporate query strings, cookies and other attributes of the request. The idea is that you can use this feature to handle a wide variety of clients with differing display capabilities by choosing the right stylesheet.

Recognizing that not everyone is a fan of XSL's somewhat obtuse syntax, Matt Sergeant has provided an alternate stylesheet language called XPathScript. XPathScript allows you to write a stylesheet using text with embedded Perl code. This is similar to the other embedded Perl templating tools, but the focus is on using the built-in XPath functions for querying an XML document and manipulating the retrieved data. XPathScript can also be used in a declarative fashion, specifying the formatting of particular elements in the XML input. For example, this snippet will change all <foo> tags in an XML document to BAR in the output::

  <%
    $t->{'foo'}{pre}   = 'BAR';
    $t->{'foo'}{post}    = '';
    $t->{'foo'}{showtag} = 0;
  %>
  <%= apply_templates() %>

By using XPathScript's include function (which looks just like SSI), you can build libraries of useful transformations that use this technique.

This is all well and good if you have a bunch of XML files sitting on a disk somewhere, but what about dynamic content? AxKit handles this by allowing you to substitute a different data source for the default file-based one. This can include running some dynamic code on each request to generate the XML data that will be transformed. The distribution includes a module for doing this called XSP. XSP is a language for building an XML DOM using in-line Perl and tag libraries. The tag libraries are specified as stylesheets that can turn XML tags into Perl code. This is demonstrated through the included SQL tag library, which allows you to write an XSP page using XML tags that will connect to a database, execute queries and generate an XML document with the results.

AxKit has some nice performance boosts built into it. It can cache the full output of a page and serve it as a static file on future requests. It can also compress output to speed up downloads for browsers that understand gzip encoding. These can be done with other systems, but they require you to setup additional software. With AxKit, you just enable them in the configuration file.

If all of these languages, tag libraries and stylesheets sound intimidating to you, AxKit may be overkill for your project. However, AxKit has the advantage of being built on approved W3C standards, and many of the skills used in developing for it carry over to other languages and tools.

Apache::ASP

http://www.apache-asp.org/

Apache::ASP started as a port of Microsoft's Active Server Pages technology, and its basic design still follows that model. It uses in-line Perl with a compilation approach and provides a set of simple objects for accessing the request information and formulating a response. Scripts written for Microsoft's ASP using Perl (via ActiveState's PerlScript) can usually be run on this system without changes. (Pages written in VBScript are not supported.)

Like the original ASP, it has hooks for calling specified code when certain events are triggered, such as the start of a new user session. It also provides the same easy-to-use state and session management. Storing and retrieving state data for a whole application or a specific user is as simple as a single method call. It can even support user sessions without cookies -- a unique feature among these systems.

A significant addition that did not come from Microsoft ASP is the XML and XSLT support. There are two options provided: XMLSubs and XSLT transforms. XMLSubs is a way of adding custom tags to your pages. It maps XML tags to your subroutines, so that you can add something like <site:header page="Page Title" /> to your pages and have it translate into a subroutine call like &site::header({title => "Page Title"}). It can handle processing XML tags with body text as well.

The XSLT support allows the output of ASP scripts to be filtered through XSLT for presentation. This allows your ASP scripts to generate XML data and then format that data with a separate XSL stylesheet. This support is provided through integration with the XML::XSLT module.

Apache::ASP provides sticky widgets for forms through the use of the HTML::FillInForm module. It also has built-in support for removing extra whitespace from generated output, gzip compressing output (for browsers that support it), tracking performance using Time::HiRes, automatically mailing error messages to an administrator and many other conveniences and tuning options. This is a mature package that has evolved to handle real-world problems.

One thing to note about the session and state management in this system is that it currently only supports clusters through the use of network file systems such as NFS or SMB. (Joshua Chamas, the module's author, has reported much better results from Samba file sharing than from NFS.) This may be an issue for large-scale server clusters, which usually rely on a relational database for network storage of sessions. Support for database storage of sessions is planned in a future release. In the meantime, instructions are provided for hooking up to Apache::Session.

Text::Template

http://search.cpan.org/search?dist=Text-Template

This module has become the de facto standard general purpose templating module on CPAN. It has an easy interface and thorough documentation. The examples in the docs show a pipeline execution style, but it's easy to write a mod_perl handler that directly invokes templates, allowing a callback style. The module uses in-line Perl. It has the ability to run the in-line code in a Safe compartment, in case you are concerned about mistakes in the code crashing your server.

The module relies on creative uses of in-line code to provide things that people usually expect from templating tools, like includes. This can be good or bad. For example, to include a file you could just call Text::Template::fill_in_file(filename). However, you'll have to specify the complete file path and nothing will stop you from using /etc/passwd as the file to be included. Most of the fancier templating tools have concepts like include paths, which allow you to specify a list of directories to search for included files. You could write a subroutine that works this way, and make it available in your template's namespace, but it's not built in.

Each template is loaded as a separate object. Templates are compiled to Perl and only parsed the first time they are used. However, to take full advantage of this caching in a persistent environment like mod_perl, your program will have to keep track of which templates have been used, since Text::Template does not have a way of globally tracking this and returning cached templates when possible.

Text::Template is not tied to HTML, and is just a templating module, not a Web application framework. It is perfectly at home generating e-mails, PDFs, etc.

Template Toolkit

http://template-toolkit.org/

One of the more recent additions to the templating scene, Template Toolkit, is a flexible mini-language system. It has a complete set of directives for working with data, including loops and conditionals, and it can be extended in a number of ways. In-line Perl code can be enabled with a configuration option, but is generally discouraged. It uses compilation, caching the compiled bytecode in memory and optionally caching the generated Perl code for templates on disk. Although it is commonly used in a pipeline style, the included Apache::Template module allows templates to be invoked directly from URLs.

Template Toolkit has a large feature set, so we'll only be able cover some of the highlights here. The TT distribution sets a gold standard for documentation thoroughness and quality, so it's easy to learn more if you choose to.

One major difference between TT and other systems is that it provides simple access to complex data structures through the concept of a dot operator. This allows people who don't know Perl to access nested lists and hashes or call object methods. For example, we could pass in this Perl data structure:

  $vars = {
           customer => {
                        name    => 'Bubbles',
                        address => {
                                    city => 'Townsville',
                                   }
                       }
          };

Then we can refer to the nested data in the template:

  Hi there, [% customer.name %]!
  How are things in [% customer.address.city %]?

This is simpler and more uniform than the equivalent syntax in Perl. If we pass in an object as part of the data structure, we can use the same notation to call methods within that object. If you've modeled your system's data as a set of objects, this can be convenient.

Templates can define macros and include other templates, and parameters can be passed to either. Included templates can optionally localize their variables so that changes made while the included template is executing do not affect the values of variables in the larger scope.

There is a filter directive, which can be used for post-processing output. Uses for this range from simple HTML entity conversion to automatic truncation (useful for pulldown menus when you want to limit the size of entries) and printing to STDERR.

TT supports a plugin API, which can be used to add extra capabilities to your templates. The provided plug-ins can be broadly organized into data access and formatting. Standard data access plugins include modules for accessing XML data or a DBI data source and using that data within your template. There's a plugin for access to CGI.pm as well.

Formatting plug-ins allow you to display things like dates and prices in a localized style. There's also a table plugin for use in displaying lists in a multi-column format. These formatting plug-ins do a good job of covering the final 5 percent of data display problems that often cause people who are using an in-house system to embed a little bit of HTML in their Perl modules.

In a similar vein, TT includes some nice convenience features for template writers, including eliminating white space around tags and the ability to change the tag delimiters -- things that may sound a little esoteric, but can sometimes make templates significantly easier to use.

The TT distribution also includes a script called ttree, which allows for processing an entire directory tree of templates. This is useful for sites that pre-publish their templated pages and serve them statically. The script checks modification times and only updates pages that require it, providing a make-like functionality. The distribution also includes a sample set of template-driven HTML widgets that can be used to give a consistent look and feel to a collection of documents.

HTML::Template

http://search.cpan.org/search?dist=HTML-Template

HTML::Template is a popular module among those looking to use a mini-language rather than in-line Perl. It uses a simple set of tags that allow looping (even on nested data structures) and conditionals in addition to basic value insertion. The tags are intentionally styled to look like HTML tags, which may be useful for some situations.

As the documentation says, it ``does just one thing and it does quickly and carefully'' -- there is no attempt to add application features like form-handling or session tracking. The module follows a pipeline execution style. Parsed templates are stored in a Perl data structure that can be cached in any combination of memory, shared memory (using IPC::SharedCache) and disk. The documentation is complete and well-written, with plenty of examples.

You may be wondering how this module is different from Template Toolkit, the other popular mini-language system. Beyond the obvious differences in syntax, HTML::Template is faster and simpler, while Template Toolkit has more advanced features, like plug-ins and dot notation. Here's a simple example comparing the syntax:

HTML::Template:

  <TMPL_LOOP list>
      <a href="<TMPL_VAR url>"><b><TMPL_VAR name></b></A>
  </TMPL_LOOP>

Template Toolkit:

  [% FOREACH list %]
      <a href="[% url %]"><b>[% name %]</a></a>
  [% END %]

And now, a few honorable mentions:

HTML_Tree

http://homepage.mac.com/pauljlucas/software/html_tree/

As mentioned earlier, HTML Tree uses a fairly unique method of templating: it loads in an HTML page, parses it to a DOM and then programmatically modifies the contents of nodes. This allows it to use genuine valid HTML documents as templates, something that none of these other modules can do. The learning curve is a little steeper than average, but this may be just the thing if you are concerned about keeping things simple for your HTML coders. Note that the name is ``HTML_Tree,'' not ``HTML::Tree.''

Apache::XPP

http://search.cpan.org/~cnation/Apache-XPP-2.02

XPP is an in-line Perl system that compiles to bytecode. Although it is a perfectly good implementation, it has little to differentiate it except for an easy mechanism to define new HTML-like tags that can be used to replace in-line code in templates.

ePerl

http://search.cpan.org/search?dist=Apache-ePerl

Possibly the first module to embed Perl code in a text or HTML file, ePerl is still a viable option in the form of Apache::ePerl. It caches compiled bytecode in memory to achieve solid performance, and some people find it refreshingly simple to use.

CGI::FastTemplate

http://search.cpan.org/search?dist=CGI-FastTemplate

This module takes a minimalistic approach to templating, which makes it unusually well-suited to use in CGI programs. It parses templates with a single regular expression and does not support anything in templates beyond simple variable interpolation. Loops are handled by including the output of other templates. Unfortunately, this leads to a Perl coding style that is more confusing than most, and a proliferation of template files. However, some people swear by this dirt-simple approach.

Performance

People always seem to worry about the performance of templating systems. If you've ever built a large-scale application, you should have enough perspective on the relative costs of different actions to know that your templating system is not the first place to look for performance gains. All of the systems mentioned here have excellent performance characteristics in persistent execution environments like mod_perl. Compared to such glacially slow operations as fetching data from a database or file, the time added by the templating system is almost negligible.

If you think your templating system is slowing you down, get the facts: pull out Devel::DProf and see. If one of the tools mentioned here is at the top of the list for wall clock time used, you should pat yourself on the back -- you've done a great job tuning your system and removing bottlenecks! Personally, I have only seen this happen when I had managed to successfully cache nearly every part of the work to handle a request except running a template.

However, if you really are in a situation where you need to squeeze a few extra microseconds out of your page generation time, there are performance differences between systems. They're pretty much what you would expect: systems that do the least run the fastest. Using in-line print() statements is faster than using templates. Using simple substitution is faster than using in-line Perl code. Using in-line Perl code is faster than using a mini-language.

The only templating benchmark available at this time is one developed by Joshua Chamas, author of Apache::ASP. It includes a ``hello world'' test, which simply checks how fast each system can spit back those famous words, and a ``hello 2000'' test, which exercises the basic functions used in most dynamic pages. It is available from the following URL:

http://www.chamas.com/bench/

Results from this benchmark currently show SSI, Apache::ASP and HTML::Embperl having the best performance. Not all of the systems mentioned here are currently included in the test. If your favorite was missed, you might want to download the benchmark code and add it. As you can imagine, benchmarking people's pet projects is largely a thankless task and Joshua deserves some recognition and support for this contribution to the community.

CGI Performance Concerns

If you're running under CGI, you have bigger fish to fry than worrying about the performance of your templating system. Nevertheless, some people are stuck with CGI but still want to use a templating system with reasonable performance. CGI is a tricky situation, since you have to worry about how much time it will take for Perl to compile the code for a large templating system on each request. CGI also breaks the in-memory caching of templates used by most of these systems, although the slower disk-based caching provided by Mason, HTML::Template and Template Toolkit will still work. (HTML::Template does provide a shared memory cache for templates, which may improve performance, although shared memory on my Linux system is usually slower than using the filesystem. Benchmarks and additional information are welcome.)

Your best performance bet with CGI is to use one of the simpler tools, like CGI::FastTemplate or Text::Template. They are small and compile quickly, and CGI::FastTemplate gets an extra boost since it relies on simple regex parsing and doesn't need to eval any in-line Perl code. Almost everything else mentioned here will add tenths of seconds to each page in compilation time alone.

Matrix

To help you choose a system, I'll summarize the basic characteristics of the major systems along the decision points I've explained in the beginning of the article. Keep in mind that in many cases a system can be used in more than one way, and I've simply shown the dominant method as seen in the documentation and real world use. You should not eliminate options based on this chart without reading the more detailed explanations above.

 | Application Framework | Pipeline or Callback | Parsing Method | Language
HTML::Mason | Framework | Callback | Compiled | Perl
Template Toolkit | Just Templates | Pipeline | Compiled | Mini-Language
Apache::ASP | Framework | Callback | Compiled | Perl and XSL
HTML::Embperl | Framework | Callback | Compiled | Perl
SSI | Just Templates | Callback | Repeated Parse | Mini-Language
AxKit | Framework | Pipeline | Compiled or Cached Parse Tree | Perl and XSL and Mini-Language(s)
HTML::Template | Just Templates | Pipeline | Cached Parse Tree | Mini-Language
Text::Template | Just Templates | Pipeline | Compiled | Perl

Updates

These modules are moving targets, and a document like this is bound to contain some mistakes. Send your corrections to perrin@elem.com. Future versions of this document will be announced on the mod_perl mailing list, and possibly other popular Perl locations.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: An Introduction to Testing

Published on Perl.com
http://www.perl.com/pub/a/2001/12/04/testing.html
See this if you're having trouble printing code examples

An Introduction to Testing
By chromatic

Someday, you'll be dubiously blessed with the job of maintenance programming. You might need to add new features or to fix long-standing bugs. The code may be your own or the apparently disturbed mutterings of a long-disappeared agent of chaos. If you haven't yet been this fortunate, then download a Perl CGI script circa 1996 and try to make it operate under use strict, warnings and taint mode.

Maintenance is rarely pretty, mixing forensics, psychology and playing-card house construction. Complicating the matter are concerns such as backward compatibility, portability and interoperability. You'll probably hate the learning experience, but don't miss the chance to learn some important lessons:

  • Software spends more time being maintained than being developed.
  • Things that were obvious in development are easily obscured.
  • Fixing bugs is easier than finding them and making sure nothing else breaks.
  • The real cost of software is programmer time and effort, not length of code, licenses or required hardware.

These rules have been well-established since the early days (think Grace Hopper) of software engineering. Good practices remain the same: Write good comments, document your assumptions and logic, test your code to death, test it again.

Every serious software engineering methodology promotes testing. It is essential to newer approaches, like Extreme Programming. A comprehensive test suite helps to verify that the code performs as expected, helps to minimize the scope of future modifications, and frees developers to improve the structure and design of code without changing its behavior. Yes, this can actually work.

Caveats

Experienced readers (especially those with strong math backgrounds) rightly note that testing cannot prove the absence of bugs. If it's theoretically impossible to write a non-trivial program with zero defects, it's impossible to write enough tests to prove that the program works completely. Programmers try to write bug-free code anyway, so why not test anything and everything possible? A tested program may have unknown bugs, but an untested program will.

Of course, some things are truly untestable. This category includes the ``black boxes,'' such as other processes and machines, and system libraries. More things are testable than not, though. Perl allows good programmers to perform scary black magic, including system table and run-time manipulations. It's possible to create your own fake little world just to satisfy a testable interface. A little megalomania can be handy.

Testing can be difficult. A wad of code with minimal documentation -- a design from the Perl 4 days -- and business logic that relies on prayer, global variables and animal sacrifice may push you to new heights of productivity, or teach you how to manage programmers. If you don't fix it now, then when do you fix it? Extreme Programming recommends revising untestable code to make it easier to maintain and to test. Sometimes, you must write simple tests, rework the code slightly, and iterate until it's palatable.

Don't let the enormity of the task get you down. If you can write Perl code worth testing, then you can write tests.

How Perl Module Testing Works

This section assumes you're already familiar with perlmodinstall, having installed a module manually. After the perl Makefile.PL and make stages, make test runs any tests shipped with the module, either test.pl or all files in the t/ directory that end in ``.t.'' The blib/ directories are added to @INC, and Test::Harness runs the test files, captures their output and provides a short summary of the results, including success and failure.

At its heart, a test either prints ``ok'' or ``not ok.'' That's it. Any test program or testing framework that prints results to standard output can use Test::Harness. If you're feeling epistemological (a good trait to cultivate for writing tests), you could ask ``What is truth?'':

        print "1..1\n";

        if (1) {
                print "ok\n";
        } else {
                print "not ok\n";
        }

Basic? Yes. Bogus? Not really. This is a variant of an actual Perl core test. If you understood that code, then you can write tests. Ignoring the first line for now, simply stick it in a file (truth.t) and run either the command line:

        perl -MTest::Harness -e "runtests 'truth.t'";

or the program:

        #!/usr/bin/perl -w

        use strict;
        use Test::Harness;

        runtests 'truth.t';

This should produce a message saying that all tests succeeded. If not, then something is broken, and many people would be interested in fixing it.

The first line of the test corresponds to Test::Harness' handy test-numbering feature. The harness needs to know how many tests to expect, and each individual test within a group can have its own number. This is for your benefit. If one test in a 100 mysteriously fails, then it's much easier to track down number 93 than it is to run through the debugger, comment out large swaths of the test suite or rely on intuitively placed print statements.

Knowing truth is good, and so is discerning falsehood. Let's extend truth.t slightly. Note the addition of test numbers to each potential printable line. This is both a boon and a bane.

        print "1..2\n";

        if (1) {
                print "ok 1\n";
        } else {
                print "not ok 1\n";
        }

        if (0) {
                print "not ok 2\n";
        } else {
                print "ok 2\n";
        }

Besides the increasingly duplicate code, keeping test numbers synchronized is painful. False laziness is painful -- Test::Harness emits warnings if the number of actual tests run does not meet its expectations. Test writers may not mind, but spurious warnings will confuse end users and healthily lazy developers. As a rule, the simpler the output, the more people will believe that things succeeded. The stuffed, smiling Pikachu (hey, it was a birthday present from an attractive female Web designer) perched atop my monitor makes me think that a giant yellow smiley face would be even better than a simple ``ok'' message. ASCII artists, fire up your editors!

Unfortunately, the truth test is repetitive and fragile. Adding a third test between the first two (the progression from ``truth'' to ``hidden truth'' to ``falsehood'' makes sense) means duplicating the if/else block and renumbering the previously second test. There's also room for a subtle bug:

        print "1..2\n";

        if (1) {
                print "ok 1\n";
        } else {
                print "not ok 1\n";
        }

        if ('0 but true') {
                print "ok 2\n";
        } else {
                print "not ok 2\n";
        }

        if (0) {
                print "not ok 3\n";
        } else {
                print "ok 3\n";
        }

Forgetting to update the first line is common. Two tests were expected; three tests ran. The confused Test::Harness will report strange things, like negative failure percentages. Baby Pikachu may cry. Smarter programmers eventually apply good programming style, writing their own ok() functions:

        print "1..3\n";

        my $testnum = 1;
        sub ok {
                my $condition = shift;
                print $condition ? "ok $testnum\n" : "not ok $testnum\n";
                $testnum++;
        }

        ok( 1 );
        ok( '0 but true' );
        ok( ! 0 );

The lowest levels of the Perl core test suite use this approach. It's simpler to write and handles numbering almost automatically. It lacks some features, though, and is little easier to debug.

by chromatic

Enter Test::More

Several modules exist to make testing easier and almost enjoyable. Test ships with modern Perl distributions and plays well with Test::Harness. The Perl-Unit suite reimplements the popular JUnit framework in Perl. The rather new Test::More module adds several features beyond those of Test. (I admit a particular bias toward the latter, though these and other modules are fine choices.)

Test::More has its own ok() function, but it is rarely used in favor of more specific functions. is() compares two expressions. For example, testing an addition function is as simple as:

        is( add(2, 2), 4 );

This handles strings and numbers equally well. Since version 0.36, it also distinguishes between 0, '' (the empty string), and undef -- we hope.

like() applies a regular expression to a scalar. This is also useful for trapping fatal errors:

        $self->eat('garden salad'):

        eval { $self->write_article() };
        like( $@, qr/not enough sugar/ );

The second argument can be either a regular expression compiled with the qr// operator (introduced in Perl 5.005), or a string that resembles a regular expression. Modifiers are allowed. If you absolutely must rewrite the previous example to run on Perl 5.004 and to use StudlyCaps, then you can:

        eval { $self->write_article() };
        like( $@, '/NoT eNoUgH sUgAr/i' );

That's too cute/hideous for a real test, but the regex form is completely valid.

Test::More Makes Debugging Nicer

That's useful enough already, but there's more to Test::More.

Test::More supports test numbering just as Test::Harness does, and automatically provides the numbers. This is a big win in two cases: where the test suite may accidentally fail (from a die() call, a segmentation fault, or spontaneous combustion), or if the tests can accidentally repeat (due to an improper chdir(), unexpected input in a loop condition, or a time warp). Test::Harness is happy to warn whether the number of tests actually run do not match its expectations. You just have to tell it how many should run. This is usually done when using Test::More:

        use Test::More tests => 50;

When writing new tests, you may not know how many there will be. Use the no_plan option:

        use Test::More 'no_plan';

Extreme Programming recommends this game-like approach: add a test, run it, write code to pass the test, repeat. When you've finished, update the use line to reflect the actual number of tests.

Test::More also handles failures gracefully. Given the following file with a final, doomed test:

        use Test::More tests => 4;

        is( 1, 1 );
        is( !0, 1 );
        is( 0, 0 );
        is( undef, 1 );

Test::More run on its own, not through Test::Harness, produces:

        1..4
        ok 1
        ok 2
        ok 3
        not ok 4
        #     Failed test (numbers.t at line 6)
        #          got: undef
        #     expected: '1'
        # Looks like you failed 1 tests of 1.

The error message provides the name of the file containing the tests, the number of the failed test, the line number containing the failed test, and expected and received data. This makes for easier debugging. Count tests to find an error just once, and you'll prefer this approach.

Test::Harness also supports optional test comments attached to test messages. That is, it allows raw tests to say:

        print "ok 1 # the most basic test possible\n";

Nearly all Test::More functions support this as an optional parameter:

        ok( 1, 'the number 1 should evaluate to true' );
        is( 2 + "2", 4, 'numeric strings should numerify in addition' );
        like( 'abc', qr/z*/, '* quantifier should match zero elements' );

These names are required by nothing except social convention. Think of them as little test comments. If the test is wrong, or exposes a fixed bug that should never reoccur, then a descriptive name makes it clear what the test should be testing. Test::Harness silently eats the names, but they're present when run manually:

        ok 1 - the number 1 should evaluate to true
        ok 2 - numeric strings should numerify in addition
        ok 3 - * quantifier should match zero elements

Manual test runs make for improved bug reports. Ignore these convenient tools at your own peril.

Intermediate Test::More Features

If the previous features weren't enough, Test::More supports still more! One such is the notion of skippable tests. Occasionally, the presence or absence of certain criteria obviate the need to test a feature. Consider the qr// operator explained earlier. A module that needs to be backward compatible to Perl 5.004 can gradefully degrade its test suite with skippable tests:

        SKIP: {
                skip( 'qr// not supported in this version', 2 ) unless $] >= 5.005;

                my $foo = qr/i have a cat/;
                ok( 'i have a caterpillar' =~ $foo,
                        'compiled regex should match similar string' );

                ok( 'i have a cold' !~ $foo,
                        'compiled regex should not match dissimilar string' );
        }

There's a lot to digest. First, the skippable tests are contained in a labelled block. The label must be SKIP. (Don't worry: you can have several of these within a file.) Next, there should be a condition that governs whether to skip the tests. This example checks the special variable perlvar to find the current Perl version. skip() will only be called when run with an older version.

The skip() function always confuses me with its unique parameter order. The first argument is the name to display for each skipped test. The second argument is the number of tests to skip. This must match the number of tests within the block, at the risk of certain confusion. Run on Perl 5.004, the above test produces:

        ok 1 # skip qr// not supported in this version
        ok 2 # skip qr// not supported in this version

Though the message says ok, Test::Harness will see skip and report the tests as skipped, not passed. This should only be used for tests that absolutely will not run due to platform or version differences. For tests you just can't figure out yet, use todo().

Though everything is built on Test::Builder::ok(), other functions offer helpful shortcuts. use_ok() and require_ok load and optionally import the named file, reporting the success or error. These verify that a module can be found and compiled, and are often used for the first test in a suite. The can_ok() function attempts to resolve a class or an object method. isa_ok() checks inheritance:

        use_ok( 'My::Module' );
        require_ok( 'My::Module::Sequel' );

        my $foo = My::Module->new();
        can_ok( $foo->boo() );
        isa_ok( $foo, 'My::Module' );

They produce their own test names:

        ok 1 - use My::Module;
        ok 2 - require My::Module::Sequel;
        ok 3 - My::Myodule->can(boo)
        ok 4 - object->isa('My::Module')

Other functions and features are documented in the Test::More documentation. As well, the Test::Tutorial manpage explains similar things with a different wit.

Finally, do not forget good programming practices. Test functions are simply standard subroutines. Tests are just Perl code. Use loops, variables, helper subs, map(), and anything else, when they make things easier. For example, basic inherited interface testing can be made easier with:

        # see if IceCreamBar inherits these methods from Popsicle
        my $icb = IceCreamBar->new();

        foreach my $method (qw( fall_off_stick freeze_tongue drip_on_carpet )) {
                can_ok( $icb, $method, "IceCreamBar should be able to $method()" );
        }

That beats writing several individual can_ok() tests. Interpolating things into the test name is also handy.

Conclusion

Testing is unfortunately often neglected, especially among free software projects. Think of it as getting plenty of sleep, eating vegetables, and working out regularly. It may cramp your style at first, but will improve things immensely if you do it consistently. (Results may vary if you're adding tests to a huge system that doesn't have them, like, say, Perl itself.)

One goal of Perl is to make your life easier. Perl 5.8 will include Test::More and its hearty brethren, the Test::Simple manpage and the Test::Builder manpage. They exist to make writing tests less of a hassle, and even more pleasant. Consider them.

The easier it is to write and maintain tests, the more likely people will do it. More and better tests improve software portability, maintainability, and reliability. You may currently compare testing to broccoli, brussel sprouts, and wind sprints. Try Test::More or another framework, and you may grow to see them as oranges, sweet potatoes with marshmallows, and a trip to the sauna. It really is good for you.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Testing mod_perl 2.0

Published on Perl.com
http://www.perl.com/pub/a/2003/05/22/testing.html
See this if you're having trouble printing code examples

Testing mod_perl 2.0
By Geoffrey Young

Last time, we looked at writing a simple Apache output filter - Apache::Clean - using the mod_perl 2.0 API. How did I know that the filter I presented really worked? I wrote a test suite for it, one that exercised the code against a live Apache server using the Apache-Test testing framework.

Writing a series of tests that executes against a live Apache server has become much simpler since the advent of Apache-Test. Although Apache-Test, as part of the Apache HTTP Test Project, is generic enough to be used with virtually any version of Apache (with or without mod_perl enabled), it comes bundled with mod_perl 2.0, making it the tool of choice for writing tests for your mod_perl 2.0 modules.

Testing, Testing, 1, 2, 3

There are many advantages to writing tests. For instance, maintaining the test suite as I coded Apache::Clean allowed me to test each functional unit as I implemented it, which made development easier. The individual tests also allowed me to be fairly certain that the module would behave as expected once distributed. As an added bonus, tests offer additional end-user documentation in the form of test scripts, supporting libraries and configuration files, available to anyone who wants to snoop around the distribution a bit. All in all, having a test suite increases the value of your code exponentially, while at the same time making your life easier.

Of course, these benefits come from having any testing environment, and are not limited to just Apache-Test. The particular advantage that Apache-Test brings to the table is the ease at which it puts a whole, pristine, and isolated Apache server at your disposal, allowing you to test and exercise your code in a live environment with a minimum of effort. No more Apache::FakeRequest, no more httpd.conf configurations strewn across development environments or corrupted with proof-of-concept handlers that keep you busy following non-bugs for half a day. No more mess, no more tears.

If you have ever used tools like Test.pm or Test::More as the basis for testing your modules, then you already know most of what using Apache-Test is going to look like. In fact, Apache-Test uses Test.pm under the hood, so the layout and syntax are similar. If you have never written a test before, (and shame on you)then An Introduction to Testing provides a nice overview of testing with Perl. For the most part, though, Apache-Test is really simple enough that you should be able to follow along here without any trouble or previous knowledge.

Leveraging the Apache-Test framework requires only a few steps - generating the test harness, configuring Apache to your specific needs, and writing the tests - each of which is relatively straightforward.

Generating the Test Harness

The first step to using Apache-Test is to tweak the Makefile.PL for your module. If you don't yet have a Makefile.PL, or are not familiar with how to generate one, then don't worry - all that is required is a simple call to h2xs, which provides us with a standard platform both for distributing our module and deploying the Apache-Test infrastructure.

$ h2xs -AXPn Apache::Clean
Defaulting to backward compatibility with perl 5.9.0
If you intend this module to be compatible with earlier perl versions, then please
specify a minimum perl version with the -b option.

Writing Apache/Clean/Clean.pm
Writing Apache/Clean/Makefile.PL
Writing Apache/Clean/README
Writing Apache/Clean/t/1.t
Writing Apache/Clean/Changes
Writing Apache/Clean/MANIFEST

h2xs generates the necessary structure for our module, namely the Clean.pm template and the Makefile.PL, as well as the t/ subdirectory where our tests and supporting files will eventually live. You can take some extra steps and shuffle the distribution around a bit (such as removing t/1.t and putting everything into Apache-Clean/ instead of Apache/Clean/) but it is not required. Once you have the module layout sorted out and have replaced the generated Clean.pm stub with the actual Clean.pm filter from before, it's time to start preparing the basic test harness.

To begin, we need to modify the Makefile.PL significantly. The end result should look something like:

#!perl

use 5.008;

use Apache2 ();
use ModPerl::MM ();
use Apache::TestMM qw(test clean);
use Apache::TestRunPerl ();

# configure tests based on incoming arguments
Apache::TestMM::filter_args();

# provide the test harness
Apache::TestRunPerl->generate_script();

# now, write out the Makefile
ModPerl::MM::WriteMakefile(
  NAME      => 'Apache::Clean',
  VERSION   => '2.0',
  PREREQ_PM => { HTML::Clean      => 0.8,
                 mod_perl         => 1.9909, },
);

Let's take a moment to analyze our nonstandard Makefile.PL. We begin by importing a few new mod_perl 2.0 libraries. The first is Apache2.pm. In order to peacefully co-exist with mod_perl 1.0 installations, mod_perl 2.0 gives you the option of installing mod_perl relative to Apache2/ in your @INC, as to avoid collisions with 1.0 modules of the same name. For instance, the mod_perl 2.0 Apache::Filter we used to write our output filter interface would be installed as Apache2/Apache/Filter.pm. Of course, ordinary calls that require() or use() Apache::Filter in mod_perl 2.0 code would fail to find the correct version (if one was found at all), since it was installed in a nonstandard place. Apache2.pm extends @INC to include any (existing) Apache2/ directories so that use() and related statements work as intended. In our case, we need to use() Apache2 in order to ensure that, no matter how the end-user configured his mod_perl 2.0 installation, we can find the rest of the libraries we need.

Secure in the knowledge that our Makefile.PL will be able to find all our other mod_perl 2.0 packages (wherever they live), we can proceed. ModPerl::MM provides the WriteMakefile() function, which is similar to the ExtUtils::MakeMaker function of the same name and takes the same options. The reason that you will want to use the WriteMakefile() from ModPerl::MM is that, through means highly magical, all of your mod_perl-specific needs are satisfied. For instance, your module will be installed relative to Apache/ or Apache2/, depending on how mod_perl itself is installed. Other nice features are automatic inclusion of mod_perl's typemap and the header files required for XS-based modules, as well as magical cross-platform compatibility for Win32 compilation, which has been troublesome in the past.

Keep in mind that neither Apache2.pm nor ModPerl::MM are required in order to use Apache-Test - both are packages specific to mod_perl 2.0 and any handlers you may write for this version (as will be touched on later, Apache-Test can be used for mod_perl 1.0 based modules as well, or even Apache 1.3 or 2.0 modules independent of mod_perl, for that matter). The next package, Apache::TestMM, is where the real interface for Apache-Test begins.

Apache::TestMM, contains the functions we will need to configure the test harness. The first thing we do is import the test() and clean() functions, which generate their respective Makefile targets so that we can run (and re-run) our tests. After that, we call the filter_args() function. This allows us to configure various parts of our tests on the command line using different options, which will be discussed later.

The final part of our configuration uses the generate_script() method from the Apache::TestRunPerl class, which writes out the script responsible for running our tests, t/TEST. It is t/TEST that will be invoked when a user issues make test, although the script can be called directly as well. While t/TEST can end up containing lots of information, if you crack it open, then you would see that the engine that really drives the test suite is rather simple.

use Apache::TestRunPerl ();
Apache::TestRunPerl->new->run(@ARGV);

Believe it or not, the single call to run() does all intricate work of starting, configuring, and stopping Apache, as well as running the individual tests we (still) have yet to define.

Despite the long explanations, the net result of our activity thus far has been a few modifications to a typical Makefile.PL so that it reflects the needs of both our mod_perl 2.0 module and our forthcoming use of the Apache-Test infrastructure. Next, we need to configure Apache for the tests specific to the functionality in our handler.

Configuring Apache

Ordinarily, there are many things you need to stuff into httpd.conf in order to get the server responding to requests, only some of which are related to the content the server will provide. The Apache-Test framework provides a minimal Apache configuration, such as default DocumentRoot, ErrorLog, Listen, and other settings required for normal operation of the server. In fact, with no intervention on your part, Apache-Test provides a configuration that enables you to successfully request /index.html from the server. Chances are, though, that you will need something above a basic configuration in order to test your module appropriately.

To add additional settings to the defaults, we create the file t/conf/extra.conf.in, adding any required directories along the way. If Apache-Test sees extra.conf.in, then it would pull the file into its default configuration using an Include directive (after some manipulations we will discuss shortly). This provides a nice way of adding only the configuration data you require for your tests, and saves you from the need to worry about the mundane aspects of running the server.

One of the first aspects of Apache::Clean we should test is whether it can clean up a simple, static HTML file. So, we begin our extra.conf.in with the following:

PerlSwitches -w

Alias /level @DocumentRoot@
<Location /level>
  PerlOutputFilterHandler Apache::Clean
  PerlSetVar CleanLevel 2
</Location>

This activates our output filter for requests to /level. Note the introduction of a new directive, PerlSwitches, which allows you to pass command line switches to the embedded perl interpreter. Here, we use it to enable warnings, similar to the way that PerlWarn worked in mod_perl 1.0. PerlSwitches can actually take any perl command line switch, which makes it a fairly useful and flexible tool. For example, we could use the -I switch to extend @INC in place of adding use lib statements to a startup.pl, or use -T to enable taint mode in place of the former PerlTaintMode directive, which is not part of mod_perl 2.0.

Next, we come to the familiar Alias directive, albeit with a twist. As previously mentioned, Apache-Test configures several defaults, including DocumentRoot and ServerRoot. One of the nice features of Apache-Test is that it keeps track of its defaults for you and provides some helpful variable expansions. In my particular case, the @DocumentRoot@ variable in the Alias directive is replaced with the value of the default DocumentRoot that Apache-Test calculated for my build. The real configuration ends up looking like

Alias /level /src/perl.com/Apache-Clean-2.0/t/htdocs

when the tests are run. This is handy, especially when you take into consideration that your tests may run on different platforms.

The rest of the configuration closely resembles our example from last time - using the PerlOutputFilterHandler to specify Apache::Clean as our output filter, and PerlSetVar to specify the specific HTML::Clean level. The only thing missing before we have prepared our module enough to run our first test is some testable content in DocumentRoot.

As you can see from the @DocumentRoot@ expansion in the previous example, DocumentRoot resolves to ServerRoot/t/htdocs/, so that is one place where we can put any documents we are interested in retrieving for our tests. So, we create t/htdocs/index.html and place some useful content in it.

<i    ><strong>&quot;This is a test&quot;</strong></i   >

Our index.html contains a number of different elements that HTML::Clean can tidy, making it useful for testing various configurations of Apache::Clean.

Now we have all the Apache configuration that is required: some custom configuration directives in t/conf/extra.conf.in and some useful content in t/htdocs/index.html. All that is left to do is write the tests.

Writing the Tests

The Apache configuration we have created thus far provides a way to test Apache::Clean through /level/index.html. The result of this request should be that the default Apache content handler serves up index.html, applying our PerlOutputFilterHandler to the file before it is sent over the wire. Given the configured PerlSetVar CleanLevel 2 we would expect the end results of the request to be

<i><b>&quot;This is a test&quot;</b></i>

where tags are shortened and whitespace removed but the &quot; entity is left untouched. Well, maybe this is not what you would have expected, but cracking open the code for HTML::Clean reveals that level(2) includes the whitespace and shortertags options, but not the entities option. This brings us to the larger issue of test design and the possibility that flawed expectations can mask true bugs - when a test fails, is the bug in the test or in the code? - but that is a discussion for another time.

Given our configuration and expected results, we can craft a test that requests /level/index.html, isolates the content from the server response, then tests the content against our expectations. The file t/01level.t shown here does exactly that.

use strict;
use warnings FATAL => 'all';

use Apache::Test qw(plan ok have_lwp);
use Apache::TestRequest qw(GET);
use Apache::TestUtil qw(t_cmp);

plan tests => 1, have_lwp;

my $response = GET '/level/index.html';
chomp(my $content = $response->content);

ok ($content eq q!<i><b>&quot;This is a test&quot;</b></i>!);

t/01level.t illustrates a few of the things that will be common to most of the tests you will write. First, we do some bookkeeping and plan the number of tests that will be attempted using the plan() function from Apache::Test - in our case just one. The final, optional argument to plan() uses the have_lwp() function to check for the availability of the modules from the libwww-perl distribution. If have_lwp() returns true, then we know we can take advantage of the LWP shortcuts Apache::TestRequest provides. If have_lwp() returns false, then no tests are planned and the entire test is skipped at runtime.

After planning our test, we use the shortcut function GET() from Apache::TestRequest to issue a request to /level/index.html. GET() returns an HTTP::Response object, so if you are familiar with the LWP suite of modules you should feel right at home with what follows. Using the object in $response we isolate the server response using the content() method and compare it against our expected string. The comparison uses a call to ok(), which will report success if the two strings are equivalent.

Keep in mind that even though this example explicitly imported the plan(), ok(), have_lwp(), and GET() functions into our test script, that was just to illustrate the origins of the different parts of the test - each of these functions, along with just about all the others you may want, are exported by default. So, the typical test script will usually just call

use Apache::Test;
use Apache::TestRequest;

and go from there.

That is all there is to writing the test. In its simplest form, using Apache-Test involves pretty much the same steps as when writing tests using other Perl testing tools: plan() the number of tests in the script, do some stuff, and call ok() for each test you plan(). Apache-Test and its utility classes merely offer shortcuts that make writing tests against a running Apache server idiomatic.

Running the Tests

With all the preparation behind us - generating and customizing the Makefile.PL, configuring Apache with extra.conf.in, writing index.html and 01level.t - we have all the pieces in place and can (finally) run our test.

There are a few different ways we can run the tests in a distribution, but all require that we go through the standard build steps first.

$ perl Makefile.PL -apxs /usr/local/apache2/bin/apxs
Checking if your kit is complete ...
Looks good
Writing Makefile for Apache::Clean

$ make
cp Clean.pm blib/lib/Apache2/Apache/Clean.pm
Manifying blib/man3/Apache::Clean.3

Makefile.PL starts the process by generating the t/TEST script via the call to Apache::TestRunPerl->generate_script(). The additional argument we pass, -apxs, is trapped by Apache::TestMM::filter_args() and is used to specify the Apache installation we want to test our code against. Here, I use -apxs to specify the location of the apxs binary in my local Apache DSO installation - for static builds you will want to use -httpd to point to the httpd binary instead. By the time Makefile.PL exits, we have our test harness and know where our server lives.

Running make creates our build directory, blib/, and installs Clean.pm locally so we can use it in our tests. Note that ModPerl::MM installed Clean.pm relative to Apache2, magically following the path of my current mod_perl 2.0 installation.

At this point, we can run our tests. Issuing make test will run all the tests in t/, as you might expect. However, we can run our tests individually as well, which is particularly useful when debugging. To run a specific test we call t/TEST directly and give it the name of the test we are interested in.

$ t/TEST t/01level.t
*** setting ulimit to allow core files
ulimit -c unlimited; t/TEST 't/01level.t'
/usr/local/apache2/bin/httpd  -d /src/perl.com/Apache-Clean-2.0/t
    -f /src/perl.com/Apache-Clean-2.0/t/conf/httpd.conf
    -DAPACHE2 -DPERL_USEITHREADS
using Apache/2.1.0-dev (prefork MPM)

waiting for server to start: ..
waiting for server to start: ok (waited 1 secs)
server localhost:8529 started
01level....ok
All tests successful.
Files=1, Tests=1,  4 wallclock secs ( 3.15 cusr +  0.13 csys =  3.28 CPU)
*** server localhost:8529 shutdown

As you can see, the server was started, our test was run, the server was shutdown, and a report was generated - all with what is really minimal work on our part. Major kudos to the Apache-Test developers for making the development of live tests as easy as they are.

Beyond the Basics

What we have talked about so far is just the basics, and the framework is full of a number of different options designed to make writing and debugging tests easier. One of these is the Apache::TestUtil package, which provides a number of utility functions you can use in your tests. Probably the most helpful of these is t_cmp(), a simple equality testing function that also provides additional information when you run tests in verbose mode. For instance, after adding use Apache::TestUtil; to our 01level.t test, we can alter the call to ok() to look like

ok t_cmp(q!<i><b>&quot;This is a test&quot;</b></i>!, $content);

and the result would include expected and received notices (in addition to standard verbose output)

$ t/TEST t/01level.t -v
[lines snipped]
01level....1..1
# Running under perl version 5.009 for linux
# Current time local: Mon May  5 11:04:09 2003
# Current time GMT:   Mon May  5 15:04:09 2003
# Using Test.pm version 1.24
# expected: <i><b>&quot;This is a test&quot;</b></i>
# received: <i><b>&quot;This is a test&quot;</b></i>
ok 1
ok
All tests successful.

which is particularly helpful when debugging problems reported by end users of your code. See the Apache::TestUtil manpage for a long list of helper functions, as well as the README in the Apache-Test distribution for additional command line options over and above -v.

Of course, 01level.t only tests one aspect of our Clean.pm output filter, and there is much more functionality in the filter that we might want verify. So, let's take a quick look at some of the other tests that accompany the Apache::Clean distribution.

One of the features of Apache::Clean is that it automatically declines processing non-HTML documents. The logic for this was defined in just a few lines at the start of our filter.

# we only process HTML documents
unless ($r->content_type =~ m!text/html!i) {
  $log->info('skipping request to ', $r->uri, ' (not an HTML document)');

  return Apache::DECLINED;
}

A good test for this code would be verifying that content from a plain-text document does indeed pass through our filter unaltered, even if it has HTML tags that HTML::Clean would ordinary manipulate. Our test suite includes a file t/htdocs/index.txt whose content is identical to the index.html file we created earlier. Remembering that we already have an Apache configuration for /level that inserts our filter into the request cycle, we can use a request for /level/index.txt to test the decline logic.

use Apache::Test;
use Apache::TestRequest;

plan tests => 1, have_lwp;

my $response = GET '/level/index.txt';
chomp(my $content = $response->content);

ok ($content eq q!<i><strong>&quot;This is a test&quot;</strong></i>!);

It may be obvious, but if you think about what we are really testing here it is not that the content is unaltered - that is just what we use to measure the success of our test. The real test is against the criterion that determines whether the filter acts on the content. If we wanted to be really thorough, then we could add

AddDefaultCharset On

to our extra.conf.in to test the Content-Type logic against headers that look like text/html; charset=iso-8859-1 instead of just text/html. I actually have had more than one person comment that using a regular expression for testing the Content-Type is excessive - adding the AddDefaultCharset On directive shows that the regex logic can handle more runtime environments than a simple $r->content_type eq 'text/html' check. Oh, the bugs you will find, fix, and defend when you start writing tests.

More and More Tests

What other aspects of the filter can we put to the test? If you recall from our discussion of output filters last time, one of the responsibilities of filters that alter content is to remove the generated Content-Length header from the server response. The relevant code for this in our filter was as follows.

# output filters that alter content are responsible for removing
# the Content-Length header, but we only need to do this once.
$r->headers_out->unset('Content-Length');

Here is the test for this bit of logic, which checks that the Content-Length header is indeed present for plain documents, but removed by our filter for HTML documents. Again, we will be using the existing /level URI to request both index.txt and index.html.

use Apache::Test;
use Apache::TestRequest;

plan tests => 2, have_lwp;

my $response = GET '/level/index.txt';
ok ($response->content_length == 58);

$response = GET '/level/index.html';
ok (! $response->content_length);

Note the use of the content_length() method on our HTTP::Response object to retrieve the Content-Length of the server response. Remember that you have all the methods from that class to choose from in your tests.

The final test we will take a look at is the example we used previous time to illustrate our filter does indeed co-exist with both mod_include and mod_cgi. As it turns out, the example was taken right from the test suite (always a good place from which to draw examples). Here is the extra.conf.in snippet.

Alias /cgi-bin @ServerRoot@/cgi-bin
<Location /cgi-bin>
  SetHandler cgi-script

  SetOutputFilter INCLUDES
  PerlOutputFilterHandler Apache::Clean

  PerlSetVar CleanOption shortertags
  PerlAddVar CleanOption whitespace
  Options +ExecCGI +Includes
</Location>

The nature of our test requires that both mod_include and a suitable CGI platform (either mod_cgi or mod_cgid) be available to Apache - without both of these, our tests are doomed to failure, so we need a way to test whether these modules are available to the server before planning the individual tests. Also required are some CGI scripts, the location of which is specified by expanding @ServerRoot@. To include these scripts, we could just create a t/cgi-bin/ directory and place the relevant files in it. However, any CGI scripts we create would probably include a platform-specific shebang line like #!/usr/bin/perl. A better solution is to generate the scripts on-the-fly, specifying a shebang line that matches the version of Perl we are using to build and test the module.

Despite the extra work required, the test script used for this test is only a bit more complex than others we have seen so far.

use Apache::Test;
use Apache::TestRequest;
use Apache::TestUtil qw(t_write_perl_script);

use File::Spec::Functions qw(catfile);

plan tests => 4, (have_lwp &&
                  have_cgi &&
                  have_module('include'));

my @lines = <DATA>;
t_write_perl_script(catfile(qw(cgi-bin plain.cgi)), @lines[0,2]);
t_write_perl_script(catfile(qw(cgi-bin include.cgi)), @lines[1,2]);

my $response = GET '/cgi-bin/plain.cgi';
chomp(my $content = $response->content);

ok ($content eq q!<strong>/cgi-bin/plain.cgi</strong>!);
ok ($response->content_type =~ m!text/plain!);

$response = GET '/cgi-bin/include.cgi';
chomp($content = $response->content);

ok ($content eq q!<b>/cgi-bin/include.cgi</b>!);
ok ($response->content_type =~ m!text/html!);

__END__
print "Content-Type: text/plain\n\n";
print "Content-Type: text/html\n\n";
print '<strong><!--#echo var="DOCUMENT_URI" --></strong>';

The first thing to note is that we have joined the familiar call to have_lwp() with additional calls to have_cgi() and have_module(). The Apache::Test package comes with a number of handy shortcuts for querying the server for information. have_cgi() returns true if either mod_cgi or mod_cgid are installed. have_module() is more generic and can be used to test for either Apache C modules or Perl modules - for instance, have_module('Template') could be used to check whether the Template Toolkit is installed.

For generation of the CGI scripts, we use the t_write_perl_script() function from the Apache::TestUtil package. t_write_perl_script() takes two arguments, the first of which is the name of the file to generate, relative to the t/ directory in the distribution. If the file includes a path, any necessary directories are automatically created. In the interests of portability, we use catfile() from the File::Spec::Functions package to join the file with the directory. In general, you will want to keep File::Spec and its associated classes in mind when writing your tests - you never know when somebody is going to try and run them on Win32 or VMS. The second argument to t_write_perl_script() is a list of lines to append to the file after the (calculated) shebang line.

Although t_write_perl_script() cleans up any generated files and directories when the test completes, if we were to intercept include.cgi before removal it would look similar to something we would have written ourselves.

#!/src/bleedperl/bin/perl
# WARNING: this file is generated, do not edit
# 01: /src/bleedperl/lib/site_perl/5.9.0/i686-linux-thread-multi/
      Apache/TestUtil.pm:129
# 02: 06mod_cgi.t:18
print "Content-Type: text/html\n\n";
print '<strong><!--#echo var="DOCUMENT_URI" --></strong>';

As you probably have guessed by now, just as we ran tests against scripts in the (generated) t/cgi-bin/ directory, we can add other directories to t/ for other kinds of tests. For instance, we can create t/perl-bin/ to hold standard ModPerl::Registry scripts (remember, you don't need to generate a shebang line for those). We can even create t/My/ to hold a custom My::ContentGenerator handler, which can be used just like any other Perl module during Apache's runtime. All in all, you can simulate practically any production environment imaginable.

But Wait, There's More!

The tests presented here should be enough to get you started writing tests for your own modules, but they are only part of the story. If you are interested in seeing some of the other tests written to support this article, the Apache::Clean distribution is full of all kinds of different tests and test approaches, including some that integrate custom handlers as well as one that tests the POD syntax for the module. In fact, you will find 26 different tests in 12 test files there, free for the taking.

Stuck using mod_perl 1.0? One of the best things about Apache-Test is that it is flexible and intelligent enough to be used for mod_perl 1.0 handlers as well. In fact, the recent release of Apache-Test as a CPAN module outside of the mod_perl 2.0 distribution makes it even easier for all mod_perl developers to take advantage of the framework. For the most part, the instructions in this article should be enough to get you going writing tests for 1.0-based modules - the only changes specific to 1.0 modules rest in the Makefile.PL. I took the time to whip up a version of Apache::Clean for mod_perl 1.0 that parallels the functionality in these articles, which you can find next to the 2.0 version. The 1.0 distribution runs against the exact same *.t files (where applicable) and includes a sample 1.0 Makefile.PL.

Personally, I don't know how I ever got along without Apache-Test, and I'm sure that once you start using it you will feel the same. Secretly, I'm hoping that Apache-Test becomes so popular that end-users start wrapping their bug reports up in little, self-contained, Apache-Test-based tarballs so anyone can reproduce the problem.

More Information

This article was derived from Recipe 7.7 in the mod_perl Developer's Cookbook, adjusted to accommodate both mod_perl 2.0 and changes in the overall Apache-Test interface that have happened since publication. Despite these differences, the recipe is useful for its additional descriptions and coverage of features not discussed here. You can read Recipe 7.7, as well as the rest of Chapter 7 from the book's website. Also, in addition to the Apache-Test manpage and README there is also the Apache-Test tutorial on the mod_perl Project website, all of which are valuable sources of information.

Thanks

The Apache-Test project is the result of the tireless efforts of many, many developers - far too many to name individually here. However, there has has been a recent surge of activity as Apache-Test made its way to CPAN, especially in making it more platform aware and solving a few back compatibility problems with the old Apache::test that ships with mod_perl 1.0. Special thanks are due to Stas Bekman, David Wheeler, and Randy Kobes for helping to polish Apache-Test on Win32 and Mac OS X without requiring major changes to the API.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Published on Perl.com
http://www.perl.com/pub/a/2003/05/29/treasures.html
See this if you're having trouble printing code examples

Hidden Treasures of the Perl Core
By Casey West

The Perl Core comes with a lot of little modules to help you get thejob done. Many of these modules are not well-known. Even some of the well-known modules have some nice features that are often overlooked. In this article, we'll dive into many of these hidden treasures of the Perl Core.

blib

This module allows you to use MakeMakers to-be-installed version of a package. Most of the distributions on the CPAN conform to MakeMakers building techniques. If you are writing a Perl module that has a build system, then there would be a good chance MakeMaker is involved. Testing on the command line is common; I know I find myself doing it often. This is one of the places that blib comes in handy. When running my test suite (you all have test suites, right?) on the command line, I'm able to execute individual tests easily.

  perl -Mblib t/deepmagic.t

If you are building someone elses module and find yourself debugging a testing failure, then blib could be used the same way.

diagnostics

PC Load Letter, what the frell does that mean?! -- Micheal Bolton

When pushed hard enough, the Perl interpreter can spew out hundreds of error messages. Some of them can be quite cryptic. Running the following code snippet under the warnings pragma yields the warning Unterminated <> operator at program.perl line 11.

  $i <<< $j;

Thankfully, diagnostics is an easy way to get a better explanation from Perl. Since we're all running our important programs under the strict and warnings pragmas, it's easy to add diagnostics to the mix.

  use strict;
  use warnings;
  use diagnostics;

The previous code snippet now yields the following warning:

  Unterminated <> operator at -e line 1 (#1)
    (F) The lexer saw a left-angle bracket in a place where it was expecting
    a term, so it's looking for the corresponding right-angle bracket, and
    not finding it.  Chances are you left some needed parentheses out
    earlier in the line, and you really meant a "less than".

  Uncaught exception from user code:
        Unterminated <> operator at program.perl line 11.

Use of the diagnostics pragma should be kept to development only (where it's truly useful).

Benchmark

It can be difficult to benchmark code. When trying to optimise a program or routine, you want to try several approaches and see which comes out faster. That's what the Benchmark module is for. This way, you don't have to calculate start and stop times yourself, and in general you can do high-level profiling quickly. Here is an example that tries to determine which is faster, literal hash slices or retrieving hash values one at a time.

  use Benchmark;

  sub literal_slice {
    my %family = (
      Daughter => 'Evilina',
      Father => 'Casey',
      Mother => 'Chastity',
    );
    my ($mom, $dad) = @family{qw[Mother Father]};
  }

  sub one_at_a_time {
    my %family = (
      Daughter => 'Evelina',
      Father => 'Casey',
      Mother => 'Chastity',
    );
    my $mom = $family{Mother};
    my $dad = $family{Father};
  }

  timethese(
    5_000_000 => {
      slice       => \&literal_slice,
      one_at_time => \&one_at_a_time,
    },
  );

On the hardware I have at work, a dual G4 PowerMac, the answer seems obvious. Being cute and clever doesn't hurt us too badly. Here is the output.

  Benchmark: timing 5000000 iterations of one_at_time, slice...
  one_at_time: 53 wallclock secs (53.63 usr +  0.00 sys = 53.63 CPU)
         @ 93231.40/s (n=5000000)
        slice: 56 wallclock secs (56.72 usr +  0.00 sys = 56.72 CPU)
         @ 88152.33/s (n=5000000)

CGI::Pretty

Many of you know you can use Perl to write your HTML, in fact, this trick is often used in CGI programs. If you have used the CGI module to create HTML, then it would be obvious that the output is not intended for humans to parse. The ``browser only'' nature of the output makes debugging nearly impossible.

  use CGI qw[:standard];

  print header,
    start_html( 'HTML from Perl' ),
    h2('Writiing HTML using Perl' ),
    hr,
    p( 'Writing HTML with Perl is simple with the CGI module.' ),
    end_html;

The previous program produces the following incomprehensible output.

  Content-Type: text/html; charset=ISO-8859-1

  <?xml version="1.0" encoding="iso-8859-1"?>
  <!DOCTYPE html
          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">;
  <html xmlns="http://www.w3.org/1999/xhtml"; lang="en-US">
  <head><title>HTML from Perl</title></head><body><h2>Writing
  HTML using Perl</h2><hr /><p>Writing HTML with Perl is simple with the
  CGI module.</p></body></html>

By changing the first line to use CGI::Pretty qw[:standard];, our output is now manageable.

  Content-Type: text/html; charset=ISO-8859-1

  <?xml version="1.0" encoding="iso-8859-1"?>
  <!DOCTYPE html
          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">;
  <html xmlns="http://www.w3.org/1999/xhtml"; lang="en-US">
  <head><title>HTML from Perl</title>
  </head><body>
  <h2>
          Writing HTML using Perl
  </h2>
  <hr><p>
          Writing HTML with Perl is simple with the CGI module.
  </p>
  </body></html>

While not as attractive as I'd like, there are lots of customizations to be made, all outlined in the CGI::Pretty documentation.

Class::ISA

The world of class inheritance is a complex and twisting maze. This module provides some functions to help us navigate the maze. The most common need is for the function super_path(). When dealing with complex OO hierarchies, super_path() can help us know which classes we're inheriting from (it isn't always obvious), and find method declarations.

I have a little project that requires Class::DBI, so I ran super_path() on one of the classes to determine how Perl would search the inheritance tree for a method.

  perl -MJobSearch -MClass::ISA -le'print for
      Class::ISA::super_path( "JobSearch::Job" )'

The following list of classes is in the order Perl would search to find a method.

  JobSearch::Object
  Class::DBI::mysql
  Class::DBI
  Class::DBI::__::Base
  Class::Data::Inheritable
  Class::Accessor
  Ima::DBI
  Class::WhiteHole
  DBI
  Exporter
  DynaLoader

Now if I have a question about a method implementation, or where methods are coming from, I have a nice list to look through. Class::ISA intentionally leaves out the current class (in this case JobSearch::Job), and UNIVERSAL.

Here is a little trick that allows me to find out which classes may implement the mk_accessors method.

  perl -MJobSearch -MClass::ISA -le \
    'for (Class::ISA::super_path( "JobSearch::Job" )) {
        print if $_->can("mk_accessors") }'

Because of inheritance, all of the classes listed can invoke mk_accessors, but not all of them actually define mk_accessors. It still manages to narrow the list.

Class::ISA was introduced to the Perl Core in release 5.8.0. If you're using an older Perl, you can download it from the CPAN.

Cwd

This module makes it simple to find the current working directory. There is no need to go to the shell, as so many of us do. Instead, use Cwd.

  use Cwd;
  my $path = cwd;

Env

Perl provides access to environment variables via the global %ENV hash. For many applications, this is fine. Other times it can get in the way. Enter the Env module. By default, this module will create global scalars for all the variables in your environment.

  use Env;
  print "$USER uses $SHELL";

Some variables are of better use as a list. You can alter the behavior of Env by specifying an import list.

  use Env qw[@PATH $USER];
  print "$USER's  path is @PATH";

Yet another module to save time and energy when writing programs.

File::Path

This module has a useful function called mkpath. With mkpath you can create more than one level of directory at a time. In some cases, this could reduce a recursive function or a loop construct to a simple function call.

  use File::Path;
  mkpath "/usr/local/apache/htdocs/articles/2003";

Since mkpath will create any directory it needs to in order to finally create the 2003 directory, a tremendous amount of code is no longer needed.

File::Spec::Functions

This module implements a sane and useful interface over the File::Spec module. File::Spec must be used by calling class methods, while File::Spec::Functions turns those methods into functions. There are many functions that are all useful (and fully documented in File::Spec::Unix). Here are a few examples.

  use File::Spec::Functions qw[splitpath canonpath splitdir abs2rel];

  # split a path into logical pieces
  my ($volume, $dir_path, $file) = splitpath( $path );

  # clean up directory path
  $dir_path = canonpath $dir_path;

  # split the directories into a list
  my @dirs = splitdir $dir_path;

  # turn the full path into a relative path
  my $rel_path = abs2rel $path;

As you can see, there are plenty of ways to save yourself coding time by using File::Spec::Functions. Don't forget, these functions are portable because they use different symantecs behind the senses for the operating system Perl is running on.

File::Temp

If you need a temporary file, then use File::Temp. This module will find a temporary directory that is suitable for the operating system Perl is running on and open a temporary file in that location. This is yet another example of the Perl Core saving you time.

  use File::Temp;
  my $fh = tempfile;

  print $fh "temp data";

This will open a temporary file for you and return the filehandle for you to write to. When your program exits, the temporary file will be deleted.

FindBin

FindBin has a small but useful purpose: to find the original directory of the Perl script being run. When a program is invoked, it can be hard to determine this directory. If a program is calling chdir, then it can be even more difficult. FindBin makes it easy.

  use FindBin;
  my $program_dir = $FindBin::Bin;

Shell

Shell takes the ugliness of dealing with the command line and wraps it up in pretty functions. The effect here is prettier programs. Here is a simple demonstration.

  use Shell qw[ls du];
  use File::Spec::Functions qw[rel2abs];

  chomp( my @files = ls );
  foreach ( @files ) {
        print du "-sk", rel2abs $_;
  }

Time::localtime

This module allows localtime to return an object. The object gives you by-name access to the individual elements returned by localtime in list context. This doesn't save us much coding time, but is can save us a trip to the documentation.

  use Time::localtime;
  my $time = localtime;
  print $time->year += 1900;

There is a similar module called Time::gmtime, which provides the same functionality for the gmtime function.

UNIVERSAL

The UNIVERSAL module is handy. Two of its most common functions, isa and can are almost always used in OO programming as methods. isa is used to determine what class an object belongs to, and can will tell us whether an object supports a method. This is useful for testing. For example.

  use Time::localtime;
  my $time = localtime;

  if ( $time->isa( 'Time::localtime' ) ) {
    print "We have a Time::localtime object";
  }

  if ( $time->can( "year" ) ) {
    print "We can get the year from our object";
  }

Another less-known function in UNIVERSAL is VERSION. I often need to know the version of an installed module and I find myself writing a one-liner like:

  perl -MTest::More -le'print $Test::More::VERSION'

That's just not as pretty as this.

  perl -MTest::More -le'print Test::More->VERSION'

Conclusion

The Perl Core has many hidden wonders, and I've just laid out a few here. Trolling the Core for interesting functions and modules has saved me a lot of work over the years. If you would like to look further, then browse the perlmodlib manpage for a list of the core modules. Whether your interest is CGI, I18N, Locale, or Math, you can find something there that saves a few hours of work.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Published on Perl.com
http://www.perl.com/pub/a/2003/06/19/treasures.html
See this if you're having trouble printing code examples

Hidden Treasures of the Perl Core, Part II
By Casey West

In the previous hidden treasures article, we looked at some easy-to-use (but not well-known) modules in the Perl Core. In this article, we dig deeper to uncover some of the truly precious and unique gems in the Perl Core.

constant

The constant pragma is not new or unknown, but it is a nice feature enhancement. Many people have used constant. Here is a standard example of using the constant for π.

use constant PI => 22/7;

When constants are used in programs or modules, they are often used in a set. Older versions of Perl shipped with a constant pragma that required a high level of work to produce a set.

        use constant SUNDAY  => 0;
        use constant MONDAY  => 1;
        use constnat TUESDAY => 2;

Wow, that's a lot of work! I've already given up on my program, not to mention the syntax error in the declaration of TUESDAY. Now let's try this again using the multiple declaration syntax, new to the constant pragma for Perl 5.8.0.

        use constant {
                SUNDAY    => 0,
                MONDAY    => 1,
                TUESDAY   => 2,
                WEDNESDAY => 3,
                THURSDAY  => 4,
                FRIDAY    => 5,
                SATURDAY  => 6,
        };

The only warning here is that this syntax is new to Perl 5.8.0. If you intend to distribute a program using multiple constant declarations, then remember the limitations of the program. You may want to specify what version of Perl is required for your program to work.

        use 5.8.0;

Perl will throw a fatal error if the version is anything less than 5.8.0.

Attribute::Handlers

This module allows us to play with Perl's subroutine attribute syntax by defining our attributes. This is a powerful module with a rich feature set. Here I'll give you an example of writing a minimal debugger using subroutine attributes.

First, we need to create an attribute. An attribute is any subroutine that has an attribute of :ATTR. Setting up our debug attribute is easy.

        use Attribute::Handlers;
        sub debug :ATTR {
                my (@args) = @_;
                warn "DEBUG: @args\n";
        }

Now we have a simple debug attribute named :debug. Using our attribute is also easy.

        sub table :debug {
                # ...
        }
        table(%data);
        table(%other_data);

Now, since attributes are compiled just before runtime, in the CHECK phase, our debugging output will only be sent to STDERR once. For the code above, we might get output like this:

        DEBUG: main GLOB(0x523d8) CODE(0x2e758) debug  CHECK
           Casey  Dad
        Chastity  Mom
         Evelina  Kid
        Coffee  Oily
          Cola  Fizzy

That debug string represents some of the information we get in an attribute subroutine. The first argument is the name of the package the attribute was declared in. Next is a reference to the symbol table entry for the subroutine, followed by a reference to the subroutine itself. Next comes the name of the attribute, followed by any data associated with the attribute (none in this case). Finally, the name of the phase that invoked the handler passed.

At this point, our debugging attribute isn't useful, but the parameters we are given to work with are promising. We can use them to invoke debugging output each time the subroutine is called. Put on your hard hat, this is where things get interesting.

First, let us take a look at how we want to debug our subroutine. I think we'd like different levels of debugging output. At the lowest level (1), the name of the subroutine being invoked should be sent to STDERR. At the next level (2), it would be nice to be notified of entry and exit of the subroutine. Going further (level 3), we might want to see the arguments passed to the subroutine. Even more detail can be done, but we'll save that for later and stop at three debug levels.

In order to do this voodoo, we need to replace our subroutine with one doing the debugging for us. The subroutine doing the debugging must then invoke our original code with the parameters passed to it, and return the proper output from it. Here is the implementation for debug level one (1).

        use Attribute::Handlers;
        use constant {
                PKG    => 0,
                SYMBOL => 1,
                CODE   => 2,
                ATTR   => 3,
                DATA   => 4,
                PHASE  => 5,
        };
        sub debug :ATTR {
                my ($symbol, $code, $level) = @_[SYMBOL, CODE, DATA];
                $level ||= 1;

                my $name = join '::', *{$symbol}{PACKAGE}, *{$symbol}{NAME};

                no warnings 'redefine';
                *{$symbol} = sub {
                        warn "DEBUG: entering $name\n";
                        return $code->(@_);
                };
        }
        sub table :debug {
                # ...
        }
        table(%data);
        table(%other_data);

There are some sticky bits in the debug subroutine that I need to explain in more detail.

        my $name = join '::', *{$symbol}{PACKAGE}, *{$symbol}{NAME};

This line is used to find the name and package of the subroutine we're debugging. We do the lookups from the symbol table, using the reference to the symbol that our attribute is given.

        no warnings 'redefine';

Here we turn off warnings about redefining a subroutine, because we're going to redefine a subroutine on purpose.

        *{$symbol} = sub { ... };

This construct simply replaces the code section in the symbol table with this anonymous subroutine (which is a code reference).

In this example, we set the default log level to one (1), set up some helper variables, and replace our table() subroutine with a debugging closure. I call the anonymous subroutine a closure because we are reusing some variables that are defined in the debug() subroutine. Closures are explained in greater detail in perlref (perldoc perlref from the command line).

To set the debug level for a subroutine, just a number the :debug attribute.

        sub table :debug(1) {
                # ...
        }

The output looks something like this:

        DEBUG: entering main::table
           Casey  Dad
        Chastity  Mom
         Evelina  Kid
        DEBUG: entering main::table
        Coffee  Oily
          Cola  Fizzy

Creating debug level two (2) is pretty easy from here. Time stamps will also be added to the output, which are useful for calculating how long your subroutine takes to run.

        *{$symbol} = sub {
                warn sprintf "DEBUG[%s]: entering %s\n",
                        scalar(localtime), $name;
                my @output = $code->(@_);
                if ( $level >= 2 ) {
                        warn sprintf "DEBUG[%s]: leaving %s\n",
                                scalar(localtime), $name;
                }
                return @output;
        };

In this example, we use sprintf to make out debugging statements a little more readable as complexity grows. This time, we cannot return directly from the original code reference. Instead, we have to capture the output and return it at the end of the routine. When the table() subroutine defines its debug level as :debug(2) the output is thus.

        DEBUG[Wed Jun 18 12:18:44 2003]: entering main::table
           Casey  Dad
        Chastity  Mom
         Evelina  Kid
        DEBUG[Wed Jun 18 12:18:44 2003]: leaving main::table
        DEBUG[Wed Jun 18 12:18:44 2003]: entering main::table
        Coffee  Oily
          Cola  Fizzy
        DEBUG[Wed Jun 18 12:18:44 2003]: leaving main::table

Finally, debug level three (3) should also print the arguments passed to the subroutine. This is a simple modification to the first debugging statement.

        warn sprintf "DEBUG[%s]: entering %s(%s)\n",
                scalar(localtime), $name, ($level >= 3 ? "@_" : '' );

The resulting output.

        DEBUG[Wed Jun 18 12:21:06 2003]: entering main::table(Chastity Mom Casey Dad Evelina Kid)
           Casey  Dad
        Chastity  Mom
         Evelina  Kid
        DEBUG[Wed Jun 18 12:21:06 2003]: leaving main::table
        DEBUG[Wed Jun 18 12:21:06 2003]: entering main::table(Coffee Oily Cola Fizzy)
        Coffee  Oily
          Cola  Fizzy
        DEBUG[Wed Jun 18 12:21:06 2003]: leaving main::table

Attribute::Handlers can do quite a lot more than what I've shown you already. If you like what you see, then you may want to add attributes to variables or worse. Please read the thorough documentation provided with the module.

B::Deparse

This module is a well-known Perl debugging module. It generates Perl source code from Perl source code provided to it. This may seem useless to some, but to the aspiring obfuscator, it's useful in understanding odd code.

        perl -snle'$w=($b="bottles of beer")." on the wall";$i>=0?print:last
        LINE for(map "$i $_",$w,$b),"take one down, pass it around",
        do{$i--;"$i $w!"}' -- -i=100

That is an example of an obfuscated program. It could be worse, but it's pretty bad already. Understanding this gem is as simple as adding -MO=Deparse to the command line. This will use B::Deparse to turn that mess into more readable Perl source code.

        LINE: while (defined($_ = <ARGV>)) {
                chomp $_;
                $w = ($b = 'bottles of beer') . ' on the wall';
                foreach $_ (
                         map("$i $_", $w, $b),
                         'take one down, pass it around',
                         do { --$i; "$i $w!" }
                       ) {
                        $i >= 0 ? print($_) : last LINE;
                }
        }

To use B::Deparse in the everyday example, just run your program using it on the command line.

        perl -MO=Deparse prog.pl

But if you want to have some real fun, then dig into the object-oriented interface for B::Deparse. There you will find an amazing method called coderef2text(). This method turns any code reference to text, just like the command line trick does for an entire program. Here is a short example.

        use B::Deparse;

        my $deparser = B::Deparse->new;

        print $deparser->coderef2text(
                sub { print "Hello, world!" }
        );

The output will be the code block, after it's been deparsed.

        {
        print 'Hello, world!';
        }

We can use this to add another debug level to our Attribute::Handlers example. Here, debug level four (4) will print out the source of our subroutine.

Before our debug() subroutine declaration we add the following lines of code.

        use B::Deparse;
        my $deparser = B::Deparse->new;

Next, our debugging closure declaration is updated to print out the full subroutine with the DEBUG: prefix on each line.

        *{$symbol} = sub {
                warn sprintf "DEBUG[%s]: entering %s(%s)\n",
                        scalar(localtime), $name, ($level >= 3 ? "@_" : '' );
                if ( $level >= 4 ) {
                        my $sub = sprintf "sub %s %s",
                                $name, $deparser->coderef2text( $code );
                        $sub =~ s/\n/\nDEBUG: /g;
                        warn "DEBUG: $sub\n";
                }
                my @output = $code->(@_);
                if ( $level >= 2 ) {
                        warn sprintf "DEBUG[%s]: leaving %s\n",
                                scalar(localtime), $name;
                }
                return @output;
        };

The verbose debugging output looks like this.

        DEBUG[Wed Jun 18 12:47:22 2003]: entering main::table(Chastity Mom Casey Dad Evelina Kid)
        DEBUG: sub main::table {
        DEBUG:    BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"}
        DEBUG:    use strict 'refs';
        DEBUG:    my(%data) = @_;
        DEBUG:    my $length = 0;
        DEBUG:    foreach $_ (keys %data) {
        DEBUG:        $length = length $_ if length $_ > $length;
        DEBUG:    }
        DEBUG:    my $output = '';
        DEBUG:    while (my($k, $v) = each %data) {
        DEBUG:        $output .= sprintf("%${length}s  %s\n", $k, $v);
        DEBUG:    }
        DEBUG:    print "\n$output";
        DEBUG:}
           Casey  Dad
        Chastity  Mom
         Evelina  Kid
        DEBUG[Wed Jun 18 12:47:22 2003]: leaving main::table

There are more methods in the B::Deparse class that you can use to muck around with the results of coderef2text(). This module is powerful and useful for debugging. I suggest you at least use the simple version if code becomes ambiguous and incomprehensible.

While B::Deparse is good at what it does, it's not complete. Each version of Perl has made it better, and it's good in Perl 5.8.0. Don't trust B::Deparse to get everything right, though. For instance, I wouldn't trust it to serialize code for later use.

Class::Struct

This module, just like the constant pragma, is well-known. The difference is that Class::Struct is not often used. For many programs, setting up a class to represent data would be ideal, but overkill. Class::Struct gives us the opportunity to live in our ideal world without the pain of setting up any classes by hand. Here is an example of creating a class with Class::Struct. In this example, we're going to use compile time-class declarations, a new feature in Perl 5.8.0.

        use Class::Struct Person => {
                name => '$',
                mom  => 'Person',
                dad  => 'Person',
        };

Here we've created a class called Person with three attributes. name can contain a simple scalar value, represented by the dollar sign ($). mom and dad are both objects of type Person. Using our class within the same program is the same as using any other class.

        my $self = Person->new( name => 'Casey West' );
        my $wife = Person->new( name => 'Chastity West' );
        my $baby = Person->new(
                name => 'Evelina West',
                mom  => $wife,
                dad  => $self,
        );
        printf <<__FORMAT__, $baby->name, $baby->mom->name;
        %s, daughter of %s,
        went on to cure cancer and disprove Fermat's Theorem.
        __FORMAT__

Class::Struct classes are simple by design, and can get more complex with further creativity. For instance, to add a method to the Person class you can simply declare it in the Person package. Here is a method named birth() which should be called on a Person object. It takes the name of the baby as an argument, and optionally the father (a Person object). Returned is a new Person object representing the baby.

        sub Person::birth {
                my ($self, $name, $dad) = @_;
                return Person->new(
                        name => $name,
                        mom  => $self,
                        dad  => ( $dad || undef ),
                );
        }

These object are not meant to be persistent. If you want persistent objects, then you need to look elsewhere, perhaps Class::DBI or any other implementation, of which there are many.

These in-memory objects can help to clean up your code, but they add a bit of overhead. You have to decide where the balance in your program is. In most cases, using Class::Struct is going to be OK.

Encode

Encode is Perl's interface to Unicode. An explanation of Unicode itself is far beyond the scope of this article. In fact, it's far beyond the scope of most of us. This module is powerful. I'm going to provide some examples and lots of pointers to the appropriate documentation.

The first function of the API to learn is encode(). encode() will convert a string for Perl's internal format to a series of octets in the encoding you choose. Here is an example.

        use Encode;
        my $octets = encode( "utf8", "Hello, world!" );

Here we have turned the string Hello, world! into a utf8 string, which is now in $octets. We can also decode strings using the decode() function.

        my $string = decode( "utf8", $utf8_string );

Now we've decoded a utf8 string into Perl's internal string representation. Since utf8 is a common encoding to deal with, there are two helper functions: encode_utf8(), and decode_utf8. Both of these function take a string as the argument.

A list of supported encodings can be found in Encode::Supported, or by using the encodings() method.

        my @encodings = Encode->encodings;

For even more Unicode fun, dive into the documentation in Encode (perldoc Encode on the command line).

Filter::Simple

This module gives us an easy way to write source-code filters. These filters may change the behavior of calling Perl code, or implement new features of Perl, or do anything else they want. Some of the more infamous source-filter modules on the CPAN include Acme::Bleach, Semi::Semicolons, and even Switch.

In this article, I'm going to implement a new comment syntax for Perl. Using the following source-filter package will allow you to comment your code using SQL comments. SQL comments begin with two consecutive dashes (--). For our purposes, these dashes cannot be directly followed by a semicolon (;) or be preceded by something other than whitespace or a the beginning of a line.

        package SQLComments;
        use Filter::Simple sub {
                s/(?:^|\s)--(?!;)/#/g;
        };
        1;

In this example, we create an anonymous subroutine that is passed on to Filter::Simple. The entire source of the calling program is in $_, and we use a regular expression to search for our SQL comments and change them to Perl comments.

Using our new source filter works like this.

        use SQLComments;
        -- Here is some code that decrements a variable.
        my $i = 100; -- start at 100.
        while ( $i ) {
                $i--; -- decrement
        }
        -- That's it!.

Using B::Deparse on the command line, we can see what the code looks like after it's filtered. Just remember that B::Deparse doesn't preserve comments.

        use SQLComments;

        my $i = 100;
        while ($i) {
            --$i;
        }

The output is exactly as we expect. Filtering source code is a complex art. If your filters are not perfect, then you can break code in unexpected ways. Our SQLComments filter will break the following code.

        print "This is nice -- I mean really nice!\n";

It will turn into this.

        print "This is nice# I mean really nice!\n";

Not exactly the results we want. This particular problem can be avoided, however, using Filter::Simple in a slightly different way. You can specify filters for different sections of the source code, here is how we can limit our SQLComments filter to just code and not quote-like constructs.

        package SQLComments;

        use Filter::Simple;

        FILTER_ONLY code => sub { s/(?:^|\s)--(?!;)/#/g };

If you want to learn more about source filters, then read the documentation provided in Filter::Simple.

Variable Utility Modules

There are some functions that are repeated in hundreds (probably thousands) of programs. Think of all the sorting functions written in C programs. Perl programs have them, too, and the following utility modules try to clean up our code, eliminating duplication is simple routines.

There are a number of useful functions in each of these modules. I'm going to highlight a few, but be sure to read the documentation provided with each of them for a full list.

Scalar::Util
blessed() will return the package name that the variable is blessed into, or undef if the variable isn't blessed.
        my $baby  = Person->new;
        my $class = blessed $baby;

$class will hold the string Person. weaken is a function that takes a reference and makes it weak. This means that the variable will not hold a reference count on the thing it references. This is useful for objects, where you want to keep a copy but you don't want to stop the object from being DESTROY-ed at the right time.

List::Util
The first() function returns the first element in the list for which the block returns true.
        my $person = first { $_->age < 18 } @people;

shuffle() will return the elements of the list in random order. Here is an example of breaking a group of people into teams.

        my @people = shuffle @people;

        my @team1  = splice @people,  0, (@people/2);
        my @team2  = @people;

Finally, sum returns the sum of all the elements in a list.

        my $sum = sum 1 .. 10;
Hash::Util
Hash::Util has a slightly different function than the previously discussed variable utility modules. This module implements restricted hashes, which are the predecessor to the undesirable (and now obsolete) pseudo-hashes.

lock_keys() is a function that will restrict the allowed keys of a hash. If a list of keys is given, the hash will be restricted to that set, otherwise the hash is locked down to the currently existing keys.

        use Hash::Util qw[lock_keys];

        my %person = (
                name => "Casey West",
                dad  => $dad,
                mom  => $mom,
        );

        lock_keys( %person );

The %person hash is now restricted. Any keys currently in the hash may be modified, but no keys may be added. The following code will result in a fatal error.

        $person{wife} = $wife;

You can use the unlock_keys() function to release your restricted hash.

You can also lock (or unlock) a value in the hash.

        lock_value( %person, "name" );
        $person{name} = "Bozo"; # Fatal error!

Finally, you can lock and unlock an entire hash, making it read only in the first case.

        lock_hash( %person );

Now our %person hash is really restricted. No keys can be added or deleted, and no values can be changed. I know all those OO folks out there wishing Perl made it easy to keep class and instance data private are smiling.

Locale Modules

I've seen these modules implemented time and time again. Perl 5.8.0 introduced them. Each of them implements a set of functions that handle locale issues for you.

Locale::Language
This module will translate language codes to names, and vice-versa.
        my $lang = code2language( 'es' );      # Spanish
        my $code = language2code( 'English' ); # en

You can also get a full list of supported language names and codes.

        my @codes = all_language_codes();
        my @names = all_language_names();
Locale::Country

Convert country names to codes, and vice-versa. By default country codes are represented in two character codes.

        my $code = country2code( 'Finland' ); # fi

You can change the default behavior to get three character codes, or the numeric country codes.

        my $code = country2code( 'Russia', LOCALE_CODE_ALPHA_3 ); # rus
        my $num  = country2code( 'Australia', LOCALE_CODE_NUMERIC ); # 036

You can also go from any code type to country name.

        my $name = code2country( 'jp' ); # Japan

You can specify any type of code, but if it's not the default two character representation you must supply the extra argument to define what type it is.

        my $name = code2country( "120", LOCALE_CODE_NUMERIC ); # Cameroon

Just as before, you can get a full list of codes and countries using the two query functions: all_country_codes(), and all_country_names(). Both of these functions accept an optional argument specifying the code set to use for the resulting list.

Locale::Currency

This module has the same properties as the other locale modules. You can convert currency codes into full names, and vice-versa.

        my $curr = code2currency( 'jpy' ); # Yen
        my $code = currency2code( 'US Dollar' ); # usd

The query functions are: all_currency_codes(), and all_currency_names().

Memoize

Memoize is a module that performs code optimization for you. In a general sense, when you memoize a function, it is replaced by a memoized version of the same function. OK, that was too general. More specifically, every time your memoized function is called, the calling arguments are cached and anything the function returns is cached as well. If the function is called with a set of arguments that has been seen before, then the cached return value is sent back and the actual function is never called. This makes the function faster.

Not all functions can be memoized. For instance, if your function would return a different value on two calls, even for the exact same set of calling arguments, then it will be broken. Only the first sets return values will be returned for every call. Many function do not act this way, and that's what makes Memoize so useful.

Here is an example of a memoizeable function.

        sub add {
                my ($x, $y) = @_;
                return $x + $y;
        }

For every time this function is called as add( 2, 2 ), the result will be 4. Rather than compute the value of 4 in every case, we can cache it away the first time and retrieve it from the cache every other time we need to compute 2 + 2.

        use Memoize;

        memoize( 'add' );

        sub add {
                my ($x, $y) = @_;
                return $x + $y;
        }

We've just made add() faster, without any work. Of course, our addition function isn't slow to begin with. The documentation of Memoize gives a much more details look into this algorithm. I highly suggest you invest time in learning about Memoize, it can give you wonderful speed increases if you know how and when to use it.

Win32

I currently don't have a Microsoft operating system running on any of my networks, but when perusing the Perl core, I happened upon the Win32 module. I wanted to bring it up because if I were using a Microsoft OS, then I would find the functions in his module invaluable. Please, if you are running in that environment, then look at the documentation for Win32 for dozens of helpful functions (perldoc Win32 on the command line).

Conclusion

Just as before, I've still not covered all of the Perl core. There is much more to explore and a full list can be found by reading perlmodlib. The benefit of having these modules in the core is great. Lots of environments require programmers to be bound to using only code that is distributed with Perl. I hope I've been able to lighten the load for anyone who has been put in that position (even by choice).

Return to Related Articles from the O'Reilly Network .

Library Navigation Links

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.


Perl.com: Having Trouble Printing Code Examples?

Published on Perl.com

Having Trouble Printing Code Examples?

If you're having trouble printing code examples from our pages, you're probably using a 4.x version of Netscape. You'll want to use something like Netscape 6 or MSIE to print articles that include example code.

Read on if you're interested in more about the details of this problem.

The problem comes with a Netscape 4.x issue with character entities in general, and specifically with the &lt; for < and &gt; for > entities. It's also not necessarily specific to printing.

If you view the source of a page using these character entities in Netscape 4.x, you'll see that the source view has converted them into the regular "<" and ">" symbols. If you view the source in Netscape 6 or MSIE, you'll see that they remain as they were originally entered: &lt; and &gt;.

It seems that Netscape 4.x turns the code for character entities into the character itself. While this doesn't seem to affect the display in the browser, it does affect what happens when the page is sent to the printer. Something that is coded into the article like:

&lt;script language="PHP"&gt;

is, in Netscape 4.x, presented instead as:

<script language="PHP">

and, since that doesn't display in HTML, it doesn't print either.

The same thing happens if you do a "View Source" and copy all of that HTML into a new file and then view it -- if you View Source in MSIE or Netscape 6, it's fine. But if you View Source in Netscape 4.x, and copy and paste from that, your code sample bits are going to be put in as actual code, and they won't display in any browser.

In any case, the solution is to use something other than Netscape 4.x for printing articles that include code samples.

Perl.com Compilation Copyright © 1998-2003 O'Reilly & Associates, Inc.

Return to Related Articles from the O'Reilly Network .

Library Navigation Links


Master Index

Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z


Index: 0

` ` backquotes/backticks: 1.5. A Whirlwind Tour of Perl (Learning Perl)
14.4. Using Backquotes to Capture Output (Learning Perl)
- hyphen: 6.2. Input from the Diamond Operator (Learning Perl)
8.1. Character Classes (Learning Perl)
- (minus sign), modifiers and: 6.18.3. Discussion (Perl Cookbook)
( ) parentheses (see parentheses)
' ' single quotes: 2.3.1. Single-Quoted String Literals (Learning Perl)
[ ] square brackets: 7.3. A Pattern Test Program (Learning Perl)
8.1. Character Classes (Learning Perl)
- subtraction operator: 2.2.5. Numeric Operators (Learning Perl)
+ addition operator: 2.2.5. Numeric Operators (Learning Perl)
& (ampersand): 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
12.2. Selecting What to Import (Learning Perl Objects, References and Modules)
3.10. Named Unary and File Test Operators (Programming Perl)
address-of operator (in C): 3.21. C Operators Missing from Perl (Programming Perl)
& (bitwise and) operator: 3.13. Bitwise Operators (Programming Perl)
&& (AND) operator: 3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
AND bitwise operator: 4.5.10. Bitwise Operators (Perl in a Nutshell)
calling subroutines: 4.7.1. Calling Subroutines (Perl in a Nutshell)
in encoded URLs: 9.2. URL Encoding (Perl in a Nutshell)
in filenames: 29.2.104. open (Programming Perl)
Perl version 5, changes in use: 1.2.2. Verbs (Programming Perl)
prototype character: 6.4. Prototypes (Programming Perl)
prototype symbol: 4.7.5. Prototypes (Perl in a Nutshell)
for subroutine names: 1.2.1. Variable Syntax (Programming Perl)
2.5. Names (Programming Perl)
2.5. Names (Programming Perl)
4.6. goto (Programming Perl)
6.1. Syntax (Programming Perl)
omitting in prototypes: 6.4. Prototypes (Programming Perl)
&&= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
3.17. Assignment Operators (Programming Perl)
&= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
< > (angle brackets)
<=> (comparison) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
<...> (line-input) operator: 4.9. Filehandles (Perl in a Nutshell)
<<= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
<< debugger commands, and: 6.2. Debugger Commands (Perl in a Nutshell)
< (less-than) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
<= (less-than-or-equal) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
>>= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
> (greater-than) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
>= (greater-than-or-equal) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
>> (to open file for appending): 4.9. Filehandles (Perl in a Nutshell)
.= append operator: 2.5.3. Binary Assignment Operators (Learning Perl)
@_ array: 4.5. Arguments (Learning Perl)
accessing instance data: 9.3. Accessing the Instance Data (Learning Perl Objects, References and Modules)
changes reflected: 3.1. Performing the Same Task on Many Arrays (Learning Perl Objects, References and Modules)
creating: 3.1. Performing the Same Task on Many Arrays (Learning Perl Objects, References and Modules)
dereferencing and: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
nested data structures: 3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
passing uninterrupted: 8.9. What to Do with @_ (Learning Perl Objects, References and Modules)
references and scoping: 4.1. More than One Reference to Data (Learning Perl Objects, References and Modules)
removing items from: 2.1. The Cure for the Common Code (Learning Perl Objects, References and Modules)
@+ array of ending positions: 28.2. Special Variables in Alphabetical Order (Programming Perl)
= assignment operator: 2.5.2. Scalar Assignment (Learning Perl)
* (asterisk): 3.10. Named Unary and File Test Operators (Programming Perl)
** (exponentiation)operator: 3.4. Exponentiation (Programming Perl)
**= (exponentiation assignment) operator: 3.17. Assignment Operators (Programming Perl)
*= (multiplication assignment) operator: 3.17. Assignment Operators (Programming Perl)
*? quantifier: 5.3.1. Metasymbol Tables (Programming Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
multiplication operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
multiplicative operator: 3.7. Multiplicative Operators (Programming Perl)
prototype character: 6.4. Prototypes (Programming Perl)
prototype symbol (typeglob): 4.7.5. Prototypes (Perl in a Nutshell)
quantifier: 1.7.1. Quantifiers (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
in quantifiers: 5.5. Quantifiers (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
typeglob: 1.2.1. Variable Syntax (Programming Perl)
7.5.1. Problem (Perl Cookbook)
2.5. Names (Programming Perl)
2.10. Typeglobs and Filehandles (Programming Perl)
** (exponentiation) operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
*= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
@ (at sign)
@_ array: 10.1.2. Solution (Perl Cookbook)
4.7.2. Passing Arguments (Perl in a Nutshell)
6.2. Semantics (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
for array names: 1.2.1. Variable Syntax (Programming Perl)
2.4. Variables (Programming Perl)
@- array of starting positions: 28.2. Special Variables in Alphabetical Order (Programming Perl)
@+ array of ending positions: 5.7.1. Capturing (Programming Perl)
@_ arrays: 6.2. Semantics (Programming Perl)
changes in use, Perl versions: 24.1.5. Previous Perl Traps (Programming Perl)
in debugger: 20.1. Using the Debugger (Programming Perl)
dereferencing with: 4.8.2. Dereferencing (Perl in a Nutshell)
@EXPORT array (use pragma): 12.1.3. Discussion (Perl Cookbook)
@EXPORT_OK array (use pragma): 12.1.3. Discussion (Perl Cookbook)
@EXPORT_TAGS array (use pragma): 12.1.3. Discussion (Perl Cookbook)
format fieldholders: 4.12. Formats (Perl in a Nutshell)
@INC array: 12.8.3. Discussion (Perl Cookbook)
inside strings, escaping with backslash: 2.6.2. String Literals (Programming Perl)
in picture lines: 7. Formats (Programming Perl)
prototype character: 6.4. Prototypes (Programming Perl)
prototype symbol (list): 4.7.5. Prototypes (Perl in a Nutshell)
references to arrays: 11.1.2. Solution (Perl Cookbook)
signifying arrays: 4.2.5.1. Arrays (Perl in a Nutshell)
splice( ): 4.12.3. Discussion (Perl Cookbook)
++ autoincrement operator: 10.6. Autoincrement and Autodecrement (Learning Perl)
\ (backslash): 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.8. References to Hashes (Learning Perl Objects, References and Modules)
6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
\1, \2, . . . (backreferences): 6.16.2. Solution (Perl Cookbook)
` string metacharacter: 1.18.3. Discussion (Perl Cookbook)
\a for terminal bell: 15.7.2. Solution (Perl Cookbook)
\... metasymbol: 5.3.1. Metasymbol Tables (Programming Perl)
creating arrays: 11.6.2. Solution (Perl Cookbook)
creating references: 11.. Anonymous Data (Perl Cookbook)
\E string metacharacter: 1.18.3. Discussion (Perl Cookbook)
entering continued commands in debugger: 20.2. Debugger Commands (Programming Perl)
to escape metacharacters: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
escaping characters: 1.18.1. Problem (Perl Cookbook)
\G anchor: 6.14.3. Discussion (Perl Cookbook)
interpretation by regex parser: 5.9.2.1. When backslashes happen (Programming Perl)
\l string escape: 1.13.2. Solution (Perl Cookbook)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
for multiline commands: 20.1. Using the Debugger (Programming Perl)
\Q notation for backslashing nonalphanumeric characters: 2.6.2. String Literals (Programming Perl)
quoted strings, avoiding overuse in: 2.6.3. Pick Your Own Quotes (Programming Perl)
quotemeta function for: 29.2.118. quotemeta (Programming Perl)
reference operator: 3.5. Ideographic Unary Operators (Programming Perl)
8.2.1. The Backslash Operator (Programming Perl)
references to arrays: 11.1.3. Discussion (Perl Cookbook)
references to scalars: 11.5.2. Solution (Perl Cookbook)
\U string escape: 1.13.2. Solution (Perl Cookbook)
\X metacharacter: 1.8.3. Discussion (Perl Cookbook)
` (backtick): 2.6.2. String Literals (Programming Perl)
16.3.1. Anonymous Pipes (Programming Perl)
executing commands without shell escapes: 19.5.3. Discussion (Perl Cookbook)
expanding: 1.15.3. Discussion (Perl Cookbook)
gathering program output: 16.1.2. Solution (Perl Cookbook)
operator: 2.7.4. Interpolative Context (Programming Perl)
2.11.1. Command Input (Backtick) Operator (Programming Perl)
running another program: 16.2.3. Discussion (Perl Cookbook)
security and: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
! (bang)
! (logical negation) operator
overloading: 13.3. Overloadable Operators (Programming Perl)
!= (not equal to) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
!! debugger command: 20.2.6. Actions and Command Execution (Programming Perl)
!~ (binding) operator: 3.6. Binding Operators (Programming Perl)
using with pattern matching operators: 5.2. Pattern-Matching Operators (Programming Perl)
complemented character sets, using for: 5.4.3.4. Defining your own character properties (Programming Perl)
CPAN.pm eval command: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
in debugger commands: 20.2.6. Actions and Command Execution (Programming Perl)
logical negation operator: 4.5.2. Unary Operators (Perl in a Nutshell)
3.5. Ideographic Unary Operators (Programming Perl)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
!! Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
=~ binding operator: 9.3. The Binding Operator, =~ (Learning Perl)
32-bit systems: 25.2. Endianness and Number Width (Programming Perl)
{ } (braces): (see also curly braces) 8.5. Braces, Brackets, and Quoting (Programming Perl)
24.3. Programming with Style (Programming Perl)
bare blocks, creating with: 4.5. Bare Blocks (Programming Perl)
{ metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
delimiting statement blocks: 4.3. Statements (Perl in a Nutshell)
precedence of: 3.1. Terms and List Operators (Leftward) (Programming Perl)
quantifier: 1.7.1. Quantifiers (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
regular expression quantifiers: 4.6.6. Quantifiers (Perl in a Nutshell)
search patterns, clarifying with use: 2.6.5. Interpolating Array Values (Programming Perl)
for statement blocks: 1.6.1.1. The if and unless statements (Programming Perl)
{{ Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
{ Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
[ ] (brackets)
[ metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
[...] character class: 5.3.1. Metasymbol Tables (Programming Perl)
character classes: 5.3.1. Metasymbol Tables (Programming Perl)
5.4.1. Custom Character Classes (Programming Perl)
to match characters: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
precedence of: 3.1. Terms and List Operators (Leftward) (Programming Perl)
regular expression metacharacter: 4.6.4. Character Classes (Perl in a Nutshell)
^ (caret)
^ caret anchor: 8.3. Anchors (Learning Perl)
in [...] construct: 4.6.4. Character Classes (Perl in a Nutshell)
assertion: 1.7.1. Quantifiers (Programming Perl)
bitwise xor operator: 3.13. Bitwise Operators (Programming Perl)
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
inverting character class
character class, inverting: 5.4.1. Custom Character Classes (Programming Perl)
line boundary: 1.7.3. Nailing Things Down (Programming Perl)
matching: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
in picture lines: 7. Formats (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
XOR bitwise operator: 4.5.10. Bitwise Operators (Perl in a Nutshell)
^= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
3.17. Assignment Operators (Programming Perl)
: (colon), in package names: 7.1. Namespaces and Packages (Perl in a Nutshell)
, (comma): 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
delimiting list values: 2.8. List Values and Arrays (Programming Perl)
2.8. List Values and Arrays (Programming Perl)
error in print statements: 24.1.1. Universal Blunders (Programming Perl)
in numbers: 2.16.1. Problem (Perl Cookbook)
key/value pairs and: 1.2.1.2.2. Hashes. (Programming Perl)
2.9. Hashes (Programming Perl)
large numbers and: 2.6.1. Numeric Literals (Programming Perl)
number legibility without: 4.2.1. Numbers (Perl in a Nutshell)
operator: 4.5.11.3. Comma operator (Perl in a Nutshell)
3.18. Comma Operators (Programming Perl)
3.18. Comma Operators (Programming Perl)
(see also => operator)
in scalar context: 24.1.5. Previous Perl Traps (Programming Perl)
printing lists with: 4.2.1. Problem (Perl Cookbook)
as separator: 1.2.1.3. Complexities (Programming Perl)
Control-C
signals, handler for: 16.1. Signals (Programming Perl)
{ } (curly braces): 1. Introduction (Perl Cookbook)
anonymous hash constructors: 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
arrays and: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
coderefs and: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
creating anonymous arrays and hashes: 11.. References (Perl Cookbook)
dereferencing: 3.7. Simplifying Nested Element References with Arrows (Learning Perl Objects, References and Modules)
dropping: 3.4. Dropping Those Braces (Learning Perl Objects, References and Modules)
3.4. Dropping Those Braces (Learning Perl Objects, References and Modules)
hashes and: 3.8. References to Hashes (Learning Perl Objects, References and Modules)
indirect object syntax and: 10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
-d (directory) file test: 1.5.7. Some File Test Operators (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
$_ default variable (see default variable)
/ division operator: 2.2.5. Numeric Operators (Learning Perl)
$ (dollar sign): 1.2.1.2.2. Hashes. (Programming Perl)
$1, $2, . . . (backreferences): 1.11.3. Discussion (Perl Cookbook)
6.. Special Variables (Perl Cookbook)
finding doubled words: 6.16.2. Solution (Perl Cookbook)
$/ variable: 8.. Basic Operations (Perl Cookbook)
$* variable (deprecated): 6.. Pattern-Matching Modifiers (Perl Cookbook)
$& variable: 1.11.3. Discussion (Perl Cookbook)
6.. Special Variables (Perl Cookbook)
$#ARRAY variable: 4.3.2. Solution (Perl Cookbook)
in debugger: 20.1. Using the Debugger (Programming Perl)
dereferencing with: 4.8.2. Dereferencing (Perl in a Nutshell)
$# prefix: 2.8.2. Array Length (Programming Perl)
$$ (current process ID): 2.5. Names (Programming Perl)
$? (exit status, last child process): 2.5. Names (Programming Perl)
$ variables
$^O variable: 25. Portable Perl (Programming Perl)
$^F variable: 12.7.3. Discussion (Perl Cookbook)
hashes: 5.. Introduction (Perl Cookbook)
$^I variable: 7.16.3. Discussion (Perl Cookbook)
line boundary: 5.6.2. Endings: The \z, \Z, and $ Assertions (Programming Perl)
in matching: 5.2.2. The m// Operator (Matching) (Programming Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
$^O variable: 7.25. Program: lockarea (Perl Cookbook)
9.10.3. Discussion (Perl Cookbook)
prototype symbol (scalar): 4.7.5. Prototypes (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
for scalar variable names: 1.2.1.2.1. Arrays. (Programming Perl)
2.4. Variables (Programming Perl)
scalar variable interpolation and: 2.6.2. String Literals (Programming Perl)
signifying scalar variables: 4.2.5. Variables (Perl in a Nutshell)
1.2.1. Variable Syntax (Programming Perl)
$VERSION variable (use pragma): 12.1.3. Discussion (Perl Cookbook)
$^W variable: 12.14.3. Discussion (Perl Cookbook)
word boundary: 1.7.3. Nailing Things Down (Programming Perl)
$ variables
$' variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
$0 ($PROGRAM_NAME): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$a and $b (sort variables): 28.2. Special Variables in Alphabetical Order (Programming Perl)
@': 5.7.1. Capturing (Programming Perl)
@&: 5.7.1. Capturing (Programming Perl)
$' ($POSTMATCH): 24.2.1. Time Efficiency (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$*: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$@ ($EVAL_ERROR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$\ ($OUTPUT_RECORD_SEPARATOR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$` ($PREMATCH): 24.2.1. Time Efficiency (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$! ($OS_ERROR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$] ($PERL_VERSION): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^ ($FORMAT_TOP_NAME): 7.1. Format Variables (Programming Perl)
7.2. Footers (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$^A ($ACCUMULATOR): 7.2.1. Accessing Formatting Internals (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
formline function output: 29.2.42. formline (Programming Perl)
$^C ($COMPILING): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^D ($DEBUGGING): 19.1.3. Switches (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$^E ($EXTENDED_OS_ERROR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^F ($SYSTEM_FD_MAX): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^H: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^I ($INPLACE_EDIT): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^L ($FORMAT_LINEFEED): 7.1. Format Variables (Programming Perl)
$^M: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^O ($OSNAME): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^P ($PERLDB): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^S ($EXCEPTIONS_BEING_CAUGHT): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^T ($BASETIME): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^V ($PERL_VERSION): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^W ($WARNING): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$^X ($EXECUTABLE_NAME): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$: ($FORMAT_LINE_BREAK_CHARACTERS): 7. Formats (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$, ($LIST_SEPARATOR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$$ ($PROCESS_ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$. ($INPUT_LINE_NUMBER): 28.2. Special Variables in Alphabetical Order (Programming Perl)
resetting with close function: 29.2.16. close (Programming Perl)
$= ($FORMAT_LINES_PER_PAGE): 7.1. Format Variables (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
@`: 5.7.1. Capturing (Programming Perl)
$< ($REAL_USER_ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$line: 1.6.2.1. The while and until statements (Programming Perl)
$- ($FORMAT_LINES_LEFT): 7. Formats (Programming Perl)
7.2. Footers (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$) ($EFFECTIVE_GROUP_ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$( ($REAL_GROUP_ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$% ($FORMAT_PAGE_NUMBER): 7.1. Format Variables (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
@+: 5.7.1. Capturing (Programming Perl)
$? ($CHILD_ERROR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
backtick operator and: 2.11.1. Command Input (Backtick) Operator (Programming Perl)
close function and: 29.2.16. close (Programming Perl)
$> ($EFFECTIVE_USER_ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$[semi] ($SUBSCRIPT_SEPARATOR): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$#
obsolete variable for numeric output: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$&: 5.2. Pattern-Matching Operators (Programming Perl)
$`: 5.2. Pattern-Matching Operators (Programming Perl)
${^ (internal variable names): 2.5. Names (Programming Perl)
$^W: 4.9.1. Controlling Warnings (Programming Perl)
$; (SUBSCRIPT_SEPARATOR): 2.9. Hashes (Programming Perl)
$': 5.2. Pattern-Matching Operators (Programming Perl)
$/ ($INPUT_RECORD_SEPARATOR): 19.1.3. Switches (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$~ ($FORMAT_NAME): 7.1. Format Variables (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$_ ($ARG) ;glob function with: 2.11.3. Filename Globbing Operator (Programming Perl)
$_ variable: 1.7. Regular Expressions (Programming Perl)
1.7.1. Quantifiers (Programming Perl)
$| ($OUTPUT_AUTOFLUSH): 7.1. Format Variables (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
${^WIDE_SYSTEM_CALLS}: 15.1. Building Character (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$1, $2, $3, ...: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
4.6.7. Pattern Match Variables (Perl in a Nutshell)
$& variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
$< variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$> variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$@ variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$ variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$` variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
$! variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$[ variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$] variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^ variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$^A variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^D variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^E variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^F variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^H variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^I variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^L variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^M variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^N variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
$^O variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^P variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$: variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$, variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$$ variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$. variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$= variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$# variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$- variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$( variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$% variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$+ variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
$? variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$" variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$; variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$/ variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$~ variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$_ ($ARG) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
angle operator and: 2.11.2. Line Input (Angle) Operator (Programming Perl)
$0 variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$| variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$^T variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^W variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$^X variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
. (dot): 3.10. Named Unary and File Test Operators (Programming Perl)
. . and . . . range operators: 6.8.2. Solution (Perl Cookbook)
... (range operator): 3.15. Range Operator (Programming Perl)
character wildcard: 1.7. Regular Expressions (Programming Perl)
5.2.1. Pattern Modifiers (Programming Perl)
5.3.3. Wildcard Metasymbols (Programming Perl)
(concatenation) operator: 1.5.2. String Operators (Programming Perl)
3.8. Additive Operators (Programming Perl)
autogeneration via stringification handler: 13.3. Overloadable Operators (Programming Perl)
in debugger command: 20.1. Using the Debugger (Programming Perl)
20.2.1. Stepping and Running (Programming Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
period in numbers: 2.16.1. Problem (Perl Cookbook)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
quantifiers, use in: 1.7.1. Quantifiers (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
separating integers in v-strings: 2.6.7. V-String Literals (Programming Perl)
.. (range) operator: 4.5.11.1. Range operator (Perl in a Nutshell)
3.15. Range Operator (Programming Perl)
... (range) operator: 4.5.11.1. Range operator (Perl in a Nutshell)
.= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
3.17. Assignment Operators (Programming Perl)
./ dot and slash: 1.4.1. A Simple Program (Learning Perl)
.. dot-dot: 13.3. Links and Files (Learning Perl)
:: (double colon): 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
12.6. What use Is Doing (Learning Perl Objects, References and Modules)
-e command-line option: 16.4.1. In-place Editing from the Command Line (Learning Perl)
= (equal sign)
= = (equal to) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
1.5.3. Assignment Operators (Programming Perl)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
3.12. Equality Operators (Programming Perl)
=~ operator: 1.1.3. Discussion (Perl Cookbook)
=> operator: 5.. Introduction (Perl Cookbook)
assignment operator: 4.2.5. Variables (Perl in a Nutshell)
4.5.6. Assignment Operators (Perl in a Nutshell)
=begin pod directive: 12.20.3. Discussion (Perl Cookbook)
debugger command: 20.2.7. Miscellaneous Commands (Programming Perl)
=end pod directive: 12.20.3. Discussion (Perl Cookbook)
-eval option, find2perl command and: B.26. Converting find Command Lines to Perl (Learning Perl)
for embedded documentation (pod): 4.1. Program Structure (Perl in a Nutshell)
= (assignment) operator: 1.2.1.1. Singularities (Programming Perl)
3.17. Assignment Operators (Programming Perl)
= => current line marker: 20.1. Using the Debugger (Programming Perl)
=> (corresponds to) operator: 1.2.1.2.2. Hashes. (Programming Perl)
2.9. Hashes (Programming Perl)
=~ (pattern binding) operator: 1.7. Regular Expressions (Programming Perl)
3.6. Binding Operators (Programming Perl)
using with pattern matching operators: 5.2. Pattern-Matching Operators (Programming Perl)
in hash name/value pairs: 4.2.5.2. Hashes (Perl in a Nutshell)
for pod commands: 4.13. Pod (Perl in a Nutshell)
=> operator, defining key/value pairs: 4.2.5.2. Hashes (Perl in a Nutshell)
4.5.11.3. Comma operator (Perl in a Nutshell)
** exponentiation operator: 2.2.5. Numeric Operators (Learning Perl)
_ _FILE_ _ and _ _LINE_ _ tokens: 11.3. Fatal Errors with die (Learning Perl)
_ filehandle: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
/ (forward slash): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
/g pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
/i pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
/s pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
/g pattern-matching modifier
finding Nth matches: 6.5.2. Solution (Perl Cookbook)
where last pattern ended: 6.14.3. Discussion (Perl Cookbook)
/m pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
multiple lines: 6.6.2. Solution (Perl Cookbook)
/o pattern-matching modifier: 6.10.2. Solution (Perl Cookbook)
root directory: 9.. Introduction (Perl Cookbook)
/s pattern-matching modifier
multiple lines: 6.6.2. Solution (Perl Cookbook)
/x pattern modifier: 1.12.3. Discussion (Perl Cookbook)
comments in regular expressions: 6.4.3. Discussion (Perl Cookbook)
-> little arrow: 5.2.3. The Big Arrow (Learning Perl)
13.8.3. The File::Spec Module (Learning Perl)
# (hash mark)
#! (shebang) line: 3. The Perl Executable (Perl in a Nutshell)
for comments: 4.1. Program Structure (Perl in a Nutshell)
format fieldholder: 4.12. Formats (Perl in a Nutshell)
- (hyphen): 3.10. Named Unary and File Test Operators (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
-0 command-line option: 8.. Basic Operations (Perl Cookbook)
-a command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-e command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-> (arrow) operator: 11.. References (Perl Cookbook)
13.. Methods (Perl Cookbook)
4.5.1. The Arrow Operator (Perl in a Nutshell)
3.2. The Arrow Operator (Programming Perl)
8.3.3. Using the Arrow Operator (Programming Perl)
dereferencing with: 4.8.2.1. Arrow dereferencing (Perl in a Nutshell)
method invocation with: 12.3.1. Method Invocation Using the Arrow Operator (Programming Perl)
-> (infix) notation: 11.. References (Perl Cookbook)
-i command-line option
modifying files with: 7.16.2. Solution (Perl Cookbook)
writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-I command-line switch: 12.8.2. Solution (Perl Cookbook)
-n command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-p command-line option
modifying files with: 7.16.2. Solution (Perl Cookbook)
writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-t command-line option: 15.2.2. Solution (Perl Cookbook)
arithmetic negation operator: 4.5.2. Unary Operators (Perl in a Nutshell)
3.5. Ideographic Unary Operators (Programming Perl)
in character ranges: 5.4.1. Custom Character Classes (Programming Perl)
character set subtraction: 5.4.3.4. Defining your own character properties (Programming Perl)
in debugger commands: 20.2.5. Locating Code (Programming Perl)
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
-*- for emacs: 19.1. Command Processing (Programming Perl)
-= (assignment) operator: 3.17. Assignment Operators (Programming Perl)
-- command-line switch: 19.1.3. Switches (Programming Perl)
->(arrow) operator: 8.3.3. Using the Arrow Operator (Programming Perl)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
subtractive operator: 3.8. Additive Operators (Programming Perl)
in [...] construct: 4.6.4. Character Classes (Perl in a Nutshell)
-- (autodecrement) operator: 4.5.5. Autoincrement and Autodecrement (Perl in a Nutshell)
1.5.4. Unary Arithmetic Operators (Programming Perl)
3.3. Autoincrement and Autodecrement (Programming Perl)
#! line: 1.4.2. What's Inside That Program? (Learning Perl)
1.5. A Whirlwind Tour of Perl (Learning Perl)
% modulus operator: 2.2.5. Numeric Operators (Learning Perl)
17.2. Picking Items from a List with grep (Learning Perl)
* multiplication operator: 2.2.5. Numeric Operators (Learning Perl)
! negation operator (see negation operator)
?: operator: 9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
( ) (parentheses): 4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
6.8.1. Exercise [30 min] (Learning Perl Objects, References and Modules)
3. Unary and Binary Operators (Programming Perl)
3.1. Terms and List Operators (Leftward) (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
24.3. Programming with Style (Programming Perl)
around function arguments: 5. Function Reference (Perl in a Nutshell)
for backreferences: 1.7.4. Backreferences (Programming Perl)
5.7.1. Capturing (Programming Perl)
5.7.1. Capturing (Programming Perl)
conditional operator, use with: 3.16. Conditional Operator (Programming Perl)
in functions: 29. Functions (Programming Perl)
grouping operator: 5.1. The Regular Expression Bestiary (Programming Perl)
null lists, representing: 2.8. List Values and Arrays (Programming Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
operator precedence and: 4.5. Operators (Perl in a Nutshell)
(...) grouping: 5.3.1. Metasymbol Tables (Programming Perl)
(?:PATTERN) notation, clustering without capturing: 5.7.2. Clustering (Programming Perl)
5.7.2. Clustering (Programming Perl)
as quote characters: 2.8. List Values and Arrays (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
(?...) extended regular expression syntax: 4.6.8. Extended Regular Expressions (Perl in a Nutshell)
% (percent sign): 3.10. Named Unary and File Test Operators (Programming Perl)
%SIG: 4.10. Signals (Perl in a Nutshell)
for checksums: 29.2.189. unpack (Programming Perl)
dereferencing with: 4.8.2. Dereferencing (Perl in a Nutshell)
for hash names: 1.2.1.2.2. Hashes. (Programming Perl)
2.4. Variables (Programming Perl)
hashes: 5.. Introduction (Perl Cookbook)
modulus operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
3.7. Multiplicative Operators (Programming Perl)
%= (modulus assignment) operator: 3.17. Assignment Operators (Programming Perl)
prototype character: 6.4. Prototypes (Programming Perl)
prototype symbol (hash): 4.7.5. Prototypes (Perl in a Nutshell)
%SIG hash: 16.15.2. Solution (Perl Cookbook)
signifying variable type: 4.2.5.2. Hashes (Perl in a Nutshell)
1.2.1. Variable Syntax (Programming Perl)
%= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
| pipe: 11.1. What Is a Filehandle? (Learning Perl)
14.5. Processes as Filehandles (Learning Perl)
+ (plus): 3.10. Named Unary and File Test Operators (Programming Perl)
1: 4.5.5. Autoincrement and Autodecrement (Perl in a Nutshell)
additive operator: 3.8. Additive Operators (Programming Perl)
in filenames: 29.2.104. open (Programming Perl)
++ (autoincrement) operator: 1.5.4. Unary Arithmetic Operators (Programming Perl)
3.3. Autoincrement and Autodecrement (Programming Perl)
quantifier: 1.7. Regular Expressions (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
unary operator: 4.5.2. Unary Operators (Perl in a Nutshell)
+= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
7.2.2. Simple Quantifiers (Learning Perl)
file-access modes: 7.1.3. Discussion (Perl Cookbook)
$!, portability of: 25.4. System Interaction (Programming Perl)
# pound sign: 1.4.2. What's Inside That Program? (Learning Perl)
with printf( ): 2.15.3. Discussion (Perl Cookbook)
? (question mark)
7.2.2. Simple Quantifiers (Learning Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
quantifier: 1.7.1. Quantifiers (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
in quantifiers: 5.5. Quantifiers (Programming Perl)
?: (conditional) operator: 3.16. Conditional Operator (Programming Perl)
4.5.1. Case Structures (Programming Perl)
?? quantifier: 5.3.1. Metasymbol Tables (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
?: (conditional) operator: 4.5.11.2. Conditional operator (Perl in a Nutshell)
?...? pattern match operator: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
?...? Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
**= raise to the power of operator: 2.5.3. Binary Assignment Operators (Learning Perl)
.. range operator: 3.3. List Literals (Learning Perl)
; (semicolon): 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
ending Perl statements: 4.1. Program Structure (Perl in a Nutshell)
in filenames, security risks of: 23.1.2. Cleaning Up Your Environment (Programming Perl)
Perl statements, terminating with: 2.2. Molecules (Programming Perl)
in prototype declarations: 4.7.5. Prototypes (Perl in a Nutshell)
simple statements, ending in: 4.1. Simple Statements (Programming Perl)
' (single quote): 1.. Introduction (Perl Cookbook)
escaping: 14.10.1. Problem (Perl Cookbook)
/ (slash): 3.10. Named Unary and File Test Operators (Programming Perl)
debugger command: 20.2.5. Locating Code (Programming Perl)
delimiters, replacing as: 2.6.3. Pick Your Own Quotes (Programming Perl)
division operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
3.7. Multiplicative Operators (Programming Perl)
encoding in URLs: 9.2. URL Encoding (Perl in a Nutshell)
root directory: 29.2.15. chroot (Programming Perl)
/=; (assignment) operator: 3.17. Assignment Operators (Programming Perl)
// (see m// operator)
/= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
/.../ pattern match operator: 4.6. Regular Expressions (Perl in a Nutshell)
/.../ Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
[] (square brackets): 1.. Introduction (Perl Cookbook)
4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
creating anonymous arrays and hashes: 11.. References (Perl Cookbook)
* star: 7.2.2. Simple Quantifiers (Learning Perl)
. string concatenate operator: 2.5.3. Binary Assignment Operators (Learning Perl)
-0 switch, perl: 19.1.3. Switches (Programming Perl)
-T (text) file test: 1.5.7. Some File Test Operators (Programming Perl)
?: ternary operator: 10.9.2. The Ternary Operator, ?: (Learning Perl)
~ (tilde)
bitwise negation operator: 4.5.2. Unary Operators (Perl in a Nutshell)
3.5. Ideographic Unary Operators (Programming Perl)
to suppress blank lines: 7. Formats (Programming Perl)
suppressing output whitespace: 4.12. Formats (Perl in a Nutshell)
~~ to print strings in fields: 4.12. Formats (Perl in a Nutshell)
in filenames, expanding: 7.3.1. Problem (Perl Cookbook)
~ tilde-prefix: 12.1. Moving Around the Directory Tree (Learning Perl)
_ underscore: 2.2.3. Integer Literals (Learning Perl)
4.10. The use strict Pragma (Learning Perl)
_ (underscore), file stat cache: 9.. Introduction (Perl Cookbook)
$0 variable: 7.12.3. Discussion (Perl Cookbook)
6.3. The Invocation Arguments (Learning Perl)
11.3. Fatal Errors with die (Learning Perl)
| (vertical bar)
||= (assignment) operator: 1.2.2. Solution (Perl Cookbook)
4.5.6. Assignment Operators (Perl in a Nutshell)
3.17. Assignment Operators (Programming Perl)
|| operator
vs. or operator: 1.2.3. Discussion (Perl Cookbook)
separating multiple comparisons: 4.16.3. Discussion (Perl Cookbook)
for alternation: 5.1. The Regular Expression Bestiary (Programming Perl)
bitwise or operator: 3.13. Bitwise Operators (Programming Perl)
for centering: 7.1. Format Variables (Programming Perl)
debugger command: 20.2.6. Actions and Command Execution (Programming Perl)
...|... alternation: 5.3.1. Metasymbol Tables (Programming Perl)
in filenames: 29.2.104. open (Programming Perl)
format fieldholders: 4.12. Formats (Perl in a Nutshell)
-| piping pseudocommand: 16.3.2. Talking to Yourself (Programming Perl)
metacharacter: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3. Metacharacters and Metasymbols (Programming Perl)
OR bitwise operator: 4.5.10. Bitwise Operators (Perl in a Nutshell)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
|| (logical or) operator: 5.9.1. Letting Perl Do the Work (Programming Perl)
12.3.3. Syntactic Snafus with Indirect Objects (Programming Perl)
|- piping pseudocommand: 16.3.2. Talking to Yourself (Programming Perl)
|| debugger command: 20.2.6. Actions and Command Execution (Programming Perl)
|= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
3.17. Assignment Operators (Programming Perl)
|| (logical OR) operator: 4.5.9. Logical Operators (Perl in a Nutshell)

Numbers

0 but true: 29.2.37. fcntl (Programming Perl)
-w exemption: 29.2.37. fcntl (Programming Perl)
-0 command-line option: 19.1. Command Processing (Programming Perl)
8. Basic Operations (Perl Cookbook)
0+ (numification) operator: 13.3. Overloadable Operators (Programming Perl)
\O038 (octal value) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

-a (autosplit) command-line switch: 19.1.3. Switches (Programming Perl)
a command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
-a command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
a command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-A (access age) file test operator: 3.10. Named Unary and File Test Operators (Programming Perl)
-A file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
\a for terminal bell: 15.7.2. Solution (Perl Cookbook)
-a option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-a option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
\a (alarm) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
\A (string boundary): 5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
abandon( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
abbrev( ): 6.20.3. Discussion (Perl Cookbook)
abbreviations, matching: 6.20.1. Problem (Perl Cookbook)
abbreviations, text: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
abort( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
abs( )
Perl built-in: 5. Function Reference (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
abs (absolute value) function: 29.2.1. abs (Programming Perl)
absent import lists: 12.2. Selecting What to Import (Learning Perl Objects, References and Modules)
absolute value: B.9.1. Advanced Math Functions (Learning Perl)
abstract methods: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
abstraction: 10. Packages (Programming Perl)
in object-oriented programming: 12.3. Method Invocation (Programming Perl)
-accelerator option (Menubutton): 21.14.1. Menu Item Options (Perl in a Nutshell)
accept( )
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
HTTP::Daemon module: 20.3.7. HTTP::Daemon (Perl in a Nutshell)
IO::Socket module: 15.2. The IO::Socket Module (Perl in a Nutshell)
15.2.2. Server-Side Sockets (Perl in a Nutshell)
15.2.3. IO::Socket Methods (Perl in a Nutshell)
Perl built-in: 5. Function Reference (Perl in a Nutshell)
socket function: 15.1. Built-in Socket Functions (Perl in a Nutshell)
15.1.3. Server Connections (Perl in a Nutshell)
accept( ): 17.2.3. Discussion (Perl Cookbook)
IO::Multiplex module: 17.19.2. Solution (Perl Cookbook)
accept function: 29.2.2. accept (Programming Perl)
access checks, setting in constructor: 12.7.5. Using Closures for Private Objects (Programming Perl)
access log, web server: 19.. Behind the Scenes (Perl Cookbook)
20.12.1. Problem (Perl Cookbook)
access time, file: 29.2.165. stat (Programming Perl)
29.2.193. utime (Programming Perl)
access to databases (see database access)
accessing
array of hashes: 9.3.3. Access and Printing of an Array of Hashes (Programming Perl)
elements, tied arrays: 14.2.1. Array-Tying Methods (Programming Perl)
hashes of arrays: 9.2.3. Access and Printing of a Hash of Arrays (Programming Perl)
multidimensional arrays: 9.1.3. Access and Printing (Programming Perl)
multidimensional hashes: 9.4.3. Access and Printing of a Hash of Hashes (Programming Perl)
overridden methods: 12.5.2. Accessing Overridden Methods (Programming Perl)
records of elaborate data structures: 9.6.1. Composition, Access, and Printing of More Elaborate Records (Programming Perl)
slices of multidimensional arrays: 9.1.4. Slices (Programming Perl)
accessor methods: 12.4.2. Initializers (Programming Perl)
Glossary (Programming Perl)
class data methods, working like: 12.8. Managing Class Data (Programming Perl)
creating: 12.7. Managing Instance Data (Programming Perl)
generating with autoloading: 12.7.3. Generating Accessors with Autoloading (Programming Perl)
generating with closures: 12.7.4. Generating Accessors with Closures (Programming Perl)
pseudohashes and: 12.7.1. Field Declarations with use fields (Programming Perl)
accessors
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
Class::MethodMaker module: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
account entries (.netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
account( ) (Net::Netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
$ACCUMULATOR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$ACCUMULATOR ($^A) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
actions (debugger)
command execution, specifying from debugger: 20.2.6. Actions and Command Execution (Programming Perl)
listing all: 20.2.2. Breakpoints (Programming Perl)
activate( )
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Scrollbar widget: 21.9.1. Scrollbar Methods (Perl in a Nutshell)
active( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
active index
Listbox widget: 21.10.1. Listbox Indexes (Perl in a Nutshell)
Menu widget: 21.15.1. Menu Indexes (Perl in a Nutshell)
-activebackground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-activeborderwidth option (Menu): 21.15. The Menu Widget (Perl in a Nutshell)
-activeborderwidth option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-activeforeground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
ActivePerl distribution: 2.3.2.1. ActivePerl (Perl in a Nutshell)
2.4.3. Installing Modules with ActiveState Perl (Perl in a Nutshell)
-activerelief option (Scrollbar): 21.9. The Scrollbar Widget (Perl in a Nutshell)
ActiveState Perl
installing documentation: 2.5.1. Installing the Documentation (Perl in a Nutshell)
installing modules with: 2.4.3. Installing Modules with ActiveState Perl (Perl in a Nutshell)
ActiveState Perl distribution
installing on Windows systems: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
Microsoft-only modules: 32.1.20. Microsoft-Related Modules (Programming Perl)
PPM (Perl Package Manager): 22.2. Using CPAN Modules (Programming Perl)
active_times( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
add( )
Digest modules: 8.57. Digest (Perl in a Nutshell)
Digest::MD5 module: 8.58. Digest::MD5 (Perl in a Nutshell)
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Net::LDAP: 19.3. Adding an Entry to the Directory with Net::LDAP (Perl in a Nutshell)
19.4. Net::LDAP Methods (Perl in a Nutshell)
AddConnection( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
add_content( ) (HTTP::Message): 20.3.8. HTTP::Message (Perl in a Nutshell)
add_cookie_header( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies (Perl in a Nutshell)
addfile( )
Digest modules: 8.57. Digest (Perl in a Nutshell)
Digest::MD5 module: 8.58. Digest::MD5 (Perl in a Nutshell)
add_group( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
AddHeader( ) Win32::Internet module: 22.7.3. HTTP Functions (Perl in a Nutshell)
adding additional array elements: 29.2.190. unshift (Programming Perl)
AddItems( ) (Menubutton): 21.14.2. Menubutton Methods (Perl in a Nutshell)
addition: 1.5.1. Some Binary Arithmetic Operators (Programming Perl)
overloaded plus (+) operator: 13.2. Overload Handlers (Programming Perl)
addition operator (+): 2.2.5. Numeric Operators (Learning Perl)
additive operators: 3.8. Additive Operators (Programming Perl)
add_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
address( ) (Mail::Address): 16.2.7. Mail::Address Reference (Perl in a Nutshell)
address-of operator (in C): 3.21. C Operators Missing from Perl (Programming Perl)
Glossary (Programming Perl)
addresses
C language, Perl vs.: 24.1.3. C Traps (Programming Perl)
email, matching: 6.19.1. Problem (Perl Cookbook)
email, parsing: 16.2.6. Parse Email Addresses with Mail::Address (Perl in a Nutshell)
getting from hostnames: 29.2.52. getnetbyname (Programming Perl)
network, getting from hostnames: 29.2.48. gethostbyname (Programming Perl)
network, translating to names: 29.2.47. gethostbyaddr (Programming Perl)
29.2.51. getnetbyaddr (Programming Perl)
packed socket: 29.2.67. getsockname (Programming Perl)
reused, displaying contents of: 20.3.3. Debugger Options (Programming Perl)
socket names as: 29.2.5. bind (Programming Perl)
add_signature( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
addTag( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
adist( ): 1.22.3. Discussion (Perl Cookbook)
administering network servers: 22.10. Win32::NetAdmin (Perl in a Nutshell)
advisory locking: 7.18.2. Solution (Perl Cookbook)
-after option (pack geometry manager): 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
_agent( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
20.2.3. LWP::UserAgent (Perl in a Nutshell)
.al file extension: 8.5. AutoLoader (Perl in a Nutshell)
10.2. Autoloading (Programming Perl)
alarm( ): 5. Function Reference (Perl in a Nutshell)
3.9.3. Discussion (Perl Cookbook)
16.21.2. Solution (Perl Cookbook)
29.2.3. alarm (Programming Perl)
pattern match, timing out: 23.3.2. Code Masquerading as Data (Programming Perl)
ringing: 15.7.1. Problem (Perl Cookbook)
alert (bell): 2.6.2. String Literals (Programming Perl)
algorithms: Glossary (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Alias module: 13.3.3. Discussion (Perl Cookbook)
aliases: Glossary (Programming Perl)
for characters: 5.3.2. Specific Characters (Programming Perl)
debugger command for: 20.2.7. Miscellaneous Commands (Programming Perl)
in for/foreach loops
searching and replacing elements in arrays: 5.2.3.1. Modifying strings en passant (Programming Perl)
for filehandles: 7.10.1. Problem (Perl Cookbook)
for functions: 10.14.3. Discussion (Perl Cookbook)
for list elements: 4.5.3. Discussion (Perl Cookbook)
for/foreach loops, creating with: 4.5.1. Case Structures (Programming Perl)
symbol table entries: 2.5.1. Name Lookups (Programming Perl)
2.10. Typeglobs and Filehandles (Programming Perl)
symbol table key, assignment to typeglob: 10.1. Symbol Tables (Programming Perl)
aliasing in foreach loops: 4.4.3. foreach Loops (Programming Perl)
:all method group: 10.2. Importing Method Groups (Perl in a Nutshell)
All( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods (Perl in a Nutshell)
Alloc( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
ALRM signal: 16.1.3. Timing Out Slow Operations (Programming Perl)
alternate quoting schemes: 4.2.2. String Interpolation (Perl in a Nutshell)
alternation: 5.1. The Regular Expression Bestiary (Programming Perl)
Glossary (Programming Perl)
character classes and: 5.4.1. Custom Character Classes (Programming Perl)
interior, limiting scope of: 5.7.2. Clustering (Programming Perl)
match one or the other (...|...): 5.3.1. Metasymbol Tables (Programming Perl)
in patterns: 5.8. Alternation (Programming Perl)
precedence, pattern matching: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
American Standard Code for Information Interchange (see ASCII)
Glossary (Programming Perl)
ampersand (&)
AND bitwise operator: 4.5.10. Bitwise Operators (Perl in a Nutshell)
calling subroutines: 4.7.1. Calling Subroutines (Perl in a Nutshell)
in encoded URLs: 9.2. URL Encoding (Perl in a Nutshell)
in subroutine names: 4.3. Invoking a Subroutine (Learning Perl)
omitting: 4.11.1. Omitting the Ampersand (Learning Perl)
prototype symbol: 4.7.5. Prototypes (Perl in a Nutshell)
&& (logical AND) operator: 4.5.9. Logical Operators (Perl in a Nutshell)
&&= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
&= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
&& operator: 1.2.3. Discussion (Perl Cookbook)
&max subroutine: 4.5. Arguments (Learning Perl)
4.8.1. A Better &max Routine (Learning Perl)
anchor index
Entry widget: 21.8.1. Text Indexes (Perl in a Nutshell)
Listbox widget: 21.10.1. Listbox Indexes (Perl in a Nutshell)
-anchor option
pack geometry manager: 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
place geometry manager: 21.2.3. The place Geometry Manager (Perl in a Nutshell)
widgets: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
anchors: 8.3. Anchors (Learning Perl)
1.7.3. Nailing Things Down (Programming Perl)
5.6. Positions (Programming Perl)
multiple-line text and: 17.5.2. Matching Multiple-line Text (Learning Perl)
in regular expressions: 4.6.5. Anchors (Perl in a Nutshell)
and (logical AND) operator: 4.5.9. Logical Operators (Perl in a Nutshell)
AND (&) operator, bitwise: 4.5.10. Bitwise Operators (Perl in a Nutshell)
AND (&&) operator, logical: 4.5.9. Logical Operators (Perl in a Nutshell)
and (&) bitwise operator: 3.13. Bitwise Operators (Programming Perl)
and (&&) logical operator: 1.5.5. Logical Operators (Programming Perl)
3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
precedence, and operator vs. &&: 12.3.3. Syntactic Snafus with Indirect Objects (Programming Perl)
AND functionality in regular expressions: 6.18.1. Problem (Perl Cookbook)
and operator: 24.3. Programming with Style (Programming Perl)
AND operator (&&): 10.9. Logical Operators (Learning Perl)
10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
angle brackets (see also angle brackets)
12.3. An Alternate Syntax for Globbing (Learning Perl)
1.4. Filehandles (Programming Perl)
1.5. A Whirlwind Tour of Perl (Learning Perl)
filename globbing and: 12.3. An Alternate Syntax for Globbing (Learning Perl)
<=> (comparison) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
<...> (line-input) operator: 4.9. Filehandles (Perl in a Nutshell)
<<= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
<< debugger commands, and: 6.2. Debugger Commands (Perl in a Nutshell)
< (less-than) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
<= (less-than-or-equal) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
>>= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
> (greater-than) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
>= (greater-than-or-equal) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
>> to open file for appending: 4.9. Filehandles (Perl in a Nutshell)
angle operator: 2.11.2. Line Input (Angle) Operator (Programming Perl)
19.1.3. Switches (Programming Perl)
24.1.2. Frequently Ignored Advice (Programming Perl)
reading filehandle from: 14.4.1. Filehandle-Tying Methods (Programming Perl)
angles, in degrees vs. radians: 2.10.1. Problem (Perl Cookbook)
anonymous: Glossary (Programming Perl)
array composer: 8.2.2.1. The anonymous array composer (Programming Perl)
arrays
hash of, creating: 9.2.1. Composition of a Hash of Arrays (Programming Perl)
two-dimensional array slice: 9.1.4. Slices (Programming Perl)
hash composer: 8.2.2.2. The anonymous hash composer (Programming Perl)
hashes
adding to multidimensional hashes: 9.4.1. Composition of a Hash of Hashes (Programming Perl)
array of, creating: 9.3.1. Composition of an Array of Hashes (Programming Perl)
data structue for objects: 12.4. Object Construction (Programming Perl)
pipes: 16.3.1. Anonymous Pipes (Programming Perl)
referents: 8.1. What Is a Reference? (Programming Perl)
subroutine composer: 8.2.2.3. The anonymous subroutine composer (Programming Perl)
subroutines: 6. Subroutines (Programming Perl)
giving names at run time: 10.1. Symbol Tables (Programming Perl)
anonymous arrays
complex data and: 5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
creating directly: 4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
defined: 4.2. What if That Was the Name? (Learning Perl Objects, References and Modules)
hash references and: 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
square brackets and: 4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
anonymous data: 11.. Anonymous Data (Perl Cookbook)
anonymous data, referencing: 4.8.1.1. Referencing anonymous data (Perl in a Nutshell)
anonymous FTP: 2.1. The CPAN Architecture (Perl in a Nutshell)
18.1. The FTP Protocol (Perl in a Nutshell)
anonymous hash
creating: 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
filesystem capture example: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
anonymous subroutines: B.20.3. Anonymous Subroutines and Closures (Learning Perl)
4.7. Subroutines (Perl in a Nutshell)
6.2. Anonymous Subroutines (Learning Perl Objects, References and Modules)
6.2. Anonymous Subroutines (Learning Perl Objects, References and Modules)
answers to exercises in this book: A. Exercise Answers (Learning Perl)
antique_client( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
AnyDBM_file manpage: 16.1. DBM Files and DBM Hashes (Learning Perl)
AnyDBM_File module: 8.1. AnyDBM_File (Perl in a Nutshell)
32.1.10. DBM Interfaces (Programming Perl)
a2p conversion program: B.25. Converting Other Languages to Perl (Learning Perl)
Apache modules: 11.7. Apache:: Modules (Perl in a Nutshell)
Apache::DumpHeaders module: 11.3. mod_perl Handlers (Perl in a Nutshell)
Apache::Include module: 11.5. Server-Side Includes with mod_perl (Perl in a Nutshell)
Apache server, mod_perl with: 11. Web Server Programmingwith mod_perl (Perl in a Nutshell)
Apache web server: 21.. Introduction (Perl Cookbook)
21.4. Embedding Perl (Using Perl from C) (Programming Perl)
CGI::Apache module: 32.1.9. World Wide Web (Programming Perl)
handlers, writing: 21.. Handlers (Perl Cookbook)
internal redirection: 21.4.3. Discussion (Perl Cookbook)
log files: 20.12.1. Problem (Perl Cookbook)
logging requests, customizing: 21.9.1. Problem (Perl Cookbook)
mod_perl extension: 18.3. Executing Your Code (Programming Perl)
notes: 21.11.3. Discussion (Perl Cookbook)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
phases of request-response transaction: 21.. Apache Phases (Perl Cookbook)
pnotes, sharing information between handlers: 21.13.2. Solution (Perl Cookbook)
Apache::Cookie module: 21.2.2. Solution (Perl Cookbook)
accessing values: 21.3.2. Solution (Perl Cookbook)
Apache::DBI module: 21.8.2. Solution (Perl Cookbook)
Apache::DBILogger module: 21.9.3. Discussion (Perl Cookbook)
Apache::DProf module: 21.15.2. Solution (Perl Cookbook)
Apache::PerlRun module: 21.. Introduction (Perl Cookbook)
migrating from CGI to mod_perl: 21.12.2. Solution (Perl Cookbook)
Apache::Registry module: 21.. Introduction (Perl Cookbook)
migrating from CGI to mod_perl: 21.12.2. Solution (Perl Cookbook)
Apache::Reload module: 21.14.2. Solution (Perl Cookbook)
Apache::Request module
accessing form parameters: 21.6.2. Solution (Perl Cookbook)
receiving uploaded files: 21.7.2. Solution (Perl Cookbook)
Apache::StatINC module: 21.14.2. Solution (Perl Cookbook)
Apache::Template module (see Template Toolkit)
Apache::Timeit module: 21.15.2. Solution (Perl Cookbook)
Apache::Traffic module: 21.9.3. Discussion (Perl Cookbook)
API (Application Programming Interface): 9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
apop( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
appe( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
append( )
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
append operator (.=): 2.5.3. Binary Assignment Operators (Learning Perl)
appendChild( ): 22.2.3. Discussion (Perl Cookbook)
appendhash_demo program: 13.15.5. Tie Example: Make a Hash That Always Appends (Perl Cookbook)
appending
elements to arrays: 9.1.2. Growing Your Own (Programming Perl)
29.2.116. push (Programming Perl)
members to existing hash: 9.3.2. Generation of an Array of Hashes (Programming Perl)
appending arrays to each other: 4.10.1. Problem (Perl Cookbook)
append_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
applications
mod_perl, benchmarking: 21.15.1. Problem (Perl Cookbook)
shopping cart: 19.11.1. Problem (Perl Cookbook)
approximate matching: 6.13.1. Problem (Perl Cookbook)
architecture: Glossary (Programming Perl)
archiving: 13. Writing a Distribution (Learning Perl Objects, References and Modules)
arctangents: 29.2.4. atan2 (Programming Perl)
$ARG: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$ARG ($_) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
argc: 6.3. The Invocation Arguments (Learning Perl)
argument lists (see parameter lists)
arguments: 4.5. Arguments (Learning Perl)
8.9. What to Do with @_ (Learning Perl Objects, References and Modules)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also parameters)
actual: Glossary (Programming Perl)
formal: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
passing to subroutines: 4.7.2. Passing Arguments (Perl in a Nutshell)
subroutine: 10.1.1. Problem (Perl Cookbook)
function prototypes: 10.11.1. Problem (Perl Cookbook)
passing by named parameter: 10.7.1. Problem (Perl Cookbook)
passing by reference: 10.5.1. Problem (Perl Cookbook)
@ARGV array: 6.3. The Invocation Arguments (Learning Perl)
4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
2.11.2. Line Input (Angle) Operator (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
ARGV filehandle: 4.4.3. Global Special Filehandles (Perl in a Nutshell)
4.9. Filehandles (Perl in a Nutshell)
28.2. Special Variables in Alphabetical Order (Programming Perl)
ARGV line input operator: 7.. I/O Operations (Perl Cookbook)
ARGV, magic: 8.25. Program: tctee (Perl Cookbook)
16.6.3. Discussion (Perl Cookbook)
-argv option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
$ARGV variable: 6.2. Input from the Diamond Operator (Learning Perl)
4.4.1. Global Special Variables (Perl in a Nutshell)
28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
ARGVOUT filehandle: 28.2. Special Variables in Alphabetical Order (Programming Perl)
arithmetic
complex (imaginary) numbers: 2.14.1. Problem (Perl Cookbook)
matrix multiplication: 2.13.1. Problem (Perl Cookbook)
overloaded objects and: 13.2. Overload Handlers (Programming Perl)
arithmetic operators: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
3.5. Ideographic Unary Operators (Programming Perl)
Glossary (Programming Perl)
binary arithmetic operators: 1.5.1. Some Binary Arithmetic Operators (Programming Perl)
order of evaluation: 1.5.1. Some Binary Arithmetic Operators (Programming Perl)
overloading: 13.3. Overloadable Operators (Programming Perl)
arity: 3. Unary and Binary Operators (Programming Perl)
highest to lowest, listing of: 3. Unary and Binary Operators (Programming Perl)
array context (see list context)
array elements: 3.1. Accessing Elements of an Array (Learning Perl)
array indices: 3.2. Special Array Indices (Learning Perl)
array reference
anonymous array constructors and: 4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
arrows and: 3.7. Simplifying Nested Element References with Arrows (Learning Perl Objects, References and Modules)
3.7. Simplifying Nested Element References with Arrows (Learning Perl Objects, References and Modules)
blessing: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
curly braces and: 3.4. Dropping Those Braces (Learning Perl Objects, References and Modules)
3.4. Dropping Those Braces (Learning Perl Objects, References and Modules)
dereferencing: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
4.2. What if That Was the Name? (Learning Perl Objects, References and Modules)
efficient sorting example: 7.3. Sorting Efficiently (Learning Perl Objects, References and Modules)
empty arrays and: 4.7. Autovivification (Learning Perl Objects, References and Modules)
features: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
hashes into: 5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
IO::File objects and: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
modifying: 3.5. Modifying the Array (Learning Perl Objects, References and Modules)
3.5. Modifying the Array (Learning Perl Objects, References and Modules)
nested data structures: 3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
Schwartzian Transform: 7.4. The Schwartzian Transform (Learning Perl Objects, References and Modules)
$#ARRAY variable: 4.3.2. Solution (Perl Cookbook)
arrayDepth option (debugger): 20.3.3. Debugger Options (Programming Perl)
arrays: 4.. Introduction (Perl Cookbook)
3. Lists and Arrays (Learning Perl)
B.10. Lists and Arrays (Learning Perl)
4.2. Data Types and Variables (Perl in a Nutshell)
4.2.5.1. Arrays (Perl in a Nutshell)
4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
1.2.1. Variable Syntax (Programming Perl)
1.2.1.2. Pluralities (Programming Perl)
2.3. Built-in Data Types (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also lists)
@_ arrays: 6.2. Semantics (Programming Perl)
copying values to my list: 6.2.1. Tricks with Parameter Lists (Programming Perl)
anonymous: 11.. Anonymous Data (Perl Cookbook)
anonymous, objects implemented as: 12.7.1. Field Declarations with use fields (Programming Perl)
use fields pragma, overcoming problems with: 12.7.1. Field Declarations with use fields (Programming Perl)
anonymous, references to: 8.2.2.1. The anonymous array composer (Programming Perl)
appending elements to: 29.2.116. push (Programming Perl)
appending multiple: 4.10.1. Problem (Perl Cookbook)
associative (see hashes)
AV (array value) typedef in C, corresponding to: 21.2. Internal Data Types (Programming Perl)
changing size of: 4.3.1. Problem (Perl Cookbook)
circular: 4.17.1. Problem (Perl Cookbook)
curly braces: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
deleting elements of: 29.2.149. shift (Programming Perl)
29.2.160. splice (Programming Perl)
dereferencing and: 3.5. Modifying the Array (Learning Perl Objects, References and Modules)
4.2. What if That Was the Name? (Learning Perl Objects, References and Modules)
elements, giving temporary values to: 29.2.87. local (Programming Perl)
exists function and: 29.2.34. exists (Programming Perl)
extracting
elements: 4.7.1. Problem (Perl Cookbook)
subsets: 4.14.1. Problem (Perl Cookbook)
subsets with grep: 4.14.2. Solution (Perl Cookbook)
first element of: 28.2. Special Variables in Alphabetical Order (Programming Perl)
functions for processing: 5.1. Perl Functions by Category (Perl in a Nutshell)
of hashes: 9.3. Arrays of Hashes (Programming Perl)
accessing and printing: 9.3.3. Access and Printing of an Array of Hashes (Programming Perl)
generating: 9.3.2. Generation of an Array of Hashes (Programming Perl)
hashes of: 11.2.1. Problem (Perl Cookbook)
9.2. Hashes of Arrays (Programming Perl)
initializing: 4.1.1. Problem (Perl Cookbook)
initializing, with comma-separated values: 4.1.2. Solution (Perl Cookbook)
initializing with x operator: 3.7. Multiplicative Operators (Programming Perl)
interpolating vs. printing: 6.4. Output to Standard Output (Learning Perl)
iterating
over by reference: 4.6.1. Problem (Perl Cookbook)
through all elements: 4.5.1. Problem (Perl Cookbook)
through elements: 4.13.1. Problem (Perl Cookbook)
last element of: 2.8.2. Array Length (Programming Perl)
last valid index ($#ARRAY): 4.3.3. Discussion (Perl Cookbook)
length of: 2.8.2. Array Length (Programming Perl)
list values vs.: 2.8. List Values and Arrays (Programming Perl)
vs. lists: 4.. Introduction (Perl Cookbook)
lists and: 2.8. List Values and Arrays (Programming Perl)
matrix multiplication: 2.13.1. Problem (Perl Cookbook)
modifying: 3.5. Modifying the Array (Learning Perl Objects, References and Modules)
3.5. Modifying the Array (Learning Perl Objects, References and Modules)
multidimensional: 4.. Introduction (Perl Cookbook)
1.2.1.3. Complexities (Programming Perl)
9.1. Arrays of Arrays (Programming Perl)
Glossary (Programming Perl)
names for: 2.4. Variables (Programming Perl)
negative subscripts, counting from end of array: 24.1.5. Previous Perl Traps (Programming Perl)
nested: 9.1. Arrays of Arrays (Programming Perl)
two-dimensional arrays, creating and accessing: 9.1.1. Creating and Accessing a Two-Dimensional Array (Programming Perl)
nested data structures and: 3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
ordered lists and: 3. Introduction to References (Learning Perl Objects, References and Modules)
output style, changing in debugger: 20.3.3. Debugger Options (Programming Perl)
package names and: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
parsing text into: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
passing by reference into or out of functions: 6.3. Passing References (Programming Perl)
performance and: 24.2.1. Time Efficiency (Programming Perl)
permute program: 4.20. Program: permute (Perl Cookbook)
pop function and: 29.2.111. pop (Programming Perl)
prepending elements to: 29.2.190. unshift (Programming Perl)
printf function and: 6.5.1. Arrays and printf (Learning Perl)
printing elements with commas: 4.2.1. Problem (Perl Cookbook)
processing, functions for: 29.1. Perl Functions by Category (Programming Perl)
processing multiple elements: 4.12.1. Problem (Perl Cookbook)
randomizing: 4.18.1. Problem (Perl Cookbook)
randomly selecting from: 2.6.3. Discussion (Perl Cookbook)
reading files backwards: 8.4.1. Problem (Perl Cookbook)
references to: 11.1.1. Problem (Perl Cookbook)
8.1. What Is a Reference? (Programming Perl)
referencing: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
replacing/removing elements: 29.2.160. splice (Programming Perl)
reversing elements of: 4.11.1. Problem (Perl Cookbook)
s/// (substitution) operator and: 5.2.3.1. Modifying strings en passant (Programming Perl)
of scalar references: 11.6.1. Problem (Perl Cookbook)
scalars and: 3. Introduction to References (Learning Perl Objects, References and Modules)
scoping considerations: 4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
slices and: 17.6.1. Array Slice (Learning Perl)
sorting
by computable field: 4.16.1. Problem (Perl Cookbook)
elements numerically: 4.15.1. Problem (Perl Cookbook)
sparse, implementing: 4.4.1. Problem (Perl Cookbook)
special (predefined): 4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
splice operator for: B.10.2. The splice Operator (Learning Perl)
subscript separator (see $[semi] variable)
taint in: 23.1. Handling Insecure Data (Programming Perl)
tied, delete function and: 24.1.5. Previous Perl Traps (Programming Perl)
treating files as: 8.18.1. Problem (Perl Cookbook)
tying: 14.2. Tying Arrays (Programming Perl)
methods for: 14.2.1. Array-Tying Methods (Programming Perl)
notational convenience: 14.2.2. Notational Convenience (Programming Perl)
Tie::Array module: 32.1.14. Convenient Classes (Programming Perl)
unions, intersections, differences: 4.8.1. Problem (Perl Cookbook)
variables of: 2.6.5. Interpolating Array Values (Programming Perl)
words program: 4.19. Program: words (Perl Cookbook)
arrow operator (->: 8.3.3. Using the Arrow Operator (Programming Perl)
12.3.1. Method Invocation Using the Arrow Operator (Programming Perl)
11.. References (Perl Cookbook)
13.. Methods (Perl Cookbook)
4.5.1. The Arrow Operator (Perl in a Nutshell)
3.2. The Arrow Operator (Programming Perl)
dereferencing with: 4.8.2.1. Arrow dereferencing (Perl in a Nutshell)
arrows: 5.2.3. The Big Arrow (Learning Perl)
17.4. Unquoted Hash Keys (Learning Perl)
drop arrow rule: 3.7. Simplifying Nested Element References with Arrows (Learning Perl Objects, References and Modules)
hash references and: 3.8. References to Hashes (Learning Perl Objects, References and Modules)
3.8. References to Hashes (Learning Perl Objects, References and Modules)
method invocation arrow: 8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
8.10. Where We Are So Far... (Learning Perl Objects, References and Modules)
10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
article command (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
article( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
articles, news: 17.1. The NNTP Protocol (Perl in a Nutshell)
artificial languages: 1.2. Natural and Artificial Languages (Programming Perl)
As( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods (Perl in a Nutshell)
ASCII: 2.1. Atoms (Programming Perl)
Glossary (Programming Perl)
converting to characters: 29.2.14. chr (Programming Perl)
values for characters: 29.2.106. ord (Programming Perl)
ASCII (American Standard Code for Information Interchange): 1.. The Universal Character Code (Perl Cookbook)
characters (see characters)
converting HTML to: 20.5.1. Problem (Perl Cookbook)
ASCII characters, converting to Unicode: 15.2. Effects of Character Semantics (Programming Perl)
ASCII mode: 1.4. How Do I Make a Perl Program? (Learning Perl)
ascii( ) (Net::FTP module): 18.2. Net::FTP (Perl in a Nutshell)
Ascii( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
ASCIIbetical order, sort operator for: 3.7.2. The sort Operator (Learning Perl)
as_HTML( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
ASP
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
aspect( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
assertions
defining your own: 5.10.4. Defining Your Own Assertions (Programming Perl)
lookaround assertions: 5.10.1. Lookaround Assertions (Programming Perl)
precedence, pattern matching: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
assertions (in matching)
\b and \B (word and non word boundary): 5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
positional
\z, \Z, and $ assertions: 5.6.2. Endings: The \z, \Z, and $ Assertions (Programming Perl)
assertions (in patterns): 5.1. The Regular Expression Bestiary (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
Glossary (Programming Perl)
character classes and: 5.4.1. Custom Character Classes (Programming Perl)
\G positional assertion: 5.2.2. The m// Operator (Matching) (Programming Perl)
positional: 5.6. Positions (Programming Perl)
\A and ^ assertions (string boundary): 5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
assign function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
assigning
hashes: 5.2.2. Hash Assignment (Learning Perl)
lists: 3.4. List Assignment (Learning Perl)
scalars: 2.5.2. Scalar Assignment (Learning Perl)
assigning to lists: 2.8.1. List Assignment (Programming Perl)
assignment
to conditional operator: 3.16. Conditional Operator (Programming Perl)
elements, two-dimsional arrays: 9.1.2. Growing Your Own (Programming Perl)
of tied variables: 14.1.1. Scalar-Tying Methods (Programming Perl)
tied array element: 14.2.1. Array-Tying Methods (Programming Perl)
assignment (||=) operator: 1.2.2. Solution (Perl Cookbook)
assignment, list: 1.3.2. Solution (Perl Cookbook)
assignment operator: 2.3. Built-in Data Types (Programming Perl)
assignment operator (=): 2.5.2. Scalar Assignment (Learning Perl)
assignment operators: 4.5.6. Assignment Operators (Perl in a Nutshell)
1.5.3. Assignment Operators (Programming Perl)
3.17. Assignment Operators (Programming Perl)
Glossary (Programming Perl)
overloading: 13.3. Overloadable Operators (Programming Perl)
13.4. The Copy Constructor (=) (Programming Perl)
(see also copy constructor)
precedence, Perl versions, differences in: 24.1.5. Previous Perl Traps (Programming Perl)
values, returning: 1.5.3. Assignment Operators (Programming Perl)
associative arrays (see also hashes)
5. Hashes (Learning Perl)
1.2.1.2.2. Hashes. (Programming Perl)
29.2.22. dbmopen (Programming Perl)
associativity: 2.6.2. Operator Precedence and Associativity (Learning Perl)
chart of: 2.6.2. Operator Precedence and Associativity (Learning Perl)
associativity of operators: Glossary (Programming Perl)
associativity, operators: 3. Unary and Binary Operators (Programming Perl)
as_something method: 14.4. SOAP::Serializer (Perl in a Nutshell)
asssociativity operators: 3.11. Relational Operators (Programming Perl)
as_string( )
HTTP::Cookies module: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
HTTP::Request module: 20.3.1. HTTP::Request (Perl in a Nutshell)
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
LWP::RobotUA module: 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
asterisk (*)
dereference operator (in C): 3.21. C Operators Missing from Perl (Programming Perl)
multiplication operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
prototype symbol (typeglob): 4.7.5. Prototypes (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
** (exponentiation) operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
**= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
*= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
typeglobs: 7.5.1. Problem (Perl Cookbook)
astronomy, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
async function: 17.2.1.1. Thread creation (Programming Perl)
asynchronous events: Glossary (Programming Perl)
at sign (@)
@_ array: 10.1.2. Solution (Perl Cookbook)
4.7.2. Passing Arguments (Perl in a Nutshell)
dereferencing with: 4.8.2. Dereferencing (Perl in a Nutshell)
@EXPORT array (use pragma): 12.1.3. Discussion (Perl Cookbook)
@EXPORT_OK array (use pragma): 12.1.3. Discussion (Perl Cookbook)
@EXPORT_TAGS array (use pragma): 12.1.3. Discussion (Perl Cookbook)
format fieldholders: 4.12. Formats (Perl in a Nutshell)
@INC array: 12.8.3. Discussion (Perl Cookbook)
prototype symbol (list): 4.7.5. Prototypes (Perl in a Nutshell)
references to arrays: 11.1.2. Solution (Perl Cookbook)
signifying arrays: 4.2.5.1. Arrays (Perl in a Nutshell)
splice( ): 4.12.3. Discussion (Perl Cookbook)
at-sign(@) indicating arrays: 3.4. List Assignment (Learning Perl)
atan2( ): 5. Function Reference (Perl in a Nutshell)
atan function: 29.2.4. atan2 (Programming Perl)
$atime file statistic: 29.2.165. stat (Programming Perl)
atime field, inode structure: 9.. Introduction (Perl Cookbook)
$atime (timestamp): 11.6.1. The stat and lstat Functions (Learning Perl)
changing: 13.7. Changing Timestamps (Learning Perl)
atoms: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Glossary (Programming Perl)
precedence, pattern matching: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
attach( ): 18.9.2. Solution (Perl Cookbook)
Attlist handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
attr( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
Attr( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
Attribute::Handlers module: 8.2. Attribute::Handlers (Perl in a Nutshell)
diagnostics: 8.2. Attribute::Handlers (Perl in a Nutshell)
attributes: 6.5. Subroutine Attributes (Programming Perl)
12.4.2. Initializers (Programming Perl)
Glossary (Programming Perl)
attributes module: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
class: 29.2.99. my (Programming Perl)
class, storing state for: 12.8. Managing Class Data (Programming Perl)
files, test operators for: 1.5.7. Some File Test Operators (Programming Perl)
locked and method, using with threads: 12.7.6. New Tricks (Programming Perl)
locked, subroutines: 17.2.2.4. The locked attribute (Programming Perl)
lvalue, subroutines: 12.7.6. New Tricks (Programming Perl)
objects, hashes of: 1.2.1.3. Complexities (Programming Perl)
subclass, overriding superclass ancestor: 12.7. Managing Instance Data (Programming Perl)
subroutines: 6.5. Subroutine Attributes (Programming Perl)
names, syntax for: 6.5.1. The locked and method Attributes (Programming Perl)
variable interpolation and: 29.2.107. our (Programming Perl)
attributes module: 8.3. attributes (Perl in a Nutshell)
attributes, object: 13.3.1. Problem (Perl Cookbook)
attrs module: 8.4. attrs (Perl in a Nutshell)
attrs module (obsolete): 32.1.13. Perl Language Extensions and Internals (Programming Perl)
attrs.pm (see attributes module)
audio, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Authen::SASL module: 18.8.3. Discussion (Perl Cookbook)
authentication
fetching password-protected web pages: 20.15.1. Problem (Perl Cookbook)
with mod_perl: 21.1.1. Problem (Perl Cookbook)
realms: 20.15.3. Discussion (Perl Cookbook)
authentication, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
32.1.12. Authentication, Security, and Encryption (Programming Perl)
authentication, POP3: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
authinfo( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
authorization, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
authorize( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
auth_type( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
autobundle command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
AutoCommit attribute (DBI): 12.2.3. Database Handles and Statement Handles (Perl in a Nutshell)
autodecrement (--) operator: 4.5.5. Autoincrement and Autodecrement (Perl in a Nutshell)
10.6. Autoincrement and Autodecrement (Learning Perl)
1.5.4. Unary Arithmetic Operators (Programming Perl)
3.3. Autoincrement and Autodecrement (Programming Perl)
magical: 13.3. Overloadable Operators (Programming Perl)
autoEscape( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
autoflush( ): 7.19.2. Solution (Perl Cookbook)
16.10.3. Discussion (Perl Cookbook)
autoflushing buffers: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
autogeneration, overloading: 13.3. Overloadable Operators (Programming Perl)
Glossary (Programming Perl)
autoincrement and autodecrement: 13.3. Overloadable Operators (Programming Perl)
preventing: 13.5. When an Overload Handler Is Missing (nomethod and fallback) (Programming Perl)
autoincrement (++) operator: 4.5.5. Autoincrement and Autodecrement (Perl in a Nutshell)
1.5.4. Unary Arithmetic Operators (Programming Perl)
3.3. Autoincrement and Autodecrement (Programming Perl)
Glossary (Programming Perl)
magical: 3.3. Autoincrement and Autodecrement (Programming Perl)
13.3. Overloadable Operators (Programming Perl)
autoincrement operator (++): 10.6. Autoincrement and Autodecrement (Learning Perl)
autoload function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
AUTOLOAD mechanism: 13.. Methods (Perl Cookbook)
generating methods: 13.12.1. Problem (Perl Cookbook)
trapping undefining function calls: 10.15.2. Solution (Perl Cookbook)
AUTOLOAD method: 12.5.4. Method Autoloading (Programming Perl)
accessors and: 11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
functionality: 11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
inheritance and: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
AUTOLOAD subroutine: 10.2. Autoloading (Programming Perl)
12.5.4. Method Autoloading (Programming Perl)
AUTOLOAD subroutines: 4.6. goto (Programming Perl)
$AUTOLOAD variable: 11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
AutoLoader core module: 11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
AutoLoader module: 12.11.1. Problem (Perl Cookbook)
8.5. AutoLoader (Perl in a Nutshell)
10.2. Autoloading (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
autoloading: Glossary (Programming Perl)
generating accessors with: 12.7.3. Generating Accessors with Autoloading (Programming Perl)
automatic, line-end processing: 19.1.3. Switches (Programming Perl)
automatic match variables: 9.5.2. The Automatic Match Variables (Learning Perl)
automation client: 23. OLE Automation (Perl in a Nutshell)
automation controller: 23. OLE Automation (Perl in a Nutshell)
automation modules: 23. OLE Automation (Perl in a Nutshell)
automation objects, creation of: 23. OLE Automation (Perl in a Nutshell)
automation server: 23. OLE Automation (Perl in a Nutshell)
autosplit mode: 19.1.3. Switches (Programming Perl)
autosplit mode (with -a switch): Glossary (Programming Perl)
AutoSplit module: 8.6. AutoSplit (Perl in a Nutshell)
10.2. Autoloading (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
AutoSplit, portability of: 25.3. Files and Filesystems (Programming Perl)
autosplitting: 10.2. Autoloading (Programming Perl)
AutoTrace option (debugger): 20.3.3. Debugger Options (Programming Perl)
autotype( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
autouse module: 8.7. autouse (Perl in a Nutshell)
32.1.17. Module Installation Support (Programming Perl)
autouse pragma: 12.3.3. Discussion (Perl Cookbook)
31.2. use autouse (Programming Perl)
autovivification: 11.. Anonymous Data (Perl Cookbook)
29.2.34. exists (Programming Perl)
Glossary (Programming Perl)
of filehandles: 29.2.104. open (Programming Perl)
hash references and: 4.8. Autovivification and Hashes (Learning Perl Objects, References and Modules)
process defined: 4.7. Autovivification (Learning Perl Objects, References and Modules)
typeglobs: 14.4.1. Filehandle-Tying Methods (Programming Perl)
AV (internal array value): 21.2. Internal Data Types (Programming Perl)
Glossary (Programming Perl)
available_drivers( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
awk: 1.7. Regular Expressions (Programming Perl)
Glossary (Programming Perl)
converting to/from Perl: 2.9. Hashes (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

\b assertion, for backspace: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
5.4.1. Custom Character Classes (Programming Perl)
-b (block special) file test operator: 3.10. Named Unary and File Test Operators (Programming Perl)
b command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
b command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-B (binary file) test operator: 3.10. Named Unary and File Test Operators (Programming Perl)
-b file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
B< > interior sequence (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
B module: 8.8. B (Perl in a Nutshell)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
\B nonword-boundary anchor: 8.3.1. Word Anchors (Learning Perl)
\B (non word boundary): 5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
-b option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
perlbug: 6.6. The perlbug Program (Perl in a Nutshell)
B-tree implementation, DB_File: 14.5.3. Description (Perl Cookbook)
\b word boundary assertion: 5.1. The Regular Expression Bestiary (Programming Perl)
5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
\b word-boundary anchor: 8.3.1. Word Anchors (Learning Perl)
1.7.3. Nailing Things Down (Programming Perl)
B::Asmdata module: 8.9. B::Asmdata (Perl in a Nutshell)
B::Assembler module: 8.10. B::Assembler (Perl in a Nutshell)
B::Bytecode module: 8.12. B::Bytecode (Perl in a Nutshell)
B::C module: 8.13. B::C (Perl in a Nutshell)
B::CC module: 8.14. B::CC (Perl in a Nutshell)
B::Concise module: 8.15. B::Concise (Perl in a Nutshell)
B::Debug module: 8.16. B::Debug (Perl in a Nutshell)
B::Deparse module: 8.17. B::Deparse (Perl in a Nutshell)
B::Disassembler module: 8.18. B::Disassembler (Perl in a Nutshell)
B::Showlex module: 8.20. B::Showlex (Perl in a Nutshell)
B::Stackobj module: 8.21. B::Stackobj (Perl in a Nutshell)
B::Terse module: 8.22. B::Terse (Perl in a Nutshell)
B::Xref module: 8.23. B::Xref (Perl in a Nutshell)
=back command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
backends, compiler: 18.4. Compiler Backends (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
generic interface to: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
modules: 18.4. Compiler Backends (Programming Perl)
modules, calling: 18.4. Compiler Backends (Programming Perl)
-background option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
backquotes (`): 1.2.1.1. Singularities (Programming Perl)
backquotes/backticks (` `)
capturing output with: 14.4. Using Backquotes to Capture Output (Learning Perl)
enclosing external commands: 1.5. A Whirlwind Tour of Perl (Learning Perl)
backreferences: 8.4.1. Backreferences (Learning Perl)
4.6.7. Pattern Match Variables (Perl in a Nutshell)
1.7.4. Backreferences (Programming Perl)
5.2.2. The m// Operator (Matching) (Programming Perl)
5.7.1. Capturing (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
$1, $2, . . .: 1.11.3. Discussion (Perl Cookbook)
6.. Special Variables (Perl Cookbook)
finding doubled words: 6.16.2. Solution (Perl Cookbook)
accessing with numbered variables: 5.7.1. Capturing (Programming Perl)
creating with parentheses: 5.7.1. Capturing (Programming Perl)
deriving patterns from matched substrings: 5.10.3.4. Match-time pattern interpolation (Programming Perl)
backslash (\)
\1, \2, . . . (backreferences): 6.16.2. Solution (Perl Cookbook)
` string metacharacter: 1.18.3. Discussion (Perl Cookbook)
\a for terminal bell: 15.7.2. Solution (Perl Cookbook)
creating arrays: 11.6.2. Solution (Perl Cookbook)
creating references: 11.. Anonymous Data (Perl Cookbook)
\E string metacharacter: 1.18.3. Discussion (Perl Cookbook)
escaping characters: 1.18.1. Problem (Perl Cookbook)
\G anchor: 6.14.3. Discussion (Perl Cookbook)
\L string escape: 1.13.2. Solution (Perl Cookbook)
passing arrays and hashes by references: 10.5.2. Solution (Perl Cookbook)
10.5.2. Solution (Perl Cookbook)
references to arrays: 11.1.3. Discussion (Perl Cookbook)
references to scalars: 11.5.2. Solution (Perl Cookbook)
\u string escape: 1.13.2. Solution (Perl Cookbook)
\X metacharacter: 1.8.3. Discussion (Perl Cookbook)
interpreting with double quotes: 1.2.1.1. Singularities (Programming Perl)
backslash escapes: 1.4.2. What's Inside That Program? (Learning Perl)
5.4.3. Hash Element Interpolation (Learning Perl)
list of: 2.3.2. Double-Quoted String Literals (Learning Perl)
\ (backslash)
double quotes, interpreting with: 1.2.1.1. Singularities (Programming Perl)
\n (newline): 1.1. Getting Started (Programming Perl)
backsniff program: 17.20. Program: backsniff (Perl Cookbook)
backspace
\b assertion in character class: 5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
\b assertion in character classes: 5.4.1. Custom Character Classes (Programming Perl)
BACKSPACE character, /b for: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
backstop method: 9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
11.1. UNIVERSAL Methods (Learning Perl Objects, References and Modules)
` (backtick): 24.3. Programming with Style (Programming Perl)
executing commands without shell escapes: 19.5.3. Discussion (Perl Cookbook)
expanding: 1.15.3. Discussion (Perl Cookbook)
gathering program output: 16.1.2. Solution (Perl Cookbook)
running another program: 16.2.3. Discussion (Perl Cookbook)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
backtracking: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Glossary (Programming Perl)
finding doubled words: 6.16.3. Discussion (Perl Cookbook)
in pattern matching: 6.. The Tricky Bits (Perl Cookbook)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
nonbacktracking subpatterns: 5.10.2. Nonbacktracking Subpatterns (Programming Perl)
backup files: 19.1.3. Switches (Programming Perl)
backup files, text databases and: 16.4. Variable-length (Text) Databases (Learning Perl)
Backup( ) (Win32::EventLog): 22.4. Win32::Eventlog (Perl in a Nutshell)
backward compatibility: Glossary (Programming Perl)
bad filehandles: 11.2.2. Bad Filehandles (Learning Perl)
bake( ): 21.2.3. Description (Perl Cookbook)
bang (!)
!= (not equal to) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
CPAN.pm eval command: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
logical negation operator: 4.5.2. Unary Operators (Perl in a Nutshell)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
!! Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
!~ (pattern match) operator: 4.5.7. Pattern Match Operators (Perl in a Nutshell)
banner( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
Barber, Stan: 17. Usenet News (Perl in a Nutshell)
bare blocks: 4.5. Bare Blocks (Programming Perl)
case structures, doing with: 4.5.1. Case Structures (Programming Perl)
bare identifiers: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
barewords: 17.4. Unquoted Hash Keys (Learning Perl)
2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
Glossary (Programming Perl)
avoiding, reasons for: 24.1.2. Frequently Ignored Advice (Programming Perl)
Perl versions, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
strict pragma, checking use of: 4.9.2. Controlling the Use of Globals (Programming Perl)
Barr, Graham: 16. Email Connectivity (Perl in a Nutshell)
base( )
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
base class: 13.. Some Notes on Object Terminology (Perl Cookbook)
empty base class test: 13.10.3. Discussion (Perl Cookbook)
overridden methods, invoking all: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
base classes: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
32.1.14. Convenient Classes (Programming Perl)
Glossary (Programming Perl)
constructors and: 12.4.2. Initializers (Programming Perl)
overriding methods of: 12.5.2. Accessing Overridden Methods (Programming Perl)
for pod filters and translators: 32.1.16. Documentation Support (Programming Perl)
UNIVERSAL module, providing for all classes: 32.1.14. Convenient Classes (Programming Perl)
base module: 8.24. base (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
basename( ), splitting filenames: 9.10.3. Discussion (Perl Cookbook)
basename, files: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
basename subroutine (File::Basename): 12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
basenames: 13.8. Using Simple Modules (Learning Perl)
File::Basename module for: 13.8.1. The File::Basename Module (Learning Perl)
B.5.4. The File::Basename Module (Learning Perl)
$BASETIME: 28.2. Special Variables in Alphabetical Order (Programming Perl)
basetime ($^T): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$BASETIME ($^T) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
BASIC programming language
logical operators borrowed from: 1.5.5. Logical Operators (Programming Perl)
B::Asmdata module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
B::Assemble module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
B::Bblock module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
bbox( )
Canvas widget: 21.12.3. Canvas Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
B::Bytecode module: 18.5.1. The Bytecode Generator (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
B::C and B::CC modules: 18.5.2. The C Code Generators (Programming Perl)
B::C module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
bcc( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
B::CC module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
-bd option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
B::Debug module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
B::Deparse module: 18.6. Code Development Tools (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
b64digest( ) (Digest modules): 8.57. Digest (Perl in a Nutshell)
b64digest (Digest::MD5 module): 8.58. Digest::MD5 (Perl in a Nutshell)
B::Disassembler module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
-before option (pack geometry manager): 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
BEGIN block: B.19. Syntax Extensions (Learning Perl)
importing subroutines: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
purpose: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
setting constants: 12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
setting paths: 12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
use list and: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
use operation and: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
BEGIN blocks: 18.1. The Life Cycle of a Perl Program (Programming Perl)
21.1. How Perl Works (Programming Perl)
altering compiler parsing of file: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
initializing variables before calling subroutines: 6.2.3. Scoping Issues (Programming Perl)
modifications to @INC array, handling with: 11.1. Using Modules (Programming Perl)
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
=begin command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
=begin pod directive: 12.20.3. Discussion (Perl Cookbook)
beginnings of strings, matching: 5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
behavior
classes and: 8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
instances and: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
passing as parameter: 6.3. Callbacks (Learning Perl Objects, References and Modules)
subroutine references and: 6. Subroutine References (Learning Perl Objects, References and Modules)
testing with isa and can methods: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
bell, ringing: 15.7.1. Problem (Perl Cookbook)
Benchmark module: 8.25. Benchmark (Perl in a Nutshell)
32.1.18. Development Support (Programming Perl)
comparing running times of alternate code versions: 32.2. Benchmark (Programming Perl)
benchmarking mod_perl applications: 21.15.1. Problem (Perl Cookbook)
Berkeley DB library: 14.. Introduction (Perl Cookbook)
-bg option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
bgets program: 8.14.3. Discussion (Perl Cookbook)
biased random numbers, generating: 2.9.1. Problem (Perl Cookbook)
bidirectional clients: 17.10.1. Problem (Perl Cookbook)
bidirectional communication, pipes: 16.3.3. Bidirectional Communication (Programming Perl)
bidirectional rendering, Unicode properties: 5.4.3.2. Standard Unicode properties (Programming Perl)
big arrow (=>): 5.2.3. The Big Arrow (Learning Perl)
17.4. Unquoted Hash Keys (Learning Perl)
big-endian: 25.2. Endianness and Number Width (Programming Perl)
Glossary (Programming Perl)
-bigincrement option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
bigint module: 8.26. bigint (Perl in a Nutshell)
bignum module: 8.27. bignum (Perl in a Nutshell)
bigrat module: 8.28. bigrat (Perl in a Nutshell)
/bin/sh: 19.1. Command Processing (Programming Perl)
binary: Glossary (Programming Perl)
files 8.11.1. Problem (Perl Cookbook)
29.2.104. open (Programming Perl)
reading null-terminated strings: 8.14.1. Problem (Perl Cookbook)
mode on filehandles: 29.2.6. binmode (Programming Perl)
numbers, converting: 2.15.1. Problem (Perl Cookbook)
operators (see bitwise operators)
pack function: 29.2.108. pack (Programming Perl)
repetition (x) operator: 1.5.2. String Operators (Programming Perl)
3.7. Multiplicative Operators (Programming Perl)
trees: 11.17. Program: Binary Trees (Perl Cookbook)
binary assignment operators: 2.5.3. Binary Assignment Operators (Learning Perl)
binary copies of Perl: 2.3.1. Installing on Unix (Perl in a Nutshell)
binary extensions, dynamic loading and: B.23. Dynamic Loading (Learning Perl)
x
binary mode: 1.4. How Do I Make a Perl Program? (Learning Perl)
binary( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
binary operators: 1.5. Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
Glossary (Programming Perl)
class handler, invoking: 13.1. The overload Pragma (Programming Perl)
binary Perl distributions: 2.3.1. Installing on Unix (Perl in a Nutshell)
2.3.2.1. ActivePerl (Perl in a Nutshell)
Binary( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
bind( ): 5. Function Reference (Perl in a Nutshell)
Canvas module: 21.12.3. Canvas Methods (Perl in a Nutshell)
LDAP server: 18.8.3. Discussion (Perl Cookbook)
Socket module: 15.1. Built-in Socket Functions (Perl in a Nutshell)
15.1.3. Server Connections (Perl in a Nutshell)
bind_col( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
bind_columns( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
bind function: 29.2.5. bind (Programming Perl)
bind( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
bind_param( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
binding: Glossary (Programming Perl)
DBM file to hash: 29.2.22. dbmopen (Programming Perl)
operators: 3.6. Binding Operators (Programming Perl)
variables to packages: 14. Tied Variables (Programming Perl)
29.2.178. tie (Programming Perl)
29.2.191. untie (Programming Perl)
binding, databases: 14.12.3. Discussion (Perl Cookbook)
binding operator (=~): 9.3. The Binding Operator, =~ (Learning Perl)
1.7. Regular Expressions (Programming Perl)
s/ substitution operator and: 9.6.4. The Binding Operator (Learning Perl)
binding operators
pattern-matching operators, using with: 5.2. Pattern-Matching Operators (Programming Perl)
tr/ (substitution) operator, use with: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
binmode: 29.2.104. open (Programming Perl)
binmode( ): 8.. I/O Layers (Perl Cookbook)
8.11.2. Solution (Perl Cookbook)
binmode function: 29.2.6. binmode (Programming Perl)
biology, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
bit-shift operators: 3.9. Shift Operators (Programming Perl)
bit-shift operators (<<, >>): Glossary (Programming Perl)
bit vector, providing array interface to: 14.6. Tie Modules on CPAN (Programming Perl)
-bitmap option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
bitmasks: 29.2.141. select (ready file descriptors) (Programming Perl)
bits: Glossary (Programming Perl)
execute bits: Glossary (Programming Perl)
bitstrings: 11.6.4. Using Bitstrings (Learning Perl)
vec operator for: B.11. Bits and Pieces (Learning Perl)
bitwise
negation (~) operator: 3.5. Ideographic Unary Operators (Programming Perl)
operators: 3.13. Bitwise Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
bitwise operators: 11.6.3. Bitwise Operators (Learning Perl)
4.5.10. Bitwise Operators (Perl in a Nutshell)
overloading: 13.3. Overloadable Operators (Programming Perl)
blank lines, truth value of: 1.6.2.1. The while and until statements (Programming Perl)
bless( ): 5. Function Reference (Perl in a Nutshell)
13.. Under the Hood (Perl Cookbook)
13.1.2. Solution (Perl Cookbook)
12.4. Object Construction (Programming Perl)
29.2.7. bless (Programming Perl)
Glossary (Programming Perl)
constructors, using with: 12.4. Object Construction (Programming Perl)
reference as argument for: 8.1. What Is a Reference? (Programming Perl)
tie vs.: 14. Tied Variables (Programming Perl)
8.2.3. Object Constructors (Programming Perl)
8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
blessed references
indirect object syntax and: 10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
instances as: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
isa method and: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
nested object destruction: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
ref operator and: 9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
returning: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
blib: 21.3.2. Creating Extensions (Programming Perl)
blib module: 8.29. blib (Perl in a Nutshell)
blib pragma: 31.4. use blib (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
B::Lint module: 18.6. Code Development Tools (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
$blksize file statistic: 29.2.165. stat (Programming Perl)
BLOCK: 4.2. Compound Statements (Programming Perl)
4.2. Compound Statements (Programming Perl)
block comments: 1.4.2. What's Inside That Program? (Learning Perl)
block curly braces (see curly braces, block)
block form
grep operator: 5.4. The map and grep Operators (Learning Perl Objects, References and Modules)
map operator: 5.5. Using map (Learning Perl Objects, References and Modules)
block of statements: 4.3. Statements (Perl in a Nutshell)
block properties, Unicode: 5.4.3.3. Unicode block properties (Programming Perl)
blocking( ): 7.. Getting a Handle on the File (Perl Cookbook)
blocking calls, lock, threads: 17.2.2.1. Synchronizing access with lock (Programming Perl)
blocking file access: 7.18.1. Problem (Perl Cookbook)
netlock program: 7.24. Program: netlock (Perl Cookbook)
reading a line from a filehandle without: 7.23.1. Problem (Perl Cookbook)
region-specific locks: 7.25. Program: lockarea (Perl Cookbook)
blocking, shared locks: 16.2.1. File Locking (Programming Perl)
blocking signals: 16.20.1. Problem (Perl Cookbook)
16.1.4. Blocking Signals (Programming Perl)
$blocks file statistic: 29.2.165. stat (Programming Perl)
Body( ) (Mail::Internet module): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
body( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
body of subroutine: 4.2. Defining a Subroutine (Learning Perl)
bookdb.dir, bookdb.pag files: 12.1. DBM Databases and DBM Hashes (Perl in a Nutshell)
books, Perl-related: 1.4.9. Books (Perl in a Nutshell)
Boolean: Glossary (Programming Perl)
context: 2.7.2. Boolean Context (Programming Perl)
Glossary (Programming Perl)
definition of truth: 1.6.1. What Is Truth? (Programming Perl)
operators: 1.5.7. Some File Test Operators (Programming Perl)
Boolean connectives in patterns: 6.18.1. Problem (Perl Cookbook)
Boolean context
bool conversion operator: 13.3. Overloadable Operators (Programming Perl)
m/ (match) operator in: 5.2.2. The m// Operator (Matching) (Programming Perl)
Boolean values: 1.2.1.1. Singularities (Programming Perl)
as handled by Perl: 2.7.1. Boolean Values (Learning Perl)
logical operators for: 10.9. Logical Operators (Learning Perl)
bootstrapping modules: 21.3.2. Creating Extensions (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
-bordermode option (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
-borderwidth option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-bottom option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
-bottomspring option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
boundaries, words (matching): 5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
boundary assertions: 1.7.3. Nailing Things Down (Programming Perl)
bounded array, creating: 14.2.1. Array-Tying Methods (Programming Perl)
-bp option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
braces { }
delimiting statement blocks: 4.3. Statements (Perl in a Nutshell)
identifiers in: 2.6.2. String Literals (Programming Perl)
regular expression quantifiers: 4.6.6. Quantifiers (Perl in a Nutshell)
{{ Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
{ Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
brackets [ ]
array composer: 8.2.2.1. The anonymous array composer (Programming Perl)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
regular expression metacharacter: 4.6.4. Character Classes (Perl in a Nutshell)
break command (in C): 24.1.3. C Traps (Programming Perl)
break statement (see last operator)
breakpoints: Glossary (Programming Perl)
deleting: 20.2.2. Breakpoints (Programming Perl)
listing all: 20.2.2. Breakpoints (Programming Perl)
setting for debugger: 20. The Perl Debugger (Programming Perl)
setting on load: 20.1. Using the Debugger (Programming Perl)
setting with debugger commands: 20.2.2. Breakpoints (Programming Perl)
watch expressions, causing: 20.2.3. Tracing (Programming Perl)
broadcasting: Glossary (Programming Perl)
browsers, redirecting
with CGI: 19.7.1. Problem (Perl Cookbook)
with mod_perl: 21.4.1. Problem (Perl Cookbook)
support for Unicode fonts: 8.21.3. Discussion (Perl Cookbook)
-bs option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
BSD (Berkeley Standard Distribution): Glossary (Programming Perl)
BSD::Resource module, per-process resource limits, setting: 23.3.2. Code Masquerading as Data (Programming Perl)
B::Showlex module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
B::Stash module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
B::Terse module: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
buckets: Glossary (Programming Perl)
buffer
flushing of: 6.4. Output to Standard Output (Learning Perl)
11.4.1. Changing the Default Output Filehandle (Learning Perl)
stat: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
buffered input/output: 7.. I/O Operations (Perl Cookbook)
7.19.3. Discussion (Perl Cookbook)
8.. Advanced Operations (Perl Cookbook)
controlling for other programs: 16.8.1. Problem (Perl Cookbook)
socket programming and: 17.3.3. Discussion (Perl Cookbook)
buffered output: 6.4. Output to Standard Output (Learning Perl)
buffering: Glossary (Programming Perl)
bi-directional pipes, problems with: 16.3.3. Bidirectional Communication (Programming Perl)
block: Glossary (Programming Perl)
commands: Glossary (Programming Perl)
line: Glossary (Programming Perl)
single-character input and: 29.2.43. getc (Programming Perl)
unflushed buffers in Perl versions: 29.2.40. fork (Programming Perl)
bug reports: 0.6.3. Bug Reports (Programming Perl)
bugs: 33. Diagnostic Messages (Programming Perl)
bugs in Perl: 1.3.2. How Can I Get Support for Perl? (Learning Perl)
reporting: 1.3.4. What If I Find a Bug in Perl? (Learning Perl)
reporting: 6.6. The perlbug Program (Perl in a Nutshell)
building
C extension modules: 12.19.1. Problem (Perl Cookbook)
modules from CPAN: 12.21.1. Problem (Perl Cookbook)
building CPAN modules: 22.2.2. Building CPAN Modules (Programming Perl)
built-in: Glossary (Programming Perl)
data types: 2.3. Built-in Data Types (Programming Perl)
functions
listing by type: 32.1.16. Documentation Support (Programming Perl)
built-in functions: 5. Function Reference (Perl in a Nutshell)
listed alphabetically: 5. Function Reference (Perl in a Nutshell)
listed by category: 5.1. Perl Functions by Category (Perl in a Nutshell)
overriding: 11.3. Overriding Built-in Functions (Programming Perl)
socket-related: 15.1. Built-in Socket Functions (Perl in a Nutshell)
subroutines, prototyping to emulate: 6.4. Prototypes (Programming Perl)
built-in methods, overridden, calling via CORE pseudopackage: 12.5.2. Accessing Overridden Methods (Programming Perl)
built-in operators, character semantics, operating on: 15.2. Effects of Character Semantics (Programming Perl)
built-in Perl variables: 4.4. Special Variables (Perl in a Nutshell)
builtin functions
ampersand and: 4.11.1. Omitting the Ampersand (Learning Perl)
mathematical functions and: B.9.1. Advanced Math Functions (Learning Perl)
builtin variables: 9.5.2. The Automatic Match Variables (Learning Perl)
B.18. Built in Variables (Learning Perl)
Bundle:: argument: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
bundles: 22.1. The CPAN modules Directory (Programming Perl)
Glossary (Programming Perl)
button( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
Button widget (Perl/Tk): 21.4. The Button Widget (Perl in a Nutshell)
B::Xref module: 18.6. Code Development Tools (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
byte meanings, character class shortcuts: 5.4.2. Classic Perl Character Class Shortcuts (Programming Perl)
byte( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
bytecode: 18.1. The Life Cycle of a Perl Program (Programming Perl)
21. Internals and Externals (Programming Perl)
Glossary (Programming Perl)
Bytecode backend (Perl compiler): 3.4. The Perl Compiler (Perl in a Nutshell)
bytecodes: 1.4.3. But How Do I Compile Perl? (Learning Perl)
Byteloader module: 18.5.1. The Bytecode Generator (Programming Perl)
byteperl interpreter: 3.4. The Perl Compiler (Perl in a Nutshell)
bytes: 2.1. Atoms (Programming Perl)
Glossary (Programming Perl)
bit-shift operators: 3.9. Shift Operators (Programming Perl)
characters vs.: 15. Unicode (Programming Perl)
29. Functions (Programming Perl)
reading: 29.2.120. read (Programming Perl)
29.2.172. sysread (Programming Perl)
storage locations (see big-endian; little-endian)
bytes, determining number of unread: 7.21.1. Problem (Perl Cookbook)
bytes I/O layer: 8.. I/O Layers (Perl Cookbook)
bytes module: 8.30. bytes (Perl in a Nutshell)
32.1.6. Internationalization and Locale (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C
extension modules, building: 12.19.1. Problem (Perl Cookbook)
writing modules in: 12.18.1. Problem (Perl Cookbook)
C, CC backends (Perl compiler): 3.4. The Perl Compiler (Perl in a Nutshell)
-c (character special) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-c (check syntax) command-line switch: 19.1.3. Switches (Programming Perl)
21.1. How Perl Works (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
-C command-line switch: 8.21.3. Discussion (Perl Cookbook)
8.21.3. Discussion (Perl Cookbook)
c command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-c file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
C header files, translating with h2ph: 12.17.1. Problem (Perl Cookbook)
C<> interior sequence (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
C language: Glossary (Programming Perl)
accesing Perl from enclosing framework: 18.4. Compiler Backends (Programming Perl)
C code generators: 18.5.2. The C Code Generators (Programming Perl)
C stack, storing C variables on: 18.3. Executing Your Code (Programming Perl)
C-style logical operators: 3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
fcntl.h definitions, loading as Perl constants: 32.1.7. Operating System Interfaces (Programming Perl)
header files: Glossary (Programming Perl)
library functions: 29. Functions (Programming Perl)
library, signals triggering core dumps in: 16.1. Signals (Programming Perl)
operators missing in Perl: 3.21. C Operators Missing from Perl (Programming Perl)
operators, precedence relationships: 3. Unary and Binary Operators (Programming Perl)
Perl, extending with: 21.3. Extending Perl (Using C from Perl) (Programming Perl)
creating extensions: 21.3.2. Creating Extensions (Programming Perl)
external C library, using functions from: 21.3.4. Using Functions from an External C Library (Programming Perl)
XSUBs and XS language: 21.3.1. XS and XSUBs (Programming Perl)
Perl extensions and: 21. Internals and Externals (Programming Perl)
Perl functions, wrapping around: 21.3.1. XS and XSUBs (Programming Perl)
Perl, running from
Perl stack, manipulating: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
Perl, using from: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
adding Perl interpreter: 21.4.2. Adding a Perl Interpreter to Your C Program (Programming Perl)
compiling embedded Perl programs: 21.4.1. Compiling Embedded Programs (Programming Perl)
Perl statement, evaluating: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
Perl subroutine, calling from: 21.4.3. Calling a Perl Subroutine from C (Programming Perl)
XSUB input and output: 21.3.3. XSUB Input and Output (Programming Perl)
preprocessor: Glossary (Programming Perl)
programming, differences from Perl: 24.1.3. C Traps (Programming Perl)
structs: 29.2.108. pack (Programming Perl)
syslog functions, using in Perl: 32.1.7. Operating System Interfaces (Programming Perl)
wrapper programs: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
\C, matching single byte in C language: 15.2. Effects of Character Semantics (Programming Perl)
/c modifier, failed matches, searching past: 5.6.4. Progressive Matching (Programming Perl)
-C (native wide characters) command-line switch: 15.1. Building Character (Programming Perl)
-c option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
-C option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
/c pattern modifier: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
C preprocessor: 19.1.3. Switches (Programming Perl)
C programming language
DBM files and: 16.1.2. Using a DBM Hash (Learning Perl)
operators and: 10.9.2. The Ternary Operator, ?: (Learning Perl)
\C wildcard metasymbol: 5.3.3. Wildcard Metasymbols (Programming Perl)
cacheout( ): 7.7.3. Discussion (Perl Cookbook)
caching: 8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
caching open filehandles: 7.7.1. Problem (Perl Cookbook)
calc_new_date( ): 3.4.2. Solution (Perl Cookbook)
calc_new_date_time( ): 3.4.2. Solution (Perl Cookbook)
calculating prime numbers: 2.18. Program: Calculating Prime Factors (Perl Cookbook)
call( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
callbacks: 8.3.7. Closures (Programming Perl)
Glossary (Programming Perl)
accessing variables: 6.4. Closures (Learning Perl Objects, References and Modules)
6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
find( ) function and: 6.4. Closures (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
invoking subroutines multiple times: 6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
subroutine references and: 6.3. Callbacks (Learning Perl Objects, References and Modules)
6.3. Callbacks (Learning Perl Objects, References and Modules)
callbacks, widget (Perl/Tk): 21.1.3. Callbacks (Perl in a Nutshell)
caller( ): 5. Function Reference (Perl in a Nutshell)
12.6.2. Solution (Perl Cookbook)
names of subroutines: 10.4.2. Solution (Perl Cookbook)
caller function: 11.3. Fatal Errors with die (Learning Perl)
29.2.8. caller (Programming Perl)
Perl versions, changes in return value: 24.1.5. Previous Perl Traps (Programming Perl)
calling
by reference: Glossary (Programming Perl)
by value: Glossary (Programming Perl)
subroutines indirectly: 6.1. Syntax (Programming Perl)
Camel book: 1.2.1. Why Didn't Larry Just Use Some Other Language? (Learning Perl)
1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
Camel image: 1.4.9. Books (Perl in a Nutshell)
can( ): 13.8.3. Discussion (Perl Cookbook)
can method: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
can method (UNIVERSAL): 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
cancel( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
CancelConnection( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
can_ok function (Test::More): 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
canon( ) (Mail::Address): 16.2.7. Mail::Address Reference (Perl in a Nutshell)
canonical decomposition, characters: 5.4.3.2. Standard Unicode properties (Programming Perl)
canonicalization: Glossary (Programming Perl)
characters, information on: 15.2. Effects of Character Semantics (Programming Perl)
CanonicalizeURL( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
can_read( ): 7.23.3. Discussion (Perl Cookbook)
Canvas widget (Perl/Tk): 21.12. The Canvas Widget (Perl in a Nutshell)
Capini, Aldo: 22. Win32 Modules and Extensions (Perl in a Nutshell)
capitalization: 2.5. Names (Programming Perl)
29.2.184. uc (Programming Perl)
barewords, problems with: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
case-insensitive hashes: 13.15.6. Tie Example: Case-Insensitive Hash (Perl Cookbook)
case shifting and: 9.6.5. Case Shifting (Learning Perl)
changing: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
converting case: 1.13.1. Problem (Perl Cookbook)
escape sequences for: 2.6.2. String Literals (Programming Perl)
honoring locale when matching: 6.12.1. Problem (Perl Cookbook)
label names: 4.4. Loop Statements (Programming Perl)
lc and lcfirst functions: 29.2.82. lc (Programming Perl)
method names, tied variables: 14. Tied Variables (Programming Perl)
in module names: 32.1. Listings by Type (Programming Perl)
module names: 11.1. Using Modules (Programming Perl)
of titles and headlines: 1.14.1. Problem (Perl Cookbook)
package/module names: 24.3. Programming with Style (Programming Perl)
subroutine names: 6.1. Syntax (Programming Perl)
uppercase, converting to (\u escape): 5.2.3. The s/// Operator (Substitution) (Programming Perl)
vs. lowercase in variable names: 2.5.1. Choosing Good Variable Names (Learning Perl)
capturing in patterns: 5.7.1. Capturing (Programming Perl)
Glossary (Programming Perl)
suppressing in clustering: 5.7.2. Clustering (Programming Perl)
words, alphanumeric: 5.2.2. The m// Operator (Matching) (Programming Perl)
caret (^)
in [...] construct: 4.6.4. Character Classes (Perl in a Nutshell)
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
line boundary: 5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
XOR bitwise operator: 4.5.10. Bitwise Operators (Perl in a Nutshell)
^= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
caret anchor (^) indicating beginning of string: 8.3. Anchors (Learning Perl)
Carp module: 12.14.2. Solution (Perl Cookbook)
8.32. Carp (Perl in a Nutshell)
14.1.1. Scalar-Tying Methods (Programming Perl)
32.1.15. Warnings and Exceptions (Programming Perl)
32.3. Carp (Programming Perl)
carriage returns: 6.6.1. Problem (Perl Cookbook)
25.1. Newlines (Programming Perl)
(see also newlines)
cascade( ) (Menubutton): 21.14.2. Menubutton Methods (Perl in a Nutshell)
cascading menu entries: 15.14.3. Discussion (Perl Cookbook)
case
case-sensitive matching, switching off: 5.9.2.1. When backslashes happen (Programming Perl)
escape sequences for
processing during variable interpolation pass: 5.3.1. Metasymbol Tables (Programming Perl)
matching, /i operator: 5.2.1. Pattern Modifiers (Programming Perl)
translation operators, using Unicode tables: 15.2. Effects of Character Semantics (Programming Perl)
case-insensitive matching, /i modifier for: 9.2.1. Case-insensitive Matching with /i (Learning Perl)
case sensitivity: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
capitalizing titles and headlines: 1.14.1. Problem (Perl Cookbook)
converting case: 1.13.1. Problem (Perl Cookbook)
hashes: 13.15.6. Tie Example: Case-Insensitive Hash (Perl Cookbook)
honoring locale when matching: 6.12.1. Problem (Perl Cookbook)
/i modifier (case insensitive): 5.2.1. Pattern Modifiers (Programming Perl)
case shifting: 9.6.5. Case Shifting (Learning Perl)
case statement: 4.5.1. Case Structures (Programming Perl)
case structure: 4.5.1. Case Structures (Programming Perl)
casting
data types: Glossary (Programming Perl)
strings and: 2.6. Scalar Values (Programming Perl)
cat command (Unix): 14.3.1. Hash-Tying Methods (Programming Perl)
categories
of functions: 29.1. Perl Functions by Category (Programming Perl)
categories, characters: 5.4.3.2. Standard Unicode properties (Programming Perl)
catfile method (File::Spec): 12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
cbreak mode: 15.6.2. Solution (Perl Cookbook)
cbreak option: 29.2.43. getc (Programming Perl)
C/C++ languages, static variables: 6.2.3. Scoping Issues (Programming Perl)
cc( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
C_constant function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
cd command (Unix): 12.1. Moving Around the Directory Tree (Learning Perl)
Cd( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
CDATA, XML: 22.. CDATA (Perl Cookbook)
CdataEnd handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
CdataStart handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
cdup( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
ceil( ): 2.2.3. Discussion (Perl Cookbook)
centering: 7.1. Format Variables (Programming Perl)
/cg pattern modifier: 5.2.2. The m// Operator (Matching) (Programming Perl)
cget( ) (Perl/Tk): 21.1.1.2. The cget method (Perl in a Nutshell)
CGI
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
:cgi, :cgi-lib method groups: 10.2. Importing Method Groups (Perl in a Nutshell)
CGI module: B.5.1. The CGI and CGI_Lite Modules (Learning Perl)
B.16. The Common Gateway Interface (CGI) (Learning Perl)
12.11. Custom Import Routines (Learning Perl Objects, References and Modules)
32.1.9. World Wide Web (Programming Perl)
managing HTML forms with: 32.4. CGI (Programming Perl)
CGI modules: 8.33. CGI (Perl in a Nutshell)
CGI::Apache module: 8.34. CGI::Apache (Perl in a Nutshell)
CGI::Carp module: 8.35. CGI::Carp (Perl in a Nutshell)
CGI::Cookie module: 8.36. CGI::Cookie (Perl in a Nutshell)
CGI::Fast module: 8.37. CGI::Fast (Perl in a Nutshell)
CGI::Pretty: 8.38. CGI::Pretty (Perl in a Nutshell)
CGI::Push module: 8.39. CGI::Push (Perl in a Nutshell)
CGI::Switch module: 8.40. CGI::Switch (Perl in a Nutshell)
CGI programming: 19.. Introduction (Perl Cookbook)
chemiserie program: 19.13. Program: chemiserie (Perl Cookbook)
cookies: 19.9.1. Problem (Perl Cookbook)
debugging raw HTTP exchange: 19.8.1. Problem (Perl Cookbook)
fixing 500 server errors: 19.3.1. Problem (Perl Cookbook)
form parameters: 19.1.3. Discussion (Perl Cookbook)
19.12.3. Discussion (Perl Cookbook)
HTTP methods: 19.. Behind the Scenes (Perl Cookbook)
19.1.3. Discussion (Perl Cookbook)
improving efficiency of: 21.12.1. Problem (Perl Cookbook)
migrating to mod_perl: 21.12.1. Problem (Perl Cookbook)
multiscreen scripts: 19.11.1. Problem (Perl Cookbook)
performance: 21.. Introduction (Perl Cookbook)
21.. Introduction (Perl Cookbook)
redirecting browsers: 19.7.1. Problem (Perl Cookbook)
redirecting error messages: 19.2.1. Problem (Perl Cookbook)
saving and mailing HTML forms: 19.12.1. Problem (Perl Cookbook)
security and: 19.. Security (Perl Cookbook)
19.4.1. Problem (Perl Cookbook)
executing user commands: 19.5.1. Problem (Perl Cookbook)
shopping cart application, developing: 19.11.1. Problem (Perl Cookbook)
sticky widgets: 19.10.1. Problem (Perl Cookbook)
writing scripts: 19.1.1. Problem (Perl Cookbook)
CGI programs: 9. CGI Overview (Perl in a Nutshell)
debugging: 10.6. Debugging (Perl in a Nutshell)
environment variables for: 9.4. CGI Environment Variables (Perl in a Nutshell)
extra path information: 9.3. Extra Path Information (Perl in a Nutshell)
maintaining state: 10.3. Maintaining State (Perl in a Nutshell)
named parameters: 10.4. Named Parameters (Perl in a Nutshell)
running with mod_perl: 11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
URL encoding: 9.2. URL Encoding (Perl in a Nutshell)
CGI scripts
input, evaluating (Safe module): 23.3.1.3. Safe examples (Programming Perl)
taint mode, necessity of running under: 23.1. Handling Insecure Data (Programming Perl)
CGI::Apache module: 32.1.9. World Wide Web (Programming Perl)
CGI::Carp module: 19.2.2. Solution (Perl Cookbook)
19.3.3.3. Is the script valid Perl? (Perl Cookbook)
32.1.9. World Wide Web (Programming Perl)
32.5. CGI::Carp (Programming Perl)
CGI::Cookie module: 21.2.3. Description (Perl Cookbook)
32.1.9. World Wide Web (Programming Perl)
accessing values: 21.3.3. Discussion (Perl Cookbook)
CGI::Fast module: 32.1.9. World Wide Web (Programming Perl)
CGI_Lite module: B.5.1. The CGI and CGI_Lite Modules (Learning Perl)
B.16. The Common Gateway Interface (CGI) (Learning Perl)
CGI.pm module: 19.. Architecture (Perl Cookbook)
9. CGI Overview (Perl in a Nutshell)
10. The CGI.pm Module (Perl in a Nutshell)
creating sticky widgets: 19.10.2. Solution (Perl Cookbook)
debugging scripts: 10.6. Debugging (Perl in a Nutshell)
generating HTML tags: 10.1. HTML Tag Generation (Perl in a Nutshell)
HTML helper functions: 19.6.2. Solution (Perl Cookbook)
importing method groups: 10.2. Importing Method Groups (Perl in a Nutshell)
JavaScript features with: 10.5. Using JavaScript Features (Perl in a Nutshell)
managing cookies: 19.9.1. Problem (Perl Cookbook)
named parameters: 10.4. Named Parameters (Perl in a Nutshell)
writing CGI scripts: 19.1.3. Discussion (Perl Cookbook)
CGI::Pretty module: 32.1.9. World Wide Web (Programming Perl)
CGI::Push module: 32.1.9. World Wide Web (Programming Perl)
Changes file: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
ChangeType( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods (Perl in a Nutshell)
Char handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
character classes: 8.1. Character Classes (Learning Perl)
4.6.4. Character Classes (Perl in a Nutshell)
1.7. Regular Expressions (Programming Perl)
5.4. Character Classes (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Glossary (Programming Perl)
confusing with array subscripts: 2.6.5. Interpolating Array Values (Programming Perl)
custom: 5.4.1. Custom Character Classes (Programming Perl)
matching against character properties in Unicode: 15.2. Effects of Character Semantics (Programming Perl)
metasymbols used within: 5.3.1. Metasymbol Tables (Programming Perl)
Perl classic: 5.4.3.4. Defining your own character properties (Programming Perl)
Perl shortcuts for: 5.4.2. Classic Perl Character Class Shortcuts (Programming Perl)
POSIX-style: 5.4.4. POSIX-Style Character Classes (Programming Perl)
predefined, availability of: 15.2. Effects of Character Semantics (Programming Perl)
Unicode properties: 5.4.3. Unicode Properties (Programming Perl)
wildcard metasymbols and: 5.3.3. Wildcard Metasymbols (Programming Perl)
character metasymbols
in character classes: 5.4.1. Custom Character Classes (Programming Perl)
character semantics, effects of: 15.2. Effects of Character Semantics (Programming Perl)
character sets
ordering and ranges of characters in: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
Unicode: 15. Unicode (Programming Perl)
character sets, portability of: 25.9. Internationalization (Programming Perl)
characters: 2.3. Strings (Learning Perl)
2.1. Atoms (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Glossary (Programming Perl)
prototype: 6.4. Prototypes (Programming Perl)
aliases for: 5.3.2. Specific Characters (Programming Perl)
bytes vs.: 15. Unicode (Programming Perl)
29. Functions (Programming Perl)
case of (see capitalization)
case shifting and: 9.6.5. Case Shifting (Learning Perl)
converting ASCII to and from HTML: 20.4.1. Problem (Perl Cookbook)
converting between fixed 8-bit and variable-length UTF-8: 15.1. Building Character (Programming Perl)
converting between values: 1.4.1. Problem (Perl Cookbook)
converting case: 1.13.1. Problem (Perl Cookbook)
decomposition of: 5.4.3.2. Standard Unicode properties (Programming Perl)
deleting: 29.2.11. chomp (Programming Perl)
$[ variable: 28.2. Special Variables in Alphabetical Order (Programming Perl)
escaping: 1.18.1. Problem (Perl Cookbook)
in formats: 29.2.108. pack (Programming Perl)
funny characters preceding variable names: 14. Tied Variables (Programming Perl)
Glossary (Programming Perl)
getting ASCII values of: 29.2.106. ord (Programming Perl)
getting from ASCII values: 29.2.14. chr (Programming Perl)
getting from Unicode values: 29.2.14. chr (Programming Perl)
hexadecimal (see hexadecimal characters)
l (lowercase) character: 4.6.4. Character Classes (Perl in a Nutshell)
length in: 29.2.84. length (Programming Perl)
matching letters: 6.2.1. Problem (Perl Cookbook)
matching with /s modifier: 9.2.2. Matching Any Character with /s (Learning Perl)
metacharacters: 5.1. The Regular Expression Bestiary (Programming Perl)
octal (see octal characters)
parsing command-line arguments: 15.1.1. Problem (Perl Cookbook)
in patterns: 5.1. The Regular Expression Bestiary (Programming Perl)
processing individually: 1.6.1. Problem (Perl Cookbook)
properties: 5.4.3.4. Defining your own character properties (Programming Perl)
Glossary (Programming Perl)
defining your own: 5.4.3.4. Defining your own character properties (Programming Perl)
replacing in strings: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
reversing: 1.7.1. Problem (Perl Cookbook)
single-character input: 29.2.43. getc (Programming Perl)
special: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
text color, changing: 15.5.1. Problem (Perl Cookbook)
transliterating/counting with tr/// operator: B.8.1. Transliteration with tr/// (Learning Perl)
u (uppercase) character: 4.6.4. Character Classes (Perl in a Nutshell)
wildcard matches for: 5.3.3. Wildcard Metasymbols (Programming Perl)
charnames: 1.5.3. Discussion (Perl Cookbook)
8.41. charnames (Perl in a Nutshell)
charnames::viacode( ): 1.5.3. Discussion (Perl Cookbook)
charnames::vianame( ): 1.5.3. Discussion (Perl Cookbook)
charnames module: 32.1.6. Internationalization and Locale (Programming Perl)
charts, generating: 7. Formats (Programming Perl)
chdir( ): 5. Function Reference (Perl in a Nutshell)
chdir command, calling without argument: 19.2. Environment Variables (Programming Perl)
chdir function: 29.2.9. chdir (Programming Perl)
precedence and: 3.1. Terms and List Operators (Leftward) (Programming Perl)
chdir operator: 12.1. Moving Around the Directory Tree (Learning Perl)
CHECK blocks: 18.1. The Life Cycle of a Perl Program (Programming Perl)
21.1. How Perl Works (Programming Perl)
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
checkbox( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
checkbox_group( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
checkbutton menu entries: 15.14.3. Discussion (Perl Cookbook)
checkbutton( ) (Menubutton): 21.14.2. Menubutton Methods (Perl in a Nutshell)
Checkbutton widget (Perl/Tk): 21.5. The Checkbutton Widget (Perl in a Nutshell)
checking, taint: 23.1. Handling Insecure Data (Programming Perl)
checksums: 29.2.189. unpack (Programming Perl)
chemiserie program: 19.13. Program: chemiserie (Perl Cookbook)
chemistry, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
child processes: 29.2.196. wait (Programming Perl)
(see also processes)
ID, returning: 29.2.40. fork (Programming Perl)
readable, starting: 16.3.1. Anonymous Pipes (Programming Perl)
starting writeable: 16.3.1. Anonymous Pipes (Programming Perl)
child processes, managing: 14. Process Management (Learning Perl)
$CHILD_ERROR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$CHILD_ERROR ($?) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
children method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
chmod( ): 5. Function Reference (Perl in a Nutshell)
1.4.1. A Simple Program (Learning Perl)
13.5. Modifying Permissions (Learning Perl)
1.3.1. How to Do It (Programming Perl)
29.2.10. chmod (Programming Perl)
13.5. Modifying Permissions (Learning Perl)
chomp( ): 5. Function Reference (Perl in a Nutshell)
chomp function: 1.4. Filehandles (Programming Perl)
29.2.11. chomp (Programming Perl)
chomp operator: 2.9. The chomp Operator (Learning Perl)
chop( ): 5. Function Reference (Perl in a Nutshell)
chop function: 1.4. Filehandles (Programming Perl)
29.2.12. chop (Programming Perl)
29.2.12. chop (Programming Perl)
(see also chomp function)
chown( ): 5. Function Reference (Perl in a Nutshell)
chown function: 13.6. Changing Ownership (Learning Perl)
29.2.13. chown (Programming Perl)
chr( ): 5. Function Reference (Perl in a Nutshell)
1.4.3. Discussion (Perl Cookbook)
15.2. Effects of Character Semantics (Programming Perl)
29.2.14. chr (Programming Perl)
Christiansen, Tom: 1.4.5. www.perl.com (Perl in a Nutshell)
chroot( ): 5. Function Reference (Perl in a Nutshell)
chroot function: 29.2.15. chroot (Programming Perl)
chroot syscall: 23.3.1.1. Restricting namespace access (Programming Perl)
chunk number, die function and: 11.3. Fatal Errors with die (Learning Perl)
circular
data structures: 13.13.1. Problem (Perl Cookbook)
lists: 4.17.1. Problem (Perl Cookbook)
circular references: 8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
breaking: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
overloading, avoiding in: 13.3. Overloadable Operators (Programming Perl)
circumfix operator: Glossary (Programming Perl)
Clark, James: 13.1. XML Parsing and Validation (Perl in a Nutshell)
class attributes (see class data)
class data: 13.4.1. Problem (Perl Cookbook)
circular data structures: 13.13.1. Problem (Perl Cookbook)
class inheritance: 12.5. Class Inheritance (Programming Perl)
Class::ISA module: 8.42. Class::ISA (Perl in a Nutshell)
class methods: 13.. Methods (Perl Cookbook)
13.. Some Notes on Object Terminology (Perl Cookbook)
13.4.2. Solution (Perl Cookbook)
7.4. Object Syntax (Perl in a Nutshell)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
building instances: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
constructors as: 12.4.1. Inheritable Constructors (Programming Perl)
File::Spec module and: 12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
instance methods and: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
OO modules and: 12.5. The Differences Between OO and Non-OO Modules (Learning Perl Objects, References and Modules)
package names as invocants for: 12.3. Method Invocation (Programming Perl)
restricting to: 9.14. Restricting a Method to Class-Only or Instance-Only (Learning Perl Objects, References and Modules)
Thread class: 17.2.1. The Thread Module (Programming Perl)
-class option
Frame widget: 21.17. The Frame Widget (Perl in a Nutshell)
toplevel widget: 21.18. The Toplevel Widget (Perl in a Nutshell)
class variables: 10.5. Using Class Variables (Learning Perl Objects, References and Modules)
Class::Contract module: 12.7.5. Using Closures for Private Objects (Programming Perl)
classes: 13.. Under the Hood (Perl Cookbook)
13.8.3. The File::Spec Module (Learning Perl)
10. Packages (Programming Perl)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
accessing overridden methods: 13.11.1. Problem (Perl Cookbook)
accessors and: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
base (see base classes)
data, managing for: 12.8. Managing Class Data (Programming Perl)
storing references to class data in object itself: 12.8. Managing Class Data (Programming Perl)
defined: 8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
definitions of
object-oriented modules as: 11.1. Using Modules (Programming Perl)
derived (see derived classes)
determining subclass membership: 13.9.1. Problem (Perl Cookbook)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
generating methods with AUTOLOAD: 13.. Methods (Perl Cookbook)
13.12.1. Problem (Perl Cookbook)
generating with Class::Struct module: 12.7.2. Generating Classes with Class::Struct (Programming Perl)
generic: 13.. Some Notes on Object Terminology (Perl Cookbook)
implementing tie: 14. Tied Variables (Programming Perl)
implementing tied filehandles: 14.4. Tying Filehandles (Programming Perl)
implementing tied hashes: 14.3. Tying Hashes (Programming Perl)
inheritance: 13.. Inheritance (Perl Cookbook)
13.10.1. Problem (Perl Cookbook)
inheritance among: 12.5. Class Inheritance (Programming Perl)
base module: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
method autoloading: 12.5.4. Method Autoloading (Programming Perl)
overridden methods, accessing: 12.5.2. Accessing Overridden Methods (Programming Perl)
private methods, avoiding with: 12.5.5. Private Methods (Programming Perl)
UNIVERSAL class and: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
instances and: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
@ISA array, including with base pragma: 12.5.1. Inheritance Through @ISA (Programming Perl)
methods working with: 9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
modules vs.: 10. Packages (Programming Perl)
objects, giving to: 12.4. Object Construction (Programming Perl)
package: 3.2. The Arrow Operator (Programming Perl)
29.2.178. tie (Programming Perl)
29.2.191. untie (Programming Perl)
packages as: 12.2. Perl's Object System (Programming Perl)
pseudohash implementations of: 29.2.99. my (Programming Perl)
quoting packages for: 12.3.4. Package-Quoted Classes (Programming Perl)
scalar-tying: 14.1.1. Scalar-Tying Methods (Programming Perl)
as structs: 13.5.1. Problem (Perl Cookbook)
superclasses: 13.. Some Notes on Object Terminology (Perl Cookbook)
UNIVERSAL class and: 11.1. UNIVERSAL Methods (Learning Perl Objects, References and Modules)
version number, returning: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
virtual methods and: A.8.1. Exercise (Section 9.15.1) (Learning Perl Objects, References and Modules)
classes, functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
classes, Perl: 5.4. Character Classes (Programming Perl)
Class::MethodMaker module: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
Class::Multimethods module: 12.5.2. Accessing Overridden Methods (Programming Perl)
Class::Struct module: 13.5.2. Solution (Perl Cookbook)
32.1.1. Data Types (Programming Perl)
32.6. Class::Struct (Programming Perl)
Class::Template module: 8.43. Class::Struct (Perl in a Nutshell)
clean command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
cleaning up after modules: 12.7.1. Problem (Perl Cookbook)
Clear( )
Win32::EventLog module: 22.4. Win32::Eventlog (Perl in a Nutshell)
clear command, clearing the screen: 15.3.2. Solution (Perl Cookbook)
clear( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies (Perl in a Nutshell)
clearerr( ): 8.5.3. Discussion (Perl Cookbook)
clearing hashes: 14.3.1. Hash-Tying Methods (Programming Perl)
clear_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
client( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
client-side socket connections: 15.1.2. Client Connections (Perl in a Nutshell)
15.2.1. Client-Side Sockets (Perl in a Nutshell)
clients: Glossary (Programming Perl)
bidirectional: 17.10.1. Problem (Perl Cookbook)
FTP: 18.2.1. Problem (Perl Cookbook)
TCP: 17.1.1. Problem (Perl Cookbook)
UDP, setting up: 17.4.1. Problem (Perl Cookbook)
clients, networking
getting name of: 16.5.2. Networking Servers (Programming Perl)
clients, TCP: 16.5.1. Networking Clients (Programming Perl)
clipboard, manipulating: 22.1. Win32::Clipboard (Perl in a Nutshell)
cloisters: 5.7.3. Cloistered Pattern Modifiers (Programming Perl)
Glossary (Programming Perl)
clone( )
HTTP::Headers module: 20.3.3. HTTP::Headers (Perl in a Nutshell)
HTTP::Message module: 20.3.8. HTTP::Message (Perl in a Nutshell)
LWP::UserAgent module: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
Clone( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods (Perl in a Nutshell)
Close( )
Win32::Internet module: 22.7.1. General Internet Methods (Perl in a Nutshell)
Win32::ODBC: 24.1. ODBC Methods and Properties (Perl in a Nutshell)
Win32::Shortcut module: 22.18. Win32::Shortcut (Perl in a Nutshell)
close( )
file descriptors: 7.9.1. Problem (Perl Cookbook)
file locks: 7.18.3. Discussion (Perl Cookbook)
filehandles: 7.. I/O Operations (Perl Cookbook)
close function: 16.3.1. Anonymous Pipes (Programming Perl)
29.2.16. close (Programming Perl)
close-on-exec flag: 28.2. Special Variables in Alphabetical Order (Programming Perl)
close operator: 11.2.1. Closing a Filehandle (Learning Perl)
closedir( ): 5. Function Reference (Perl in a Nutshell)
closedir( ): 9.. Introduction (Perl Cookbook)
closedir function: 29.2.17. closedir (Programming Perl)
closedir operator: 12.4. Directory Handles (Learning Perl)
-closeenough option (Canvas): 21.12. The Canvas Widget (Perl in a Nutshell)
Resume( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
closing
server connections (half-close): 16.5.1. Networking Clients (Programming Perl)
closing tied filehandles: 14.4.1. Filehandle-Tying Methods (Programming Perl)
closure variables: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
closures: 10.16.3. Discussion (Perl Cookbook)
11.4.3. Discussion (Perl Cookbook)
12.16.3. Discussion (Perl Cookbook)
B.20.3. Anonymous Subroutines and Closures (Learning Perl)
4.8.2. Lexically Scoped Variables: my (Programming Perl)
8.3.7. Closures (Programming Perl)
Glossary (Programming Perl)
assigning to glob to define subroutine: 10.2. Autoloading (Programming Perl)
creating: 6.1. Syntax (Programming Perl)
as function templates: 8.3.7.1. Closures as function templates (Programming Perl)
functionality: 6.4. Closures (Learning Perl Objects, References and Modules)
generating accessor methods with: 12.7.4. Generating Accessors with Closures (Programming Perl)
lexical variables and: 6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
nested subroutines, emulating with: 8.3.7.2. Nested subroutines (Programming Perl)
as objects: 11.7.1. Problem (Perl Cookbook)
persistence and: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
private objects, using for: 12.7.5. Using Closures for Private Objects (Programming Perl)
scope and: 6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
threads: 17.2.1.1. Thread creation (Programming Perl)
Cls( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
clustering in patterns: 5.7.2. Clustering (Programming Perl)
Glossary (Programming Perl)
without capturing, reasons for: 5.7.2. Clustering (Programming Perl)
cmp operator: 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
29.2.159. sort (Programming Perl)
cmp (three-way comparison operator): 15.4. Advanced Sorting (Learning Perl)
cmp_ok routine (Test::More): 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
code: 8. Introduction to Objects (Learning Perl Objects, References and Modules)
(see also OOP)
compiling: 1.4.3. But How Do I Compile Perl? (Learning Perl)
curly braces enclosing: 2.7. The if Control Structure (Learning Perl)
2.10. The while Control Structure (Learning Perl)
decoupling: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
dynamic loading and: B.23. Dynamic Loading (Learning Perl)
effienciency of: 24.2.3. Programmer Efficiency (Programming Perl)
embedding: B.24. Embedding (Learning Perl)
extracting and displaying with debugger: 20.2.5. Locating Code (Programming Perl)
insecure, handling: 23.3. Handling Insecure Code (Programming Perl)
code masquerading as data: 23.3.2. Code Masquerading as Data (Programming Perl)
safe compartments for: 23.3.1. Safe Compartments (Programming Perl)
safe examples: 23.3.1.3. Safe examples (Programming Perl)
last operator for exiting early: 10.8.1. The last Operator (Learning Perl)
mixing character semantics with byte semantics: 15.1. Building Character (Programming Perl)
reading: 10.3. Expression Modifiers (Learning Perl)
reusability of: 8.6. Overriding the Methods (Learning Perl Objects, References and Modules)
12. Using Modules (Learning Perl Objects, References and Modules)
reusing: 24.3. Programming with Style (Programming Perl)
testing coverage: 14. Essential Testing (Learning Perl Objects, References and Modules)
used in this book, web site for: 0.3. Code Examples (Learning Perl)
ways to share: 2.1. The Cure for the Common Code (Learning Perl Objects, References and Modules)
while control structure for repeating blocks of: 2.10. The while Control Structure (Learning Perl)
code generation: 18.1. The Life Cycle of a Perl Program (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
code generators: 18.4. Compiler Backends (Programming Perl)
18.5. Code Generators (Programming Perl)
Glossary (Programming Perl)
bytecode generator: 18.5.1. The Bytecode Generator (Programming Perl)
C Code generators: 18.5.2. The C Code Generators (Programming Perl)
code handlers (see handlers)
code( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
code points, Unicode: 1.. Unicode Support in Perl (Perl Cookbook)
code references
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
overview: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
code size, library: 14.. Introduction (Perl Cookbook)
code subpatterns in regular expressions: 5.10.3.3. Match-time code evaluation (Programming Perl)
Glossary (Programming Perl)
ColAttributes( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
collating sequence: Glossary (Programming Perl)
collection objects: 23.3. Win32::OLE::Enum (Perl in a Nutshell)
collisions, namespace: 2.6. The Problem of Namespace Collisions (Learning Perl Objects, References and Modules)
12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
colon (:)
module names: 12.. Modules (Perl Cookbook)
package names: 12.. Introduction (Perl Cookbook)
7.1. Namespaces and Packages (Perl in a Nutshell)
color( ): 15.5.3. Discussion (Perl Cookbook)
color of text, changing: 15.5.1. Problem (Perl Cookbook)
-colormap option
Frame widget: 21.17. The Frame Widget (Perl in a Nutshell)
toplevel widget: 21.18. The Toplevel Widget (Perl in a Nutshell)
colormapwindows( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
colors, widget: 21.1.4. Colors and Fonts (Perl in a Nutshell)
-column option (grid manager): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
columns
arranging du command output: 5.17. Program: dutree (Perl Cookbook)
outputting text by: 4.19. Program: words (Perl Cookbook)
parsing data by: 1.1.3. Discussion (Perl Cookbook)
wrapping paragraphs by: 1.17.1. Problem (Perl Cookbook)
-columnspan option (grid manager): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
CombineURL( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
combining character sequence, matching with \X: 5.3.3. Wildcard Metasymbols (Programming Perl)
combining character sequence, \X, matching with: 15.2. Effects of Character Semantics (Programming Perl)
comma (,)
1.2.1.2.2. Hashes. (Programming Perl)
in numbers: 2.16.1. Problem (Perl Cookbook)
number legibility without: 4.2.1. Numbers (Perl in a Nutshell)
operator: 4.5.11.3. Comma operator (Perl in a Nutshell)
printing lists with: 4.2.1. Problem (Perl Cookbook)
comma-separated values (see CSV)
command
entry, menu items: 15.14.3. Discussion (Perl Cookbook)
interpreters: 1.18.3. Discussion (Perl Cookbook)
command input operator (see backtick operator)
command line
calling perl interpreter from: 1.3.1. How to Do It (Programming Perl)
modules for processing: 32.1.3. Option, Argument, Parameter, and Configuration File Processing (Programming Perl)
screen appearance of: 20.3.3. Debugger Options (Programming Perl)
command-line arguments: Glossary (Programming Perl)
command-line arguments, parsing: 15.1.1. Problem (Perl Cookbook)
command-line editing, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
command line, in-place editing from: 16.4.1. In-place Editing from the Command Line (Learning Perl)
command-line options: B.17. Command-Line Options (Learning Perl)
modules for: B.27. Command-line Options in Your Programs (Learning Perl)
command-line options (perl interpreter): 3.2. Command-Line Options (Perl in a Nutshell)
"Command not found" error: 3. The Perl Executable (Perl in a Nutshell)
-command option: 21.1.3. Callbacks (Perl in a Nutshell)
Button widget: 21.4. The Button Widget (Perl in a Nutshell)
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
command processing, location of Perl: 19.1.2. Location of Perl (Programming Perl)
command processing on #! line: 3.1. Command Processing (Perl in a Nutshell)
commands
accessing under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
buffering: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
debugger: 20.2. Debugger Commands (Programming Perl)
actions and: 20.2.6. Actions and Command Execution (Programming Perl)
breakpoints: 20.2.2. Breakpoints (Programming Perl)
for display: 20.2.4. Display (Programming Perl)
20.2.4. Display (Programming Perl)
documentation, viewing: 20.2.7. Miscellaneous Commands (Programming Perl)
locating code: 20.2.5. Locating Code (Programming Perl)
options, manipulating: 20.2.7. Miscellaneous Commands (Programming Perl)
quitting debugger: 20.2.7. Miscellaneous Commands (Programming Perl)
restarting debugger: 20.2.7. Miscellaneous Commands (Programming Perl)
stepping and running: 20.2.1. Stepping and Running (Programming Perl)
tracing: 20.2.3. Tracing (Programming Perl)
for loop control: 4.4.4. Loop Control (Programming Perl)
hashes of functions, storing in: 9.5. Hashes of Functions (Programming Perl)
history, debugger and: 20.1. Using the Debugger (Programming Perl)
names for: 1.2.2. Verbs (Programming Perl)
in pod: 26.1.2. Pod Directives (Programming Perl)
processing: 19.1. Command Processing (Programming Perl)
19.1. Command Processing (Programming Perl)
(see also interpreters; Perl interpreter)
recalling, debugger option: 20.3.3. Debugger Options (Programming Perl)
commands, Perl debugger: 6.2. Debugger Commands (Perl in a Nutshell)
Comment handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
comment( ) (Mail::Address): 16.2.7. Mail::Address Reference (Perl in a Nutshell)
comments: 1.4.2. What's Inside That Program? (Learning Perl)
4.1. Program Structure (Perl in a Nutshell)
4.9.2. Exercise 2 [30 min] (Learning Perl Objects, References and Modules)
14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
Glossary (Programming Perl)
multiline: 26.1. Pod in a Nutshell (Programming Perl)
definition: 2.2. Molecules (Programming Perl)
discarding before processing: 5.9.1. Letting Perl Do the Work (Programming Perl)
extending with /x pattern modifier: 5.2.1. Pattern Modifiers (Programming Perl)
Perl vs. C syntax for: 24.1.3. C Traps (Programming Perl)
pod documentation for modules: 12.20.1. Problem (Perl Cookbook)
in regular expressions: 6.4.1. Problem (Perl Cookbook)
XML: 22.. Comments (Perl Cookbook)
commify( ): 2.16.3. Discussion (Perl Cookbook)
commify_series program: 4.2.2. Solution (Perl Cookbook)
commit( ): 14.15.2. Solution (Perl Cookbook)
commit( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
Common Gateway Interface: 9. CGI Overview (Perl in a Nutshell)
9.4. CGI Environment Variables (Perl in a Nutshell)
(see also CGI)
Common Log Format standard: 20.12.3. Discussion (Perl Cookbook)
communicating between mod_perl and PHP: 21.11.1. Problem (Perl Cookbook)
compare( ): 8.22.3. Discussion (Perl Cookbook)
compare( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
compare( ) (Text widget): 21.11.2. Text Methods (Perl in a Nutshell)
comparing
contents of two files: 8.22.1. Problem (Perl Cookbook)
filehandles: 8.22.3. Discussion (Perl Cookbook)
files: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
floating-point numbers: 2.3.1. Problem (Perl Cookbook)
currency: 2.3.3. Discussion (Perl Cookbook)
keys of hashes: 5.12.1. Problem (Perl Cookbook)
running time of alternate code versions: 32.1.18. Development Support (Programming Perl)
strings: 3.11. Relational Operators (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
thread objects: 17.2.1.5. Identifying threads (Programming Perl)
comparison operators: 2.6.3. Comparison Operators (Learning Perl)
15.4. Advanced Sorting (Learning Perl)
4.5.4.1. Relational operators (Perl in a Nutshell)
4.5.4.2. Equality operators (Perl in a Nutshell)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
3.12. Equality Operators (Programming Perl)
overloading: 13.3. Overloadable Operators (Programming Perl)
sort function and: 29.2.159. sort (Programming Perl)
compatibility decomposition, characters: 5.4.3.2. Standard Unicode properties (Programming Perl)
compilation: 21. Internals and Externals (Programming Perl)
order of: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
compilation phase, processing Perl program: 21.1. How Perl Works (Programming Perl)
compilation units: 2.5.1. Name Lookups (Programming Perl)
Glossary (Programming Perl)
compile phase: Glossary (Programming Perl)
AUTOLOAD and: 11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
BEGIN keyword and: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
declarations during: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
use base and: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
vs. compile time: 18.2. Compiling Your Code (Programming Perl)
compile time: Glossary (Programming Perl)
compile time, controlling debugger during: 20.1. Using the Debugger (Programming Perl)
compiler: 28.2. Special Variables in Alphabetical Order (Programming Perl)
compiler hints: 28.2. Special Variables in Alphabetical Order (Programming Perl)
compiler, Perl: 3.4. The Perl Compiler (Perl in a Nutshell)
backends for: 18.4. Compiler Backends (Programming Perl)
modules related to: 22.1. The CPAN modules Directory (Programming Perl)
compilers: Glossary (Programming Perl)
global declarations and: 4.7. Global Declarations (Programming Perl)
regex compiler: 5.9.3. The Regex Compiler (Programming Perl)
compilers, Perl
interpreters, interaction with: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
modules related to: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
compiling: 18. Compiling (Programming Perl)
compiling your code: 18.2. Compiling Your Code (Programming Perl)
embedded Perl program (in C): 21.4.1. Compiling Embedded Programs (Programming Perl)
life cycle of Perl programs: 18.1. The Life Cycle of a Perl Program (Programming Perl)
life cycle, Perl programs
code generation phase: 18.1. The Life Cycle of a Perl Program (Programming Perl)
compile phase: 18.1. The Life Cycle of a Perl Program (Programming Perl)
parse tree reconstruction: 18.1. The Life Cycle of a Perl Program (Programming Perl)
compiling code: 1.4.3. But How Do I Compile Perl? (Learning Perl)
comp.lang.perl newsgroups: 0.6.2. Usenet Newsgroups (Programming Perl)
comp.lang.perl.moderated newsgroup: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
complementation (see negation)
complex data structures (see also data structures)
4.8. References and Complex Data Structures (Perl in a Nutshell)
5. Manipulating Complex Data Structures (Learning Perl Objects, References and Modules)
creating in Perl: 9. Data Structures (Programming Perl)
representing as scalars: 1.2.1.3. Complexities (Programming Perl)
complex numbers: 2.14.1. Problem (Perl Cookbook)
B.9.2. Imaginary and Complex Numbers (Learning Perl)
composite Unicode properties: 5.4.3.1. Perl's Unicode properties (Programming Perl)
composition, inheritance versus: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
Comprehensive Perl Archive Network (see also CPAN)
1.3.1. What Is CPAN? (Learning Perl)
15. Contributing to CPAN (Learning Perl Objects, References and Modules)
compressing tabs: 1.11.1. Problem (Perl Cookbook)
COMSPEC environment variable: 19.2. Environment Variables (Programming Perl)
concatenating strings: 1.5.2. String Operators (Programming Perl)
Glossary (Programming Perl)
concatenation (.) operator: 4.5.11.4. String operator (Perl in a Nutshell)
1.5.2. String Operators (Programming Perl)
3.8. Additive Operators (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
autogeneration via stringification handler: 13.3. Overloadable Operators (Programming Perl)
string constants, overloading: 13.6. Overloading Constants (Programming Perl)
condition variables: 17.2.2.6. Condition variables (Programming Perl)
conditional (?:) operator: 4.5.11.2. Conditional operator (Perl in a Nutshell)
conditional code execution: 1.5.5. Logical Operators (Programming Perl)
conditional context (see Boolean context)
conditional modifiers: 4.3.1.4. Modifiers (Perl in a Nutshell)
conditional statements: 4.3.1. Conditionals and Loops (Perl in a Nutshell)
4.3. if and unless Statements (Programming Perl)
<
without braces, writing: 4.2. Compound Statements (Programming Perl)
conditional tests: 14.4. Conditional Tests (Learning Perl Objects, References and Modules)
conditionals, interpolation into patterns: 5.10.3.5. Conditional interpolation (Programming Perl)
conditions, expressions in loops: 4.4.2. for Loops (Programming Perl)
conferences, Perl-related: 1.4.8. Perl Conferences (Perl in a Nutshell)
confess( ): 12.14.2. Solution (Perl Cookbook)
%Config hash: 21.4.1. Compiling Embedded Programs (Programming Perl)
25. Portable Perl (Programming Perl)
Config module: 16.13.2. Solution (Perl Cookbook)
8.44. Config (Perl in a Nutshell)
32.1.17. Module Installation Support (Programming Perl)
operating system mapping between signal names and numbers: 16.1. Signals (Programming Perl)
ConfigDSN( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
Config.pm file: 2.3.1. Installing on Unix (Perl in a Nutshell)
config_sh( ) (Config module): 8.44. Config (Perl in a Nutshell)
configuration files
Boolean connectives in patterns: 6.18.1. Problem (Perl Cookbook)
reading: 8.16.1. Problem (Perl Cookbook)
configuration files, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
configuration, Perl, for debugging: 19.1.3. Switches (Programming Perl)
Configure command (Unix): 2.3.1. Installing on Unix (Perl in a Nutshell)
Configure event, Tk: 15.16.2. Solution (Perl Cookbook)
configure( ) (Perl/Tk): 21.1.1.1. The configure method (Perl in a Nutshell)
config_vars( ) (Config module): 8.44. Config (Perl in a Nutshell)
-confine option (Canvas): 21.12. The Canvas Widget (Perl in a Nutshell)
conn_cache( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
connect( ): 5. Function Reference (Perl in a Nutshell)
DBI module: 12.3. DBI Methods (Perl in a Nutshell)
Socket module: 15.1. Built-in Socket Functions (Perl in a Nutshell)
15.1.2. Client Connections (Perl in a Nutshell)
connect( ), LDAP server: 18.8.3. Discussion (Perl Cookbook)
connect function: 29.2.18. connect (Programming Perl)
ConnectBackoff( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
Connection( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
connections: Glossary (Programming Perl)
shutting down: 29.2.154. shutdown (Programming Perl)
ConnectRetries( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
ConnectTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
console implementation: 22.2. Win32::Console (Perl in a Nutshell)
constant module: 8.45. constant (Perl in a Nutshell)
constant pragma: B.6.1. The constant Pragma (Learning Perl)
10.1. Symbol Tables (Programming Perl)
constant( ) (Win32::FileSecurity): 22.6. Win32::FileSecurity (Perl in a Nutshell)
constants: 1.21.1. Problem (Perl Cookbook)
10.1. Symbol Tables (Programming Perl)
inlining constant functions: 6.4.1. Inlining Constant Functions (Programming Perl)
overloading: 13.6. Overloading Constants (Programming Perl)
Perl, loading fcntl.h definitions as: 32.1.7. Operating System Interfaces (Programming Perl)
System V IPC, defining for: 32.1.8. Networking and Interprocess Communication (Programming Perl)
constants, global special (predefined): 4.4.4. Global Special Constants (Perl in a Nutshell)
constants, setting: 12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
constant_types function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
constructors: 13.. Methods (Perl Cookbook)
13.1.1. Problem (Perl Cookbook)
7.3. Object-Oriented Perl (Perl in a Nutshell)
8.2.3. Object Constructors (Programming Perl)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
12.4. Object Construction (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
access checks, setting in: 12.7.5. Using Closures for Private Objects (Programming Perl)
accessing overridden methods: 13.11.1. Problem (Perl Cookbook)
anonymous array: 4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
4.5. Creating an Anonymous Array Directly (Learning Perl Objects, References and Modules)
5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
anonymous hash: 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
bless function and: 12.4. Object Construction (Programming Perl)
class names or objects, working with: 12.4.1. Inheritable Constructors (Programming Perl)
cloning parent objects: 13.6.1. Problem (Perl Cookbook)
creating instances: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
inheritable: 12.4.1. Inheritable Constructors (Programming Perl)
inheriting: 9.5. Inheriting the Constructor (Learning Perl Objects, References and Modules)
9.5. Inheriting the Constructor (Learning Perl Objects, References and Modules)
initializers: 12.4.2. Initializers (Programming Perl)
naming: 12.4.2. Initializers (Programming Perl)
new method: 29.2.100. new (Programming Perl)
tied variable classes: 14. Tied Variables (Programming Perl)
url subroutine: 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
container classes holding pointers to self-referential data structures: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
content( )
HTML::Parser module: 20.4.3. HTML::Element (Perl in a Nutshell)
HTTP::Message module: 20.3.8. HTTP::Message (Perl in a Nutshell)
content_ref( ) (HTTP::Message): 20.3.8. HTTP::Message (Perl in a Nutshell)
Content-type header: 9.1.2. Creating Virtual Documents (Perl in a Nutshell)
context: 3.8. Scalar and List Context (Learning Perl)
3.8. Scalar and List Context (Learning Perl)
4.2.6. Scalar and List Contexts (Perl in a Nutshell)
2.7. Context (Programming Perl)
2.7. Context (Programming Perl)
Glossary (Programming Perl)
Boolean context: 2.7.2. Boolean Context (Programming Perl)
interpolative (double-quoted) context: 2.7.4. Interpolative Context (Programming Perl)
scalar and list context: 2.7.1. Scalar and List Context (Programming Perl)
void: 4.4. Return Values (Learning Perl)
29.2.198. wantarray (Programming Perl)
void context: 2.7.3. Void Context (Programming Perl)
context stack: 18.3. Executing Your Code (Programming Perl)
continuation characters, reading data with: 8.1.1. Problem (Perl Cookbook)
continuation lines: 4.4.4. Loop Control (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
continue block: 10.7. The for Control Structure (Learning Perl)
10.8.2. The next Operator (Learning Perl)
B.19. Syntax Extensions (Learning Perl)
4.3.1.1. while loops (Perl in a Nutshell)
4.4.1. while and until Statements (Programming Perl)
4.4.3. foreach Loops (Programming Perl)
4.4.4. Loop Control (Programming Perl)
4.4.4. Loop Control (Programming Perl)
(see also loops)
continue command (in C): 24.1.3. C Traps (Programming Perl)
contract between module and user: 11.2.1. Module Privacy and the Exporter (Programming Perl)
contractions in words, avoiding confusion with single quotes: 5.10.1. Lookaround Assertions (Programming Perl)
Control-A: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
Control-C: 2.6.2. String Literals (Programming Perl)
Control-C or Control-Z, generating signals with: 16.1. Signals (Programming Perl)
control characters: 2.6.2. String Literals (Programming Perl)
metasymbols in patterns: 5.3.2. Specific Characters (Programming Perl)
non-ASCII on Macintosh: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
Control-D as eof: 24.5.2. Generating Perl in Other Languages (Programming Perl)
Control-D character: 2.6.8. Other Literal Tokens (Programming Perl)
Control-D key: 2.6.8. Other Literal Tokens (Programming Perl)
control structures: 10. More Control Structures (Learning Perl)
1.6. Control Structures (Programming Perl)
loop controls for: 10.8. Loop Controls (Learning Perl)
partial-evaluation operators for: 10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
stopping endless loops created by: 2.10. The while Control Structure (Learning Perl)
truth, defining: 1.6.1. What Is Truth? (Programming Perl)
control variables: 4.4.3. foreach Loops (Programming Perl)
Control-Z as eof: 24.5.2. Generating Perl in Other Languages (Programming Perl)
Control-Z character: 2.6.8. Other Literal Tokens (Programming Perl)
Control-Z key: 2.6.8. Other Literal Tokens (Programming Perl)
ControlReceiveTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
ControlSendTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
conversion operators
Boolean context, interpreting object in: 13.3. Overloadable Operators (Programming Perl)
numification (nonnumeric variable converted to number): 13.3. Overloadable Operators (Programming Perl)
stringification: 13.3. Overloadable Operators (Programming Perl)
conversion programs: B.25. Converting Other Languages to Perl (Learning Perl)
conversions: 6.5. Formatted Output with printf (Learning Perl)
converting
ASCII to and from HTML: 20.4.1. Problem (Perl Cookbook)
ASCII value to character: 29.2.14. chr (Programming Perl)
between integers and UTF-8 characters: 15.2. Effects of Character Semantics (Programming Perl)
between languages: 24.5.2. Generating Perl in Other Languages (Programming Perl)
character case: 1.13.1. Problem (Perl Cookbook)
characters and values: 1.4.1. Problem (Perl Cookbook)
characters to ASCII values: 29.2.106. ord (Programming Perl)
data types between C and Perl: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
date and time to and from Epoch seconds: 3.2.1. Problem (Perl Cookbook)
DBM files: 14.3.1. Problem (Perl Cookbook)
decimal numbers to binary digits or octals: 29.2.162. sprintf (Programming Perl)
decimal numbers to octal or hexadecimal: 29.2.162. sprintf (Programming Perl)
degrees and radians: 2.10.1. Problem (Perl Cookbook)
hexadecimal numbers to decimal: 29.2.73. hex (Programming Perl)
HTML tables into Perl data structures: 20.19.1. Problem (Perl Cookbook)
HTML to ASCII: 20.5.1. Problem (Perl Cookbook)
list values to strings: 29.2.78. join (Programming Perl)
29.2.108. pack (Programming Perl)
Microsoft files to Unicode: 8.21.1. Problem (Perl Cookbook)
numbers: 2.15.1. Problem (Perl Cookbook)
Roman numerals and: 2.5.1. Problem (Perl Cookbook)
numbers to/from hexadecimal: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
octal numbers to decimal: 29.2.103. oct (Programming Perl)
pod into other languages: 12.20.3. Discussion (Perl Cookbook)
shell wildcards for regular expression matching: 6.9.1. Problem (Perl Cookbook)
strings
case of: 1.13.1. Problem (Perl Cookbook)
between characters and values: 1.4.2. Solution (Perl Cookbook)
non-numeric: 2.. Introduction (Perl Cookbook)
strings to list values: 29.2.161. split (Programming Perl)
29.2.189. unpack (Programming Perl)
time: 29.2.70. gmtime (Programming Perl)
29.2.88. localtime (Programming Perl)
Unicode value to character: 29.2.14. chr (Programming Perl)
cookie( )
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
LWP::UserAgent module: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
Cookie header: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
cookie_jar( ): 20.14.3. Discussion (Perl Cookbook)
cookies: 8.36. CGI::Cookie (Perl in a Nutshell)
10.3. Maintaining State (Perl in a Nutshell)
accessing values with mod_perl: 21.3.1. Problem (Perl Cookbook)
CGI: 19.9.1. Problem (Perl Cookbook)
HTTP::Cookies module: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
HTTP::Cookies::Netscape module: 20.3.6.1. HTTP::Cookies::Netscape (Perl in a Nutshell)
setting in mod_perl: 21.2.1. Problem (Perl Cookbook)
web automation and: 20.14.1. Problem (Perl Cookbook)
cookies (HTTP), setting and getting: 32.1.9. World Wide Web (Programming Perl)
Cooper, Clark: 13.1. XML Parsing and Validation (Perl in a Nutshell)
coords( )
Canvas widget: 21.12.3. Canvas Methods (Perl in a Nutshell)
Scale widget: 21.13.1. Scale Methods (Perl in a Nutshell)
copy( ): 9.3.3. Discussion (Perl Cookbook)
copy constructor: 13.4. The Copy Constructor (=) (Programming Perl)
13.7.1. Problem (Perl Cookbook)
copy-on-write semantics: 17.1. The Process Model (Programming Perl)
copying
data structures: 11.12.1. Problem (Perl Cookbook)
directory trees: 9.12. Program: symirror (Perl Cookbook)
filehandles: 7.10.1. Problem (Perl Cookbook)
files: 9.3.1. Problem (Perl Cookbook)
parent objects: 13.6.1. Problem (Perl Cookbook)
surface vs. deep copies: 11.12.3. Discussion (Perl Cookbook)
copying filenames or filehandles: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
copyright notices: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
core dumps: Glossary (Programming Perl)
denial-of-service problems with pattern matching: 23.3.2. Code Masquerading as Data (Programming Perl)
dump function for: 29.2.29. dump (Programming Perl)
Thread::Signal module, preventing with: 17.2.3.3. Other standard threading modules (Programming Perl)
core dumps, signals triggering in C library: 16.1. Signals (Programming Perl)
core files: 19.1.3. Switches (Programming Perl)
core modules: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
core modules, Perl: 22.1. The CPAN modules Directory (Programming Perl)
CORE pseudopackage: 11.3. Overriding Built-in Functions (Programming Perl)
12.5.2. Accessing Overridden Methods (Programming Perl)
CORE::GLOBAL pseudopackage: 11.3. Overriding Built-in Functions (Programming Perl)
cos( ): 5. Function Reference (Perl in a Nutshell)
2.11.2. Solution (Perl Cookbook)
cos function (cosines): 29.2.19. cos (Programming Perl)
cosine: B.9.1. Advanced Math Functions (Learning Perl)
Count( ), Win32::OLE::Enum module: 23.3. Win32::OLE::Enum (Perl in a Nutshell)
counters, magical counter variables: 14.1.2. Magical Counter Variables (Programming Perl)
counting lines in files: 8.2.1. Problem (Perl Cookbook)
CPAN (Comprehensive Perl Archive Network): 12.. Not Reinventing the Wheel (Perl Cookbook)
1.3.1. What Is CPAN? (Learning Perl)
1.4.4. CPAN (Perl in a Nutshell)
2. Installing Perl (Perl in a Nutshell)
10. Packages (Programming Perl)
11. Modules (Programming Perl)
22. CPAN (Programming Perl)
Glossary (Programming Perl)
architecture: 2.1. The CPAN Architecture (Perl in a Nutshell)
building and installing modules from: 12.21.1. Problem (Perl Cookbook)
commands: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
contributing to: 15. Contributing to CPAN (Learning Perl Objects, References and Modules)
CPAN module as automated interface to: 32.8. CPAN (Programming Perl)
finding available modules: 2.4.1. Locating Modules (Perl in a Nutshell)
inside utility available from: B.4.3. Finding and Installing Modules (Learning Perl)
libraries available from: B.4.3. Finding and Installing Modules (Learning Perl)
modules
building: 22.2.2. Building CPAN Modules (Programming Perl)
categories of modules: 22.1. The CPAN modules Directory (Programming Perl)
creating: 22.3. Creating CPAN Modules (Programming Perl)
decompressing and unpacking: 22.2.1. Decompressing and Unpacking CPAN Modules (Programming Perl)
installing and building: 22.2. Using CPAN Modules (Programming Perl)
installing into Perl library: 22.2.3. Installing CPAN Modules into the Perl Library (Programming Perl)
modules available from: 13.8. Using Simple Modules (Learning Perl)
B.4.3. Finding and Installing Modules (Learning Perl)
modules directory: 22.1. The CPAN modules Directory (Programming Perl)
registering as developer: 12.9.3. Discussion (Perl Cookbook)
subdirectories: 22. CPAN (Programming Perl)
tie modules on: 14.6. Tie Modules on CPAN (Programming Perl)
version numbers and: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
website: 2.1. The CPAN Architecture (Perl in a Nutshell)
CPAN: 10. Packages (Programming Perl)
.cpan directory: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
CPAN::FirstTime module: 8.47. CPAN::FirstTime (Perl in a Nutshell)
CPAN module: 32.1.17. Module Installation Support (Programming Perl)
32.8. CPAN (Programming Perl)
installing modules with: 22.2. Using CPAN Modules (Programming Perl)
portability of: 25.7. Standard Modules (Programming Perl)
CPAN::Nox module: 8.48. CPAN::Nox (Perl in a Nutshell)
CPAN::Config: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
CPANPLUS module: 12.21.3. Discussion (Perl Cookbook)
12.23. Program: Finding Versions and Descriptions of Installed Modules (Perl Cookbook)
CPAN.pm module: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
8.46. CPAN (Perl in a Nutshell)
CPU
access in multitasking environment: 23.2. Handling Timing Glitches (Programming Perl)
condition variables allowing threads to relinquish: 17.2.2.6. Condition variables (Programming Perl)
CPU time: 29.2.181. times (Programming Perl)
CPU, yielding (threads): 17.2.1.7. Yielding the processor (Programming Perl)
crack( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
cracker: Glossary (Programming Perl)
CrackURL( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
Create( )
Win32::Process module: 22.14. Win32::Process (Perl in a Nutshell)
Win32::Registry module: 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
Connect( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
createArc( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createBitmap( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createElement( ): 22.2.3. Discussion (Perl Cookbook)
createImage( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createLine( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createOval( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createPolygon( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createRectangle( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createText( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
createTextNode( ): 22.2.3. Discussion (Perl Cookbook)
CreateURL( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
createWindow( ) (Canvas): 21.12.1. Canvas Creation Methods (Perl in a Nutshell)
creating
charts: 15.18.1. Problem (Perl Cookbook)
15.23. Program: graphbox (Perl Cookbook)
magic variables: 13.15.1. Problem (Perl Cookbook)
menus with Tk toolkit: 15.14.1. Problem (Perl Cookbook)
processes: 16.. Process Creation (Perl Cookbook)
references to methods: 11.8.1. Problem (Perl Cookbook)
robots for Web traversal: 20.11.1. Problem (Perl Cookbook)
sticky widgets: 19.10.1. Problem (Perl Cookbook)
temporary files: 7.11.1. Problem (Perl Cookbook)
creation time (see modification time, file)
credentials( ): 20.15.2. Solution (Perl Cookbook)
credentials( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
credit cards, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
CRLF: 25.1. Newlines (Programming Perl)
(see also newlines)
in Internet programs: 16.5.2. Networking Servers (Programming Perl)
crlf I/O layer: 8.. I/O Layers (Perl Cookbook)
8.. I/O Layers (Perl Cookbook)
8.11.3. Discussion (Perl Cookbook)
croak( ): 12.14.2. Solution (Perl Cookbook)
crypt( ): 5. Function Reference (Perl in a Nutshell)
crypt function: 29.2.20. crypt (Programming Perl)
cryptography: 29.2.164. srand (Programming Perl)
Crypt::SSLeay module: 20.16.2. Solution (Perl Cookbook)
C_stringify function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
CSV (comma-separated values)
initializing arrays with: 4.1.2. Solution (Perl Cookbook)
parsing: 1.20.1. Problem (Perl Cookbook)
reading records from: 6.7.1. Problem (Perl Cookbook)
CSV files, saving results of SQL queries: 14.8.1. Problem (Perl Cookbook)
$ctime file statistic: 29.2.165. stat (Programming Perl)
ctime field, inode structure: 9.. Introduction (Perl Cookbook)
$ctime (timestamp): 11.6.1. The stat and lstat Functions (Learning Perl)
changing: 13.7. Changing Timestamps (Learning Perl)
Ctrl-C, catching: 16.18.1. Problem (Perl Cookbook)
curly braces
1.2.1.2.2. Hashes. (Programming Perl)
1.7.1. Quantifiers (Programming Perl)
1.. Introduction (Perl Cookbook)
creating anonymous arrays and hashes: 11.. References (Perl Cookbook)
block, enclosing code: 2.7. The if Control Structure (Learning Perl)
2.10. The while Control Structure (Learning Perl)
enclosing hash keys: 5.2. Hash Element Access (Learning Perl)
enclosing variable names: 2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
following hash names: 5.2. Hash Element Access (Learning Perl)
indicating quantifier: 8.2. General Quantifiers (Learning Perl)
currency, comparing floating-point numbers: 2.3.3. Discussion (Perl Cookbook)
current directory
find( ) function and: 6.4. Closures (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
@INC array and: 2.5. require and @INC (Learning Perl Objects, References and Modules)
search path and: 2.5. require and @INC (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
testing and: 14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
current package: Glossary (Programming Perl)
current working directory: B.5.2. The Cwd Module (Learning Perl)
current_age( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
current index (Text widget): 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
current_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
curselection( ) (Listbox): 21.10.2. Listbox Methods (Perl in a Nutshell)
Curses module: 15.12.2. Solution (Perl Cookbook)
Curses, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
curses toolkit: 15.. Introduction (Perl Cookbook)
-cursor option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
Cursor( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
customization
debugger: 20.3. Debugger Customization (Programming Perl)
debugger options: 20.3.3. Debugger Options (Programming Perl)
editor support for: 20.3.1. Editor Support for Debugging (Programming Perl)
functions for: 20.5.1. Writing Your Own Debugger (Programming Perl)
init files, using: 20.3.2. Customizing with Init Files (Programming Perl)
customizing
Apache logging requests: 21.9.1. Problem (Perl Cookbook)
warnings: 12.15.1. Problem (Perl Cookbook)
customizing Perl debugger: 6.4. Customizing the Debugger (Perl in a Nutshell)
=cut command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
CV (internal code value): Glossary (Programming Perl)
cwd function: B.5.2. The Cwd Module (Learning Perl)
Cwd module: 12.12.3. Discussion (Perl Cookbook)
B.5.2. The Cwd Module (Learning Perl)
8.49. Cwd (Perl in a Nutshell)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
current working directory for process, determining: 32.9. Cwd (Programming Perl)
cwd( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
Cygwin: 2.3.2. Installing on Win32 (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

^D (Control-D) as eof: 24.5.2. Generating Perl in Other Languages (Programming Perl)
\d (digit) character class: 4.6.4. Character Classes (Perl in a Nutshell)
d command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
d command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
%d conversion: 6.5. Formatted Output with printf (Learning Perl)
-d (debug) command-line switch: 19.1.3. Switches (Programming Perl)
19.1.3. Switches (Programming Perl)
20. The Perl Debugger (Programming Perl)
-D (debugging) command-line switch: 19.1.3. Switches (Programming Perl)
-d file test operator: 9.7.3. Discussion (Perl Cookbook)
4.5.8. File Test Operators (Perl in a Nutshell)
d for digit=\d (for digit): 1.7. Regular Expressions (Programming Perl)
/d modifier: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
-d option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
/d pattern modifier: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
\d shortcut: 8.1.1. Character Class Shortcuts (Learning Perl)
-d switch, perl: 20.6. The Perl Profiler (Programming Perl)
daemon( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
daemon servers: 16.23. Program: sigrand (Perl Cookbook)
17.17.1. Problem (Perl Cookbook)
daemons
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
taint mode, importance of enabling for: 23.1. Handling Insecure Data (Programming Perl)
dangling statements: Glossary (Programming Perl)
dash: 4.6.4. Character Classes (Perl in a Nutshell)
Data( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
data access
threads: 17.2.2. Data Access (Programming Perl)
condition variables: 17.2.2.6. Condition variables (Programming Perl)
deadlock: 17.2.2.2. Deadlock (Programming Perl)
locking methods: 17.2.2.5. Locking methods (Programming Perl)
locking subroutines: 17.2.2.3. Locking subroutines (Programming Perl)
synchronizing with lock: 17.2.2.1. Synchronizing access with lock (Programming Perl)
unlocking: 17.2.2.1. Synchronizing access with lock (Programming Perl)
DATA command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session (Perl in a Nutshell)
Data::Dumper module: 8.50. Data::Dumper (Perl in a Nutshell)
DATA filehandle: 4.4.3. Global Special Filehandles (Perl in a Nutshell)
28.2. Special Variables in Alphabetical Order (Programming Perl)
data-flow analysis: B.14. Security (Learning Perl)
data( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
data organization in Perl: 9.1.5. Common Mistakes (Programming Perl)
data, relationships between (see variables also variables)
5.16.1. Problem (Perl Cookbook)
(see also variables)
data_sources( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
data structures: 9. Data Structures (Programming Perl)
22.1. The CPAN modules Directory (Programming Perl)
Glossary (Programming Perl)
arrays of hashes: 9.3. Arrays of Hashes (Programming Perl)
binary trees: 11.17. Program: Binary Trees (Perl Cookbook)
circular, coping with, using weak references: 11.15.1. Problem (Perl Cookbook)
complex, creating on the fly: 11.. Anonymous Data (Perl Cookbook)
complex, representing as scalars: 1.2.1.3. Complexities (Programming Perl)
copying: 11.12.1. Problem (Perl Cookbook)
flat, linear in Perl: 8. References (Programming Perl)
hashes of arrays: 9.2. Hashes of Arrays (Programming Perl)
hashes of functions: 9.5. Hashes of Functions (Programming Perl)
looping and: 4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
manipulating: 5. Manipulating Complex Data Structures (Learning Perl Objects, References and Modules)
multidimensional hashes: 9.4. Hashes of Hashes (Programming Perl)
nested: 3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
4.3. Reference Counting and Nested Data Structures (Learning Perl Objects, References and Modules)
for objects: 12.4. Object Construction (Programming Perl)
outlines: 11.16. Program: Outlines (Perl Cookbook)
parsing XML into: 22.1.1. Problem (Perl Cookbook)
persistent, providing via tie: 14.6. Tie Modules on CPAN (Programming Perl)
printing: 11.11.1. Problem (Perl Cookbook)
records of elaborate: 9.6. More Elaborate Records (Programming Perl)
recursively defined: 7.5. Recursively Defined Data (Learning Perl Objects, References and Modules)
references to: 8.1. What Is a Reference? (Programming Perl)
references to anonymous: 4. References and Scoping (Learning Perl Objects, References and Modules)
references to subroutines: 6. Subroutine References (Learning Perl Objects, References and Modules)
saving: 9.7. Saving Data Structures (Programming Perl)
self-referential, container classes holding pointers to: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
storing to disk: 11.13.1. Problem (Perl Cookbook)
stringifying: 9.7. Saving Data Structures (Programming Perl)
transparently persistent: 11.14.1. Problem (Perl Cookbook)
data structures, complex: B.20.1. Complex Data Structures (Learning Perl)
__DATA__ token: 7.12.2. Solution (Perl Cookbook)
2.6.8. Other Literal Tokens (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
data types: 4.2. Data Types and Variables (Perl in a Nutshell)
1.2.1. Variable Syntax (Programming Perl)
Glossary (Programming Perl)
built-in: 2.3. Built-in Data Types (Programming Perl)
circular data structures: 13.13.1. Problem (Perl Cookbook)
classes as structs: 13.5.1. Problem (Perl Cookbook)
complex data structures: 4.8. References and Complex Data Structures (Perl in a Nutshell)
converting between C and Perl: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
internal, Perl and C: 21.2. Internal Data Types (Programming Perl)
modules for: 32.1.1. Data Types (Programming Perl)
scalars (see scalars)
TYPE declarations in Perl: 29.2.99. my (Programming Perl)
typeglobs: 2.10. Typeglobs and Filehandles (Programming Perl)
database access: 14.. Introduction (Perl Cookbook)
DBM files
converting between: 14.3.1. Problem (Perl Cookbook)
emptying: 14.2.1. Problem (Perl Cookbook)
making and using: 14.1.1. Problem (Perl Cookbook)
merging: 14.4.1. Problem (Perl Cookbook)
sorting: 14.5.1. Problem (Perl Cookbook)
storing complex data in: 14.6.1. Problem (Perl Cookbook)
dealing with errors: 14.11.1. Problem (Perl Cookbook)
ggh program: 14.19. Program: ggh—Grep Netscape Global History (Perl Cookbook)
persistent data: 14.7.1. Problem (Perl Cookbook)
speeding up with mod_perl: 21.8.1. Problem (Perl Cookbook)
SQL: 20.9.3. Discussion (Perl Cookbook)
queries: 14.9.1. Problem (Perl Cookbook)
14.14.1. Problem (Perl Cookbook)
19.6.3. Discussion (Perl Cookbook)
using transactions: 14.15.1. Problem (Perl Cookbook)
viewing data one page at a time: 14.16.1. Problem (Perl Cookbook)
databases: 16. Simple Databases (Learning Perl)
B.7. Databases (Learning Perl)
12. Databases and Perl (Perl in a Nutshell)
Data Base Management (see DBM files)
database handles (DBI methods): 12.2.3. Database Handles and Statement Handles (Perl in a Nutshell)
DBDs (database drivers): 12.2.1. Database Drivers (DBDs) (Perl in a Nutshell)
DBI module: 12.2. Design of DBI (Perl in a Nutshell)
DBI module and: B.7.3. Relational Database Access (Learning Perl)
DBM (Database Management) facility: 12.1. DBM Databases and DBM Hashes (Perl in a Nutshell)
files for, read/write access to: 16.3. Fixed-length Random-access Databases (Learning Perl)
fixed-length random-access: 16.3. Fixed-length Random-access Databases (Learning Perl)
hashes and: 5.1.1. Why Use a Hash? (Learning Perl)
Perl connections to: 5. Pattern Matching (Programming Perl)
Perl modules for operating: 22.1. The CPAN modules Directory (Programming Perl)
see also DBI: 22.1. The CPAN modules Directory (Programming Perl)
tying hash variables to: 14. Tied Variables (Programming Perl)
variable-length text: 16.4. Variable-length (Text) Databases (Learning Perl)
Data::Dumper: 9.7. Saving Data Structures (Programming Perl)
Data::Dumper module: 11.11.2. Solution (Perl Cookbook)
5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
7.7. Displaying Recursively Defined Data (Learning Perl Objects, References and Modules)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
32.10. Data::Dumper (Programming Perl)
dataend( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
datagram sockets: 17.4.3. Discussion (Perl Cookbook)
datagrams: 16.5. Sockets (Programming Perl)
Glossary (Programming Perl)
DataHash( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
DataReceiveTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
datasend( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
DataSendTimeout( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
DataSources( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
date and time
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
HTTP::Date module: 20.3.5. HTTP::Date (Perl in a Nutshell)
date and time values: 3.. Introduction (Perl Cookbook)
arithmetic with: 3.4.1. Problem (Perl Cookbook)
converting to and from Epoch seconds: 3.2.1. Problem (Perl Cookbook)
Date::DateCalc: 3.4.1. Problem (Perl Cookbook)
Date::Manip module: 3.8.3. Discussion (Perl Cookbook)
3.11. Program: hopdelta (Perl Cookbook)
days, calculating: 3.6.1. Problem (Perl Cookbook)
number between two dates: 3.5.1. Problem (Perl Cookbook)
file access timestamps: 9.1.1. Problem (Perl Cookbook)
high-resolution timers: 3.9.1. Problem (Perl Cookbook)
hopdelta program: 3.11. Program: hopdelta (Perl Cookbook)
parsing information from strings: 3.7.1. Problem (Perl Cookbook)
printing: 3.8.1. Problem (Perl Cookbook)
seconds passed since Epoch: 3.. Introduction (Perl Cookbook)
sleeps: 3.10.1. Problem (Perl Cookbook)
sorting mail by: 10.18. Program: Sorting Your Mail (Perl Cookbook)
Time::gmtime module: 3.3.2. Solution (Perl Cookbook)
Time::HiRes module: 3.9.2. Solution (Perl Cookbook)
Time::Local module: 3.2.2. Solution (Perl Cookbook)
Time::timelocal module: 3.3.2. Solution (Perl Cookbook)
timing out operations: 16.21.1. Problem (Perl Cookbook)
today's date, finding: 3.1.1. Problem (Perl Cookbook)
years: 3.. Introduction (Perl Cookbook)
date command (Unix): 14.1. The system Function (Learning Perl)
16.4. Variable-length (Text) Databases (Learning Perl)
capturing output and: 14.4. Using Backquotes to Capture Output (Learning Perl)
date function (see localtime function)
date( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
DateCalc( ): 3.11. Program: hopdelta (Perl Cookbook)
Date::Calc module: 3.4.2. Solution (Perl Cookbook)
3.6.2. Solution (Perl Cookbook)
Date::DateCalc module: 3.. Introduction (Perl Cookbook)
Date::Manip module: 3.. Introduction (Perl Cookbook)
3.7.2. Solution (Perl Cookbook)
3.11. Program: hopdelta (Perl Cookbook)
dates
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
dates, portability of: 25.8. Dates and Times (Programming Perl)
day, month, year, hour, minute, seconds (DMYHMS): 3.. Introduction (Perl Cookbook)
daylight savings time (DST): 6.8.1. Exercise [30 min] (Learning Perl Objects, References and Modules)
Day_of_week( ): 3.6.2. Solution (Perl Cookbook)
Day_of_Year( ): 3.6.2. Solution (Perl Cookbook)
days (see date and time values)
DB module: 8.51. DB (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
DB package, caller function: 29.2.8. caller (Programming Perl)
DBD (Database drivers)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
DBD module: 14.9.2. Solution (Perl Cookbook)
DBD::CSV module: 14.17.2. Solution (Perl Cookbook)
DBDs (database drivers): 12. Databases and Perl (Perl in a Nutshell)
12.2.1. Database Drivers (DBDs) (Perl in a Nutshell)
DBD::SQLite module: 14.. Introduction (Perl Cookbook)
14.18.2. Solution (Perl Cookbook)
DB_File module: 11.14.2. Solution (Perl Cookbook)
8.52. DB_File (Perl in a Nutshell)
32.1.10. DBM Interfaces (Programming Perl)
Data::Dumper module, using with: 32.10. Data::Dumper (Programming Perl)
DB_RECNO access method: 8.8.2. Solution (Perl Cookbook)
sorting large DBM files: 14.5.2. Solution (Perl Cookbook)
db2gdbm program: 14.3.2. Solution (Perl Cookbook)
DBI (Database Interface)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
DBI_ environment variables: 12.4. DBI Environment Variables (Perl in a Nutshell)
DBI module: 14.9.2. Solution (Perl Cookbook)
B.7.3. Relational Database Access (Learning Perl)
1.1. What's Perl Good For? (Perl in a Nutshell)
12. Databases and Perl (Perl in a Nutshell)
12.2. Design of DBI (Perl in a Nutshell)
database and statement handles: 12.2.3. Database Handles and Statement Handles (Perl in a Nutshell)
environment variables for: 12.4. DBI Environment Variables (Perl in a Nutshell)
methods of: 12.3. DBI Methods (Perl in a Nutshell)
DBIx::Dump module: 14.8.2. Solution (Perl Cookbook)
DBM (Database Management) facility: 12.1. DBM Databases and DBM Hashes (Perl in a Nutshell)
DBM file
storing complex data values in: 14.6. Tie Modules on CPAN (Programming Perl)
DBM files: 16.1. DBM Files and DBM Hashes (Learning Perl)
B.21. Tied Variables (Learning Perl)
Glossary (Programming Perl)
complex data in: 14.6.1. Problem (Perl Cookbook)
complex data values, storing in: 32.10. Data::Dumper (Programming Perl)
converting between: 14.3.1. Problem (Perl Cookbook)
dbmclose and dbmopen functions: 29.2.21. dbmclose (Programming Perl)
deleting from: 29.2.24. delete (Programming Perl)
emptying: 14.2.1. Problem (Perl Cookbook)
GDBM files: 14.3.2. Solution (Perl Cookbook)
locking: 16.2.1. File Locking (Programming Perl)
making and using: 14.1.1. Problem (Perl Cookbook)
merging: 14.4.1. Problem (Perl Cookbook)
modules for: 32.1.10. DBM Interfaces (Programming Perl)
sorting: 14.5.1. Problem (Perl Cookbook)
DBM hashes: 16.1. DBM Files and DBM Hashes (Learning Perl)
B.21. Tied Variables (Learning Perl)
DBM libraries: 14.. Introduction (Perl Cookbook)
DBM modules, portability of: 25.7. Standard Modules (Programming Perl)
dbmclose( ): 5. Function Reference (Perl in a Nutshell)
dbmclose function: 16.1.1. Opening and Closing DBM Hashes (Learning Perl)
14. Tied Variables (Programming Perl)
dbmopen( ): 5. Function Reference (Perl in a Nutshell)
12.1. DBM Databases and DBM Hashes (Perl in a Nutshell)
dbmopen function: 16.1.1. Opening and Closing DBM Hashes (Learning Perl)
A.9.1. Exercise (Section 10.7.1) (Learning Perl Objects, References and Modules)
14. Tied Variables (Programming Perl)
use declarations with: 14. Tied Variables (Programming Perl)
dbprofpp program: 20.6. The Perl Profiler (Programming Perl)
dclone( ): 11.12.2. Solution (Perl Cookbook)
13.7.2. Solution (Perl Cookbook)
deadlock in threads: 17.2.2.2. Deadlock (Programming Perl)
deallocating memory: 8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
Debug( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
Debug style (XML::Parser): 13.4. XML::Parser Styles (Perl in a Nutshell)
debugger for Perl: B.15. Debugging (Learning Perl)
debugging: 6. Debugging (Perl in a Nutshell)
19.1.3. Switches (Programming Perl)
20. The Perl Debugger (Programming Perl)
23.1. Handling Insecure Data (Programming Perl)
(see also taint)
backend modules for: 18.4. Compiler Backends (Programming Perl)
bug reports: 0.6.3. Bug Reports (Programming Perl)
CGI scripts: 19.. Behind the Scenes (Perl Cookbook)
19.3.3.3. Is the script valid Perl? (Perl Cookbook)
10.6. Debugging (Perl in a Nutshell)
Changes file and: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
controlling from programs: 20.1. Using the Debugger (Programming Perl)
-d, -D options (perl): 6.1. The Perl Debugger (Perl in a Nutshell)
6.5. The Perl Profiler (Perl in a Nutshell)
DB module: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
debug level, setting through class or instances: 12.8. Managing Class Data (Programming Perl)
debugger code, command for loading: 19.2. Environment Variables (Programming Perl)
debugger customization: 20.3. Debugger Customization (Programming Perl)
debugger, customizing
options: 20.3.3. Debugger Options (Programming Perl)
debugger support, Perl: 20.5. Debugger Support (Programming Perl)
debugger, unattended execution: 20.4. Unattended Execution (Programming Perl)
Devel::Peek module for XS programs: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
enabling warnings during: A.3.1. Exercise 1 (Section 4.9.1) (Learning Perl Objects, References and Modules)
global destruction of objects other references, controlling: 19.2. Environment Variables (Programming Perl)
overloading: 13.10. Overloading Diagnostics (Programming Perl)
Perl debugger: 6.1. The Perl Debugger (Perl in a Nutshell)
commands for: 6.2. Debugger Commands (Perl in a Nutshell)
customizing: 6.4. Customizing the Debugger (Perl in a Nutshell)
Perl debugger commands: 20.2. Debugger Commands (Programming Perl)
Perl profiler (DProf): 6.5. The Perl Profiler (Perl in a Nutshell)
Perl, using C compiler -DDEBUGGING option: 12.5. Class Inheritance (Programming Perl)
perlbug program: 6.6. The perlbug Program (Perl in a Nutshell)
raw HTTP exchange: 19.8.1. Problem (Perl Cookbook)
symbolic: Glossary (Programming Perl)
turning on in tied filehandle: 14.4.1. Filehandle-Tying Methods (Programming Perl)
Unix security bugs: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
viewing complex data: 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
x command: 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
debugging flags: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$DEBUGGING ($^D) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
debug_print( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
decimal integer conversion: 6.5. Formatted Output with printf (Learning Perl)
decimal points, lining up: 7. Formats (Programming Perl)
decimals
formatting for output: 17.3. Transforming Items from a List with map (Learning Perl)
rounding
printf function and: 6.5. Formatted Output with printf (Learning Perl)
sprintf function and: 15.3.1. Using sprintf with "Money Numbers" (Learning Perl)
declarations: 4.1. Program Structure (Perl in a Nutshell)
1.1. Getting Started (Programming Perl)
4. Statements and Declarations (Programming Perl)
Glossary (Programming Perl)
structs: 12.7.2. Generating Classes with Class::Struct (Programming Perl)
fields with use fields pragma: 12.7.1. Field Declarations with use fields (Programming Perl)
global: 4.7. Global Declarations (Programming Perl)
global variables, lexically scoped: 4.8.3. Lexically Scoped Global Declarations: our (Programming Perl)
methods, lvalues, indicating return of: 12.7.6. New Tricks (Programming Perl)
package: 10. Packages (Programming Perl)
29.2.109. package (Programming Perl)
packages: 7.1. Namespaces and Packages (Perl in a Nutshell)
1.2.1.4. Simplicities (Programming Perl)
4.8. Scoped Declarations (Programming Perl)
private vs. local: 4.7.4. Private and Local Variables (Perl in a Nutshell)
scoped: 4.8. Scoped Declarations (Programming Perl)
subroutines: 4.7. Subroutines (Perl in a Nutshell)
4.7. Global Declarations (Programming Perl)
with definitions: 6.1. Syntax (Programming Perl)
use declarations: 1.2.1.4. Simplicities (Programming Perl)
variables: 4.2.7. Declarations and Scope (Perl in a Nutshell)
4. Statements and Declarations (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
declarative approach, regular expression programming: 5.10.3. Programmatic Patterns (Programming Perl)
declaring
formats: 7. Formats (Programming Perl)
subroutines: 29.2.167. sub (Programming Perl)
without defining: 6.1. Syntax (Programming Perl)
decomposing characters into simpler ones: 5.4.3.2. Standard Unicode properties (Programming Perl)
decompressing CPAN modules: 22.2.1. Decompressing and Unpacking CPAN Modules (Programming Perl)
decrementing variables: 1.5.4. Unary Arithmetic Operators (Programming Perl)
Glossary (Programming Perl)
decryption (see encryption)
deep copies: 11.12.3. Discussion (Perl Cookbook)
Default handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
default package: 4.8. Scoped Declarations (Programming Perl)
DEFAULT pseudosignal: 16.1. Signals (Programming Perl)
default values: Glossary (Programming Perl)
default values for variables: 1.2.1. Problem (Perl Cookbook)
default variable ($_): 3.7. Perl's Favorite Default: $_ (Learning Perl)
=~ binding operator and: 9.3. The Binding Operator, =~ (Learning Perl)
input stored in: 6.1. Input from Standard Input (Learning Perl)
default_port( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
defaults: 1.2.2. Is Perl Easy or Hard? (Learning Perl)
output filehandle: 11.4.1. Changing the Default Output Filehandle (Learning Perl)
defaults( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
defined( ): 5. Function Reference (Perl in a Nutshell)
defined function: 2.12. The defined Function (Learning Perl)
13.6. Changing Ownership (Learning Perl)
29.2.23. defined (Programming Perl)
Glossary (Programming Perl)
defined operator: 1.2.3. Discussion (Perl Cookbook)
definedness: 1.. Introduction (Perl Cookbook)
1.2.3. Discussion (Perl Cookbook)
defining subroutines: 6.2. Semantics (Programming Perl)
definitions: Glossary (Programming Perl)
classes (object-oriented modules as): 11.1. Using Modules (Programming Perl)
subroutines
declarations vs.: 4.7. Global Declarations (Programming Perl)
loading from other files: 4.7. Global Declarations (Programming Perl)
loading with AUTOLOAD: 10.2. Autoloading (Programming Perl)
deg2rad( ): 2.10.3. Discussion (Perl Cookbook)
deiconify( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
del( ) (DB_File module): 8.52. DB_File (Perl in a Nutshell)
DEL in hexadecimal: 2.6.2. String Literals (Programming Perl)
delay( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
delaying module loading: 12.3.1. Problem (Perl Cookbook)
delegation: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
delete( ): 5. Function Reference (Perl in a Nutshell)
Canvas widget: 21.12.3. Canvas Methods (Perl in a Nutshell)
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
Entry widget: 21.8.2. Entry Methods (Perl in a Nutshell)
HTML::Parser module: 20.4.3. HTML::Element (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Net::LDAP: 19.4. Net::LDAP Methods (Perl in a Nutshell)
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
5.4.2. Solution (Perl Cookbook)
compared to undef( ): 5.4.3. Discussion (Perl Cookbook)
multiple hash key values: 5.8.3. Discussion (Perl Cookbook)
delete function: 5.4.2. The delete Function (Learning Perl)
29.2.24. delete (Programming Perl)
tied arrays, not returning deleted value for: 24.1.5. Previous Perl Traps (Programming Perl)
Delete( ) (Win32::Internet module): 22.7.2. FTP Functions (Perl in a Nutshell)
delete_all( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
delete_content( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
DeleteKey( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
delete_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
delete_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
DeleteValue( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
deleting
all debugger actions: 20.2.6. Actions and Command Execution (Programming Perl)
array elements: 29.2.111. pop (Programming Perl)
29.2.149. shift (Programming Perl)
29.2.160. splice (Programming Perl)
breakpoints: 20.2.2. Breakpoints (Programming Perl)
characters: 29.2.11. chomp (Programming Perl)
clearing the screen: 15.3.1. Problem (Perl Cookbook)
directories: 29.2.135. rmdir (Programming Perl)
29.2.188. unlink (Programming Perl)
directories and their contents: 9.8.1. Problem (Perl Cookbook)
DOS shell window: 15.17.1. Problem (Perl Cookbook)
emptying DBM files: 14.2.1. Problem (Perl Cookbook)
files: 9.2.1. Problem (Perl Cookbook)
29.2.188. unlink (Programming Perl)
last line of: 8.10.1. Problem (Perl Cookbook)
found but unreplaced characters: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
hash elements: 5.4.1. Problem (Perl Cookbook)
29.2.24. delete (Programming Perl)
HTML tags from strings: 20.6.1. Problem (Perl Cookbook)
selected subroutine return values: 10.8.1. Problem (Perl Cookbook)
whitespace at string ends: 1.19.1. Problem (Perl Cookbook)
del_group( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
delimiters: 1.. Introduction (Perl Cookbook)
Glossary (Programming Perl)
changing for s/// substitution operator: 9.6.2. Different Delimiters (Learning Perl)
in lists: 3.3.1. The qw Shortcut (Learning Perl)
nonpaired: 9.1. Matches with m// (Learning Perl)
pattern-matching operators and: 5.2. Pattern-Matching Operators (Programming Perl)
delta( ) (Scrollbar): 21.9.1. Scrollbar Methods (Perl in a Nutshell)
Delta_Days( ): 3.5.3. Discussion (Perl Cookbook)
Delta_DHMS( ): 3.5.3. Discussion (Perl Cookbook)
denial-of-service problems (patterns and regular expressions), security concerns: 23.3.2. Code Masquerading as Data (Programming Perl)
Deparse backend (Perl compiler): 3.4. The Perl Compiler (Perl in a Nutshell)
dequote( ): 1.16.3. Discussion (Perl Cookbook)
dereference-address operator (*), C language: 3.21. C Operators Missing from Perl (Programming Perl)
dereference operators, overloading: 13.3. Overloadable Operators (Programming Perl)
dereferencing: 11.3.1. Problem (Perl Cookbook)
4.8.2. Dereferencing (Perl in a Nutshell)
8.1. What Is a Reference? (Programming Perl)
8.1. What Is a Reference? (Programming Perl)
8.3. Using Hard References (Programming Perl)
8.3.1. Using a Variable as a Variable Name (Programming Perl)
8.3.3. Using the Arrow Operator (Programming Perl)
Glossary (Programming Perl)
array elements: 9.1.3. Access and Printing (Programming Perl)
array references: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
4.2. What if That Was the Name? (Learning Perl Objects, References and Modules)
coderefs: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
hash references: 3.8. References to Hashes (Learning Perl Objects, References and Modules)
hash values as functions: 9.5. Hashes of Functions (Programming Perl)
lexical variables and: 6.4. Closures (Learning Perl Objects, References and Modules)
operator for (see arrow operator)
typeglobs: 10.1. Symbol Tables (Programming Perl)
derived classes: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
empty subclass test: Glossary (Programming Perl)
methods as wrappers around base class methods: 12.5.2. Accessing Overridden Methods (Programming Perl)
descriptors (see file descriptors)
deselect( )
Checkbutton widget: 21.5.1. Checkbutton Methods (Perl in a Nutshell)
Radiobutton widget: 21.6.1. Radiobutton Methods (Perl in a Nutshell)
DESTROY method: 7.3. Object-Oriented Perl (Perl in a Nutshell)
inheritance and: 10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
nested objects: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
purpose: 10. Object Destruction (Learning Perl Objects, References and Modules)
10. Object Destruction (Learning Perl Objects, References and Modules)
destroying threads
detach method: 17.2.1.4. The detach method (Programming Perl)
join method: 17.2.1.2. Thread destruction (Programming Perl)
destructors: 13.. Methods (Perl Cookbook)
13.2.1. Problem (Perl Cookbook)
12.6. Instance Destructors (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
class variables and: 10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
controlling: 19.2. Environment Variables (Programming Perl)
garbage collection with: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
IO::File objects and: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
nested objects example: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
shared memory and semaphore: 16.4. System V IPC (Programming Perl)
detach method: 17.2.1.4. The detach method (Programming Perl)
$dev file statistic: 29.2.165. stat (Programming Perl)
$dev (device number): 11.6.1. The stat and lstat Functions (Learning Perl)
Devel::DProf module: 8.53. Devel::DProf (Perl in a Nutshell)
Devel::PPPort module: 8.54. Devel::PPPort (Perl in a Nutshell)
Devel::Dprof module: 20.6. The Perl Profiler (Programming Perl)
profiling subroutine execution with: 20.6. The Perl Profiler (Programming Perl)
development support, modules for: 22.1. The CPAN modules Directory (Programming Perl)
DevelopMentor: 14.1. What Is SOAP? (Perl in a Nutshell)
Devel::Peek module: 11.15.3. Description (Perl Cookbook)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
Devel::SelfStubber module: 32.1.17. Module Installation Support (Programming Perl)
8.55. Devel::SelfStubber (Perl in a Nutshell)
Devel::SmallProf module: 20.6. The Perl Profiler (Programming Perl)
devices (hardware): Glossary (Programming Perl)
diacritics: 1.8.3. Discussion (Perl Cookbook)
converting case and: 1.13.3. Discussion (Perl Cookbook)
diagnostic messages, from diamond operator\: 6.2. Input from the Diamond Operator (Learning Perl)
diagnostics module: 8.56. diagnostics (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
diagnostics pragma: B.6.2. The diagnostics Pragma (Learning Perl)
dialog boxes with Tk toolkit: 15.15.1. Problem (Perl Cookbook)
DialogBox widget, Tk: 15.15.2. Solution (Perl Cookbook)
diamond operator ( ): 6.2. Input from the Diamond Operator (Learning Perl)
@ARGV array and: 6.3. The Invocation Arguments (Learning Perl)
in-place editing of text files and: 16.4. Variable-length (Text) Databases (Learning Perl)
die( ): 4.9. Filehandles (Perl in a Nutshell)
5. Function Reference (Perl in a Nutshell)
die function: 10.12.2. Solution (Perl Cookbook)
11.3. Fatal Errors with die (Learning Perl)
29.2.25. die (Programming Perl)
exit function versus: 29.2.35. exit (Programming Perl)
fatal errors, causing: Glossary (Programming Perl)
quit signal handling and: 16.1. Signals (Programming Perl)
__DIE__ signal: 16.15.3. Discussion (Perl Cookbook)
dieLevel option (debugger): 20.3.3. Debugger Options (Programming Perl)
differences of lists: 4.8.1. Problem (Perl Cookbook)
computing: 4.9.1. Problem (Perl Cookbook)
simple and symmetric: 4.9.3. Discussion (Perl Cookbook)
digest( )
(Digest modules): 8.57. Digest (Perl in a Nutshell)
(Digest::MD5 module): 8.58. Digest::MD5 (Perl in a Nutshell)
Digest modules: 8.57. Digest (Perl in a Nutshell)
Digest::MD5 module: 8.58. Digest::MD5 (Perl in a Nutshell)
digits: 1.7. Regular Expressions (Programming Perl)
in names: 2.5. Names (Programming Perl)
digits, \d shortcut for: 8.1.1. Character Class Shortcuts (Learning Perl)
-digits option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
dir( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
direct object syntax: 10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
directives (pod): 26.1.2. Pod Directives (Programming Perl)
Glossary (Programming Perl)
directories: 9.. Introduction (Perl Cookbook)
13.3. Links and Files (Learning Perl)
changing working: 29.2.9. chdir (Programming Perl)
closing: 29.2.17. closedir (Programming Perl)
copying and moving files: 9.3.1. Problem (Perl Cookbook)
creating: 29.2.94. mkdir (Programming Perl)
creating or removing portably: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
current working, getting pathname of: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
deleting: 9.8.1. Problem (Perl Cookbook)
29.2.135. rmdir (Programming Perl)
29.2.188. unlink (Programming Perl)
deleting files: 9.2.1. Problem (Perl Cookbook)
DirHandle module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
file-related functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
file test checks on trees: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
file test operator: 1.5.7. Some File Test Operators (Programming Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
handles: Glossary (Programming Perl)
IO::Dir module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
making/removing: 13.4. Making and Removing Directories (Learning Perl)
manipulating: 12. Directory Operations (Learning Perl)
multiple names for same file: 9.4.1. Problem (Perl Cookbook)
of modules: 12.8.1. Problem (Perl Cookbook)
opendir function: 29.2.105. opendir (Programming Perl)
parsing filenames: 9.10.1. Problem (Perl Cookbook)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
prepending to @INC: 19.1.3. Switches (Programming Perl)
processing all files in: 9.5.1. Problem (Perl Cookbook)
recursively: 9.7.1. Problem (Perl Cookbook)
reading entries from: 29.2.121. readdir (Programming Perl)
recursively duplicating: 9.12. Program: symirror (Perl Cookbook)
renaming files: 9.9.1. Problem (Perl Cookbook)
represented as hashes: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
rewinddir function: 29.2.133. rewinddir (Programming Perl)
root, redefining: 29.2.15. chroot (Programming Perl)
seekdir function: 29.2.139. seekdir (Programming Perl)
separating with colon: 2.5.2. Extending @INC with PERL5LIB (Learning Perl Objects, References and Modules)
sorting contents of: 9.. Introduction (Perl Cookbook)
9.13. Program: lst (Perl Cookbook)
t files and: 14.1. What the Test Harness Does (Learning Perl Objects, References and Modules)
timestamps: 9.1.1. Problem (Perl Cookbook)
directory handles: 9.. Executive Summary (Perl Cookbook)
12.4. Directory Handles (Learning Perl)
directory service: 19. Lightweight Directory Access with Net::LDAP (Perl in a Nutshell)
DirHandle module: 8.59. DirHandle (Perl in a Nutshell)
dirname( ): 9.10.3. Discussion (Perl Cookbook)
dirname function, File::Basename module and: 13.8.1. The File::Basename Module (Learning Perl)
dirname subroutine (File::Basename): 12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
-disabledforeground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
disciplines: 29.2.104. open (Programming Perl)
filehandles, setting up with binmode: 29.2.6. binmode (Programming Perl)
disconnect( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
Disconnect( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
disk usage, library: 14.. Introduction (Perl Cookbook)
dispatch_from( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
Display( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
Distinguished Name (DN): 18.8.3. Discussion (Perl Cookbook)
distributions
alternate installation locations: 13.6. Alternate Installation Locations (PREFIX=...) (Learning Perl Objects, References and Modules)
announcing CPAN modules: 15.5. Announcing the Module (Learning Perl Objects, References and Modules)
copyrights and licensing: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
embedded documentation: 13.4. Embedded Documentation (Learning Perl Objects, References and Modules)
Exporter module: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
h2xs tool: 13.1. Starting with h2xs (Learning Perl Objects, References and Modules)
make dist and: 13.9. Trivial make dist (Learning Perl Objects, References and Modules)
13.9. Trivial make dist (Learning Perl Objects, References and Modules)
Makefile.PL: 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
modules within: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
POD format: 13.4. Embedded Documentation (Learning Perl Objects, References and Modules)
preparing: 15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
qw( ) lists: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
template files: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
testing: 13.7. Trivial make test (Learning Perl Objects, References and Modules)
14. Essential Testing (Learning Perl Objects, References and Modules)
Test::More module: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
Test::Simple module: 14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
uploading to CPAN: 15.4. Uploading Your Distribution (Learning Perl Objects, References and Modules)
15.4. Uploading Your Distribution (Learning Perl Objects, References and Modules)
version numbers: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
distributions( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
division (see multiplicative operators)
division operator (/): 2.2.5. Numeric Operators (Learning Perl)
4.5.3. Arithmetic Operators (Perl in a Nutshell)
dlineinfo( ) (Text widget): 21.11.2. Text Methods (Perl in a Nutshell)
DMYHMS (day, month, year, hour, minute, seconds): 3.. Introduction (Perl Cookbook)
DMYHMS values (see date and time values)
DN (Distinguished Name): 18.8.3. Discussion (Perl Cookbook)
DNS (domain name server): 16.5. Sockets (Programming Perl)
DNS lookups: 18.1.1. Problem (Perl Cookbook)
do( ): 5. Function Reference (Perl in a Nutshell)
DBI module: 12.3. DBI Methods (Perl in a Nutshell)
10.. Introduction (Perl Cookbook)
configuration files, reading: 8.16.3. Discussion (Perl Cookbook)
finding number of rows returned by SQL queries: 14.14.2. Solution (Perl Cookbook)
do {} operator: 3.1. Terms and List Operators (Leftward) (Programming Perl)
do BLOCK
iterating: 4.5. Bare Blocks (Programming Perl)
terminating: 4.5. Bare Blocks (Programming Perl)
29.2.26. do (block) (Programming Perl)
do FILE operator: 29.2.27. do (file) (Programming Perl)
do loops: 24.1.1. Universal Blunders (Programming Perl)
do operator: 2.3. Using do (Learning Perl Objects, References and Modules)
do statement, conditional modifiers with: 4.3.1.4. Modifiers (Perl in a Nutshell)
do SUBROUTINE operator: 29.2.28. do (subroutine) (Programming Perl)
doc directory (CPAN), official Perl manpages: 22. CPAN (Programming Perl)
Doctype handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
DoctypeFin handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
Document Object Model (DOM): 22.. History of Perl and XML (Perl Cookbook)
documentation
books on Perl: 0.5. Offline Documentation (Programming Perl)
bug reports: 0.6.3. Bug Reports (Programming Perl)
C library functions: 29. Functions (Programming Perl)
default system viewer, calling: 20.2.7. Miscellaneous Commands (Programming Perl)
distribution considerations: 13. Writing a Distribution (Learning Perl Objects, References and Modules)
embedded for distribution: 13.4. Embedded Documentation (Learning Perl Objects, References and Modules)
modules for: 32.1.16. Documentation Support (Programming Perl)
Perl manpages: 0.4. Online Documentation (Programming Perl)
testing and: 14. Essential Testing (Learning Perl Objects, References and Modules)
documentation,Perl: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
B.1. Further Documentation (Learning Perl)
embedding: B.28. Embedded Documentation (Learning Perl)
2.5. Documentation (Perl in a Nutshell)
4.13. Pod (Perl in a Nutshell)
= to signify in programs: 4.1. Program Structure (Perl in a Nutshell)
utilities for: 4.13.3. Pod Utilities (Perl in a Nutshell)
documentation, standard modules: 11. Modules (Programming Perl)
documentation,embedded in Perl programs: 26. Plain Old Documentation (Programming Perl)
(see also pod)
dollar sign ($): 1.2.1.2.2. Hashes. (Programming Perl)
$1, $2, . . . (backreferences): 1.11.3. Discussion (Perl Cookbook)
6.. Special Variables (Perl Cookbook)
finding doubled words: 6.16.2. Solution (Perl Cookbook)
$0 variable: 7.12.3. Discussion (Perl Cookbook)
18.16. Program: expn and vrfy (Perl Cookbook)
$* variable (deprecated): 6.. Pattern-Matching Modifiers (Perl Cookbook)
$& variable: 1.11.3. Discussion (Perl Cookbook)
6.. Special Variables (Perl Cookbook)
$#ARRAY variable: 4.3.2. Solution (Perl Cookbook)
dereferencing with: 4.8.2. Dereferencing (Perl in a Nutshell)
$^F variable: 12.7.3. Discussion (Perl Cookbook)
hashes: 5.. Introduction (Perl Cookbook)
$^I variable: 7.16.3. Discussion (Perl Cookbook)
in regular text: 2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
in scalar variable names: 2.5. Scalar Variables (Learning Perl)
indicating end of string: 8.3. Anchors (Learning Perl)
$^O variable: 7.25. Program: lockarea (Perl Cookbook)
9.10.3. Discussion (Perl Cookbook)
preceding hash names: 5.2. Hash Element Access (Learning Perl)
prototype symbol (scalar): 4.7.5. Prototypes (Perl in a Nutshell)
signifying scalar variables: 4.2.5. Variables (Perl in a Nutshell)
special variables: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
$VERSION variable (use pragma): 12.1.3. Discussion (Perl Cookbook)
$^W variable: 12.14.3. Discussion (Perl Cookbook)
$^T ($BASETIME): 3.10. Named Unary and File Test Operators (Programming Perl)
$. ($INPUT_LINE_NUMBER): 3.15. Range Operator (Programming Perl)
DOM (Document Object Model): 22.. History of Perl and XML (Perl Cookbook)
trees: 22.. History of Perl and XML (Perl Cookbook)
building while validating XML: 22.5.3. Discussion (Perl Cookbook)
parsing XML into: 22.2.1. Problem (Perl Cookbook)
domain-name databases: B.7.1. Direct System Database Access (Learning Perl)
domain( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
domains for sockets: 17.. Introduction (Perl Cookbook)
do_push( ) (CGI::Push module): 8.39. CGI::Push (Perl in a Nutshell)
DOS shell window, removing: 15.17.1. Problem (Perl Cookbook)
dosish.h file: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
dot (.)
. . and . . . range operators: 6.8.2. Solution (Perl Cookbook)
as wildcard character: 7.2.1. About Metacharacters (Learning Perl)
/s modifier and: 9.2.2. Matching Any Character with /s (Learning Perl)
concatenation operator: 4.5.11.4. String operator (Perl in a Nutshell)
24.2.1. Time Efficiency (Programming Perl)
indicating current directory: 13.3. Links and Files (Learning Perl)
periods in numbers: 2.16.1. Problem (Perl Cookbook)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
.. (range) operator: 4.5.11.1. Range operator (Perl in a Nutshell)
... (range) operator: 4.5.11.1. Range operator (Perl in a Nutshell)
.= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
dot and slash (./): 1.4.1. A Simple Program (Learning Perl)
dot-dot (..) indicating parent directory: 13.3. Links and Files (Learning Perl)
double-ended pipe, opening with tied filehandle: 14.4.2. Creative Filehandles (Programming Perl)
double-precision floating-point values: 2.2.1. All Numbers Are the Same Format Internally (Learning Perl)
double-quote context: 2.7.4. Interpolative Context (Programming Perl)
scalar variables, expanding in: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
double-quote interpolation (see variable interpolation)
double quote ("): 1.. Introduction (Perl Cookbook)
escaping: 14.10.1. Problem (Perl Cookbook)
double-quoted string literals: 2.3.2. Double-Quoted String Literals (Learning Perl)
arrays, interpolating into: 3.5. Interpolating Arrays into Strings (Learning Perl)
hash elements, interpolating into: 5.4.3. Hash Element Interpolation (Learning Perl)
scalar variables, interpolating into: 2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
variable interpolation and: 2.3.2. Double-Quoted String Literals (Learning Perl)
double-quoted strings, interpolation and concatenation: 1.5.2. String Operators (Programming Perl)
double quotes: 1.2.1.1. Singularities (Programming Perl)
strings, use in: 1.2.1.1. Singularities (Programming Perl)
replacement string, use with: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
translation escape processing: 5.9.2.1. When backslashes happen (Programming Perl)
arrays and: 6.4. Output to Standard Output (Learning Perl)
enclosing strings: 2.3.2. Double-Quoted String Literals (Learning Perl)
omitting from hash keys: 17.4. Unquoted Hash Keys (Learning Perl)
double words, finding: 6.16.1. Problem (Perl Cookbook)
down method: 17.2.3.2. Semaphores (Programming Perl)
downloading
Perl language source code: 2. Installing Perl (Perl in a Nutshell)
Perl modules source code: 2.2. How Is CPAN Organized? (Perl in a Nutshell)
2.4. Getting and Installing Modules (Perl in a Nutshell)
downloading pattern test program: 7.4. Exercises (Learning Perl)
DProf (see Devel::Dprof module)
dprofpp utility: 6.5. The Perl Profiler (Perl in a Nutshell)
Drivers( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
drop arrow rule: 3.7. Simplifying Nested Element References with Arrows (Learning Perl Objects, References and Modules)
DropCursor( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
du command, sorting output of: 5.17. Program: dutree (Perl Cookbook)
dump( ): 5. Function Reference (Perl in a Nutshell)
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
HTML::Parser module: 20.4.3. HTML::Element (Perl in a Nutshell)
Dump( ): 11.15.3. Description (Perl Cookbook)
Dump( ) (Data::Dumper)): 8.50. Data::Dumper (Perl in a Nutshell)
dump function: 29.2.29. dump (Programming Perl)
dump_results( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
DumpData( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
Dumper( ) (Data::Dumper): 8.50. Data::Dumper (Perl in a Nutshell)
Dumper subroutine: 5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
DumperX( ) (Data::Dumper)): 8.50. Data::Dumper (Perl in a Nutshell)
dump_names function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
Dumpvalue module: 5.6.3. Discussion (Perl Cookbook)
8.60. Dumpvalue (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
Dumpxs( ) (Data::Dumper)): 8.50. Data::Dumper (Perl in a Nutshell)
dup( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
duplicate list elements, extracting: 4.7.1. Problem (Perl Cookbook)
duplicate replaced characters, eliminating: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
dutree program: 5.17. Program: dutree (Perl Cookbook)
dweomer: Glossary (Programming Perl)
dwimmer: Glossary (Programming Perl)
DynaLoader: 21.3.2. Creating Extensions (Programming Perl)
DynaLoader module: 8.61. DynaLoader (Perl in a Nutshell)
10.2. Autoloading (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
dynamic linking: 21.3.1. XS and XSUBs (Programming Perl)
C source code from Perl: 21.3. Extending Perl (Using C from Perl) (Programming Perl)
dynamic loading: B.23. Dynamic Loading (Learning Perl)
dynamic scoping: 10.13.3.3. Using local( ) on parts of aggregates (Perl Cookbook)
4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
4.8. Scoped Declarations (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
Glossary (Programming Perl)
local operator, using on global variables: 4.8.4. Dynamically Scoped Variables: local (Programming Perl)
pattern variables: 5.2. Pattern-Matching Operators (Programming Perl)
5.2.3. The s/ Operator (Substitution) (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

\E (end) character: 4.6.4. Character Classes (Perl in a Nutshell)
-e command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-e (execute) command-line switch: 19.1.3. Switches (Programming Perl)
-e (exists) file test: 1.5.7. Some File Test Operators (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
-e file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
E<> interior sequence (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
/e pattern modifier: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
-e option
(perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
(perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
-E option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
\e (escape) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
\E shortcut: 9.6.5. Case Shifting (Learning Perl)
\E string metacharacter: 1.18.3. Discussion (Perl Cookbook)
/e substitution modifier: 1.12.3. Discussion (Perl Cookbook)
6.. Pattern-Matching Modifiers (Perl Cookbook)
each( ): 5. Function Reference (Perl in a Nutshell)
5.5.2. Solution (Perl Cookbook)
a name="hashes">
hashes
merging: 5.11.3. Discussion (Perl Cookbook)
ordering elements of: 5.7.1. Problem (Perl Cookbook)
traversing: 5.5.3. Discussion (Perl Cookbook)
each function: 5.3.2. The each Function (Learning Perl)
9.4.3. Access and Printing of a Hash of Hashes (Programming Perl)
14.3.1. Hash-Tying Methods (Programming Perl)
29.2.30. each (Programming Perl)
DBM hashes and: 16.1.2. Using a DBM Hash (Learning Perl)
eager pattern matching: 6.. The Tricky Bits (Perl Cookbook)
ebcdic( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
echo and password input: 15.10.1. Problem (Perl Cookbook)
echo command: 12.2. Globbing (Learning Perl)
EDI: 14.1. What Is SOAP? (Perl in a Nutshell)
editing
files (see file contents)
input: 15.11.1. Problem (Perl Cookbook)
editors, support for debugging: 20.3.1. Editor Support for Debugging (Programming Perl)
effective GID (group ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
effective UID ($EFFECTIVE_USER_ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
(see also $< and $> variables)
$EFFECTIVE_GROUP_ID: 28.2. Special Variables in Alphabetical Order (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$EFFECTIVE_GROUP_ID ($EGID) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$EFFECTIVE_USER_ID: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$EFFECTIVE_USER_ID ($>) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
efficiency (see also performance)
profiling: 20.6. The Perl Profiler (Programming Perl)
$EGID variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
Element handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
-elementborderwidth option (Scrollbar): 21.9. The Scrollbar Widget (Perl in a Nutshell)
elements: 3. Lists and Arrays (Learning Perl)
in arrays: 1.2.1.2.1. Arrays. (Programming Perl)
of arrays (see arrays)
of hashes (see hashes)
of an array: 3.1. Accessing Elements of an Array (Learning Perl)
pop and push operators for: 3.4.1. The pop and push Operators (Learning Perl)
elements in arrays: Glossary (Programming Perl)
eleseif statements: 1.6.1.1. The if and unless statements (Programming Perl)
ellipses (...): 5.3.1. Metasymbol Tables (Programming Perl)
else clause, using with unless control structure: 10.1.1. The else Clause with unless (Learning Perl)
else keyword: 2.7. The if Control Structure (Learning Perl)
else statements: 1.6.1.1. The if and unless statements (Programming Perl)
elsif clause: 10.5. The elsif Clause (Learning Perl)
emacs
editor support for debugger: 20.3.1. Editor Support for Debugging (Programming Perl)
-*- sequences: 19.1. Command Processing (Programming Perl)
regular expressions, use of: 1.7. Regular Expressions (Programming Perl)
1.4. How Do I Make a Perl Program? (Learning Perl)
email: 16. Email Connectivity (Perl in a Nutshell)
22.1. The CPAN modules Directory (Programming Perl)
(see also mail)
attachments
extracting: 18.10.1. Problem (Perl Cookbook)
sending: 18.9.1. Problem (Perl Cookbook)
folders for (Mail::Folder module): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
handling messages (Mail::Internet module): 16.2.4. Handle Messages with Mail::Internet (Perl in a Nutshell)
header control (Mail::Send module): 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
Mail modules: 16. Email Connectivity (Perl in a Nutshell)
16.2. The Mail Modules (Perl in a Nutshell)
matching valid addresses: 6.19.1. Problem (Perl Cookbook)
parsing addresses (Mail::Address module): 16.2.6. Parse Email Addresses with Mail::Address (Perl in a Nutshell)
Perl-related mailing lists: 1.4.3. Mailing Lists (Perl in a Nutshell)
random signatures: 16.23. Program: sigrand (Perl Cookbook)
reading (Mail::Audit module): 16.2.9. Mail Filtering with Mail::Audit (Perl in a Nutshell)
reading (Mail::RBL module): 16.2.8. Checking Blacklisted Hosts with Mail::RBL (Perl in a Nutshell)
reading with POP3: 18.5.1. Problem (Perl Cookbook)
retrieving (Net::POP3 module): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
sending: 18.3.1. Problem (Perl Cookbook)
HTML forms via: 19.12.1. Problem (Perl Cookbook)
sending (Mail::Mailer module): 16.2.1. Send Email with Mail::Mailer (Perl in a Nutshell)
sending (Net::SMTP module): 16.1.1. Send Email with Net::SMTP (Perl in a Nutshell)
sorting: 10.18. Program: Sorting Your Mail (Perl Cookbook)
tracking time path of: 3.11. Program: hopdelta (Perl Cookbook)
email addresses, compile time errors and: 3.5. Interpolating Arrays into Strings (Learning Perl)
email, Net::SMTP module for: B.5.8. The Net::SMTP Module (Learning Perl)
Email::Valid module: 6.19.3. Discussion (Perl Cookbook)
embedding code: B.24. Embedding (Learning Perl)
embedding Perl: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
Glossary (Programming Perl)
adding Perl interpreter to C program: 21.4.2. Adding a Perl Interpreter to Your C Program (Programming Perl)
compiling embedded programs: 21.4.1. Compiling Embedded Programs (Programming Perl)
evaluating Perl statement from C: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
perl interpreter program: 21. Internals and Externals (Programming Perl)
Perl stack, manipulating from C: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
empty
base class test: 13.10.3. Discussion (Perl Cookbook)
strings (""): 1.. Introduction (Perl Cookbook)
empty angle operator (<>): 1.4. Filehandles (Programming Perl)
empty import lists: 12.2. Selecting What to Import (Learning Perl Objects, References and Modules)
empty subclass test: 12.5. Class Inheritance (Programming Perl)
Glossary (Programming Perl)
encapsulation: 1.2.1.3. Complexities (Programming Perl)
8.3.4. Using Object Methods (Programming Perl)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
namespace-based: 14.6. Tie Modules on CPAN (Programming Perl)
objects in closures: 12.7.5. Using Closures for Private Objects (Programming Perl)
encapsulation, object: 9.11. Don't Look Inside the Box (Learning Perl Objects, References and Modules)
Encode module: 8.20.3. Discussion (Perl Cookbook)
encoding attribute, XML: 22.. XML Declaration (Perl Cookbook)
encoding module: 8.62. encoding (Perl in a Nutshell)
encoding( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
encoding URLs: 9.2. URL Encoding (Perl in a Nutshell)
encodingspace( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
encryption: 29.2.20. crypt (Programming Perl)
modules for: 32.1.12. Authentication, Security, and Encryption (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
__END__; use of: 24.5.2. Generating Perl in Other Languages (Programming Perl)
END blocks: 10. Object Destruction (Learning Perl Objects, References and Modules)
18.1. The Life Cycle of a Perl Program (Programming Perl)
exit value of program, modifying: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
skipping: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
=end command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
_ _END_ _ constant: 4.4.4. Global Special Constants (Perl in a Nutshell)
End handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
end index
Entry widget: 21.8.1. Text Indexes (Perl in a Nutshell)
Listbox widget: 21.10.1. Listbox Indexes (Perl in a Nutshell)
Menu widget: 21.15.1. Menu Indexes (Perl in a Nutshell)
Text widget: 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
_ _END_ _ marker: 8.5. AutoLoader (Perl in a Nutshell)
13.4. Embedded Documentation (Learning Perl Objects, References and Modules)
end-of-file/end-of-input: 3.9. <STDIN> in List Context (Learning Perl)
bad filehandles and: 11.2.2. Bad Filehandles (Learning Perl)
end of string, matching: 5.6.2. Endings: The \z, \Z, and $ Assertions (Programming Perl)
=end pod directive: 12.20.3. Discussion (Perl Cookbook)
__END__ token: 7.12.2. Solution (Perl Cookbook)
2.6.8. Other Literal Tokens (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
endgrent( ): 5. Function Reference (Perl in a Nutshell)
endgrent function: 29.2.44. getgrent (Programming Perl)
endhostent( ): 5. Function Reference (Perl in a Nutshell)
endhostent function: 29.2.49. gethostent (Programming Perl)
ending (see terminating)
ending escape sequences for character modification: 2.6.2. String Literals (Programming Perl)
endless loop (see infinite loops)
endless loop, stopping: 2.10. The while Control Structure (Learning Perl)
endnetent( ): 5. Function Reference (Perl in a Nutshell)
endpoint( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
endprotoent( ): 5. Function Reference (Perl in a Nutshell)
endprotoent function: 29.2.60. getprotoent (Programming Perl)
endpwent( ): 5. Function Reference (Perl in a Nutshell)
endpwent function: 29.2.61. getpwent (Programming Perl)
endservent( ): 5. Function Reference (Perl in a Nutshell)
endservent function: 29.2.66. getservent (Programming Perl)
endtag( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
English module: 8.63. English (Perl in a Nutshell)
7.1. Format Variables (Programming Perl)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
enqueue method: 17.2.3.1. Queues (Programming Perl)
Entity handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
Entry widget (Perl/Tk): 21.8. The Entry Widget (Perl in a Nutshell)
entrycget( )
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Menubutton widget: 21.14.2. Menubutton Methods (Perl in a Nutshell)
entryconfigure( )
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Menubutton widget: 21.14.2. Menubutton Methods (Perl in a Nutshell)
EnumerateRights( ) (Win32::FileSecurity): 22.6. Win32::FileSecurity (Perl in a Nutshell)
enumeration methods: 23.3. Win32::OLE::Enum (Perl in a Nutshell)
%ENV hash: 14.3. The Environment Variables (Learning Perl)
4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
28.2. Special Variables in Alphabetical Order (Programming Perl)
deleting from: 29.2.24. delete (Programming Perl)
portability of: 25.4. System Interaction (Programming Perl)
Env module: 8.64. Env (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
env program, starting Perl with: 19.1. Command Processing (Programming Perl)
environment: Glossary (Programming Perl)
cleaning up: 23.1.2. Cleaning Up Your Environment (Programming Perl)
environment variables: 14.3. The Environment Variables (Learning Perl)
3.3. Environment Variables (Perl in a Nutshell)
19.2. Environment Variables (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
CGI-related: 9.4. CGI Environment Variables (Perl in a Nutshell)
DBI-related: 12.4. DBI Environment Variables (Perl in a Nutshell)
Env module: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
MHCONTEXTFD: 7.9.3. Discussion (Perl Cookbook)
modules, Perl use of: 19.2. Environment Variables (Programming Perl)
PERLDB_OPTS, setting debugger options with: 20.4. Unattended Execution (Programming Perl)
PERL_DESTRUCT_LEVEL: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
PERL_UNICODE: 8.21.3. Discussion (Perl Cookbook)
portability of: 25.4. System Interaction (Programming Perl)
shells vs. Perl: 24.1.4. Shell Traps (Programming Perl)
taint checking: 23.1. Handling Insecure Data (Programming Perl)
env_proxy( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
eof( ): 5. Function Reference (Perl in a Nutshell)
HTML::Parser module: 20.4.1. HTML::Parser (Perl in a Nutshell)
EOF (end-of-file): Glossary (Programming Perl)
eof function: 1.6.2.1. The while and until statements (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.31. eof (Programming Perl)
tied filehandle, using on: 14.4.1. Filehandle-Tying Methods (Programming Perl)
eparams( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
epath( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
Epoch: 3.2.1. Problem (Perl Cookbook)
11.6.1. The stat and lstat Functions (Learning Perl)
eq (equal to) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
eq operator: 24.1.1. Universal Blunders (Programming Perl)
eq( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
=; (equal sign)
=;> (corresponds to) operator: 3.18. Comma Operators (Programming Perl)
equal method: 17.2.1.5. Identifying threads (Programming Perl)
equal sign (=)
assignment operator: 4.2.5. Variables (Perl in a Nutshell)
4.5.6. Assignment Operators (Perl in a Nutshell)
for embedded documentation (pod): 4.1. Program Structure (Perl in a Nutshell)
in hash name/value pairs: 4.2.5.2. Hashes (Perl in a Nutshell)
for pod commands: 4.13. Pod (Perl in a Nutshell)
== (equal to) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
=> operator, defining key/value pairs: 4.2.5.2. Hashes (Perl in a Nutshell)
4.5.11.3. Comma operator (Perl in a Nutshell)
=~ (pattern match) operator: 4.5.7. Pattern Match Operators (Perl in a Nutshell)
equal to (=) operator: 3.12. Equality Operators (Programming Perl)
equality operators: 4.5.4.2. Equality operators (Perl in a Nutshell)
3.12. Equality Operators (Programming Perl)
equals sign (=)
=~ operator: 1.1.3. Discussion (Perl Cookbook)
=begin pod directive: 12.20.3. Discussion (Perl Cookbook)
=end pod directive: 12.20.3. Discussion (Perl Cookbook)
=> operator: 5.. Introduction (Perl Cookbook)
equery( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
erasing (see deleting)
err( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
errno: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
Errno module: 8.65. Errno (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
$ERRNO ($!) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
Error( )
(Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
(Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
(Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
error log, web server: 19.. Behind the Scenes (Perl Cookbook)
error messages: 2.4. Perl's Built-in Warnings (Learning Perl)
24.3. Programming with Style (Programming Perl)
33. Diagnostic Messages (Programming Perl)
printed by die function: 11.3. Fatal Errors with die (Learning Perl)
sending to a file: 11.5. Reopening a Standard Filehandle (Learning Perl)
standard output and: 14.4. Using Backquotes to Capture Output (Learning Perl)
user efficiency, improving with: 24.2.6. User Efficiency (Programming Perl)
error_as_HTML( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
errors: 7.4.2. Solution (Perl Cookbook)
11.3. Fatal Errors with die (Learning Perl)
29.2.38. fileno (Programming Perl)
33. Diagnostic Messages (Programming Perl)
Carp module: 32.3. Carp (Programming Perl)
CGI scripts: 19.. Behind the Scenes (Perl Cookbook)
fixing 500 server in: 19.3.1. Problem (Perl Cookbook)
redirecting messages from: 19.2.1. Problem (Perl Cookbook)
CGI::Carp module, handling of: 32.5. CGI::Carp (Programming Perl)
controlling for other programs: 16.9.1. Problem (Perl Cookbook)
database: 14.11.1. Problem (Perl Cookbook)
$@ variable for: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$! variable for: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$? variable for: 28.2. Special Variables in Alphabetical Order (Programming Perl)
failed symbol exports: 11.2.1.3. Managing unknown symbols (Programming Perl)
insecure data: 23.1. Handling Insecure Data (Programming Perl)
number (errno): Glossary (Programming Perl)
out-of-memory errors: 28.2. Special Variables in Alphabetical Order (Programming Perl)
reading STDERR from programs: 16.7.1. Problem (Perl Cookbook)
reporting filenames in: 7.4.1. Problem (Perl Cookbook)
reporting like built-ins: 12.14.1. Problem (Perl Cookbook)
subroutines: 6.2.2. Error Indications (Programming Perl)
exceptions in: 10.12.1. Problem (Perl Cookbook)
returning failure from: 10.10.1. Problem (Perl Cookbook)
trapping in require and use statements: 12.2.1. Problem (Perl Cookbook)
trapping undefined function calls: 10.15.1. Problem (Perl Cookbook)
turning signals into: 16.22.1. Problem (Perl Cookbook)
warn function, producing error messages: 29.2.199. warn (Programming Perl)
web server error log: 20.13.1. Problem (Perl Cookbook)
writing to httpd or other CGI errors logs: 32.1.9. World Wide Web (Programming Perl)
errstr( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
ESC character: 2.6.2. String Literals (Programming Perl)
ESC in octal: 2.6.2. String Literals (Programming Perl)
escape sequences for control characters: 2.6.2. String Literals (Programming Perl)
escaped sequences: 4.6.3. Escaped Sequences (Perl in a Nutshell)
escape_from( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
escaping characters: 1.18.1. Problem (Perl Cookbook)
/etc/group file: 24.2.1. Time Efficiency (Programming Perl)
29.2.44. getgrent (Programming Perl)
/etc/hosts file: 29.2.49. gethostent (Programming Perl)
/etc/networks file: 29.2.53. getnetent (Programming Perl)
/etc/passwd file: 24.2.1. Time Efficiency (Programming Perl)
29.2.61. getpwent (Programming Perl)
/etc/protocols file: 29.2.60. getprotoent (Programming Perl)
/etc/services file: 29.2.66. getservent (Programming Perl)
/etc/utmp file: 29.2.50. getlogin (Programming Perl)
$EUID ($>) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
eval( ): 5. Function Reference (Perl in a Nutshell)
eval {} operator: 3.1. Terms and List Operators (Leftward) (Programming Perl)
loop controls and: 4.5. Bare Blocks (Programming Perl)
eval block: 17.1. Trapping Errors with eval (Learning Perl)
caution with: 17.1. Trapping Errors with eval (Learning Perl)
eval function: 2.2. Inserting Code with eval (Learning Perl Objects, References and Modules)
2.2. Inserting Code with eval (Learning Perl Objects, References and Modules)
8. References (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.32. eval (Programming Perl)
die function and: 29.2.25. die (Programming Perl)
loops and: 24.2.1. Time Efficiency (Programming Perl)
packages and: 10. Packages (Programming Perl)
translating with variables: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
eval method
restricted (reval): 23.3.1.1. Restricting namespace access (Programming Perl)
threads, catching exceptions with: 17.2.1.3. Catching exceptions from join (Programming Perl)
$EVAL_ERROR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$EVAL_ERROR ($@) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
eval_sv and eval_pv functions: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
event-based parsing: 13.3. Expat Handlers (Perl in a Nutshell)
events, Tk resize: 15.16.1. Problem (Perl Cookbook)
example Perl scripts: 2.3.1.1. Perl examples (Perl in a Nutshell)
Excel, saving SQL query results to: 14.8.1. Problem (Perl Cookbook)
exceptions: Glossary (Programming Perl)
intercepting: 28.2. Special Variables in Alphabetical Order (Programming Perl)
in detached child threads: 17.2.1.4. The detach method (Programming Perl)
die function and: 29.2.25. die (Programming Perl)
fatal errors, causing: Glossary (Programming Perl)
functions raising: 29.2. Perl Functions in Alphabetical Order (Programming Perl)
handling in subroutines: 10.12.1. Problem (Perl Cookbook)
insecure data: 23.1. Handling Insecure Data (Programming Perl)
modules for: 32.1.15. Warnings and Exceptions (Programming Perl)
raising on failure: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
raising to indicate subroutine errors: 6.2.2. Error Indications (Programming Perl)
threads, catching: 17.2.1.3. Catching exceptions from join (Programming Perl)
trapping: 29.2.32. eval (Programming Perl)
trapping undefined function calls: 10.15.1. Problem (Perl Cookbook)
$EXCEPTIONS_BEING_CAUGHT: 28.2. Special Variables in Alphabetical Order (Programming Perl)
exclamation point: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
exclusive file locks: 16.2.1. File Locking (Programming Perl)
obtaining: 16.2.1. File Locking (Programming Perl)
exclusive locks: 7.18.3. Discussion (Perl Cookbook)
exclusive or (xor) operator: 3.13. Bitwise Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
exec( ): 5. Function Reference (Perl in a Nutshell)
replacing programs: 16.3.2. Solution (Perl Cookbook)
shell escapes: 19.5.3. Discussion (Perl Cookbook)
14.2. The exec Function (Learning Perl)
29.2.33. exec (Programming Perl)
Glossary (Programming Perl)
filehandles, leaving open across calls: 16.2.2. Passing Filehandles (Programming Perl)
list argument form, avoiding shell with: 23.3.2. Code Masquerading as Data (Programming Perl)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
executable files: Glossary (Programming Perl)
executable image file: 18.1. The Life Cycle of a Perl Program (Programming Perl)
$EXECUTABLE_NAME: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$EXECUTABLE_NAME ($^X) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
execute bit: Glossary (Programming Perl)
execute( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
executing
code: 18.3. Executing Your Code (Programming Perl)
code, conditionally: 1.5.5. Logical Operators (Programming Perl)
methods: 12.3. Method Invocation (Programming Perl)
other programs from Perl: 29.2.174. system (Programming Perl)
Perl program: 1.3.1. How to Do It (Programming Perl)
Perl programs: 19.1. Command Processing (Programming Perl)
execution
code, order of: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
Perl programs: 18.1. The Life Cycle of a Perl Program (Programming Perl)
unattended, debugger: 20.4. Unattended Execution (Programming Perl)
execv function (in C): 29.2.33. exec (Programming Perl)
execvp function (in C): 29.2.33. exec (Programming Perl)
exercises in this book: 1.1.3. What About the Exercises and Their Answers? (Learning Perl)
answers to: A. Exercise Answers (Learning Perl)
existence of a process: 16.1.1. Signaling Process Groups (Programming Perl)
exists( ): 5. Function Reference (Perl in a Nutshell)
News::Newsrc module: 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
5.2.2. Solution (Perl Cookbook)
multiple hash key values: 5.8.3. Discussion (Perl Cookbook)
5.4.1. The exists Function (Learning Perl)
29.2.34. exists (Programming Perl)
invoking on hash: 14.3.1. Hash-Tying Methods (Programming Perl)
exit( ): 5. Function Reference (Perl in a Nutshell)
11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
exit function: 29.2.35. exit (Programming Perl)
29.2.40. fork (Programming Perl)
threads and: 17.2.1.2. Thread destruction (Programming Perl)
exit status: 11.3. Fatal Errors with die (Learning Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
exiting
debugger: 20.3.3. Debugger Options (Programming Perl)
if or unless blocks: 4.5. Bare Blocks (Programming Perl)
infinite loop: 4.4.2. for Loops (Programming Perl)
once-through blocks: 4.5. Bare Blocks (Programming Perl)
Perl debugger: 20.2.7. Miscellaneous Commands (Programming Perl)
exiting programs: 1.1. Getting Started (Programming Perl)
exp( ): 5. Function Reference (Perl in a Nutshell)
exp function: 29.2.36. exp (Programming Perl)
expand( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
-expand option (pack geometry manager): 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
expanding
tabs: 1.11.1. Problem (Perl Cookbook)
variables in user input: 1.12.1. Problem (Perl Cookbook)
expansion, filename: 29.2.69. glob (Programming Perl)
Expat: 13.1. XML Parsing and Validation (Perl in a Nutshell)
handlers: 13.3. Expat Handlers (Perl in a Nutshell)
Expect: 22.1. The CPAN modules Directory (Programming Perl)
Expect module: 15.13.2. Solution (Perl Cookbook)
16.3.3. Bidirectional Communication (Programming Perl)
controlling programs with: 15.13.1. Problem (Perl Cookbook)
explicit method invocations: 12.3. Method Invocation (Programming Perl)
EXPN command: 18.16. Program: expn and vrfy (Perl Cookbook)
expn program: 18.16. Program: expn and vrfy (Perl Cookbook)
exponential notation: 2.6.1. Numeric Literals (Programming Perl)
exponentiation (**) operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
3.4. Exponentiation (Programming Perl)
exponentiation of integers: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
exponentiation operator (**): 2.2.5. Numeric Operators (Learning Perl)
@EXPORT array: 28.2. Special Variables in Alphabetical Order (Programming Perl)
@EXPORT array (use pragma): 12.1.3. Discussion (Perl Cookbook)
@EXPORT variable: 12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
Exporter: 21.3.2. Creating Extensions (Programming Perl)
Exporter module: 12.. Import/Export Regulations (Perl Cookbook)
12.1.1. Problem (Perl Cookbook)
8.66. Exporter (Perl in a Nutshell)
32.1.17. Module Installation Support (Programming Perl)
distributions: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
importing with: 12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
module privacy and: 11.2.1. Module Privacy and the Exporter (Programming Perl)
package variables: 12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
export_fail method: 11.2.1.3. Managing unknown symbols (Programming Perl)
export_fail method (Exporter): 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
exporting: 11. Modules (Programming Perl)
OO modules and: 12.5. The Differences Between OO and Non-OO Modules (Learning Perl Objects, References and Modules)
12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
symbols: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
exporting symbols: 11.2. Creating Modules (Programming Perl)
11.2.1. Module Privacy and the Exporter (Programming Perl)
Glossary (Programming Perl)
without using import method from Exporter: 11.2.1.1. Exporting without using Exporter's import method (Programming Perl)
exporting to modules: 12.. Import/Export Regulations (Perl Cookbook)
@EXPORT_OK variable: 12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
@EXPORT_OK array: 28.2. Special Variables in Alphabetical Order (Programming Perl)
@EXPORT_OK array (use pragma): 12.1.3. Discussion (Perl Cookbook)
-exportselection option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
@EXPORT_TAGS array (use pragma): 12.1.3. Discussion (Perl Cookbook)
%EXPORT_TAGS hash: 28.2. Special Variables in Alphabetical Order (Programming Perl)
export_to_level method: 11.2.1.1. Exporting without using Exporter's import method (Programming Perl)
export_to_level method (Exporter): 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
expression form
grep operator: 5.4. The map and grep Operators (Learning Perl Objects, References and Modules)
map operator: 5.5. Using map (Learning Perl Objects, References and Modules)
expressions: Glossary (Programming Perl)
context and: 3.8. Scalar and List Context (Learning Perl)
EXPR and LIST: 4.2. Compound Statements (Programming Perl)
loops, separating with commas (,): 4.4.2. for Loops (Programming Perl)
modifiers for: 10.3. Expression Modifiers (Learning Perl)
multiple, in loops: 4.4.2. for Loops (Programming Perl)
Perl, supplying in replacement strings: 5.10.3. Programmatic Patterns (Programming Perl)
expressions, interpolating within strings: 1.15.1. Problem (Perl Cookbook)
EXPRs: 4.2. Compound Statements (Programming Perl)
goto operator, use with: 4.6. goto (Programming Perl)
extended regular expression syntax: 4.6.8. Extended Regular Expressions (Perl in a Nutshell)
$EXTENDED_OS_ERROR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$EXTENDED_OS_ERROR ($^E) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
extending
class variables: 10.5. Using Class Variables (Learning Perl Objects, References and Modules)
subroutines: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
superclass methods: 10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
extending arrays: 2.8.2. Array Length (Programming Perl)
extending Perl: 21.3. Extending Perl (Using C from Perl) (Programming Perl)
extensions, creating: 21.3.2. Creating Extensions (Programming Perl)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
Glossary (Programming Perl)
using functions from external C libraby: 21.3.4. Using Functions from an External C Library (Programming Perl)
XSUB input and output: 21.3.3. XSUB Input and Output (Programming Perl)
XSUBs and XS language, wrapping Perl in: 21.3.1. XS and XSUBs (Programming Perl)
Extensible Markup Language (see XML)
extension modules, C, building: 12.19.1. Problem (Perl Cookbook)
external redirection: 21.4.3. Discussion (Perl Cookbook)
external subroutines
portability of: 25.6. External Subroutines (XS) (Programming Perl)
ExternEnt handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
ExternEntFin handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
extra path information: 9.3. Extra Path Information (Perl in a Nutshell)
extract_bracketed( ), matching nested patterns: 6.17.2. Solution (Perl Cookbook)
extract_cookies( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies (Perl in a Nutshell)
extracting array subsets: 4.14.2. Solution (Perl Cookbook)
extracting from arrays (see arrays)
extracting Perl source code: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
extracting substrings: 29.2.168. substr (Programming Perl)
extract_links( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
ExtUtils modules: 8.67. ExtUtils::Command (Perl in a Nutshell)
ExtUtils::Command::MM module: 8.68. ExtUtils::Command::MM (Perl in a Nutshell)
ExtUtils::Constant module: 8.69. ExtUtils::Constant (Perl in a Nutshell)
ExtUtils::MM module: 8.79. ExtUtils::MM (Perl in a Nutshell)
ExtUtils::MM_Any module: 8.80. ExtUtils::MM_Any (Perl in a Nutshell)
ExtUtils::MM_BeOS module: 8.81. ExtUtils::MM_BeOS (Perl in a Nutshell)
ExtUtils::MM_DOS: 8.82. ExtUtils::MM_DOS (Perl in a Nutshell)
ExtUtils::MM_NW5: 8.83. ExtUtils::MM_NW5 (Perl in a Nutshell)
ExtUtils::MM_UWIN: 8.86. ExtUtils::MM_UWIN (Perl in a Nutshell)
ExtUtils::MY: 8.89. ExtUtils::MY (Perl in a Nutshell)
ExtUtils::Command module: 8.67. ExtUtils::Command (Perl in a Nutshell)
ExtUtils::Embed module: 8.70. ExtUtils::Embed (Perl in a Nutshell)
ExtUtils::Install module: 8.71. ExtUtils::Install (Perl in a Nutshell)
ExtUtils::Installed module: 8.72. ExtUtils::Installed (Perl in a Nutshell)
ExtUtils::Liblist module: 8.73. ExtUtils::Liblist (Perl in a Nutshell)
ExtUtils::MakeMaker module: 8.74. ExtUtils::MakeMaker (Perl in a Nutshell)
ExtUtils::Manifest module: 8.75. ExtUtils::Manifest (Perl in a Nutshell)
ExtUtils::Miniperl module: 8.76. ExtUtils::Miniperl (Perl in a Nutshell)
ExtUtils::Mkbootstrap module: 8.77. ExtUtils::Mkbootstrap (Perl in a Nutshell)
ExtUtils::Mksymlists module: 8.78. ExtUtils::Mksymlists (Perl in a Nutshell)
ExtUtils::MM_OS2 module: 8.84. ExtUtils::MM_OS2 (Perl in a Nutshell)
ExtUtils::MM_Unix module: 8.85. ExtUtils::MM_Unix (Perl in a Nutshell)
ExtUtils::MM_VMS module: 8.87. ExtUtils::MM_VMS (Perl in a Nutshell)
ExtUtils::MM_WIN32 module: 8.88. ExtUtils::MM_Win32 (Perl in a Nutshell)
ExtUtils::Packlist module: 8.90. ExtUtils::Packlist (Perl in a Nutshell)
ExtUtils::testlib module: 8.91. ExtUtils::testlib (Perl in a Nutshell)
ExtUtils::Command module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Embed module: 21.4.1. Compiling Embedded Programs (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Install module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Installed module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Liblist module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::MakeMaker: 22.3. Creating CPAN Modules (Programming Perl)
22.3. Creating CPAN Modules (Programming Perl)
(see also MakeMaker)
ExtUtils::MakeMaker module: 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Manifest module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Mkbootstrap module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Mksymlists module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::MM_Cygwin module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::MM_OS2 module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::MM_Unix module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::MM_VMS module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::MM_Win32 module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::Packlist module: 32.1.17. Module Installation Support (Programming Perl)
ExtUtils::testlib module: 32.1.17. Module Installation Support (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

@F array: 4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
28.2. Special Variables in Alphabetical Order (Programming Perl)
f command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
%f conversion: 6.5. Formatted Output with printf (Learning Perl)
-f file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
F<\\> interior sequence (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
-F option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-f option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
-F (pattern to split on) command-line switch: 19.1.3. Switches (Programming Perl)
\\\\f (formfeed) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
factorial( ): 4.20. Program: permute (Perl Cookbook)
failed matches, searching past position of: 5.6.4. Progressive Matching (Programming Perl)
failure, returning from subroutines: 10.10.1. Problem (Perl Cookbook)
fallback overloading key: 13.5. When an Overload Handler Is Missing (nomethod and fallback) (Programming Perl)
false values: 1.. Introduction (Perl Cookbook)
1.2.1.1. Singularities (Programming Perl)
Glossary (Programming Perl)
FAQ, Perl online: 24.1. Common Goofs for Novices (Programming Perl)
FAQs, Perl-related: 1.4.2. Frequently Asked Questions Lists (FAQs) (Perl in a Nutshell)
Fast CGI protocol, using: 32.1.9. World Wide Web (Programming Perl)
FastCGI: 8.37. CGI::Fast (Perl in a Nutshell)
fastcwd (Cwd module): 8.49. Cwd (Perl in a Nutshell)
fatal errors: Glossary (Programming Perl)
Glossary (Programming Perl)
die function for: 11.3. Fatal Errors with die (Learning Perl)
trapping with eval block: 17.1. Trapping Errors with eval (Learning Perl)
Fatal module: B.5.3. The Fatal Module (Learning Perl)
8.92. Fatal (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
fcntl( ): 5. Function Reference (Perl in a Nutshell)
fcntl( ), return values: 10.10.3. Discussion (Perl Cookbook)
fcntl function: 29.2.37. fcntl (Programming Perl)
security risks associated with: 23.2.3. Temporary Files (Programming Perl)
Fcntl module: 8.93. Fcntl (Perl in a Nutshell)
32.1.7. Operating System Interfaces (Programming Perl)
fcntl syscall, filehandle close-on exec flag, manipulating: 16.2.2. Passing Filehandles (Programming Perl)
fd (DB_File module): 8.52. DB_File (Perl in a Nutshell)
FETCH( ): 13.15.3. Discussion (Perl Cookbook)
fetch( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
fetchall_arrayref( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
fetching URLs from Perl scripts: 20.1.1. Problem (Perl Cookbook)
FetchRow( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
fetchrow_array( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
fetchrow_arrayref( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
fetchrow_hashref( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
FetchURL( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
-fg option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
<FH> line input operator: 8.. Basic Operations (Perl Cookbook)
field declarations with use fields pragma: 12.7.1. Field Declarations with use fields (Programming Perl)
field separator, specifying different: 19.1.3. Switches (Programming Perl)
Glossary (Programming Perl)
fieldholders: 4.12. Formats (Perl in a Nutshell)
FieldNames( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
%FIELDS hash: 28.2. Special Variables in Alphabetical Order (Programming Perl)
fields module: 8.94. fields (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
FIFOs: 16.3.4. Named Pipes (Programming Perl)
Glossary (Programming Perl)
FIFOs (named pipes): 16.11.1. Problem (Perl Cookbook)
__FILE__; setting: 24.5.2. Generating Perl in Other Languages (Programming Perl)
file access: 9.. Introduction (Perl Cookbook)
access modes: 7.. I/O Operations (Perl Cookbook)
7.1.3. Discussion (Perl Cookbook)
copying and moving files: 9.3.1. Problem (Perl Cookbook)
editing files (see file contents)
filehandles: 7.. Getting a Handle on the File (Perl Cookbook)
7.. Standard Filehandles (Perl Cookbook)
caching open: 7.7.1. Problem (Perl Cookbook)
copying: 7.10.1. Problem (Perl Cookbook)
printing to multiple: 7.8.1. Problem (Perl Cookbook)
reading a line from, without blocking: 7.23.1. Problem (Perl Cookbook)
reading from multiple: 7.22.1. Problem (Perl Cookbook)
filtering filename input: 7.14.1. Problem (Perl Cookbook)
command-line options: 7.14.3.2. Command-line options (Perl Cookbook)
flushing output: 7.19.1. Problem (Perl Cookbook)
locking files: 7.18.1. Problem (Perl Cookbook)
netlock program: 7.24. Program: netlock (Perl Cookbook)
region-specific locks: 7.25. Program: lockarea (Perl Cookbook)
non-blocking I/O: 7.20.1. Problem (Perl Cookbook)
opening and closing file descriptors: 7.9.1. Problem (Perl Cookbook)
processing all files in directories: 9.5.1. Problem (Perl Cookbook)
recursively: 9.7.1. Problem (Perl Cookbook)
storing files in program text: 7.12.1. Problem (Perl Cookbook)
timestamps: 9.1.1. Problem (Perl Cookbook)
unread bytes, determining number of: 7.21.1. Problem (Perl Cookbook)
_ _FILE_ _ constant: 4.4.4. Global Special Constants (Perl in a Nutshell)
file contents: 8.. Introduction (Perl Cookbook)
9.. Introduction (Perl Cookbook)
adding records to wtmp file: 8.24. Program: tailwtmp (Perl Cookbook)
comparing two files: 8.22.1. Problem (Perl Cookbook)
configuration files, reading: 8.16.1. Problem (Perl Cookbook)
continually growing files, reading: 8.5.1. Problem (Perl Cookbook)
converting Microsoft files to Unicode: 8.21.1. Problem (Perl Cookbook)
counting lines, paragraphs, and records: 8.2.1. Problem (Perl Cookbook)
extracting single line: 8.8.1. Problem (Perl Cookbook)
fixed-length records: 8.. Advanced Operations (Perl Cookbook)
reading: 8.15.1. Problem (Perl Cookbook)
I/O layers: 8.. I/O Layers (Perl Cookbook)
modifying
with -i switch: 7.16.1. Problem (Perl Cookbook)
with temporary files: 7.15.1. Problem (Perl Cookbook)
without temporary files: 7.17.1. Problem (Perl Cookbook)
processing all words in: 8.3.1. Problem (Perl Cookbook)
processing binary files: 8.11.1. Problem (Perl Cookbook)
random access
input/output: 8.12.1. Problem (Perl Cookbook)
updating: 8.13.1. Problem (Perl Cookbook)
random lines from, selecting: 8.6.1. Problem (Perl Cookbook)
randomizing line order: 8.7.1. Problem (Perl Cookbook)
reading
backwards: 8.4.1. Problem (Perl Cookbook)
lines with continuation characters: 8.1.1. Problem (Perl Cookbook)
null-terminated strings from binary files: 8.14.1. Problem (Perl Cookbook)
reading and writing hash records to file: 11.10.1. Problem (Perl Cookbook)
reading and writing Unicode from filehandles: 8.20.1. Problem (Perl Cookbook)
setting default I/O layers: 8.19.1. Problem (Perl Cookbook)
tctee program: 8.25. Program: tctee (Perl Cookbook)
testing for trustworthiness: 8.17.1. Problem (Perl Cookbook)
treating
files as arrays: 8.18.1. Problem (Perl Cookbook)
strings as files: 8.23.1. Problem (Perl Cookbook)
variable-length text fields: 8.9.1. Problem (Perl Cookbook)
viewing lastlog file information: 8.26. Program: laston (Perl Cookbook)
file conversions, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
file descriptors: 29.2.38. fileno (Programming Perl)
29.2.141. select (ready file descriptors) (Programming Perl)
Glossary (Programming Perl)
filehandles, passing with: 16.2.2. Passing Filehandles (Programming Perl)
opening and closing: 7.9.1. Problem (Perl Cookbook)
passing through environment variable or command-line option: 16.2.2. Passing Filehandles (Programming Perl)
returning for tied filehandles: 14.4.1. Filehandle-Tying Methods (Programming Perl)
file extensions: 12.. Other Kinds of Library Files (Perl Cookbook)
1.4.1. A Simple Program (Learning Perl)
File modules: 8.95. File::Basename (Perl in a Nutshell)
File::Basename module: 8.95. File::Basename (Perl in a Nutshell)
File::CheckTree module: 8.96. File::CheckTree (Perl in a Nutshell)
File::Compare module: 8.97. File::Compare (Perl in a Nutshell)
File::Copy module: 8.98. File::Copy (Perl in a Nutshell)
File::DosGlob module: 8.99. File::DosGlob (Perl in a Nutshell)
File::Find module: 8.100. File::Find (Perl in a Nutshell)
File::Path module: 8.101. File::Path (Perl in a Nutshell)
File::Spec module: 8.102. File::Spec (Perl in a Nutshell)
File::Spec::Mac module: 8.104. File::Spec::Mac (Perl in a Nutshell)
File::Spec::Os2 module: 8.105. File::Spec::OS2 (Perl in a Nutshell)
File::Spec::Unix module: 8.106. File::Spec::Unix (Perl in a Nutshell)
File::Spec::VMS module: 8.107. File::Spec::VMS (Perl in a Nutshell)
File::Spec::Win32 module: 8.108. File::Spec::Win32 (Perl in a Nutshell)
File::Stat module: 8.109. File::stat (Perl in a Nutshell)
File::Temp module: 8.110. File::Temp (Perl in a Nutshell)
__FILE__ symbol: 10.4.3. Discussion (Perl Cookbook)
file test operators: 9.. Introduction (Perl Cookbook)
4.5.8. File Test Operators (Perl in a Nutshell)
3.10. Named Unary and File Test Operators (Programming Perl)
-p, checking for FIFO: 16.3.4. Named Pipes (Programming Perl)
file tests: Glossary (Programming Perl)
race conditions with: 23.2.2. Handling Race Conditions (Programming Perl)
__FILE__ token: 2.6.8. Other Literal Tokens (Programming Perl)
File::Basename module: 9.10.2. Solution (Perl Cookbook)
12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
25.3. Files and Filesystems (Programming Perl)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
FileCache module: 7.7.2. Solution (Perl Cookbook)
8.111. FileCache (Perl in a Nutshell)
File::CheckTree module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::chmod module: 9.11.3. Discussion (Perl Cookbook)
29.2.10. chmod (Programming Perl)
File::Compare module: 8.22.2. Solution (Perl Cookbook)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Copy module: B.5.5. The File::Copy Module (Learning Perl)
File::DosGlob module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Find library: 12.5. Recursive Directory Listing (Learning Perl)
File::Find module: 9.7.2. Solution (Perl Cookbook)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
features: 6.3. Callbacks (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
removing directories recursively: 9.8.2. Solution (Perl Cookbook)
returning coderefs: 6.8.1. Exercise [30 min] (Learning Perl Objects, References and Modules)
File::Glob module: 7.3.3. Discussion (Perl Cookbook)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
fileglob operator: 2.11.3. Filename Globbing Operator (Programming Perl)
FileHandle module: 8.112. FileHandle (Perl in a Nutshell)
7.1. Format Variables (Programming Perl)
7.2.1. Accessing Formatting Internals (Programming Perl)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
filehandle-tying: 14.4.1. Filehandle-Tying Methods (Programming Perl)
filehandles: 7.. Getting a Handle on the File (Perl Cookbook)
11.1. What Is a Filehandle? (Learning Perl)
4.9. Filehandles (Perl in a Nutshell)
1.4. Filehandles (Programming Perl)
Glossary (Programming Perl)
anonymous: 8.2.4. Handle References (Programming Perl)
angle operator and: 2.11.2. Line Input (Angle) Operator (Programming Perl)
autovivified: 7.5.3. Discussion (Perl Cookbook)
bad: 11.2.2. Bad Filehandles (Learning Perl)
caching: 7.7.1. Problem (Perl Cookbook)
comparing: 8.22.3. Discussion (Perl Cookbook)
copying: 7.10.1. Problem (Perl Cookbook)
creating: 1.4. Filehandles (Programming Perl)
default for output, changing: 11.4.1. Changing the Default Output Filehandle (Learning Perl)
duplicating, reasons for: 29.2.104. open (Programming Perl)
ending with _TOP: 7. Formats (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
file locks on: 16.2.1. File Locking (Programming Perl)
formats associated with, default names of: 7. Formats (Programming Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
implicit referencing in: 8.1. What Is a Reference? (Programming Perl)
indirect: Glossary (Programming Perl)
instance variables: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
local: 10.13.3.2. Using local( ) for local handles (Perl Cookbook)
local, creating: 29.2.87. local (Programming Perl)
localizing: 2.10. Typeglobs and Filehandles (Programming Perl)
names for: 2.5. Names (Programming Perl)
non-blocking I/O: 7.20.1. Problem (Perl Cookbook)
object methods for, using: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
ok function (Test::More) and: 14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
open function: 29.2.104. open (Programming Perl)
opening/closing: 11.2. Opening a Filehandle (Learning Perl)
package names and: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
passing: 10.13.3.2. Using local( ) for local handles (Perl Cookbook)
12.6.3. Discussion (Perl Cookbook)
6.4. Prototypes (Programming Perl)
passing in IPC: 16.2.2. Passing Filehandles (Programming Perl)
through standard filehandles: 16.2.2. Passing Filehandles (Programming Perl)
|| operator and: A.10.1. Exercise (Section 11.8.1) (Learning Perl Objects, References and Modules)
piped, explicitly closing: 29.2.104. open (Programming Perl)
positioning file pointer for: 29.2.138. seek (Programming Perl)
printing to multiple simultaneously: 7.8.1. Problem (Perl Cookbook)
processes as: 14.5. Processes as Filehandles (Learning Perl)
reading
a line from, without blocking: 7.23.1. Problem (Perl Cookbook)
from many: 7.22.1. Problem (Perl Cookbook)
reading and writing Unicode from: 8.20.1. Problem (Perl Cookbook)
reading bytes of data from: 29.2.120. read (Programming Perl)
reading, vs. globbing: 12.3. An Alternate Syntax for Globbing (Learning Perl)
references to: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
8.2.4. Handle References (Programming Perl)
reopening: 11.5. Reopening a Standard Filehandle (Learning Perl)
reporting filenames in errors: 7.4.1. Problem (Perl Cookbook)
seek offset: 7.. I/O Operations (Perl Cookbook)
selecting for output: 29.2.140. select (output filehandle) (Programming Perl)
SelectSaver module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
special (predefined): 4.4.3. Global Special Filehandles (Perl in a Nutshell)
4.4.6. Filehandle Special Variables (Perl in a Nutshell)
standard: 7.. Standard Filehandles (Perl Cookbook)
storing in a hash: A.10.1. Exercise (Section 11.8.1) (Learning Perl Objects, References and Modules)
storing in variables: 7.5.1. Problem (Perl Cookbook)
syslog tying output to: 14.6. Tie Modules on CPAN (Programming Perl)
temporary files: 10. Object Destruction (Learning Perl Objects, References and Modules)
tests for: 11.6. File Tests (Learning Perl)
list of: 11.6. File Tests (Learning Perl)
tied: 13.15.1. Problem (Perl Cookbook)
tying: 14.4. Tying Filehandles (Programming Perl)
creative filehandles: 14.4.2. Creative Filehandles (Programming Perl)
methods for: 14.4.1. Filehandle-Tying Methods (Programming Perl)
typeglobs for: 2.10. Typeglobs and Filehandles (Programming Perl)
underscore: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
use instead of filenames, security benefits of: 23.2.2. Handling Race Conditions (Programming Perl)
using: 11.4. Using Filehandles (Learning Perl)
using filename as: 7.4.2. Solution (Perl Cookbook)
File::KGlob module: 6.9.3. Discussion (Perl Cookbook)
File::LockDir module: 7.24. Program: netlock (Perl Cookbook)
filename extensions: 1.4.1. A Simple Program (Learning Perl)
filename globbing operator (see glob operator)
filenames: 2.6.8. Other Literal Tokens (Programming Perl)
Glossary (Programming Perl)
& (ampersand) in: 29.2.104. open (Programming Perl)
changing name of: 29.2.128. rename (Programming Perl)
expanding tildes in: 7.3.1. Problem (Perl Cookbook)
expansions of: 29.2.69. glob (Programming Perl)
external data in, security risks of: 23.1.2. Cleaning Up Your Environment (Programming Perl)
filtering as input: 7.14.1. Problem (Perl Cookbook)
command-line options: 7.14.3.2. Command-line options (Perl Cookbook)
getting from symbolic links: 29.2.123. readlink (Programming Perl)
globbing: 9.6.1. Problem (Perl Cookbook)
25.4. System Interaction (Programming Perl)
%INC hash of: 28.2. Special Variables in Alphabetical Order (Programming Perl)
linking symbolically: 29.2.169. symlink (Programming Perl)
linking with hard links: 29.2.85. link (Programming Perl)
mode, separating from: 29.2.104. open (Programming Perl)
multiple, for same file: 9.4.1. Problem (Perl Cookbook)
parsing: 9.10.1. Problem (Perl Cookbook)
renaming: 9.9.1. Problem (Perl Cookbook)
reporting in errors: 7.4.1. Problem (Perl Cookbook)
sorting: 9.. Introduction (Perl Cookbook)
9.13. Program: lst (Perl Cookbook)
unusual, opening files with: 7.2.1. Problem (Perl Cookbook)
using as filehandle: 7.4.2. Solution (Perl Cookbook)
viewing different program or eval statement: 20.2.5. Locating Code (Programming Perl)
filenames, File::Spec module for manipulating: B.5.6. The File::Spec Module (Learning Perl)
File::NFSLock module: 7.18.3. Discussion (Perl Cookbook)
fileno( ): 5. Function Reference (Perl in a Nutshell)
fileno function: 29.2.38. fileno (Programming Perl)
fileparse( ): 9.10.3. Discussion (Perl Cookbook)
fileparse subroutine (File::Basename): 12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
File::Path module: 9.8.2. Solution (Perl Cookbook)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
files: Glossary (Programming Perl)
access and modification times: 29.2.165. stat (Programming Perl)
29.2.193. utime (Programming Perl)
accessing under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
ages for: 3.10. Named Unary and File Test Operators (Programming Perl)
binary: 8.11.1. Problem (Perl Cookbook)
reading null-terminated strings: 8.14.1. Problem (Perl Cookbook)
C header, translating with h2ph: 12.17.1. Problem (Perl Cookbook)
changing name of: 29.2.128. rename (Programming Perl)
closing: 29.2.16. close (Programming Perl)
comparing file contents: 8.22.1. Problem (Perl Cookbook)
configuration, reading: 8.16.1. Problem (Perl Cookbook)
core: 19.1.3. Switches (Programming Perl)
creating temporary: 7.11.1. Problem (Perl Cookbook)
database, in-place editing of: 16.4. Variable-length (Text) Databases (Learning Perl)
from command line: 16.4.1. In-place Editing from the Command Line (Learning Perl)
deleting: 9.2.1. Problem (Perl Cookbook)
29.2.188. unlink (Programming Perl)
last line of: 8.10.1. Problem (Perl Cookbook)
distribution templates: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
do FILE operator: 29.2.27. do (file) (Programming Perl)
downloading, resuming HTTP GET: 20.17.1. Problem (Perl Cookbook)
end-of-file: 29.2.31. eof (Programming Perl)
end-of-file (EOF): Glossary (Programming Perl)
executable: Glossary (Programming Perl)
File::Copy module for copying/moving: B.5.5. The File::Copy Module (Learning Perl)
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
find subroutine: 6.4. Closures (Learning Perl Objects, References and Modules)
finding timestamps: 6.8.1. Exercise [30 min] (Learning Perl Objects, References and Modules)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
getting statistics of: 29.2.165. stat (Programming Perl)
image, Image::Size module for: B.5.7. The Image::Size Module (Learning Perl)
in interprocess communication: 16.2. Files (Programming Perl)
locking mechanisms: 16.2.1. File Locking (Programming Perl)
passing filehandles: 16.2.2. Passing Filehandles (Programming Perl)
lexically scoped variables and: 2.5.1. Name Lookups (Programming Perl)
links to, finding with stat function: 11.6.1. The stat and lstat Functions (Learning Perl)
locking: 7.18.1. Problem (Perl Cookbook)
advisory locking: 7.18.2. Solution (Perl Cookbook)
netlock program: 7.24. Program: netlock (Perl Cookbook)
manipulating: 13. Manipulating Files and Directories (Learning Perl)
Microsoft, converting to Unicode: 8.21.1. Problem (Perl Cookbook)
modules, autoloading: 10.2. Autoloading (Programming Perl)
modules for cross-platform access methods: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
names of, directory handles for reading: 12.4. Directory Handles (Learning Perl)
open function: 29.2.104. open (Programming Perl)
opening: 7.1.1. Problem (Perl Cookbook)
opening via low-level system call: 29.2.171. sysopen (Programming Perl)
ownership and group, changing: 29.2.13. chown (Programming Perl)
ownership of, changing: 13.6. Changing Ownership (Learning Perl)
parsing specifications: 12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
path components, separators for: 25.3. Files and Filesystems (Programming Perl)
Perl module, housing in single: 10. Packages (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
22.1. The CPAN modules Directory (Programming Perl)
permissions: 29.2.10. chmod (Programming Perl)
29.2.171. sysopen (Programming Perl)
29.2.186. umask (Programming Perl)
portably opening: 25.4. System Interaction (Programming Perl)
processing all in directories: 9.5.1. Problem (Perl Cookbook)
random-access, updating: 8.13.1. Problem (Perl Cookbook)
read in binary mode: 29.2.6. binmode (Programming Perl)
reading via low-level system call: 29.2.172. sysread (Programming Perl)
removing: 13.1. Removing Files (Learning Perl)
renaming: 13.2. Renaming Files (Learning Perl)
renaming, program for: 29.2.32. eval (Programming Perl)
returning current position for: 29.2.176. tell (Programming Perl)
RSS, reading and writing: 22.9.1. Problem (Perl Cookbook)
scopes: 4.8.2. Lexically Scoped Variables: my (Programming Perl)
size of, scalar variable for finding: 11.6.1. The stat and lstat Functions (Learning Perl)
specifications of, File::Spec module for manipulating: 13.8.3. The File::Spec Module (Learning Perl)
B.5.6. The File::Spec Module (Learning Perl)
storing in program text: 7.12.1. Problem (Perl Cookbook)
symbolically linking: 29.2.169. symlink (Programming Perl)
test operators: 1.5.7. Some File Test Operators (Programming Perl)
tests for: 11.6. File Tests (Learning Perl)
list of: 11.6. File Tests (Learning Perl)
text/binary distinction: 29.2.104. open (Programming Perl)
treating
as arrays: 8.18.1. Problem (Perl Cookbook)
strings as: 8.23.1. Problem (Perl Cookbook)
truncating: 29.2.183. truncate (Programming Perl)
with unusual filenames, opening: 7.2.1. Problem (Perl Cookbook)
uploaded, receiving with mod_perl handler: 21.7.1. Problem (Perl Cookbook)
Win32API::File module: 32.1.20. Microsoft-Related Modules (Programming Perl)
writing via low-level system call: 29.2.175. syswrite (Programming Perl)
XML, larger than available memory, processing: 22.8.1. Problem (Perl Cookbook)
File::Spec module: 13.8.3. The File::Spec Module (Learning Perl)
B.5.6. The File::Spec Module (Learning Perl)
File::Spec modules
File::Spec::Cygwin module: 8.103. File::Spec::Cygwin (Perl in a Nutshell)
File::Spec::Functions module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::Mac module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::OS2 module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::Unix module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::VMS module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::Win32 module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::stat module: 8.5.3. Discussion (Perl Cookbook)
9.. Introduction (Perl Cookbook)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
filesystems: Glossary (Programming Perl)
Glossary (Programming Perl)
capturing information about: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
portability: 25.3. Files and Filesystems (Programming Perl)
walking through hierarchy: 6.3. Callbacks (Learning Perl Objects, References and Modules)
6.3. Callbacks (Learning Perl Objects, References and Modules)
File::Temp module: 7.11.2. Solution (Perl Cookbook)
File::Temp module, dealing with race conditions: 23.2.3. Temporary Files (Programming Perl)
-fill option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
pack geometry manager: 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
FillAttr( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
FillChar( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
filled field fieldholders: 4.12. Formats (Perl in a Nutshell)
filtering
filenames as input: 7.14.1. Problem (Perl Cookbook)
command-line options: 7.14.3.2. Command-line options (Perl Cookbook)
output: 16.5.1. Problem (Perl Cookbook)
XML: 22.4.1. Problem (Perl Cookbook)
filtering output with forking open: 16.3.2. Talking to Yourself (Programming Perl)
filters: Glossary (Programming Perl)
source code: 24.5.3. Source Filters (Programming Perl)
filters, source code: 1.8. List Processing (Programming Perl)
Filter::Simple module: 8.113. Filter::Simple (Perl in a Nutshell)
Filter::Util::Call module: 8.114. Filter::Util::Call (Perl in a Nutshell)
Final handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
find( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
find command: 1.7. Regular Expressions (Programming Perl)
find command (Unix): 14.5. Processes as Filehandles (Learning Perl)
B.26. Converting find Command Lines to Perl (Learning Perl)
find function, traversing file trees like: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
find subroutine (File::Find): 6.3. Callbacks (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
FindBin module: 12.8.3. Discussion (Perl Cookbook)
8.115. FindBin (Perl in a Nutshell)
32.1.17. Module Installation Support (Programming Perl)
finddepth( ): 9.8.2. Solution (Perl Cookbook)
finding
fresh hyperlinks: 20.8.1. Problem (Perl Cookbook)
most common anything: 5.15.1. Problem (Perl Cookbook)
patterns (see regular expressions)
text and elements in XML documents: 22.6.1. Problem (Perl Cookbook)
versions and descriptions of modules: 12.23. Program: Finding Versions and Descriptions of Installed Modules (Perl Cookbook)
findnodes( ) vs. getElementsByTagName( ): 22.6.3. Discussion (Perl Cookbook)
find2perl command: B.26. Converting find Command Lines to Perl (Learning Perl)
findstr function: 1.7. Regular Expressions (Programming Perl)
1.7. Regular Expressions (Programming Perl)
finish( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
FIONREAD call: 7.21.2. Solution (Perl Cookbook)
firewalls, fetching web pages through: 17.21. Program: fwdport (Perl Cookbook)
first found occurrence of a substring, index function for: 15.1. Finding a Substring with index (Learning Perl)
first_labeled_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
first_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
fixed 8-bit chracters: 15.1. Building Character (Programming Perl)
fixed-length data/records, functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
fixed-length random-access databases: 16.3. Fixed-length Random-access Databases (Learning Perl)
fixed-length records: 8.. Advanced Operations (Perl Cookbook)
flat-file index program: 8.27. Program: Flat File Indexes (Perl Cookbook)
reading: 8.15.1. Problem (Perl Cookbook)
fixed-precision numeric fields: 4.12. Formats (Perl in a Nutshell)
FixNum class: 13.14.5. Example: Overloaded FixNum Class (Perl Cookbook)
fixstyle program: 1.23. Program: fixstyle (Perl Cookbook)
flags: 9.2. Option Modifiers (Learning Perl)
3.2. Command-Line Options (Perl in a Nutshell)
5.2.1. Pattern Modifiers (Programming Perl)
19.1.3. Switches (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also modifiers; switches)
flash( )
Button widget: 21.4.1. Button Methods (Perl in a Nutshell)
Checkbutton widget: 21.5.1. Checkbutton Methods (Perl in a Nutshell)
Radiobutton widget: 21.6.1. Radiobutton Methods (Perl in a Nutshell)
flat-file databases: B.7.2. Flat-file Database Access (Learning Perl)
flat file index program: 8.27. Program: Flat File Indexes (Perl Cookbook)
flattened lists: 4.. Introduction (Perl Cookbook)
Flintstones
anchors and: 8.3.1. Word Anchors (Learning Perl)
illustrating backreferences: 8.4.1. Backreferences (Learning Perl)
illustrating hash names: 5.2. Hash Element Access (Learning Perl)
illustrating Unix grep command: 7.1. What Are Regular Expressions? (Learning Perl)
precedence and: 8.5.1. Examples of Precedence (Learning Perl)
floating-point conversion: 6.5. Formatted Output with printf (Learning Perl)
floating-point literals: 2.2.2. Floating-Point Literals (Learning Perl)
floating-point numbers: 2.. Introduction (Perl Cookbook)
2.6. Scalar Values (Programming Perl)
29.2.108. pack (Programming Perl)
Glossary (Programming Perl)
comparing: 2.3.1. Problem (Perl Cookbook)
computer storage, order of: 25.2. Endianness and Number Width (Programming Perl)
Math::BigFloat module: 32.1.1. Data Types (Programming Perl)
rand function, returning: 29.2.119. rand (Programming Perl)
rounding: 2.2.1. Problem (Perl Cookbook)
flock( ): 5. Function Reference (Perl in a Nutshell)
7.18.2. Solution (Perl Cookbook)
compared to SysV lockf( ): 7.18.3. Discussion (Perl Cookbook)
flock function: 14.1.1. Scalar-Tying Methods (Programming Perl)
16.2.1. File Locking (Programming Perl)
29.2.39. flock (Programming Perl)
alarms and: 16.1.3. Timing Out Slow Operations (Programming Perl)
floor( ): 2.2.3. Discussion (Perl Cookbook)
flow control functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
flow of program control, functions for: 29.1. Perl Functions by Category (Programming Perl)
Flush( ) (Win32::Console module): 22.2. Win32::Console (Perl in a Nutshell)
flushed buffer: 6.4. Output to Standard Output (Learning Perl)
flushing buffers: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
flushing output: 7.19.1. Problem (Perl Cookbook)
fmt program: 1.17.3. Discussion (Perl Cookbook)
fmt (Unix utility): 7.1. Format Variables (Programming Perl)
FMTEYEWTK (Far More Than Everything You Ever Wanted to Know): Glossary (Programming Perl)
fnctl( ), locking files: 7.18.3. Discussion (Perl Cookbook)
focus( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
focusmodel( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
folded_demo program: 13.15.6. Tie Example: Case-Insensitive Hash (Perl Cookbook)
foldername( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
folders for email messages: 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
-font option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
fonts, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
fonts, Unicode, support for: 8.21.3. Discussion (Perl Cookbook)
fonts, widget: 21.1.4. Colors and Fonts (Perl in a Nutshell)
foodfind program: 5.9.3. Discussion (Perl Cookbook)
footers: 7.2. Footers (Programming Perl)
footnotes in this book: 1.1.2. Why Are There So Many Footnotes? (Learning Perl)
for, as an alias of foreach: 4.4.3. foreach Loops (Programming Perl)
=for command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
for control structure: 10.7. The for Control Structure (Learning Perl)
vs. foreach control structure: 10.7.1. The Secret Connection Between foreach and for (Learning Perl)
=for escape pod directive: 12.20.3. Discussion (Perl Cookbook)
for loops: 4.3.1.2. for loops (Perl in a Nutshell)
1.6.2.2. The for statement (Programming Perl)
searching and replacing elements in arrays: 5.2.3.1. Modifying strings en passant (Programming Perl)
for modifier: 4.1. Simple Statements (Programming Perl)
4.4.2. for Loops (Programming Perl)
force command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
ForceArray option: 22.1.3. Discussion (Perl Cookbook)
force_last_request( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
foreach control structure: 3.6. The foreach Control Structure (Learning Perl)
naked block control structure and: 10.4. The Naked Block Control Structure (Learning Perl)
vs. for control structure: 10.7.1. The Secret Connection Between foreach and for (Learning Perl)
foreach loop: 4.13.2. Solution (Perl Cookbook)
printing to multiple filehandles: 7.8.2. Solution (Perl Cookbook)
renaming files: 9.9.2. Solution (Perl Cookbook)
traversing hashes: 5.5.2. Solution (Perl Cookbook)
4.3.1.3. foreach loops (Perl in a Nutshell)
1.6.2.3. The foreach statement (Programming Perl)
4.4.3. foreach Loops (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
aliasing capability, using: 4.5.1. Case Structures (Programming Perl)
loop variable, Perl vs. shell programming: 24.1.4. Shell Traps (Programming Perl)
Perl versions, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
searching and replacing elements in arrays: 5.2.3.1. Modifying strings en passant (Programming Perl)
foreach modifier: 10.3. Expression Modifiers (Learning Perl)
10.3. Expression Modifiers (Learning Perl)
4.1. Simple Statements (Programming Perl)
-foreground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
fork( ): 5. Function Reference (Perl in a Nutshell)
16.10.2. Solution (Perl Cookbook)
16.10.3. Discussion (Perl Cookbook)
(see also processes)
avoiding zombie processes: 16.19.1. Problem (Perl Cookbook)
closing sockets after: 17.9.1. Problem (Perl Cookbook)
forking servers: 17.11.1. Problem (Perl Cookbook)
non-forking servers: 17.13.1. Problem (Perl Cookbook)
preforking servers: 17.12.1. Problem (Perl Cookbook)
shell escapes: 19.5.3. Discussion (Perl Cookbook)
29.2.40. fork (Programming Perl)
Glossary (Programming Perl)
child processes, inheriting parent filehandles: 16.2.2. Passing Filehandles (Programming Perl)
fork-open: 16.3.2. Talking to Yourself (Programming Perl)
locks, inheriting across calls to: 29.2.39. flock (Programming Perl)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
servers, cloning themselves with: 16.5.2. Networking Servers (Programming Perl)
zombie processes and: 16.1.2. Reaping Zombies (Programming Perl)
fork syscall: 16.3.1. Anonymous Pipes (Programming Perl)
fork system call: 14.6. Getting Down and Dirty with Fork (Learning Perl)
using instead of threads: B.31. Threads and Forking (Learning Perl)
forks: 29.2.104. open (Programming Perl)
cloned interpreter on Windows: 17.1. The Process Model (Programming Perl)
fork open: 29.2.104. open (Programming Perl)
open command, two-argument form: 29.2.104. open (Programming Perl)
form feed: 28.2. Special Variables in Alphabetical Order (Programming Perl)
form geometry manager (Perl/Tk): 21.2.4. The form Geometry Manager (Perl in a Nutshell)
:form method group: 10.2. Importing Method Groups (Perl in a Nutshell)
<form\\> tag: 9.1. A Typical CGI Interaction (Perl in a Nutshell)
formal arguments: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Glossary (Programming Perl)
format( )
HTML::FormatPS module: 20.4.5. HTML::FormatPS (Perl in a Nutshell)
HTML::FormatText module: 20.4.6. HTML::FormatText (Perl in a Nutshell)
Mail::Address module: 16.2.7. Mail::Address Reference (Perl in a Nutshell)
declaration: 29.2.41. format (Programming Perl)
output accumulator: 29.2.42. formline (Programming Perl)
format keyword: 4.12. Formats (Perl in a Nutshell)
format letters: 16.2. Manipulating Data with pack and unpack (Learning Perl)
format strings: 16.2. Manipulating Data with pack and unpack (Learning Perl)
$FORMAT_FORMFEED: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_FORMFEED ($^L) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$FORMAT_LINE_BREAK_CHARACTERS: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_LINE_BREAK_CHARACTERS ($:) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$FORMAT_LINES_LEFT: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_LINES_LEFT ($-) variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$FORMAT_LINES_PER_PAGE: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_LINES_PER_PAGE ($=) variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$FORMAT_NAME: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_NAME ($~) variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
$FORMAT_PAGE_NUMBER: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_PAGE_NUMBER ($%) variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
formats: B.12. Formats (Learning Perl)
4.12. Formats (Perl in a Nutshell)
7. Formats (Programming Perl)
Glossary (Programming Perl)
accessing formatting internals: 7.2.1. Accessing Formatting Internals (Programming Perl)
argument lists for, evaluating in list context: 24.1.5. Previous Perl Traps (Programming Perl)
B::Xref module, cross-references with C: 18.6. Code Development Tools (Programming Perl)
characters in: 29.2.108. pack (Programming Perl)
declaring: 7. Formats (Programming Perl)
fmt (Unix utility): 7.1. Format Variables (Programming Perl)
footers: 7.2. Footers (Programming Perl)
integers: 29.2.108. pack (Programming Perl)
lexical variables in: 7. Formats (Programming Perl)
pack/unpack: 29.2.108. pack (Programming Perl)
for strings: 29.2.162. sprintf (Programming Perl)
top-of-form processing: 7. Formats (Programming Perl)
variables: 7.1. Format Variables (Programming Perl)
format_string( ): 20.5.3. Discussion (Perl Cookbook)
formatted output: 6.5. Formatted Output with printf (Learning Perl)
$FORMAT_TOP_NAME: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$FORMAT_TOP_NAME ($^) variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
formCheck( ) (form geometry manager): 21.2.4. The form Geometry Manager (Perl in a Nutshell)
formForget( ) (form geometry manager): 21.2.4. The form Geometry Manager (Perl in a Nutshell)
formGrid( ) (form geometry manager): 21.2.4. The form Geometry Manager (Perl in a Nutshell)
formInfo( ) (form geometry manager): 21.2.4. The form Geometry Manager (Perl in a Nutshell)
formline( ): 5. Function Reference (Perl in a Nutshell)
formline function: 29.2.42. formline (Programming Perl)
formline operator: 7.2.1. Accessing Formatting Internals (Programming Perl)
forms, HTML: 19.. HTML and Forms (Perl Cookbook)
saving and emailing: 19.12.1. Problem (Perl Cookbook)
sticky widgets: 19.10.1. Problem (Perl Cookbook)
submitting: 20.2.1. Problem (Perl Cookbook)
formSlaves( ) (form geometry manager): 21.2.4. The form Geometry Manager (Perl in a Nutshell)
Fortran: 2.2. Molecules (Programming Perl)
forward slash (/)
/e substitution modifier: 1.12.3. Discussion (Perl Cookbook)
6.. Pattern-Matching Modifiers (Perl Cookbook)
/g pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
finding Nth matches: 6.5.2. Solution (Perl Cookbook)
where last pattern ended: 6.14.3. Discussion (Perl Cookbook)
/i pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
/m pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
multiple lines: 6.6.2. Solution (Perl Cookbook)
/o pattern-matching modifier: 6.10.2. Solution (Perl Cookbook)
root directory: 9.. Introduction (Perl Cookbook)
/s pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
multiple lines: 6.6.2. Solution (Perl Cookbook)
/x pattern modifier: 1.12.3. Discussion (Perl Cookbook)
comments in regular expressions: 6.4.3. Discussion (Perl Cookbook)
enclosing a pattern: 7.2. Using Simple Patterns (Learning Perl)
vs. m// operator: 9.1. Matches with m// (Learning Perl)
fraction( ) (Scrollbar): 21.9.1. Scrollbar Methods (Perl in a Nutshell)
frag( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
frame( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
frame option (debugger): 20.3.3. Debugger Options (Programming Perl)
Frame widget (Perl/Tk): 21.17. The Frame Widget (Perl in a Nutshell)
Frame widget, Tk: 15.14.2. Solution (Perl Cookbook)
FrameMaker, translating pod to: 4.13.3. Pod Utilities (Perl in a Nutshell)
free-form languages: 2.2. Molecules (Programming Perl)
Free( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
freeware: Glossary (Programming Perl)
freshness_lifetime( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
fresh_until( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
Friedl, Jeffrey: B.2. Regular expressions (Learning Perl)
friend classes: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
from( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
20.2.3. LWP::UserAgent (Perl in a Nutshell)
20.2.3. LWP::UserAgent (Perl in a Nutshell)
-from option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
FTP clients: 18.2.1. Problem (Perl Cookbook)
FTP (File Transfer Protocol): 18. FTP (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Net::Netrc module: 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
obtaining Perl: 2.1. The CPAN Architecture (Perl in a Nutshell)
Win32::Internet functions for: 22.7.2. FTP Functions (Perl in a Nutshell)
FTP( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
full-screen mode: 15.. Introduction (Perl Cookbook)
full_path( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
fully-qualified names: 2.5. Names (Programming Perl)
func( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
function call, pipe, low-level for bi-directional communication: 16.3.3. Bidirectional Communication (Programming Perl)
function calls: 3.1. Terms and List Operators (Leftward) (Programming Perl)
function calls, parentheses and: 6.4. Output to Standard Output (Learning Perl)
function templates, closures as: 8.3.7.1. Closures as function templates (Programming Perl)
functions: 1.2.2. Verbs (Programming Perl)
6. Subroutines (Programming Perl)
29. Functions (Programming Perl)
29. Functions (Programming Perl)
Glossary (Programming Perl)
autoloading: 10.2. Autoloading (Programming Perl)
12.5.4. Method Autoloading (Programming Perl)
built-in, listing by type: 32.1.16. Documentation Support (Programming Perl)
builtin, ampersand and: 4.11.1. Omitting the Ampersand (Learning Perl)
by category: 29.1. Perl Functions by Category (Programming Perl)
byte-oriented wrappers for: 15.2. Effects of Character Semantics (Programming Perl)
C library: 29. Functions (Programming Perl)
debugger, calling internal: 20.3.2. Customizing with Init Files (Programming Perl)
debugger customization: 20.5.1. Writing Your Own Debugger (Programming Perl)
default arguments, avoiding errors with: 24.1.2. Frequently Ignored Advice (Programming Perl)
defaults for: 1.2.2. Is Perl Easy or Hard? (Learning Perl)
generation of: 8.3.7. Closures (Programming Perl)
hashes of: 9.5. Hashes of Functions (Programming Perl)
interpolating: 14.2.2. Notational Convenience (Programming Perl)
interpolating within strings: 1.15.1. Problem (Perl Cookbook)
in list or scalar context: 29. Functions (Programming Perl)
vs. methods: 13.10.3. Discussion (Perl Cookbook)
modules, exporting to programs: 11.2.1. Module Privacy and the Exporter (Programming Perl)
named unary operators: 3.10. Named Unary and File Test Operators (Programming Perl)
names for: 24.3. Programming with Style (Programming Perl)
operators and: 3. Unary and Binary Operators (Programming Perl)
for overloading: 13.7. Public Overload Functions (Programming Perl)
overriding: 11.3. Overriding Built-in Functions (Programming Perl)
Perl, varying across platforms: 25. Portable Perl (Programming Perl)
Perl, wrapping around C: 21.3.1. XS and XSUBs (Programming Perl)
private for variables: 12.5.1. Problem (Perl Cookbook)
references to: 11.4.1. Problem (Perl Cookbook)
references, using for both input and output: 6.3. Passing References (Programming Perl)
return operators in: 4.4.4. Loop Control (Programming Perl)
returning tainted data: 29.2. Perl Functions in Alphabetical Order (Programming Perl)
signal-handling: 16.1. Signals (Programming Perl)
socket-related in Perl: 16.5. Sockets (Programming Perl)
temporary filenames, generating: 23.2.3. Temporary Files (Programming Perl)
Thread module: 17.2.1. The Thread Module (Programming Perl)
types of: 1.1.3. Discussion (Perl Cookbook)
functions, built-in: 5. Function Reference (Perl in a Nutshell)
listed alphabetically: 5. Function Reference (Perl in a Nutshell)
listed by category: 5.1. Perl Functions by Category (Perl in a Nutshell)
socket-related: 15.1. Built-in Socket Functions (Perl in a Nutshell)
functions, loading
AutoLoader module: 8.5. AutoLoader (Perl in a Nutshell)
DynaLoader module: 8.61. DynaLoader (Perl in a Nutshell)
SelfLoader module: 8.184. SelfLoader (Perl in a Nutshell)
funny characters: 14. Tied Variables (Programming Perl)
Glossary (Programming Perl)
fuzzy matching: 6.13.1. Problem (Perl Cookbook)
$^F variable: 29.2.38. fileno (Programming Perl)
29.2.38. fileno (Programming Perl)
fwdport program: 17.21. Program: fwdport (Perl Cookbook)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

\G anchor: 6.14.3. Discussion (Perl Cookbook)
%g conversion: 6.5. Formatted Output with printf (Learning Perl)
-g (setgid) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-g file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
/g (global) pattern modifier: 5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
/g pattern modifier: 5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
/g modifier, s/// substitution operator and: 9.6.1. Global Replacements with /g (Learning Perl)
g pattern match modifier: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
/g pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
finding Nth matches: 6.5.2. Solution (Perl Cookbook)
where last pattern ended: 6.14.3. Discussion (Perl Cookbook)
\G positional assertion: 5.2.2. The m// Operator (Matching) (Programming Perl)
5.6.5. Where You Left Off: The \G Assertion (Programming Perl)
games, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
garbage collection: 13.2.3. Discussion (Perl Cookbook)
4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
circular data structures and: 13.13.1. Problem (Perl Cookbook)
with DESTROY methods: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
of globals: Glossary (Programming Perl)
objects associated with tied variables: 14.1.1. Scalar-Tying Methods (Programming Perl)
gaussian_rand( ): 2.9.2. Solution (Perl Cookbook)
GD module: 15.20.2. Solution (Perl Cookbook)
GDBM files: 14.. Introduction (Perl Cookbook)
db2gdbm program: 14.3.2. Solution (Perl Cookbook)
GDBM_File module: 11.14.2. Solution (Perl Cookbook)
8.116. GDBM_File (Perl in a Nutshell)
32.1.10. DBM Interfaces (Programming Perl)
GD::Graph modules: 15.18.2. Solution (Perl Cookbook)
GD::Graph::Bars module: 15.23. Program: graphbox (Perl Cookbook)
GDMB files (GNU DBM), locking: 16.2.1. File Locking (Programming Perl)
ge (greater-than-or-equal) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
-gen option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
general numeric conversion: 6.5. Formatted Output with printf (Learning Perl)
GenerateCtrlEvent( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
generated patterns: 5.10.3.1. Generated patterns (Programming Perl)
generators, Perl programs: 24.5. Program Generation (Programming Perl)
in other languages: 24.5.2. Generating Perl in Other Languages (Programming Perl)
other languages in Perl: 24.5.1. Generating Other Languages in Perl (Programming Perl)
source filters: 24.5.3. Source Filters (Programming Perl)
generic classes: 13.. Some Notes on Object Terminology (Perl Cookbook)
geometry( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
geometry managers (Perl/Tk): 21.2. Geometry Managers (Perl in a Nutshell)
get( )
Entry widget: 21.8.2. Entry Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
LWP::Simple module: 20.2.2. LWP::Simple (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
Scale widget: 21.13.1. Scale Methods (Perl in a Nutshell)
Scrollbar widget: 21.9.1. Scrollbar Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
get( ), fetching URLs from Perl scripts: 20.1.2. Solution (Perl Cookbook)
get_basic_credentials( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
BufferSize( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
get( ) (DB_File module): 8.52. DB_File (Perl in a Nutshell)
get( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
GET method (CGI): 20.3.1. HTTP::Request (Perl in a Nutshell)
GET request: 19.. Behind the Scenes (Perl Cookbook)
19.1.3. Discussion (Perl Cookbook)
resuming: 20.17.1. Problem (Perl Cookbook)
using HTTP 1.1 Range header: 20.17.2. Solution (Perl Cookbook)
GetActiveObject( ) (Win32::OLE): 23.1. Creating Objects (Perl in a Nutshell)
GetAttributes( ) (Win32::File): 22.5. Win32::File (Perl in a Nutshell)
getc( ): 5. Function Reference (Perl in a Nutshell)
getc function: 24.2.1. Time Efficiency (Programming Perl)
29.2.43. getc (Programming Perl)
GETC method: 14.4.1. Filehandle-Tying Methods (Programming Perl)
GetConnections( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
GetConnectOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
GetCursorName( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
getcwd (Cwd module): 8.49. Cwd (Perl in a Nutshell)
GetData( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
GetDomainController( ) (Win32::NetAdmin): 22.10. Win32::NetAdmin (Perl in a Nutshell)
getDSN( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
getElementsByTagName( )
vs. findnodes( ): 22.6.3. Discussion (Perl Cookbook)
returning a list of elements by nodes: 22.2.3. Discussion (Perl Cookbook)
GetError( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
GetEvents( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
GetExitCode( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
get_fields( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
GetFunctions( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
getgrent( ): 5. Function Reference (Perl in a Nutshell)
getgrent function: 29.2.44. getgrent (Programming Perl)
getgrgid( ): 5. Function Reference (Perl in a Nutshell)
getgrgid function: 29.2.45. getgrgid (Programming Perl)
getgrnam( ): 5. Function Reference (Perl in a Nutshell)
getgrnam function: 13.6. Changing Ownership (Learning Perl)
29.2.46. getgrnam (Programming Perl)
get_header( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
gethost* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication (Programming Perl)
gethostbyaddr( ): 5. Function Reference (Perl in a Nutshell)
gethostbyaddr( ): 17.7.3. Discussion (Perl Cookbook)
gethostbyaddr function: 29.2.47. gethostbyaddr (Programming Perl)
converting characters back into bytes: 15.1. Building Character (Programming Perl)
gethostbyname( ): 5. Function Reference (Perl in a Nutshell)
gethostbyname( ): 17.7.3. Discussion (Perl Cookbook)
finding IP addresses: 18.1.2. Solution (Perl Cookbook)
gethostbyname function: 29.2.48. gethostbyname (Programming Perl)
gethostent function: 29.2.49. gethostent (Programming Perl)
gethostest( ): 5. Function Reference (Perl in a Nutshell)
GetInfo( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
24.1. ODBC Methods and Properties (Perl in a Nutshell)
getitimer( ): 3.9.3. Discussion (Perl Cookbook)
GetKeys( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
getline( ): 7.5.3. Discussion (Perl Cookbook)
getlogin( ): 5. Function Reference (Perl in a Nutshell)
getlogin function: 29.2.50. getlogin (Programming Perl)
get_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
get_message_file( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
get_mime_header( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
get_mime_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
getnet* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication (Programming Perl)
getnetbyaddr( ): 5. Function Reference (Perl in a Nutshell)
getnetbyaddr function: 29.2.51. getnetbyaddr (Programming Perl)
getnetbyname( ): 5. Function Reference (Perl in a Nutshell)
getnetbyname function: 29.2.52. getnetbyname (Programming Perl)
getnetent( ): 5. Function Reference (Perl in a Nutshell)
getnetent function: 29.2.53. getnetent (Programming Perl)
GetNumber( ) (Win32::EventLog): 22.4. Win32::Eventlog (Perl in a Nutshell)
GetObject( ) (Win32::OLE): 23.1. Creating Objects (Perl in a Nutshell)
GetOldest( ) (Win32::EventLog): 22.4. Win32::Eventlog (Perl in a Nutshell)
getopt( ): 15.1.3. Discussion (Perl Cookbook)
get_option( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
GetOptions( ): 15.1.3. Discussion (Perl Cookbook)
Getopt::Long module: B.27. Command-line Options in Your Programs (Learning Perl)
8.117. Getopt::Long (Perl in a Nutshell)
getopts( ): 15.1.3. Discussion (Perl Cookbook)
Getopts::* modules: 4.4.4. Loop Control (Programming Perl)
Getopt::Std module: B.27. Command-line Options in Your Programs (Learning Perl)
8.118. Getopt::Std (Perl in a Nutshell)
getpeername( ): 5. Function Reference (Perl in a Nutshell)
17.16.3. Discussion (Perl Cookbook)
17.20. Program: backsniff (Perl Cookbook)
16.5.2. Networking Servers (Programming Perl)
29.2.54. getpeername (Programming Perl)
getpgrp( ): 5. Function Reference (Perl in a Nutshell)
getpgrp function: 29.2.55. getpgrp (Programming Perl)
getppid( ): 5. Function Reference (Perl in a Nutshell)
getppid function: 29.2.56. getppid (Programming Perl)
getprint( ) (LWP::Simple): 20.2.2. LWP::Simple (Perl in a Nutshell)
getpriority( ): 5. Function Reference (Perl in a Nutshell)
getpriority function: 29.2.57. getpriority (Programming Perl)
GetPriorityClass( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
getproto* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication (Programming Perl)
getprotobyname( ): 5. Function Reference (Perl in a Nutshell)
15.1.1. Initializing a Socket (Perl in a Nutshell)
getprotobyname( ): 17.. Introduction (Perl Cookbook)
getprotobyname function: 29.2.58. getprotobyname (Programming Perl)
getprotobynumber( ): 5. Function Reference (Perl in a Nutshell)
getprotobynumber function: 29.2.59. getprotobynumber (Programming Perl)
getprotoent( ): 5. Function Reference (Perl in a Nutshell)
getprotoent function: 29.2.60. getprotoent (Programming Perl)
getpwent( ): 5. Function Reference (Perl in a Nutshell)
getpwent function: 29.2.61. getpwent (Programming Perl)
getpwnam( ): 5. Function Reference (Perl in a Nutshell)
getpwnam function: 13.6. Changing Ownership (Learning Perl)
29.2.62. getpwnam (Programming Perl)
getpwuid( ): 5. Function Reference (Perl in a Nutshell)
getpwuid function: 29.2.50. getlogin (Programming Perl)
29.2.63. getpwuid (Programming Perl)
get_request( ): 22.7.3. Discussion (Perl Cookbook)
get_request( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
GetResponse( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
getserv* functions, overriding built-in: 32.1.8. Networking and Interprocess Communication (Programming Perl)
getservbyname( ): 5. Function Reference (Perl in a Nutshell)
getservbyname function: 29.2.64. getservbyname (Programming Perl)
getservbyport( ): 5. Function Reference (Perl in a Nutshell)
getservbyport function: 29.2.65. getservbyport (Programming Perl)
GetServices( ) (Win32::Service): 22.17. Win32::Service (Perl in a Nutshell)
getservent( ): 5. Function Reference (Perl in a Nutshell)
getservent function: 29.2.66. getservent (Programming Perl)
GetSharedResource( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
getsockname( ): 5. Function Reference (Perl in a Nutshell)
17.16.2. Solution (Perl Cookbook)
17.20. Program: backsniff (Perl Cookbook)
getsockname function: 29.2.67. getsockname (Programming Perl)
getsockopt( ): 5. Function Reference (Perl in a Nutshell)
getsockopt function: 29.2.68. getsockopt (Programming Perl)
GetSQLState( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
GetStatus( ) (Win32::Service): 22.17. Win32::Service (Perl in a Nutshell)
GetStatusCallback( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
GetStmtCloseType( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
GetStmtOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
getstore( ) (LWP::Simple): 20.2.2. LWP::Simple (Perl in a Nutshell)
gettags( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
GetTerminalSize( ): 15.4.3. Discussion (Perl Cookbook)
getters
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
creating easily: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
doubling as setters: 9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
encapsulation and: 9.11. Don't Look Inside the Box (Learning Perl Objects, References and Modules)
optimizing: 9.12. Faster Getters and Setters (Learning Perl Objects, References and Modules)
gettimeofday( ): 3.9.3. Discussion (Perl Cookbook)
get_token( ), parsing HTML: 20.18.3. Discussion (Perl Cookbook)
GetUNCName( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
GetValues( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
ggh program: 14.19. Program: ggh—Grep Netscape Global History (Perl Cookbook)
$gid file statistic: 29.2.165. stat (Programming Perl)
gid (group ID), assumed: 16.3.2. Talking to Yourself (Programming Perl)
GID (group ID), effective: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$GID ($( ) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
GIFs, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Gimp, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
glob( ): 5. Function Reference (Perl in a Nutshell)
7.3.2. Solution (Perl Cookbook)
9.6.2. Solution (Perl Cookbook)
glob function: 2.11.3. Filename Globbing Operator (Programming Perl)
29.2.69. glob (Programming Perl)
glob operator: 12.2. Globbing (Learning Perl)
7.8.1. Exercise 1 [15 min] (Learning Perl Objects, References and Modules)
11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
11.7. References to Filehandles (Learning Perl Objects, References and Modules)
2.11.3. Filename Globbing Operator (Programming Perl)
combining with unlink operator: 13.1. Removing Files (Learning Perl)
global declarations: 4.7. Global Declarations (Programming Perl)
global names, prefixing with module name: 1.2.1.4. Simplicities (Programming Perl)
global replacements: 9.6.1. Global Replacements with /g (Learning Perl)
global search and replace: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
global special variables: 4.4.1. Global Special Variables (Perl in a Nutshell)
global values, saving: 10.13.1. Problem (Perl Cookbook)
global variables
controlling use with strict pragma: 4.9.2. Controlling the Use of Globals (Programming Perl)
data destruction and: 10. Object Destruction (Learning Perl Objects, References and Modules)
declaring: 4.8.3. Lexically Scoped Global Declarations: our (Programming Perl)
29.2.107. our (Programming Perl)
local operator, using on: 4.8.4. Dynamically Scoped Variables: local (Programming Perl)
localizing: 29.2.87. local (Programming Perl)
package variables as: 2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
10. Packages (Programming Perl)
predeclaring, vars module: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
scope and: 6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
threads, accessing in: 17.2.2. Data Access (Programming Perl)
globbing: 9.6.1. Problem (Perl Cookbook)
12.2. Globbing (Learning Perl)
vs. directory handles: 12.4. Directory Handles (Learning Perl)
vs. filehandle reading: 12.3. An Alternate Syntax for Globbing (Learning Perl)
globbing filenames: 2.11.3. Filename Globbing Operator (Programming Perl)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
Glossary (Programming Perl)
portability of: 25.4. System Interaction (Programming Perl)
globs: 7.1. What Are Regular Expressions? (Learning Perl)
glue language, Perl as: 1.4. Filehandles (Programming Perl)
Glossary (Programming Perl)
gmtime( ): 3.. Introduction (Perl Cookbook)
3.3.2. Solution (Perl Cookbook)
3.8.2. Solution (Perl Cookbook)
Time::localtime and Time::gmtime: 3.. Introduction (Perl Cookbook)
today's date: 3.1.3. Discussion (Perl Cookbook)
11.6.2. The localtime Function (Learning Perl)
29.2.70. gmtime (Programming Perl)
32.1.1. Data Types (Programming Perl)
Gnome, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
GNU, utilities for Win32: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
goto( ): 5. Function Reference (Perl in a Nutshell)
goto command: 4.3.1.6. goto (Perl in a Nutshell)
goto function: 4.6. goto (Programming Perl)
10.2. Autoloading (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.71. goto (Programming Perl)
Perl versions, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
graphbox program: 15.23. Program: graphbox (Perl Cookbook)
graphical user interfaces (GUIs): 15.. Introduction (Perl Cookbook)
B.32. Graphical User Interfaces (GUIs) (Learning Perl)
graphs, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
grave accents (see backticks)
greater-than (>, gt) operators: 4.5.4.1. Relational operators (Perl in a Nutshell)
greater than (>) operator: 3.11. Relational Operators (Programming Perl)
greater-than-or-equal (>=, ge) operators: 4.5.4.1. Relational operators (Perl in a Nutshell)
greater than or equal (>=) operator: 3.11. Relational Operators (Programming Perl)
greater-than sign (>) for creating files: 11.2. Opening a Filehandle (Learning Perl)
greedy matching: 4.6.6. Quantifiers (Perl in a Nutshell)
1.7.1. Quantifiers (Programming Perl)
5.5. Quantifiers (Programming Perl)
5.5. Quantifiers (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Glossary (Programming Perl)
tokens: 2.2. Molecules (Programming Perl)
greedy pattern matching: 6.. The Tricky Bits (Perl Cookbook)
vs. non-greedy pattern matching: 6.15.1. Problem (Perl Cookbook)
Greenwich Mean Time: 11.6.2. The localtime Function (Learning Perl)
Greenwich Mean Time (GMT): 29.2.70. gmtime (Programming Perl)
grep( ): 5. Function Reference (Perl in a Nutshell)
grep command: 1.7. Regular Expressions (Programming Perl)
grep command (Unix)
regular expressions and: 7.1. What Are Regular Expressions? (Learning Perl)
writing Perl program resembling: 9.4. Interpolating into Patterns (Learning Perl)
grep function: 1.7. Regular Expressions (Programming Perl)
24.3. Programming with Style (Programming Perl)
29.2.72. grep (Programming Perl)
grep operator (see Schwartzian Transform also Schwartzian Transform)
5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
(see also Schwartzian Transform)
filehandles and: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
11.7. References to Filehandles (Learning Perl Objects, References and Modules)
functionality: 5.4. The map and grep Operators (Learning Perl Objects, References and Modules)
indices and: 7.2. Sorting with Indices (Learning Perl Objects, References and Modules)
indirection and: 5.6. Applying a Bit of Indirection (Learning Perl Objects, References and Modules)
perlfunc manpage and: B.10.1. map and grep (Learning Perl)
picking items from a list with: 17.2. Picking Items from a List with grep (Learning Perl)
scalar context and: 3.1. Performing the Same Task on Many Arrays (Learning Perl Objects, References and Modules)
5.4. The map and grep Operators (Learning Perl Objects, References and Modules)
selecting complex data: 5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
vs. map operator: 17.3. Transforming Items from a List with map (Learning Perl)
vs. Unix's grep command: 17.2. Picking Items from a List with grep (Learning Perl)
grep program: 5.9.2.1. When backslashes happen (Programming Perl)
grep program (Unix), Perl rewrite of: 6.22. Program: tcgrep (Perl Cookbook)
grep utility: Glossary (Programming Perl)
grid( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
grid geometry manager (Perl/Tk): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
gridBBox( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridColumnconfigure( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridForget( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridInfo( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridLocation( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridPropagate( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridRemove( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridRowconfigure( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridSize( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
gridSlaves( ) (grid manager): 21.2.2.1. grid methods (Perl in a Nutshell)
group( )
Frame widget: 21.18.1. Toplevel Methods (Perl in a Nutshell)
Net::NNTP module: 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
group( ), Usenet news messages: 18.4.3. Discussion (Perl Cookbook)
group command (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
group ID (see GID)
group-ID ($gid): 11.6.1. The stat and lstat Functions (Learning Perl)
changing group membership and: 13.6. Changing Ownership (Learning Perl)
group name: 29.2.46. getgrnam (Programming Perl)
grouping operator: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
for expressions: 3. Unary and Binary Operators (Programming Perl)
groupings, nesting of: 5.7.1. Capturing (Programming Perl)
groups
process
killing: 29.2.80. kill (Programming Perl)
returning priority of: 29.2.57. getpriority (Programming Perl)
processes: 16.1.1. Signaling Process Groups (Programming Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
users: Glossary (Programming Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
group name: 29.2.46. getgrnam (Programming Perl)
members, login names: 29.2.44. getgrent (Programming Perl)
groups, fetching information on: 5.1. Perl Functions by Category (Perl in a Nutshell)
groups( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
gt (greater-than) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
> greater-than sign: 11.2. Opening a Filehandle (Learning Perl)
> (right angle bracket), file-access modes: 7.. I/O Operations (Perl Cookbook)
7.1.3. Discussion (Perl Cookbook)
Gtk, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
guestbook (CGI example): 9.1. A Typical CGI Interaction (Perl in a Nutshell)
GUI, using PerlTk: 24.2.6. User Efficiency (Programming Perl)
GUIs, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
GUIs (graphical user interfaces): 15.. Introduction (Perl Cookbook)
B.32. Graphical User Interfaces (GUIs) (Learning Perl)
guts: 21. Internals and Externals (Programming Perl)
GV (internal glob value): 21.2. Internal Data Types (Programming Perl)
Glossary (Programming Perl)
.gz extension: 2.3.1. Installing on Unix (Perl in a Nutshell)
gzi: 2.3.1. Installing on Unix (Perl in a Nutshell)
gzip for Win32: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

h command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
h command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-h (help) command-line switch: 19.1.3. Switches (Programming Perl)
-h option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
hacker: Glossary (Programming Perl)
handlers: 8.2. Attribute::Handlers (Perl in a Nutshell)
Glossary (Programming Perl)
Apache: 21.. Handlers (Perl Cookbook)
overload: 13.1. The overload Pragma (Programming Perl)
13.2. Overload Handlers (Programming Perl)
missing: 13.5. When an Overload Handler Is Missing (nomethod and fallback) (Programming Perl)
overloading
as_string handler: 13.3. Overloadable Operators (Programming Perl)
sharing information between: 21.13.1. Problem (Perl Cookbook)
for signals: 16.1. Signals (Programming Perl)
handlers for signals (see signal handlers)
handles: 13.15.1. Problem (Perl Cookbook)
1.2.1. Variable Syntax (Programming Perl)
directories: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
Glossary (Programming Perl)
references to: 8.2.4. Handle References (Programming Perl)
tied, base class definitons for: 32.1.14. Convenient Classes (Programming Perl)
hard links: 9.. Introduction (Perl Cookbook)
13.3. Links and Files (Learning Perl)
13.3. Links and Files (Learning Perl)
hard links, filenames: 29.2.85. link (Programming Perl)
hard references: 3.2. The Arrow Operator (Programming Perl)
8.1. What Is a Reference? (Programming Perl)
8.2. Creating References (Programming Perl)
Glossary (Programming Perl)
%SIG array: 16.1. Signals (Programming Perl)
using: 8.3. Using Hard References (Programming Perl)
closures: 8.3.7. Closures (Programming Perl)
hardware devices: Glossary (Programming Perl)
hardware drivers, Perl modules for interacting with: 22.1. The CPAN modules Directory (Programming Perl)
hash elements, accessing: 5.2. Hash Element Access (Learning Perl)
hash functions: 5.3. Hash Functions (Learning Perl)
hash keys: 5.1. What Is a Hash? (Learning Perl)
delete function for removing: 5.4.2. The delete Function (Learning Perl)
exists function for checking: 5.4.1. The exists Function (Learning Perl)
omitting quotes from: 17.4. Unquoted Hash Keys (Learning Perl)
sorting: 15.4.1. Sorting a Hash by Value (Learning Perl)
hash-list equivalence: 5.. Introduction (Perl Cookbook)
hash mark (#)
#! (shebang) line: 3. The Perl Executable (Perl in a Nutshell)
for comments: 4.1. Program Structure (Perl in a Nutshell)
format fieldholders: 4.12. Formats (Perl in a Nutshell)
hash prototype symbol (%): 4.7.5. Prototypes (Perl in a Nutshell)
hash reference
anonymous hash constructors: 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
autovivification and: 4.8. Autovivification and Hashes (Learning Perl Objects, References and Modules)
Data::Dumper example: 5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
debugging example: 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
dereferencing: 3.8. References to Hashes (Learning Perl Objects, References and Modules)
features: 3.8. References to Hashes (Learning Perl Objects, References and Modules)
filesystem capture example: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
object destruction: 10. Object Destruction (Learning Perl Objects, References and Modules)
as parameters: 3.9.2. Exercise 2 [30 min] (Learning Perl Objects, References and Modules)
as return values: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
hashDepth option (debugger): 20.3.3. Debugger Options (Programming Perl)
hashes: 4.7.3. Discussion (Perl Cookbook)
5.. Introduction (Perl Cookbook)
5. Hashes (Learning Perl)
4.2. Data Types and Variables (Perl in a Nutshell)
4.2.5.2. Hashes (Perl in a Nutshell)
7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
1.2.1. Variable Syntax (Programming Perl)
1.2.1.2. Pluralities (Programming Perl)
1.2.1.2.2. Hashes. (Programming Perl)
2.3. Built-in Data Types (Programming Perl)
2.9. Hashes (Programming Perl)
Glossary (Programming Perl)
printing out in sorted order: 4.4.3. foreach Loops (Programming Perl)
accessing elements of: 5.2. Hash Element Access (Learning Perl)
adding elements to: 5.1.1. Problem (Perl Cookbook)
10.11.3.2. Mimicking built-ins (Perl Cookbook)
anonymous: 11.. Anonymous Data (Perl Cookbook)
data structure for objects: 12.7. Managing Instance Data (Programming Perl)
references to: 12.4. Object Construction (Programming Perl)
anonymous, references to: 8.2.2.2. The anonymous hash composer (Programming Perl)
of arrays: 11.2.1. Problem (Perl Cookbook)
9.2. Hashes of Arrays (Programming Perl)
9.3. Arrays of Hashes (Programming Perl)
access and printing of: 9.2.3. Access and Printing of a Hash of Arrays (Programming Perl)
generating: 9.2.2. Generation of a Hash of Arrays (Programming Perl)
9.3.2. Generation of an Array of Hashes (Programming Perl)
arrays and: 5.. Introduction (Perl Cookbook)
assigning: 5.2.2. Hash Assignment (Learning Perl)
autoincrements/autodecrements and: 10.6.1. The Value of Autoincrement (Learning Perl)
binding DBM files to: 29.2.22. dbmopen (Programming Perl)
buckets: Glossary (Programming Perl)
cascading conditionals, using instead of: 4.5.1. Case Structures (Programming Perl)
comparing keys of: 5.12.1. Problem (Perl Cookbook)
of complex records: 9.6.3. Generation of a Hash of Complex Records (Programming Perl)
counting how often something appears: 5.15.3. Discussion (Perl Cookbook)
deleting elements of: 5.4.1. Problem (Perl Cookbook)
deleting values from: 29.2.24. delete (Programming Perl)
directories as: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
dutree program: 5.17. Program: dutree (Perl Cookbook)
elements, giving temporary values to: 29.2.87. local (Programming Perl)
elements of, interpolating into double-quoted string literals: 5.4.3. Hash Element Interpolation (Learning Perl)
exists function and: 29.2.34. exists (Programming Perl)
finding most common anything: 5.15.1. Problem (Perl Cookbook)
flat lookup tables, providing access to: 9. Data Structures (Programming Perl)
functions for: 5.3. Hash Functions (Learning Perl)
functions for processing: 5.1. Perl Functions by Category (Perl in a Nutshell)
HV (hash value) typedef in C: 21.2. Internal Data Types (Programming Perl)
%INC for modules: 11.1. Using Modules (Programming Perl)
initializing: 5.. Introduction (Perl Cookbook)
initializing with x operator: 3.7. Multiplicative Operators (Programming Perl)
instances and: 9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
instead of linear searches: 24.2.1. Time Efficiency (Programming Perl)
inverting: 5.9.1. Problem (Perl Cookbook)
29.2.132. reverse (Programming Perl)
keys: Glossary (Programming Perl)
keys, finding number in: 2.9. Hashes (Programming Perl)
keys, returning list of: 29.2.79. keys (Programming Perl)
key/value pair precedence: 2.9. Hashes (Programming Perl)
key/value pairs: 2.3. Built-in Data Types (Programming Perl)
2.9. Hashes (Programming Perl)
capturing from string with m//g operator: 5.2.2. The m// Operator (Matching) (Programming Perl)
key/value pairs in: 1.2.1.2.2. Hashes. (Programming Perl)
for list unions, intersections, differences: 4.8.3. Discussion (Perl Cookbook)
lookups by key or value: 13.15.7. Tie Example: Hash That Allows Lookups by Key or Value (Perl Cookbook)
map operator and: 5.5. Using map (Learning Perl Objects, References and Modules)
merging: 5.11.1. Problem (Perl Cookbook)
multidimensional: 9.4. Hashes of Hashes (Programming Perl)
accessing and printing: 9.4.3. Access and Printing of a Hash of Hashes (Programming Perl)
generation of: 9.4.2. Generation of a Hash of Hashes (Programming Perl)
multiple values per key: 5.8.1. Problem (Perl Cookbook)
names for: 2.4. Variables (Programming Perl)
names of: 5.2. Hash Element Access (Learning Perl)
output style, changing in debugger: 20.3.3. Debugger Options (Programming Perl)
package names and: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
passing by reference into or out of functions: 6.3. Passing References (Programming Perl)
Perl data organization in: 9.1.5. Common Mistakes (Programming Perl)
presizing: 5.14.1. Problem (Perl Cookbook)
printing: 5.6.1. Problem (Perl Cookbook)
processing, functions for: 29.1. Perl Functions by Category (Programming Perl)
reading and writing records to file: 11.10.1. Problem (Perl Cookbook)
reasons for using: 5.1.1. Why Use a Hash? (Learning Perl)
as records: 11.. Records (Perl Cookbook)
references and: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
references as elements: 5.13.2. Solution (Perl Cookbook)
references as keys: 8.5.1. References Don't Work as Hash Keys (Programming Perl)
references to: 11.3.1. Problem (Perl Cookbook)
8.1. What Is a Reference? (Programming Perl)
representing data relationships: 5.16.1. Problem (Perl Cookbook)
representing relationships between data: 5.16.2. Solution (Perl Cookbook)
restricted, implementing: 12.7.5. Using Closures for Private Objects (Programming Perl)
retrieving in insertion order: 5.7.1. Problem (Perl Cookbook)
returning key/value pairs: 29.2.30. each (Programming Perl)
returning values of: 29.2.194. values (Programming Perl)
scalars and: 3. Introduction to References (Learning Perl Objects, References and Modules)
%SIG, references to signal handlers: 16.1. Signals (Programming Perl)
slices and: 17.6.2. Hash Slice (Learning Perl)
slices of: 4.8.3. Discussion (Perl Cookbook)
sorting elements: 5.10.1. Problem (Perl Cookbook)
special (predefined): 4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
storing filehandles: A.10.1. Exercise (Section 11.8.1) (Learning Perl Objects, References and Modules)
symbol tables: 10.1. Symbol Tables (Programming Perl)
key/value pairs in: 10.1. Symbol Tables (Programming Perl)
typeglobs in: 10.1. Symbol Tables (Programming Perl)
taint in: 23.1. Handling Insecure Data (Programming Perl)
testing for keys: 5.2.1. Problem (Perl Cookbook)
ties for: 13.15.5. Tie Example: Make a Hash That Always Appends (Perl Cookbook)
traversing: 5.5.1. Problem (Perl Cookbook)
tying: 14. Tied Variables (Programming Perl)
14.3. Tying Hashes (Programming Perl)
methods for: 14.3.1. Hash-Tying Methods (Programming Perl)
Tie::Hash module, providing base class definitions: 32.1.14. Convenient Classes (Programming Perl)
unwinding: 5.2.1. The Hash as a Whole (Learning Perl)
Hash::Util module: 8.119. Hash::Util (Perl in a Nutshell)
HASH(0x1a2b3c): 3.8. References to Hashes (Learning Perl Objects, References and Modules)
head( )
LWP::UserAgent: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
LWP::Simple module: 20.2.2. LWP::Simple (Perl in a Nutshell)
20.2.2. LWP::Simple (Perl in a Nutshell)
Mail::Internet module: 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
Net::NNTP module: 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
finding stale hyperlinks: 20.7.2. Solution (Perl Cookbook)
=head2 command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
HEAD method: 19.. Behind the Scenes (Perl Cookbook)
header( )
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
HTTP::Headers module: 20.3.3. HTTP::Headers (Perl in a Nutshell)
HTTP::Message module: 20.3.8. HTTP::Message (Perl in a Nutshell)
header files: Glossary (Programming Perl)
Glossary (Programming Perl)
(see also modules)
headers, format names: 7.2. Footers (Programming Perl)
headers, HTTP: 20.3.3. HTTP::Headers (Perl in a Nutshell)
headers, interrogating with mod_perl: 21.5.1. Problem (Perl Cookbook)
-height option
place geometry manager: 21.2.3. The place Geometry Manager (Perl in a Nutshell)
widgets: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
hello( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
`Hello, world' program: 1.4.1. A Simple Program (Learning Perl)
HELO command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session (Perl in a Nutshell)
help( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
here documents: 1.. Introduction (Perl Cookbook)
B.8.2. Here documents (Learning Perl)
2.6.6. "Here" Documents (Programming Perl)
Glossary (Programming Perl)
end-of-file: Glossary (Programming Perl)
indentation of: 2.6.6. "Here" Documents (Programming Perl)
indenting: 1.16.1. Problem (Perl Cookbook)
semicolon (;), omitting trailing: 24.1.1. Universal Blunders (Programming Perl)
hex( ): 5. Function Reference (Perl in a Nutshell)
2.15.2. Solution (Perl Cookbook)
29.2.73. hex (Programming Perl)
hexadecimal: Glossary (Programming Perl)
converting numbers to: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
hexadecimal characters: 2.6.1. Numeric Literals (Programming Perl)
hexadecimal literals: 2.2.4. Nondecimal Integer Literals (Learning Perl)
hexadecimal memory address: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.8. References to Hashes (Learning Perl Objects, References and Modules)
hexadecimal numbers: 29.2.73. hex (Programming Perl)
character numbers, specifying as: 5.3.2. Specific Characters (Programming Perl)
hexadecimal numbers, converting: 2.15.1. Problem (Perl Cookbook)
hexdigest( )
Digest modules: 8.57. Digest (Perl in a Nutshell)
Digest::MD5 module: 8.58. Digest::MD5 (Perl in a Nutshell)
hidden( ), generating sticky hidden fields: 19.11.3. Discussion (Perl Cookbook)
hidden( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
Hietaniemi, Jarkko: 2.1. The CPAN Architecture (Perl in a Nutshell)
high-level programming languages: 1.2.1. Why Didn't Larry Just Use Some Other Language? (Learning Perl)
1.2.2. Is Perl Easy or Hard? (Learning Perl)
high-precision numbers: B.9.3. Large and High-Precision Numbers (Learning Perl)
high-resolution timers: 3.9.1. Problem (Perl Cookbook)
-highlightbackground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-highlightcolor option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-highlightthickness option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
hints, compiler: 28.2. Special Variables in Alphabetical Order (Programming Perl)
history, command: 20.1. Using the Debugger (Programming Perl)
history of Perl: 27.1. History Made Practical (Programming Perl)
history.db file, grepping: 14.19. Program: ggh—Grep Netscape Global History (Perl Cookbook)
home directory: 12.1. Moving Around the Directory Tree (Learning Perl)
29.2.9. chdir (Programming Perl)
Glossary (Programming Perl)
home page, Perl: 0.6.1. Perl on the Web (Programming Perl)
HOME variable: 3.3. Environment Variables (Perl in a Nutshell)
19.2. Environment Variables (Programming Perl)
hopdelta program: 3.11. Program: hopdelta (Perl Cookbook)
host( )
Mail::Address module: 16.2.6. Parse Email Addresses with Mail::Address (Perl in a Nutshell)
16.2.7. Mail::Address Reference (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
hostname function: B.5.10. The Sys::Hostname Module (Learning Perl)
hostnames
getting from network addresses: 29.2.47. gethostbyaddr (Programming Perl)
identifying at socket end: 17.7.2. Solution (Perl Cookbook)
obtaining your own: 17.8.1. Problem (Perl Cookbook)
Sys::Hostname module: 32.1.7. Operating System Interfaces (Programming Perl)
translating to addresses: 29.2.48. gethostbyname (Programming Perl)
29.2.52. getnetbyname (Programming Perl)
hostpath (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
hosts: Glossary (Programming Perl)
hosts file (see /etc/hosts file)
hosts (remote), checking for reachability: 32.1.8. Networking and Interprocess Communication (Programming Perl)
host_wait( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
HotKey module: 15.8.3. Description (Perl Cookbook)
hours (see date and time values)
household appliances, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
h2ph tool, translating C header files: 12.17.1. Problem (Perl Cookbook)
hpush( ): 10.11.3.2. Mimicking built-ins (Perl Cookbook)
HREF fields, substitutions for: 20.21. Program: hrefsub (Perl Cookbook)
hrefsub program: 20.21. Program: hrefsub (Perl Cookbook)
HTML
CGI module, generation of: 32.1.9. World Wide Web (Programming Perl)
code, producing nicely formatted: 32.1.9. World Wide Web (Programming Perl)
converting ASCII to and from: 20.4.1. Problem (Perl Cookbook)
extracting tags: 20.6.1. Problem (Perl Cookbook)
extracting URLs from: 20.3.1. Problem (Perl Cookbook)
finding stale or fresh links: 20.7.1. Problem (Perl Cookbook)
parsing: 20.18.1. Problem (Perl Cookbook)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
pod files, converting to: 32.1.16. Documentation Support (Programming Perl)
putting links around URLs: 6.21. Program: urlify (Perl Cookbook)
shortcuts, formatting lists and tables with: 19.6.1. Problem (Perl Cookbook)
tables in, extracting data from: 20.19.1. Problem (Perl Cookbook)
templates: 20.9.1. Problem (Perl Cookbook)
text substitutions: 20.20. Program: htmlsub (Perl Cookbook)
XML and: 22.. Introduction (Perl Cookbook)
HTML forms: 19.. HTML and Forms (Perl Cookbook)
accessing parameters with mod_perl: 21.6.1. Problem (Perl Cookbook)
automating submission: 20.2.1. Problem (Perl Cookbook)
Boolean connectives in patterns: 6.18.1. Problem (Perl Cookbook)
saving and mailing: 19.12.1. Problem (Perl Cookbook)
sticky widgets: 19.10.1. Problem (Perl Cookbook)
HTML (Hypertext Markup Language)
tags, generating with CGI.pm: 10.1. HTML Tag Generation (Perl in a Nutshell)
translating pod to: 4.13.3. Pod Utilities (Perl in a Nutshell)
8.174. Pod::Html (Perl in a Nutshell)
:html method groups: 10.2. Importing Method Groups (Perl in a Nutshell)
HTML modules: 20.4. The HTML Modules (Perl in a Nutshell)
HTML::Element module: 20.4.3. HTML::Element (Perl in a Nutshell)
HTML::FormatPS module: 20.4.5. HTML::FormatPS (Perl in a Nutshell)
HTML::FormatText module: 20.4.6. HTML::FormatText (Perl in a Nutshell)
HTML::Parser module: 20.4. The HTML Modules (Perl in a Nutshell)
20.4.1. HTML::Parser (Perl in a Nutshell)
HTML::TreeBuilder module: 20.4.4. HTML::TreeBuilder (Perl in a Nutshell)
HTML::FormatText module: 20.5.3. Discussion (Perl Cookbook)
HTML::LinkExtor module: 20.3.2. Solution (Perl Cookbook)
HTML::Mason module: 21.16.1. Problem (Perl Cookbook)
autohandlers: 21.16.3.4. Autohandlers (Perl Cookbook)
configuration: 21.16.3.1. Configuration (Perl Cookbook)
dhandlers: 21.16.3.5. Dhandlers (Perl Cookbook)
21.16.3.5. Dhandlers (Perl Cookbook)
Mason syntax: 21.16.3.2. Basic Mason syntax (Perl Cookbook)
objects: 21.16.3.3. Objects (Perl Cookbook)
htmlsub program: 20.20. Program: htmlsub (Perl Cookbook)
HTML::TableContentParser module: 20.19.2. Solution (Perl Cookbook)
HTML::TextToHTML module: 20.4.3. Discussion (Perl Cookbook)
HTML::TokeParser module: 20.18.3. Discussion (Perl Cookbook)
HTTP
cookies, setting and getting: 32.1.9. World Wide Web (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
HTTP (Hypertext Transfer Protocol)
links, searching for: 1.7. Regular Expressions (Programming Perl)
request messages: 20.1. LWP Overview (Perl in a Nutshell)
Win32::Internet functions for: 22.7.3. HTTP Functions (Perl in a Nutshell)
HTTP methods: 19.. Behind the Scenes (Perl Cookbook)
19.1.3. Discussion (Perl Cookbook)
HTTP modules
HTTP::Cookies module: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
HTTP::Cookies::Netscape module: 20.3.6.1. HTTP::Cookies::Netscape (Perl in a Nutshell)
HTTP::Daemon module: 20.3.7. HTTP::Daemon (Perl in a Nutshell)
HTTP::Daemon::ClientConn module: 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
HTTP::Date module: 20.3.5. HTTP::Date (Perl in a Nutshell)
HTTP::Headers module: 20.3.3. HTTP::Headers (Perl in a Nutshell)
HTTP::Message module: 20.3.8. HTTP::Message (Perl in a Nutshell)
HTTP::Request module: 20.1. LWP Overview (Perl in a Nutshell)
20.3.1. HTTP::Request (Perl in a Nutshell)
HTTP::Response module: 20.1. LWP Overview (Perl in a Nutshell)
20.3.2. HTTP::Response (Perl in a Nutshell)
HTTP::Status module: 20.3.4. HTTP::Status (Perl in a Nutshell)
HTTP( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
HTTP::Cookies module: 20.14.3. Discussion (Perl Cookbook)
HTTP::Response module: 20.1.3. Discussion (Perl Cookbook)
hubris: Glossary (Programming Perl)
HV (internal hash value): 21.2. Internal Data Types (Programming Perl)
Glossary (Programming Perl)
h2xs tool: 22.3. Creating CPAN Modules (Programming Perl)
12.9.2. Solution (Perl Cookbook)
distributions and: 13.1. Starting with h2xs (Learning Perl Objects, References and Modules)
Makefile.PL and: 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
making a module with C code: 12.18.1. Problem (Perl Cookbook)
multiple test scripts and: 14.5. More Complex Tests (Multiple Test Scripts) (Learning Perl Objects, References and Modules)
21.3.1. XS and XSUBs (Programming Perl)
21.3.2. Creating Extensions (Programming Perl)
hyperlinks
clearing link list: 20.3.3. Discussion (Perl Cookbook)
extracting from HTML: 20.3.1. Problem (Perl Cookbook)
finding stale or fresh: 20.7.1. Problem (Perl Cookbook)
hyphen (-)
-0 command-line option: 8.. Basic Operations (Perl Cookbook)
-a command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
in [...] construct: 4.6.4. Character Classes (Perl in a Nutshell)
-e command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-> (arrow) operator: 11.. References (Perl Cookbook)
13.. Methods (Perl Cookbook)
4.5.1. The Arrow Operator (Perl in a Nutshell)
dereferencing with: 4.8.2.1. Arrow dereferencing (Perl in a Nutshell)
-> (infix) notation: 11.. References (Perl Cookbook)
-i command-line option
modifying files with: 7.16.2. Solution (Perl Cookbook)
writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-I command-line switch: 12.8.2. Solution (Perl Cookbook)
-n command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-p command-line option
modifying files with: 7.16.2. Solution (Perl Cookbook)
writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-t command-line option: 15.2.2. Solution (Perl Cookbook)
arithmetic negation operator: 4.5.2. Unary Operators (Perl in a Nutshell)
grid geometry manager placeholder: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
indicating standard input stream: 6.2. Input from the Diamond Operator (Learning Perl)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
specifying range of characters: 8.1. Character Classes (Learning Perl)
-= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
-- (autodecrement) operator: 4.5.5. Autoincrement and Autodecrement (Perl in a Nutshell)
hyphenating text, Perl module for: 22.1. The CPAN modules Directory (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

i command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
-i command-line option
modifying files with: 7.16.2. Solution (Perl Cookbook)
writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
-I command-line switch: 12.8.2. Solution (Perl Cookbook)
-i (in-place editing) command-line switch: 19.1.3. Switches (Programming Perl)
-I (include path) command-line switch: 19.1.3. Switches (Programming Perl)
I<\\> interior sequence (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
/i modifier: 9.2.1. Case-insensitive Matching with /i (Learning Perl)
s/// substitution operator and: 9.6.3. Option Modifiers (Learning Perl)
-I option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
/i pattern modifier: 5.2.1. Pattern Modifiers (Programming Perl)
5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
i pattern match modifier: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
4.6.8. Extended Regular Expressions (Perl in a Nutshell)
/i pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
$^I variable: 16.4. Variable-length (Text) Databases (Learning Perl)
iconbitmap( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
iconify( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
iconmask( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
iconname( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
iconposition( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
iconwindow( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
icursor( ) (Entry): 21.8.2. Entry Methods (Perl in a Nutshell)
idempotency: 19.. Behind the Scenes (Perl Cookbook)
identifiers: 2.2. Molecules (Programming Perl)
2.5. Names (Programming Perl)
29.2.63. getpwuid (Programming Perl)
Glossary (Programming Perl)
bare, barewords vs.: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
effective UID or GID, setting back to real: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
effective user or group IDs, differing from real: 23.1. Handling Insecure Data (Programming Perl)
enclosing in braces: 2.6.2. String Literals (Programming Perl)
GID (group ID): Glossary (Programming Perl)
line-oriented quoting: 2.6.6. "Here" Documents (Programming Perl)
names vs.: 2.5. Names (Programming Perl)
Perl modules: 11.1. Using Modules (Programming Perl)
PIDs, guessing: 23.2.3. Temporary Files (Programming Perl)
process group ID: 16.1.1. Signaling Process Groups (Programming Perl)
processes (pid): 29.2.104. open (Programming Perl)
semaphores: 29.2.143. semget (Programming Perl)
shared memory segments: 29.2.151. shmget (Programming Perl)
single quotes (') in: 2.6.2. String Literals (Programming Perl)
starting with underscore (_), changes in Perl versions: 24.1.5. Previous Perl Traps (Programming Perl)
thread IDs: 17.2.1.5. Identifying threads (Programming Perl)
Unicode alphanumeric characters, containing: 15.2. Effects of Character Semantics (Programming Perl)
identifiers, package: 10. Packages (Programming Perl)
in package symbol table: 10. Packages (Programming Perl)
identify( )
Scale widget: 21.13.1. Scale Methods (Perl in a Nutshell)
Scrollbar widget: 21.9.1. Scrollbar Methods (Perl in a Nutshell)
ideographic unary operators: 3.5. Ideographic Unary Operators (Programming Perl)
ideographs: 1.7. Regular Expressions (Programming Perl)
matching with \w: 15.2. Effects of Character Semantics (Programming Perl)
idioms, Perl: 24.4. Fluent Perl (Programming Perl)
if control structure: 2.7. The if Control Structure (Learning Perl)
else clause and: 10.1.1. The else Clause with unless (Learning Perl)
unless control structure and: 10.1. The unless Control Structure (Learning Perl)
If-Modified-Since header: 20.10.3. Discussion (Perl Cookbook)
if modifier: 10.3. Expression Modifiers (Learning Perl)
4.3.1.4. Modifiers (Perl in a Nutshell)
4.1. Simple Statements (Programming Perl)
if module: 8.124. if (Perl in a Nutshell)
if statement: 4.3.1. Conditionals and Loops (Perl in a Nutshell)
if statements: 1.5.5. Logical Operators (Programming Perl)
1.6.1.1. The if and unless statements (Programming Perl)
4.3. if and unless Statements (Programming Perl)
C language, differences from Perl: 24.1.3. C Traps (Programming Perl)
in case structure: 4.5.1. Case Structures (Programming Perl)
logical operators and: 1.5.5. Logical Operators (Programming Perl)
if-then-else test, ternary operator for: 10.9.2. The Ternary Operator, ?: (Learning Perl)
IGNORE pseudosignal: 16.1. Signals (Programming Perl)
ignore_text( ) (HTML::Parser): 20.4.4. HTML::TreeBuilder (Perl in a Nutshell)
ignore_unknown( ) (HTML::Parser): 20.4.4. HTML::TreeBuilder (Perl in a Nutshell)
ihave( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
image files, Image::Size module for: B.5.7. The Image::Size Module (Learning Perl)
-image option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
image_button( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
Image::Magick module: 15.19.2. Solution (Perl Cookbook)
images
adding text to: 15.20.1. Problem (Perl Cookbook)
thumbnailing: 15.19.1. Problem (Perl Cookbook)
Image::Size module: B.5.7. The Image::Size Module (Learning Perl)
imaginary numbers: 2.14.1. Problem (Perl Cookbook)
B.9.2. Imaginary and Complex Numbers (Learning Perl)
impatience: Glossary (Programming Perl)
imperative programming style: 5.10.3. Programmatic Patterns (Programming Perl)
implementing sparse arrays: 4.4.1. Problem (Perl Cookbook)
implicit( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
implicit method invocation: 12.3. Method Invocation (Programming Perl)
implicit referencing or dereferencing: 8.1. What Is a Reference? (Programming Perl)
implicit_tags( ) (HTML::Parser): 20.4.4. HTML::TreeBuilder (Perl in a Nutshell)
import function: 11.1. Using Modules (Programming Perl)
11.2.1.1. Exporting without using Exporter's import method (Programming Perl)
29.2.74. import (Programming Perl)
import lists: 13.8.2. Using Only Some Functions from a Module (Learning Perl)
import method: Glossary (Programming Perl)
overloading constants: 13.6. Overloading Constants (Programming Perl)
importing: 4.7. Global Declarations (Programming Perl)
-nosticky option: 12.11. Custom Import Routines (Learning Perl Objects, References and Modules)
custom routines: 12.11. Custom Import Routines (Learning Perl Objects, References and Modules)
Exporter module and: 12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
File::Basename module and: 12.2. Selecting What to Import (Learning Perl Objects, References and Modules)
semantics into package: 29.2.192. use (Programming Perl)
subroutines: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
subroutines from another module: 6.1. Syntax (Programming Perl)
symbols from one package to another: 10.1. Symbol Tables (Programming Perl)
use operation and: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
importing from modules: 10.14.3. Discussion (Perl Cookbook)
12.. Modules (Perl Cookbook)
importing symbols: 11.2.1. Module Privacy and the Exporter (Programming Perl)
(see also Exporter module; exporting symbols)
import_names( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
in interprocess communication
bidirectional communication: 16.3.3. Bidirectional Communication (Programming Perl)
I18N modules: 8.120. I18N::Collate (Perl in a Nutshell)
I18N::Collate module: 8.120. I18N::Collate (Perl in a Nutshell)
I18N::Langinfo module: 8.121. I18N::Langinfo (Perl in a Nutshell)
I18N::LangTags module: 8.122. I18N::LangTags (Perl in a Nutshell)
I18N::LangTags::List module: 8.123. I18N::LangTags::List (Perl in a Nutshell)
-in option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
grid geometry manager: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
pack geometry manager: 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
place geometry manager: 21.2.3. The place Geometry Manager (Perl in a Nutshell)
in( ) (Win32::OLE): 23.2.2. Win32::OLE Functions (Perl in a Nutshell)
INADDR_ANY: 17.1.3. Discussion (Perl Cookbook)
17.16.2. Solution (Perl Cookbook)
INADDR_ANY( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
INADDR_BROADCAST( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
INADDR_LOOPBACK( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
INADDR_NONE( ) (Socket)
.25i: 15.1.4. Socket Module Functions (Perl in a Nutshell)
@INC array: 12.8.3. Discussion (Perl Cookbook)
4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
11.1. Using Modules (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
require operator and: 2.5. require and @INC (Learning Perl Objects, References and Modules)
use operation and: 12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
%INC hash: 4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
11.1. Using Modules (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
I18N::Collate module: 32.1.6. Internationalization and Locale (Programming Perl)
incrementing variables: 1.5.4. Unary Arithmetic Operators (Programming Perl)
indents (see whitespace)
index( ): 5. Function Reference (Perl in a Nutshell)
Entry widget: 21.8.2. Entry Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
index function: 15.1. Finding a Substring with index (Learning Perl)
29.2.75. index (Programming Perl)
Glossary (Programming Perl)
using with substr operator: 15.2. Manipulating a Substring with substr (Learning Perl)
indexing arrays: 9.2.3. Access and Printing of a Hash of Arrays (Programming Perl)
indexing elements: 3. Lists and Arrays (Learning Perl)
-indicatoron option
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
21.14.1. Menu Item Options (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
indices
fixed-length records program: 8.27. Program: Flat File Indexes (Perl Cookbook)
of hash elements: 5.. Introduction (Perl Cookbook)
indices, sorting with: 7.2. Sorting with Indices (Learning Perl Objects, References and Modules)
7.2. Sorting with Indices (Learning Perl Objects, References and Modules)
indirect filehandle read: 12.3. An Alternate Syntax for Globbing (Learning Perl)
indirect filehandles: 29.2.104. open (Programming Perl)
Glossary (Programming Perl)
indirect notation: 13.. A Warning on Indirect Object Notation (Perl Cookbook)
indirect object notation: 7.5.3. Discussion (Perl Cookbook)
10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
indirect object slot: 12.3.2. Method Invocation Using Indirect Objects (Programming Perl)
indirect object syntax: 12.3.2. Method Invocation Using Indirect Objects (Programming Perl)
ambiguities in: 12.3.3. Syntactic Snafus with Indirect Objects (Programming Perl)
indirect objects: Glossary (Programming Perl)
explicit path, passing in slot: 23.1. Handling Insecure Data (Programming Perl)
indirection: 2.5.1. Name Lookups (Programming Perl)
8. References (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also hard references; symbolic references)
applying: 5.6. Applying a Bit of Indirection (Learning Perl Objects, References and Modules)
between class use and implementation: 12.3. Method Invocation (Programming Perl)
sorting indices: 7.2. Sorting with Indices (Learning Perl Objects, References and Modules)
inequality (see equality operators[semi] relational operators)
inet_aton( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
inet_ntoa( ): 17.. Introduction (Perl Cookbook)
18.1.2. Solution (Perl Cookbook)
inet_ntoa function: 29.2.47. gethostbyaddr (Programming Perl)
inet_ntoa( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
infinite loops: 4.4.2. for Loops (Programming Perl)
infix (->) notation: 11.. References (Perl Cookbook)
infix dereference (-\: 7.4. Object Syntax (Perl in a Nutshell)
infix dereference (->) operator: 4.5.1. The Arrow Operator (Perl in a Nutshell)
4.8.2.1. Arrow dereferencing (Perl in a Nutshell)
infix dereference operator (see arrow operator)
infix operators: 1.5. Operators (Programming Perl)
Glossary (Programming Perl)
Info( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
inheritance: 13.. Inheritance (Perl Cookbook)
13.10.1. Problem (Perl Cookbook)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
base class, establishing at compile time: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
class: 10. Packages (Programming Perl)
12.5. Class Inheritance (Programming Perl)
single or multiple: 12.5. Class Inheritance (Programming Perl)
class accessors: 12.8. Managing Class Data (Programming Perl)
classes and objects
pseudohash implementation and: 12.7.1. Field Declarations with use fields (Programming Perl)
code reusability through: 8.6. Overriding the Methods (Learning Perl Objects, References and Modules)
composition versus: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
constructors: 12.4.1. Inheritable Constructors (Programming Perl)
constructors and: 9.5. Inheriting the Constructor (Learning Perl Objects, References and Modules)
9.5. Inheriting the Constructor (Learning Perl Objects, References and Modules)
DESTROY method and: 10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
through @ISA array: 12.5.1. Inheritance Through @ISA (Programming Perl)
isa method testing: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
@ISA variable and: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
method invocation and: 8.4. Calling a Second Method to Simplify Things (Learning Perl Objects, References and Modules)
8.4. Calling a Second Method to Simplify Things (Learning Perl Objects, References and Modules)
modules, from Exporter class: 11.2.1. Module Privacy and the Exporter (Programming Perl)
multiple inheritance: 11.6. Multiple Inheritance (Learning Perl Objects, References and Modules)
overloading and: 13.8. Inheritance and Overloading (Programming Perl)
restricted access and: 12.7.5. Using Closures for Private Objects (Programming Perl)
inhibit_exit option (debugger): 20.3.3. Debugger Options (Programming Perl)
INIT blocks: 18.1. The Life Cycle of a Perl Program (Programming Perl)
initializing variables before calling subroutine: 6.2.3. Scoping Issues (Programming Perl)
order of running: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
Init handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
init program: 29.2.56. getppid (Programming Perl)
initial caps (see capitalization)
initialization
debugger, customizing with init files: 20.3.2. Customizing with Init Files (Programming Perl)
initialization expressions: 4.4.2. for Loops (Programming Perl)
initializers (see constructors)
initializing
arrays and hash slices: 3.7. Multiplicative Operators (Programming Perl)
arrays and lists: 4.1.1. Problem (Perl Cookbook)
hash variables: 2.9. Hashes (Programming Perl)
hashes: 5.. Introduction (Perl Cookbook)
modules: 12.7.1. Problem (Perl Cookbook)
objects: 12.4.2. Initializers (Programming Perl)
variables before calling subroutines: 6.2.3. Scoping Issues (Programming Perl)
initializing NNTP clients: 17.2.1. Initializing the NNTP Client (Perl in a Nutshell)
initializing sockets: 15.1.1. Initializing a Socket (Perl in a Nutshell)
Inline::C module: 12.19.2. Solution (Perl Cookbook)
inlining constant functions: 6.4.1. Inlining Constant Functions (Programming Perl)
preventing inlining: 6.4.1. Inlining Constant Functions (Programming Perl)
inner( ): 10.16.3. Discussion (Perl Cookbook)
$ino file statistic: 29.2.165. stat (Programming Perl)
$ino (inode number): 11.6.1. The stat and lstat Functions (Learning Perl)
inode structure: 9.. Introduction (Perl Cookbook)
inodes: 13.3. Links and Files (Learning Perl)
inplace editing ($^I, $INPLACE_EDIT): 19.1.3. Switches (Programming Perl)
inplace edits with $^I: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$INPLACE_EDIT ($^I) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
input: 6. I/O Basics (Learning Perl)
29.2.38. fileno (Programming Perl)
(see also STDIN filehandle)
checking file descriptors for: 29.2.141. select (ready file descriptors) (Programming Perl)
comma-separated, parsing: 1.20.1. Problem (Perl Cookbook)
controlling for other programs: 16.8.1. Problem (Perl Cookbook)
16.9.1. Problem (Perl Cookbook)
debugger, setting: 20.4. Unattended Execution (Programming Perl)
editing: 15.11.1. Problem (Perl Cookbook)
executing shell commands from: 19.5.1. Problem (Perl Cookbook)
expanding variables in: 1.12.1. Problem (Perl Cookbook)
Expect-controlled programs and: 15.13.3. Discussion (Perl Cookbook)
extracting variable-length fields: 8.9.1. Problem (Perl Cookbook)
files, locating end with eof: 19.1.3. Switches (Programming Perl)
files, open mode for: 29.2.104. open (Programming Perl)
from HTML forms [input
HTML forms (see CGI programming)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
ioctl function: 29.2.77. ioctl (Programming Perl)
line input operator: 7.. I/O Operations (Perl Cookbook)
8.. Basic Operations (Perl Cookbook)
managing multiple streams: 17.19.1. Problem (Perl Cookbook)
operators: 2.11. Input Operators (Programming Perl)
parsing command-line arguments: 15.1.1. Problem (Perl Cookbook)
pipes: 16.3. Pipes (Programming Perl)
16.3. Pipes (Programming Perl)
bidirectional: 16.3.3. Bidirectional Communication (Programming Perl)
multistage pipelines: 16.3.1. Anonymous Pipes (Programming Perl)
tridirectional: 16.3.3. Bidirectional Communication (Programming Perl)
preprocessing: 16.6.1. Problem (Perl Cookbook)
random-access I/O: 8.12.1. Problem (Perl Cookbook)
reading
from keyboard: 15.6.1. Problem (Perl Cookbook)
from other programs: 16.4.1. Problem (Perl Cookbook)
passwords: 15.10.1. Problem (Perl Cookbook)
records with pattern separators: 6.7.1. Problem (Perl Cookbook)
STDERR from programs: 16.7.1. Problem (Perl Cookbook)
reading with diamond operator: 6.2. Input from the Diamond Operator (Learning Perl)
record separator (see $/ variable)
single-character, buffered and unbuffered: 29.2.43. getc (Programming Perl)
waiting, checking for: 15.9.1. Problem (Perl Cookbook)
while control structure shortcut for: 6.1. Input from Standard Input (Learning Perl)
XSUBs: 21.3.3. XSUB Input and Output (Programming Perl)
input filehandles: 1.4. Filehandles (Programming Perl)
input, functions for: 4.4.1. Global Special Variables (Perl in a Nutshell)
5.1. Perl Functions by Category (Perl in a Nutshell)
<input\\> tag: 9.1. A Typical CGI Interaction (Perl in a Nutshell)
Input( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
InputChar( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
InputCP( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
$INPUT_LINE_NUMBER: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$INPUT_LINE_NUMBER ($.) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
input/output (I/O): 6. I/O Basics (Learning Perl)
6. I/O Basics (Learning Perl)
filehandles and: 11.1. What Is a Filehandle? (Learning Perl)
$INPUT_RECORD_SEPARATOR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$INPUT_RECORD_SEPARATOR ($/) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
insecure dependency errors: 23.1. Handling Insecure Data (Programming Perl)
insert( )
Entry widget: 21.8.2. Entry Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
insert index
Entry widget: 21.8.1. Text Indexes (Perl in a Nutshell)
Text widget: 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
-insertbackground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-insertborderwidth option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
insert_element( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
-insertofftime option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-insertontime option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-insertwidth option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
inside utility: B.4.3. Finding and Installing Modules (Learning Perl)
install command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
installation
modules, CPAN: 22.2. Using CPAN Modules (Programming Perl)
into Perl library: 22.2.3. Installing CPAN Modules into the Perl Library (Programming Perl)
modules supporting: 32.1.17. Module Installation Support (Programming Perl)
installation (of modules)
alternate library locations: 13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
alternate locations: 13.6. Alternate Installation Locations (PREFIX=...) (Learning Perl Objects, References and Modules)
distribution considerations: 13. Writing a Distribution (Learning Perl Objects, References and Modules)
installed modules, inventory of: 32.1.17. Module Installation Support (Programming Perl)
installing
mod_perl module: 11.2. Installing mod_perl (Perl in a Nutshell)
modules from CPAN: 12.21.1. Problem (Perl Cookbook)
Perl documentation: 2.5.1. Installing the Documentation (Perl in a Nutshell)
Perl modules: 2.4.2. Module Installation (Perl in a Nutshell)
Perl source code: 2.3. Installing Perl (Perl in a Nutshell)
signal handlers: 16.15.1. Problem (Perl Cookbook)
instance data: Glossary (Programming Perl)
circular data structures: 13.13.1. Problem (Perl Cookbook)
managing: 13.3.1. Problem (Perl Cookbook)
12.7. Managing Instance Data (Programming Perl)
generating accesors with autoloading: 12.7.3. Generating Accessors with Autoloading (Programming Perl)
generating accessors with closures: 12.7.4. Generating Accessors with Closures (Programming Perl)
generating classes with Class::Struct: 12.7.2. Generating Classes with Class::Struct (Programming Perl)
new features, Perl 5.6: 12.7.6. New Tricks (Programming Perl)
using closures for private objects: 12.7.5. Using Closures for Private Objects (Programming Perl)
instance methods: 13.. Methods (Perl Cookbook)
13.. Some Notes on Object Terminology (Perl Cookbook)
7.4. Object Syntax (Perl in a Nutshell)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
APIs and: 9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
class methods and: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
invoking: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
Math::BigInt module: 12.4. A More Typical Object-Oriented Module: Math::BigInt (Learning Perl Objects, References and Modules)
object references as invocants for: 12.3. Method Invocation (Programming Perl)
OO modules and: 12.5. The Differences Between OO and Non-OO Modules (Learning Perl Objects, References and Modules)
parameters and: 9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
restricting to: 9.14. Restricting a Method to Class-Only or Instance-Only (Learning Perl Objects, References and Modules)
instance variables: 12.4.2. Initializers (Programming Perl)
defined: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
filehandles as: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
hash keys: 9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
object destruction and: 10. Object Destruction (Learning Perl Objects, References and Modules)
separate functions, writing for each: 12.7. Managing Instance Data (Programming Perl)
in subclasses: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
instances: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
accessors and: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
blessed references and: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
building: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
defined: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
hashes and: 9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
isa method testing: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
methods working with: 9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
instances of classes: 7.3. Object-Oriented Perl (Perl in a Nutshell)
InstMsi.exe: 2.3.2.1. ActivePerl (Perl in a Nutshell)
int( ): 5. Function Reference (Perl in a Nutshell)
2.2.3. Discussion (Perl Cookbook)
a href="../prog/ch29_02.htm#INDEX-4935"> 29.2.76. int (Programming Perl)
integer literals: 2.2.3. Integer Literals (Learning Perl)
integer module: 8.125. integer (Perl in a Nutshell)
integer pragma: 2.2.1. All Numbers Are the Same Format Internally (Learning Perl)
integers: 2.4.1. Problem (Perl Cookbook)
2.2.1. All Numbers Are the Same Format Internally (Learning Perl)
29.2.76. int (Programming Perl)
Glossary (Programming Perl)
computer storage, order of: 25.2. Endianness and Number Width (Programming Perl)
converting to UTF-8 characters: 15.2. Effects of Character Semantics (Programming Perl)
exponentiation: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
formats: 29.2.108. pack (Programming Perl)
formats for: 29.2.162. sprintf (Programming Perl)
integer truncation: 2.2.3. Discussion (Perl Cookbook)
IV (internal integer value): Glossary (Programming Perl)
IV (internal integer values): 21.2. Internal Data Types (Programming Perl)
IV typedef in C: 21.2. Internal Data Types (Programming Perl)
Math::BigInt module: 13. Overloading (Programming Perl)
standard modules for arithmetic with: 32.1.1. Data Types (Programming Perl)
strings as vectors of: 29.2.195. vec (Programming Perl)
interactivity, testing for: 15.2.1. Problem (Perl Cookbook)
intercept signals, handler for: 16.1. Signals (Programming Perl)
interfaces: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
byte vs. character semantics in: 15.1. Building Character (Programming Perl)
distribution considerations: 13. Writing a Distribution (Learning Perl Objects, References and Modules)
File::Basename module: 12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
maintenance considerations: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
version numbers and: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
interior sequences (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
internal integers: 2.2.1. All Numbers Are the Same Format Internally (Learning Perl)
internal redirection: 21.4.3. Discussion (Perl Cookbook)
internal variable names, Perl: 2.5. Names (Programming Perl)
internationalization: 2.1. Atoms (Programming Perl)
25.9. Internationalization (Programming Perl)
localization, first week of the year: 3.6.3. Discussion (Perl Cookbook)
modules for: 32.1.6. Internationalization and Locale (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
textual data, with Unicode: 15. Unicode (Programming Perl)
Unicode: 1.. Unicode Support in Perl (Perl Cookbook)
Internet (see also Web)
domain sockets: 17.. Introduction (Perl Cookbook)
protocols: 18.. Introduction (Perl Cookbook)
Internet-domain sockets: 15. Sockets (Perl in a Nutshell)
Internet protocols, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Internet services: 18.. Introduction (Perl Cookbook)
accessing LDAP server: 18.8.1. Problem (Perl Cookbook)
DNS lookups: 18.1.1. Problem (Perl Cookbook)
expn and vrfy programs: 18.16. Program: expn and vrfy (Perl Cookbook)
FTP client: 18.2.1. Problem (Perl Cookbook)
mail (see email)
pinging machines: 18.7.1. Problem (Perl Cookbook)
remote procedure calls: 18.. Introduction (Perl Cookbook)
simulating telnet connection: 18.6.1. Problem (Perl Cookbook)
SOAP client: 18.14.1. Problem (Perl Cookbook)
SOAP server: 18.13.1. Problem (Perl Cookbook)
Usenet news: 18.4.1. Problem (Perl Cookbook)
XML-RPC client: 18.12.1. Problem (Perl Cookbook)
XML-RPC server: 18.11.1. Problem (Perl Cookbook)
Internet services, CPAN modules for: 16.5. Sockets (Programming Perl)
Internet TCP clients/servers: 16.5.1. Networking Clients (Programming Perl)
interpolating variables
pattern matching, controlling with: 5.9.2. Variable Interpolation (Programming Perl)
interpolation
array variables: 2.6.5. Interpolating Array Values (Programming Perl)
backreference variables: 1.7.4. Backreferences (Programming Perl)
conditionals into patterns: 5.10.3.5. Conditional interpolation (Programming Perl)
double-quoted strings: 1.5.2. String Operators (Programming Perl)
double quotes ("), using: 5.2. Pattern-Matching Operators (Programming Perl)
functions: 14.2.2. Notational Convenience (Programming Perl)
glob operator, using for: 2.11.3. Filename Globbing Operator (Programming Perl)
list: 2.8. List Values and Arrays (Programming Perl)
match-time pattern interpolation: 5.10.3.4. Match-time pattern interpolation (Programming Perl)
scalar values: 2.6.2. String Literals (Programming Perl)
characters into double-quoted strings: 2.6.2. String Literals (Programming Perl)
variables
in double-quoted strings: 2.6.2. String Literals (Programming Perl)
into patterns: 5.2. Pattern-Matching Operators (Programming Perl)
interpolation of variables: 1.2.1.1. Singularities (Programming Perl)
interpolation, variable: Glossary (Programming Perl)
interpolative context: 2.7.4. Interpolative Context (Programming Perl)
interpreter, Perl: 3. The Perl Executable (Perl in a Nutshell)
18.3. Executing Your Code (Programming Perl)
18.3. Executing Your Code (Programming Perl)
Glossary (Programming Perl)
accessing from C: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
adding to C program: 21.4.2. Adding a Perl Interpreter to Your C Program (Programming Perl)
command-line options: 3.2. Command-Line Options (Perl in a Nutshell)
command processing: 3.1. Command Processing (Perl in a Nutshell)
compiler, interaction with: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
embedding in applications: 18.3. Executing Your Code (Programming Perl)
invoking with #! (shebang) line: 19.1. Command Processing (Programming Perl)
multiple, running: 18.3. Executing Your Code (Programming Perl)
persistent: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
interpreters: 1.2. Natural and Artificial Languages (Programming Perl)
for commands: 19.1. Command Processing (Programming Perl)
quoting on Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
object destruction at shutdown: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
threads: 17.1. The Process Model (Programming Perl)
interpreters, Perl: 1.3.1. How to Do It (Programming Perl)
interprocess communication: B.13.1. System V IPC (Learning Perl)
pipes: 16.3. Pipes (Programming Perl)
interprocess communication, functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
interrupt signals, handler for: 16.1. Signals (Programming Perl)
intersection of sets: 6.3. Passing References (Programming Perl)
intersections on lists: 4.8.1. Problem (Perl Cookbook)
4.9.1. Problem (Perl Cookbook)
ints: 29.2.108. pack (Programming Perl)
inverse_select( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
inverting arrays and hashes: 29.2.132. reverse (Programming Perl)
inverting hashes: 5.9.1. Problem (Perl Cookbook)
invocant: 13.. Methods (Perl Cookbook)
12.3. Method Invocation (Programming Perl)
Glossary (Programming Perl)
invocation arguments: 6.2. Input from the Diamond Operator (Learning Perl)
6.3. The Invocation Arguments (Learning Perl)
Catalog( ) (Win32::ODBC module): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
invoking (see executing)
invoking subroutines: 4.3. Invoking a Subroutine (Learning Perl)
I/O (input/output): 6. I/O Basics (Learning Perl)
6. I/O Basics (Learning Perl)
4.9.1. Perl 5.8 and PerlIO (Perl in a Nutshell)
Glossary (Programming Perl)
filehandles and: 11.1. What Is a Filehandle? (Learning Perl)
IO (internal I/O object): Glossary (Programming Perl)
Glossary (Programming Perl)
(see also indirect objects)
I/O layers: 7.. I/O Operations (Perl Cookbook)
7.19.3. Discussion (Perl Cookbook)
8.. I/O Layers (Perl Cookbook)
bytes: 8.. I/O Layers (Perl Cookbook)
crlf: 8.. I/O Layers (Perl Cookbook)
8.. I/O Layers (Perl Cookbook)
8.11.3. Discussion (Perl Cookbook)
raw: 8.. I/O Layers (Perl Cookbook)
8.11.3. Discussion (Perl Cookbook)
reading and writing Unicode from filehandles: 8.20.2. Solution (Perl Cookbook)
scalars: 8.23.3. Discussion (Perl Cookbook)
setting default: 8.19.1. Problem (Perl Cookbook)
stdio: 7.. I/O Operations (Perl Cookbook)
7.10.3. Discussion (Perl Cookbook)
unix: 7.. I/O Operations (Perl Cookbook)
7.19.3. Discussion (Perl Cookbook)
utf8: 8.. I/O Layers (Perl Cookbook)
IO module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO modules: 8.126. IO (Perl in a Nutshell)
IO::File module: 8.127. IO::File (Perl in a Nutshell)
IO::Handle module: 8.128. IO::Handle (Perl in a Nutshell)
IO::Pipe module: 8.129. IO::Pipe (Perl in a Nutshell)
IO::Seekable module: 8.130. IO::Seekable (Perl in a Nutshell)
8.131. IO::Select (Perl in a Nutshell)
IO::Socket module: 8.132. IO::Socket (Perl in a Nutshell)
I/O operations
access modes: 7.. I/O Operations (Perl Cookbook)
buffering: 7.. I/O Operations (Perl Cookbook)
7.19.3. Discussion (Perl Cookbook)
8.. Advanced Operations (Perl Cookbook)
17.3.3. Discussion (Perl Cookbook)
controlling for other programs: 16.8.1. Problem (Perl Cookbook)
flushing output: 7.19.1. Problem (Perl Cookbook)
non-blocking: 7.20.1. Problem (Perl Cookbook)
preprocessing input: 16.6.1. Problem (Perl Cookbook)
random-access I/O: 8.12.1. Problem (Perl Cookbook)
reading and writing to other programs: 16.4.1. Problem (Perl Cookbook)
ioctl( ): 5. Function Reference (Perl in a Nutshell)
7.21.2. Solution (Perl Cookbook)
12.17.3. Discussion (Perl Cookbook)
return values: 10.10.3. Discussion (Perl Cookbook)
29.2.77. ioctl (Programming Perl)
IO::Dir module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::File class: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
11.7. References to Filehandles (Learning Perl Objects, References and Modules)
IO::File module: 7.. Getting a Handle on the File (Perl Cookbook)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::Handle module: 7.5.3. Discussion (Perl Cookbook)
7.9.2. Solution (Perl Cookbook)
7.23.2. Solution (Perl Cookbook)
8.5.3. Discussion (Perl Cookbook)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::modules: 22.1. The CPAN modules Directory (Programming Perl)
IO::Multiplex module: 17.19.2. Solution (Perl Cookbook)
IO::Pipe module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::Poll module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::Pty module: 15.13.3. Discussion (Perl Cookbook)
16.3.3. Bidirectional Communication (Programming Perl)
IO::Seekable module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::Select module: 7.22.2. Solution (Perl Cookbook)
16.9.2. Solution (Perl Cookbook)
16.9.3. Discussion (Perl Cookbook)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
IO::Socket module: 15.2. The IO::Socket Module (Perl in a Nutshell)
IO::Socket::INET subclass: 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
IO::Socket::UNIX subclass: 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
IO::Socket::INET class: 17.1.2. Solution (Perl Cookbook)
IO::Socket::INET module: 16.5.1. Networking Clients (Programming Perl)
32.1.8. Networking and Interprocess Communication (Programming Perl)
IO::Socket::SSL module: 20.16.3. Discussion (Perl Cookbook)
IO::Socket::UNIX module: 17.6.2. Solution (Perl Cookbook)
32.1.8. Networking and Interprocess Communication (Programming Perl)
IO::Stty module: 15.13.3. Discussion (Perl Cookbook)
IO::Tee module: 7.8.3. Discussion (Perl Cookbook)
IP addresses
determining your own: 17.8.1. Problem (Perl Cookbook)
DNS lookups: 18.1.1. Problem (Perl Cookbook)
expn and vrfy programs: 18.16. Program: expn and vrfy (Perl Cookbook)
identifying socket ends: 17.7.1. Problem (Perl Cookbook)
multihomed servers: 17.16.1. Problem (Perl Cookbook)
network names and: 29.2.53. getnetent (Programming Perl)
packed, converting to ASCII strings: 17.. Introduction (Perl Cookbook)
using v-string notation for: 29.2.47. gethostbyaddr (Programming Perl)
UTF-8 representation of: 15.1. Building Character (Programming Perl)
IP addresses, hashes and: 5.1.1. Why Use a Hash? (Learning Perl)
IP (Internet Protocol): 16.5. Sockets (Programming Perl)
Glossary (Programming Perl)
-ipadx, -ipady options
grid geometry manager: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
pack geometry manager: 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
IPC: B.13. Networking and IPC (Learning Perl)
IPC (interprocess communication): 16. Interprocess Communication (Programming Perl)
between processes on same machine: 16. Interprocess Communication (Programming Perl)
modules for: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
32.1.8. Networking and Interprocess Communication (Programming Perl)
portability and: 25.5. Interprocess Communication (IPC) (Programming Perl)
signals: 16.1. Signals (Programming Perl)
IPC modules: 8.133. IPC::Msg (Perl in a Nutshell)
IPC::Msg module: 8.133. IPC::Msg (Perl in a Nutshell)
IPC::Open3 module: 8.135. IPC::Open3 (Perl in a Nutshell)
IPC::Semaphore module: 8.136. IPC::Semaphore (Perl in a Nutshell)
IPC::SysV module: 8.137. IPC::SysV (Perl in a Nutshell)
IPC::Msg module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
IPC::Open3: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
IPC::Open2 module: 16.8.2. Solution (Perl Cookbook)
32.1.8. Networking and Interprocess Communication (Programming Perl)
IPC::Semaphore module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
IPC::Shareable module: 16.12.3. Discussion (Perl Cookbook)
16.4. System V IPC (Programming Perl)
IPC::SysV module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
irregular files: 1.5.7. Some File Test Operators (Programming Perl)
is-a: Glossary (Programming Perl)
is function (Test::More): 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
@ISA variable
features: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
inheritance hierarchies and: 11.1. UNIVERSAL Methods (Learning Perl Objects, References and Modules)
multiple inheritance: 11.6. Multiple Inheritance (Learning Perl Objects, References and Modules)
isa( ): 13.9.3. Discussion (Perl Cookbook)
@ISA array: 12.5. Class Inheritance (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
inheritance through: 12.5.1. Inheritance Through @ISA (Programming Perl)
use base pragma and: 31.3. use base (Programming Perl)
isa method: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
isa method (UNIVERSAL): 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
isany method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
isa_ok function (Test::More): 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
ischoice method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
is_client_error( ) (HTTP::Status: 20.3.4. HTTP::Status (Perl in a Nutshell)
is_empty( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
isempty method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
is_error( )
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
HTTP::Status module: 20.3.4. HTTP::Status (Perl in a Nutshell)
LWP::Simple module: 20.2.2. LWP::Simple (Perl in a Nutshell)
is_fresh( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
20.3.2. HTTP::Response (Perl in a Nutshell)
isindex( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
is_info( )
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
HTTP::Status module: 20.3.4. HTTP::Status (Perl in a Nutshell)
is_inside( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
ismixed method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
isname method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
isnt function (Test::More): 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
is_numeric( ): 2.1.3. Discussion (Perl Cookbook)
is_protocol_supported( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
is_readonly( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
is_redirect( )
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
HTTP::Status module: 20.3.4. HTTP::Status (Perl in a Nutshell)
is_safe( ): 8.17.3. Discussion (Perl Cookbook)
isseq method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
is_server_error( ) (HTTP::Status: 20.3.4. HTTP::Status (Perl in a Nutshell)
is_success( )
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
HTTP::Status module: 20.3.4. HTTP::Status (Perl in a Nutshell)
LWP::Simple module: 20.2.2. LWP::Simple (Perl in a Nutshell)
=item command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
item tags (Canvas widgets): 21.12.2. Item Tags and IDs (Perl in a Nutshell)
Item( ) (Win32::OLE::Enum): 23.3. Win32::OLE::Enum (Perl in a Nutshell)
itemcget( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
itemconfigure( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
iteration: 4.4.4. Loop Control (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also loops)
iteration versus recursion: 7.5. Recursively Defined Data (Learning Perl Objects, References and Modules)
iterations, next and redo operators for: 10.8.2. The next Operator (Learning Perl)
iterative operator, overloading: 13.3. Overloadable Operators (Programming Perl)
iterative statements: 1.6.2. Iterative (Looping) Constructs (Programming Perl)
for loops: 1.6.2.2. The for statement (Programming Perl)
foreach statement: 1.6.2.3. The foreach statement (Programming Perl)
until statements: 1.6.2.1. The while and until statements (Programming Perl)
while loops: 1.6.2.1. The while and until statements (Programming Perl)
iterator variables: 4.5.3. Discussion (Perl Cookbook)
ithreads: 17.1. The Process Model (Programming Perl)
Perl API to: 18.3. Executing Your Code (Programming Perl)
itimer routines: 29.2.3. alarm (Programming Perl)
IV (internal integer value): 21.2. Internal Data Types (Programming Perl)
Glossary (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAPH (Just Another Perl Hacker): Glossary (Programming Perl)
Java, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
JavaScript features with CGI.pm: 10.5. Using JavaScript Features (Perl in a Nutshell)
Johnson, Kevin: 16. Email Connectivity (Perl in a Nutshell)
16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
join( ): 5. Function Reference (Perl in a Nutshell)
using reverse( ) with: 1.7.2. Solution (Perl Cookbook)
9.8. The join Function (Learning Perl)
29.2.78. join (Programming Perl)
join method: 17.2.1.2. Thread destruction (Programming Perl)
catching exceptions from: 17.2.1.3. Catching exceptions from join (Programming Perl)
-jump option (Scrollbar): 21.9. The Scrollbar Widget (Perl in a Nutshell)
jumpenv stack: 18.3. Executing Your Code (Programming Perl)
justification: 7. Formats (Programming Perl)
-justify option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

-k file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
-k (sticky) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
kernels
autoreaping zombies on: 16.1.2. Reaping Zombies (Programming Perl)
generating signals: 16.1. Signals (Programming Perl)
signal reliability on: 16.1.2. Reaping Zombies (Programming Perl)
threads and: 17.2. The Thread Model (Programming Perl)
Unix, set-id script bug in: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
key mapping, pseudohashes: 12.7.1. Field Declarations with use fields (Programming Perl)
key-value pairs: 5.1. What Is a Hash? (Learning Perl)
keyboard input: 15.11.1. Problem (Perl Cookbook)
checking for: 15.9.1. Problem (Perl Cookbook)
keyboard sequences, generating signals with: 16.1. Signals (Programming Perl)
keys( ): 5. Function Reference (Perl in a Nutshell)
5.5.2. Solution (Perl Cookbook)
5.12.2. Solution (Perl Cookbook)
hashes
ordering elements: 5.7.1. Problem (Perl Cookbook)
presizing: 5.14.2. Solution (Perl Cookbook)
sorting: 5.10.2. Solution (Perl Cookbook)
traversing: 5.5.3. Discussion (Perl Cookbook)
5.3.1. The keys and values Functions (Learning Perl)
1.8. List Processing (Programming Perl)
2.9. Hashes (Programming Perl)
14.3.1. Hash-Tying Methods (Programming Perl)
29.2.79. keys (Programming Perl)
key/value pairs:
1.2.1.2.2. Hashes. (Programming Perl)
Glossary (Programming Perl)
2.3. Built-in Data Types (Programming Perl)
2.9. Hashes (Programming Perl)
deleting: 14.3. Tying Hashes (Programming Perl)
modules, %INC hash: 11.1. Using Modules (Programming Perl)
organizing and accessing data in: 9.1.5. Common Mistakes (Programming Perl)
returning with each function: 29.2.30. each (Programming Perl)
symbol tables: 10.1. Symbol Tables (Programming Perl)
keywords (see reserved words)
keywords( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
kill( ): 5. Function Reference (Perl in a Nutshell)
kill command: 16.13.2. Solution (Perl Cookbook)
listing available signals: 16.13.1. Problem (Perl Cookbook)
sending signals: 16.14.1. Problem (Perl Cookbook)
kill function: 16.1. Signals (Programming Perl)
16.1. Signals (Programming Perl)
29.2.80. kill (Programming Perl)
Microsoft systems and: 16.1.1. Signaling Process Groups (Programming Perl)
Kill( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
Koenig, Andreas: 2.1. The CPAN Architecture (Perl in a Nutshell)
Kolinko, Paul: 14.2. SOAP::Lite (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

-l (automatic line ending) command-line switch: 19.1.3. Switches (Programming Perl)
\\\\L (lowercase) characters: 4.6.4. Character Classes (Perl in a Nutshell)
l command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-l file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
L<\\> interior sequence (pod): 4.13.2. Interior Sequences (Perl in a Nutshell)
-l option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
-l option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-L option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
\\\\l shortcut: 9.6.5. Case Shifting (Learning Perl)
\l string escape: 1.13.2. Solution (Perl Cookbook)
-l (symbolic link) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-label option
Frame widget: 21.17. The Frame Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Label widget (Perl/Tk): 21.7. The Label Widget (Perl in a Nutshell)
label_exists( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
-labelPack option (Frame): 21.17. The Frame Widget (Perl in a Nutshell)
labels: 10.8.4. Labeled Blocks (Learning Perl)
4.2. Compound Statements (Programming Perl)
4.4.4. Loop Control (Programming Perl)
Glossary (Programming Perl)
with goto statement: 4.6. goto (Programming Perl)
29.2.71. goto (Programming Perl)
loops: 4.3.1.5. Loop control (Perl in a Nutshell)
loops and: Glossary (Programming Perl)
names for: 2.5. Names (Programming Perl)
packages and: 10. Packages (Programming Perl)
statement blocks: 4.3. Statements (Perl in a Nutshell)
labels, menu: 15.14.3. Discussion (Perl Cookbook)
-labelVariable option (Frame): 21.17. The Frame Widget (Perl in a Nutshell)
language extensions, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
languages
checking characters for: 5.4.3.3. Unicode block properties (Programming Perl)
natural vs. artificial: 1.2. Natural and Artificial Languages (Programming Perl)
translating: 24.5.2. Generating Perl in Other Languages (Programming Perl)
large numbers: B.9.3. Large and High-Precision Numbers (Learning Perl)
Larry (see Wall, Larry)
last( ): 5. Function Reference (Perl in a Nutshell)
Net::NNTP module: 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
4.13.2. Solution (Perl Cookbook)
4.3.1.5. Loop control (Perl in a Nutshell)
do {} while construct, not taking: 24.1.3. C Traps (Programming Perl)
last found occurrence of a substring, rindex function for: 15.1. Finding a Substring with index (Learning Perl)
last function: 24.3. Programming with Style (Programming Perl)
last index (Menu widget): 21.15.1. Menu Indexes (Perl in a Nutshell)
last operator: 10.8.1. The last Operator (Learning Perl)
1.6.2.4. Breaking out: next and last (Programming Perl)
4.4.2. for Loops (Programming Perl)
4.4.4. Loop Control (Programming Perl)
4.4.4. Loop Control (Programming Perl)
4.5.1. Case Structures (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.81. last (Programming Perl)
used in a do while: 4.5. Bare Blocks (Programming Perl)
LastError( ) (Win32::OLE): 23.2.1. Win32::OLE Methods (Perl in a Nutshell)
last_labeled_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
last_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
laston program: 8.26. Program: laston (Perl Cookbook)
$LAST_PAREN_MATCH: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$LAST_PAREN_MATCH ($+) variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
LaTeX, translating pod to: 4.13.3. Pod Utilities (Perl in a Nutshell)
laziness: Glossary (Programming Perl)
lc( ): 5. Function Reference (Perl in a Nutshell)
1.13.2. Solution (Perl Cookbook)
29.2.82. lc (Programming Perl)
lcfirst( ): 5. Function Reference (Perl in a Nutshell)
1.13.2. Solution (Perl Cookbook)
29.2.83. lcfirst (Programming Perl)
LDAP (Lightweight Directory Access Protocol): 18.8.1. Problem (Perl Cookbook)
19. Lightweight Directory Access with Net::LDAP (Perl in a Nutshell)
Net::LDAP, searching with: 19.2. Searching an LDAP Directory with Net::LDAP (Perl in a Nutshell)
server: 18.8.1. Problem (Perl Cookbook)
modify( ) and: 18.8.3. Discussion (Perl Cookbook)
search( ) and: 18.8.3. Discussion (Perl Cookbook)
LDAPm (Lightweight Directory Access Protocol)
data structure: 19.1. How Data Is Stored in LDAP (Perl in a Nutshell)
LDIF (LDAP Directory Interchange Format): 19.1. How Data Is Stored in LDAP (Perl in a Nutshell)
le (less-than-or-equal) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
leading whitespace, removing: 1.19.1. Problem (Perl Cookbook)
leading zero: 2.2.4. Nondecimal Integer Literals (Learning Perl)
left angle bracket (<)
file-access modes: 7.. I/O Operations (Perl Cookbook)
7.1.3. Discussion (Perl Cookbook)
<&= and <& open modes: 7.9.2. Solution (Perl Cookbook)
<FH> line input operator: 7.. I/O Operations (Perl Cookbook)
<=> numerical comparison operator: 4.15.2. Solution (Perl Cookbook)
left justification: 7.1. Format Variables (Programming Perl)
-left option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
left-shift (<<) operator: 3.9. Shift Operators (Programming Perl)
leftmost longest matching: 5.5. Quantifiers (Programming Perl)
Glossary (Programming Perl)
-leftspring option form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
length( ): 5. Function Reference (Perl in a Nutshell)
LENGTH (awk variable): 28.2. Special Variables in Alphabetical Order (Programming Perl)
length function: 16.3. Fixed-length Random-access Databases (Learning Perl)
29.2.84. length (Programming Perl)
byte-oriented wrapper for: 15.2. Effects of Character Semantics (Programming Perl)
length, matching: 5.5. Quantifiers (Programming Perl)
-length option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
less module: 8.138. less (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
less-than (<, lt) operators: 4.5.4.1. Relational operators (Perl in a Nutshell)
less than (<) operator: 3.11. Relational Operators (Programming Perl)
less-than-or-equal (<, le) operators: 4.5.4.1. Relational operators (Perl in a Nutshell)
less than or equal (<=) operator: 3.11. Relational Operators (Programming Perl)
less-than sign (<) for opening files: 11.2. Opening a Filehandle (Learning Perl)
lexer: 18.2. Compiling Your Code (Programming Perl)
Glossary (Programming Perl)
lexical analysis: 21.1. How Perl Works (Programming Perl)
Glossary (Programming Perl)
in the Perl compiler: 18.2. Compiling Your Code (Programming Perl)
lexical scope: 10.2.3. Discussion (Perl Cookbook)
4.8.2. Lexically Scoped Variables: my (Programming Perl)
pragmas and: 4.9. Pragmas (Programming Perl)
lexical scopes: 2.5. Names (Programming Perl)
Glossary (Programming Perl)
package variables, searching for: 2.5.1. Name Lookups (Programming Perl)
variables attached to: 2.5. Names (Programming Perl)
lexical scoping: 4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
lexical variables: 4.6. Private Variables in Subroutines (Learning Perl)
4.9. Notes on Lexical (my) Variables (Learning Perl)
7. Formats (Programming Perl)
29.2.99. my (Programming Perl)
Glossary (Programming Perl)
accessing from functions: 6.2.3. Scoping Issues (Programming Perl)
closures and: 6.4. Closures (Learning Perl Objects, References and Modules)
6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
data destruction and: 10. Object Destruction (Learning Perl Objects, References and Modules)
defined: 2.3. Using do (Learning Perl Objects, References and Modules)
file-scoped, storing anonymous subroutine in: 12.5.5. Private Methods (Programming Perl)
in functions or files, showing: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
@ISA and: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
packages and: 2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
persistence across function calls: 6.2.3. Scoping Issues (Programming Perl)
recursive lexical pad stack: 18.3. Executing Your Code (Programming Perl)
reference longevity: 4.1. More than One Reference to Data (Learning Perl Objects, References and Modules)
subroutine references: 6.4. Closures (Learning Perl Objects, References and Modules)
6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
symbolic references and: 8.4. Symbolic References (Programming Perl)
threads, accessing in: 17.2.2. Data Access (Programming Perl)
typed: Glossary (Programming Perl)
lexical warnings: 2.4. Perl's Built-in Warnings (Learning Perl)
32.1.15. Warnings and Exceptions (Programming Perl)
${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order (Programming Perl)
lexically scoped declarations: 4.8. Scoped Declarations (Programming Perl)
lexicals: 4.8.1. Scoped Variable Declarations (Programming Perl)
(see also lexical scope)
lib module: 8.139. lib (Perl in a Nutshell)
32.1.17. Module Installation Support (Programming Perl)
lib pragma: B.6.3. The lib Pragma (Learning Perl)
11.1. Using Modules (Programming Perl)
lib-win32 library: 22. Win32 Modules and Extensions (Perl in a Nutshell)
lib-www-perl file: 20. The LWP Library (Perl in a Nutshell)
libnet modules: 16. Email Connectivity (Perl in a Nutshell)
libraries: 12.. Other Kinds of Library Files (Perl Cookbook)
B.4.1. Libraries (Learning Perl)
Glossary (Programming Perl)
alternate installation locations: 13.6. Alternate Installation Locations (PREFIX=...) (Learning Perl Objects, References and Modules)
13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
C/C++, loading as Perl extensions: 32.1.17. Module Installation Support (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
DBM: 14.. Introduction (Perl Cookbook)
ExtUtils::Liblist module: 32.1.17. Module Installation Support (Programming Perl)
libxml2: 22.. History of Perl and XML (Perl Cookbook)
22.5.3. Discussion (Perl Cookbook)
loading only once: 2.4. Using require (Learning Perl Objects, References and Modules)
math library, C: 21.3.4. Using Functions from an External C Library (Programming Perl)
OpenSSL: 20.16.3. Discussion (Perl Cookbook)
Perl, installing modules into: 22.2.3. Installing CPAN Modules into the Perl Library (Programming Perl)
Perl library files, searching for: 19.2. Environment Variables (Programming Perl)
permissions: 19.3.3.3. Is the script valid Perl? (Perl Cookbook)
search path for: 2.5. require and @INC (Learning Perl Objects, References and Modules)
uninstalled extensions from MakeMaker: 32.1.17. Module Installation Support (Programming Perl)
library modules, functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
libwww-perl modules: 20.. Introduction (Perl Cookbook)
libxml2 library: 22.. History of Perl and XML (Perl Cookbook)
22.5.3. Discussion (Perl Cookbook)
licenses for Perl: 1.3. How Can I Get Perl? (Learning Perl)
embedding code snippets and: B.24. Embedding (Learning Perl)
licensing: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
life cycle, Perl programs: 18.1. The Life Cycle of a Perl Program (Programming Perl)
code generation phase: 18.1. The Life Cycle of a Perl Program (Programming Perl)
compilation phase: 18.1. The Life Cycle of a Perl Program (Programming Perl)
execution phase: 18.1. The Life Cycle of a Perl Program (Programming Perl)
parse tree reconstruction: 18.1. The Life Cycle of a Perl Program (Programming Perl)
LIFO (Last In, First Out): Glossary (Programming Perl)
Lightweight Directory Access Protocol (see LDAP)
like function (Test::More): 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
__LINE__; setting: 24.5.2. Generating Perl in Other Languages (Programming Perl)
line breaks
extracting ranges of lines: 6.8.1. Problem (Perl Cookbook)
lines in files
counting: 8.2.1. Problem (Perl Cookbook)
deleting last: 8.10.1. Problem (Perl Cookbook)
randomizing order: 8.7.1. Problem (Perl Cookbook)
selecting random: 8.6.1. Problem (Perl Cookbook)
matching within multiple lines: 6.6.1. Problem (Perl Cookbook)
reading files backwards: 8.4.1. Problem (Perl Cookbook)
reading with continuation characters: 8.1.1. Problem (Perl Cookbook)
_ _LINE_ _ constant: 4.4.4. Global Special Constants (Perl in a Nutshell)
line counter (see $. variable)
line-end processing, automatic: 19.1.3. Switches (Programming Perl)
LINE: (implicit loop label): 7.14.3.2. Command-line options (Perl Cookbook)
line-input <...\\> operator: 4.9. Filehandles (Perl in a Nutshell)
line input operator: 7.. I/O Operations (Perl Cookbook)
8.. Basic Operations (Perl Cookbook)
line-input operators: 2.8. Getting User Input (Learning Perl)
2.8. Getting User Input (Learning Perl)
6.2. Input from the Diamond Operator (Learning Perl)
11.4. Using Filehandles (Learning Perl)
line mode interfaces: 15.. Introduction (Perl Cookbook)
line number: 2.6.8. Other Literal Tokens (Programming Perl)
die function and: 11.3. Fatal Errors with die (Learning Perl)
warn function and: 11.3.1. Warning Messages with warn (Learning Perl)
line numbers: Glossary (Programming Perl)
of input file: 28.2. Special Variables in Alphabetical Order (Programming Perl)
line-oriented quoting: 2.6.6. "Here" Documents (Programming Perl)
line reading operator: 1.4. Filehandles (Programming Perl)
line separator character: 2.2. Molecules (Programming Perl)
__LINE__ symbol: 10.4.3. Discussion (Perl Cookbook)
line terminators, Internet programs: 16.5.2. Networking Servers (Programming Perl)
__LINE__ token: 2.6.8. Other Literal Tokens (Programming Perl)
LineInfo option (debugger): 20.3.3. Debugger Options (Programming Perl)
LineInfo option (PERLDB_OPTS): 6.4. Customizing the Debugger (Perl in a Nutshell)
lines: Glossary (Programming Perl)
boundary assertions: 5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
counting in files: 8.2.1. Problem (Perl Cookbook)
reading files backward by: 8.4.1. Problem (Perl Cookbook)
single, extracting from file: 8.8.1. Problem (Perl Cookbook)
@lines array variable: 1.5. A Whirlwind Tour of Perl (Learning Perl)
linestart, lineend modifiers (Text widget): 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
Lingua::EN::Inflect module: 2.17.2. Solution (Perl Cookbook)
link( ): 5. Function Reference (Perl in a Nutshell)
link count: 13.3. Links and Files (Learning Perl)
link function: 13.3. Links and Files (Learning Perl)
29.2.85. link (Programming Perl)
links: 20.3.3. Discussion (Perl Cookbook)
13.3. Links and Files (Learning Perl)
29.2.123. readlink (Programming Perl)
Glossary (Programming Perl)
HTTP, searching for: 1.7. Regular Expressions (Programming Perl)
number of ($nlink): 11.6.1. The stat and lstat Functions (Learning Perl)
links( ), extracting URLs: 20.3.3. Discussion (Perl Cookbook)
Lint backend (Perl compiler): 3.4. The Perl Compiler (Perl in a Nutshell)
lint (C program verifier): 18.6. Code Development Tools (Programming Perl)
Linux, installing Perl and: 2.3.1. Installing on Unix (Perl in a Nutshell)
List( )
Win32::Internet module: 22.7.2. FTP Functions (Perl in a Nutshell)
list active command (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
list assignment: 1.3.2. Solution (Perl Cookbook)
list context: 3.8. Scalar and List Context (Learning Perl)
4.2.6. Scalar and List Contexts (Perl in a Nutshell)
1.8. List Processing (Programming Perl)
2.7.1. Scalar and List Context (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
angle operator in: 2.11.2. Line Input (Angle) Operator (Programming Perl)
backslash operator, supplying: 8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
comma operator in: 3.18. Comma Operators (Programming Perl)
conditional operator in: 3.16. Conditional Operator (Programming Perl)
evaluating expressions in (debugger): 20.2.4. Display (Programming Perl)
expressions in (see LISTs)
forcing scalar context instead: 29.2.137. scalar (Programming Perl)
foreach statements, providing: 1.6.2.3. The foreach statement (Programming Perl)
functions in: 29. Functions (Programming Perl)
hash variables, using in: 2.9. Hashes (Programming Perl)
hashes in: 1.2.1.2.2. Hashes. (Programming Perl)
list assignment in: 3.17. Assignment Operators (Programming Perl)
lvalues in: 4.8.1. Scoped Variable Declarations (Programming Perl)
m// (match) operator in: 5.2.2. The m// Operator (Matching) (Programming Perl)
m//g, listing all matches found: 5.2.2. The m// Operator (Matching) (Programming Perl)
operations behaving differently in: 24.1.2. Frequently Ignored Advice (Programming Perl)
range (..) operator in: 3.15. Range Operator (Programming Perl)
recognizing in debugger: 20.1. Using the Debugger (Programming Perl)
return values and: 4.4. Return Values (Learning Perl)
subroutines, calling and evaluating in: 6.2. Semantics (Programming Perl)
using backquotes in: 14.4.1. Using Backquotes in a List Context (Learning Perl)
list context, detecting: 10.6.1. Problem (Perl Cookbook)
list literals: 3.3. List Literals (Learning Perl)
list method current thread objects in process: 17.2.1.6. Listing current threads (Programming Perl)
list operators: 4.5. Operators (Perl in a Nutshell)
3. Unary and Binary Operators (Programming Perl)
3.1. Terms and List Operators (Leftward) (Programming Perl)
3.19. List Operators (Rightward) (Programming Perl)
Glossary (Programming Perl)
unary operators, distinguishing from: 3.10. Named Unary and File Test Operators (Programming Perl)
list prototype symbol (@): 4.7.5. Prototypes (Perl in a Nutshell)
list values
arrays and: 2.8. List Values and Arrays (Programming Perl)
arrays vs.: 2.8. List Values and Arrays (Programming Perl)
list_all_labels( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
Listbox widget (Perl/Tk): 21.10. The Listbox Widget (Perl in a Nutshell)
listen( ): 5. Function Reference (Perl in a Nutshell)
Socket module: 15.1. Built-in Socket Functions (Perl in a Nutshell)
15.1.3. Server Connections (Perl in a Nutshell)
listen function: 29.2.86. listen (Programming Perl)
Listen option
IO::Socket::INET module: 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
IO::Socket::UNIX module: 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
listgroup( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
listing code: 20.2.5. Locating Code (Programming Perl)
list_labels( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
LISTs: 1.8. List Processing (Programming Perl)
4.2. Compound Statements (Programming Perl)
$LIST_SEPARATOR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$LIST_SEPARATOR ($") variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
LISTs===>lists: 1.8. List Processing (Programming Perl)
List::Util module: 8.140. List::Util (Perl in a Nutshell)
literal strings (see string literals)
literals: 2.2.2. Floating-Point Literals (Learning Perl)
5.1. The Regular Expression Bestiary (Programming Perl)
Glossary (Programming Perl)
numeric (see numeric literals)
pseudoliterals (see input operators)
string (see string literals)
UTF-8, enabling use in: 15.2. Effects of Character Semantics (Programming Perl)
little arrow (->): 5.2.3. The Big Arrow (Learning Perl)
in method names: 13.8.3. The File::Spec Module (Learning Perl)
little-endian: 25.2. Endianness and Number Width (Programming Perl)
Glossary (Programming Perl)
Llama book: 1. Introduction (Learning Perl)
1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
.lnk files: 22.18. Win32::Shortcut (Perl in a Nutshell)
Load( )
Win32::OLE::Const module: 23.5. Win32::OLE::Const (Perl in a Nutshell)
Win32::Registry module: 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
Win32::Shortcut module: 22.18. Win32::Shortcut (Perl in a Nutshell)
loading data structures: 9.6.3. Generation of a Hash of Complex Records (Programming Perl)
loading functions
AutoLoader module: 8.5. AutoLoader (Perl in a Nutshell)
DynaLoader module: 8.61. DynaLoader (Perl in a Nutshell)
SelfLoader module: 8.184. SelfLoader (Perl in a Nutshell)
loading modules: 12.10.1. Problem (Perl Cookbook)
with mod_perl: 21.14.1. Problem (Perl Cookbook)
local( ): 5. Function Reference (Perl in a Nutshell)
global values: 10.13.3.1. Using local( ) for temporary values for globals (Perl Cookbook)
overriding signal handlers: 16.16.2. Solution (Perl Cookbook)
redefining functions: 10.14.2. Solution (Perl Cookbook)
signals, and: 4.10. Signals (Perl in a Nutshell)
local declaration: 29.2.87. local (Programming Perl)
local function: 4.8.1. Scoped Variable Declarations (Programming Perl)
4.8.2. Lexically Scoped Variables: my (Programming Perl)
29.2.87. local (Programming Perl)
common programming errors with: 24.1.1. Universal Blunders (Programming Perl)
my declaration, using instead of: 24.1.2. Frequently Ignored Advice (Programming Perl)
local operator: 10.13.2. Solution (Perl Cookbook)
4.7. The local Operator (Learning Perl)
global variables, using on: 4.8.4. Dynamically Scoped Variables: local (Programming Perl)
Local option (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
local variables: 4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
LocalAddr option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
locale, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
locale module: 8.141. locale (Perl in a Nutshell)
32.1.6. Internationalization and Locale (Programming Perl)
locale settings: 6.12.1. Problem (Perl Cookbook)
locales: B.30. Locales and Unicode (Learning Perl)
decimal points in formats: 7. Formats (Programming Perl)
declarations, string comparisons and: 3.11. Relational Operators (Programming Perl)
modules for: 32.1.6. Internationalization and Locale (Programming Perl)
Perl character class shortcuts and: 5.4.2. Classic Perl Character Class Shortcuts (Programming Perl)
Unicode and: 29.2.82. lc (Programming Perl)
use locale pragma with POSIX character classes: 5.4.4. POSIX-Style Character Classes (Programming Perl)
localization: 22.1. The CPAN modules Directory (Programming Perl)
(see also locale)
localized values, saving: 18.3. Executing Your Code (Programming Perl)
localizing functions: 10.14.1. Problem (Perl Cookbook)
LocalPort option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
localtime( ): 5. Function Reference (Perl in a Nutshell)
3.. Introduction (Perl Cookbook)
3.8.2. Solution (Perl Cookbook)
calculating days: 3.6.2. Solution (Perl Cookbook)
Time::localtime/Time::gmtime: 3.. Introduction (Perl Cookbook)
today's date: 3.1.2. Solution (Perl Cookbook)
localtime function: 11.6.2. The localtime Function (Learning Perl)
29.2.88. localtime (Programming Perl)
32.1.1. Data Types (Programming Perl)
32.1.7. Operating System Interfaces (Programming Perl)
text databases and: 16.4. Variable-length (Text) Databases (Learning Perl)
lock function
data access control in threads: 17.2.2.1. Synchronizing access with lock (Programming Perl)
reference as argument for: 8.1. What Is a Reference? (Programming Perl)
lockarea program: 7.25. Program: lockarea (Perl Cookbook)
locked attribute: 8.3. attributes (Perl in a Nutshell)
12.7.6. New Tricks (Programming Perl)
locked attribute, subroutines: 17.2.2.4. The locked attribute (Programming Perl)
locking: 29.2.89. lock (Programming Perl)
blocking signals: 16.20.1. Problem (Perl Cookbook)
files: 7.18.1. Problem (Perl Cookbook)
advisory locking: 7.18.2. Solution (Perl Cookbook)
netlock program: 7.24. Program: netlock (Perl Cookbook)
region-specific locks: 7.25. Program: lockarea (Perl Cookbook)
locking files: 16.2.1. File Locking (Programming Perl)
DBM files: 16.2.1. File Locking (Programming Perl)
29.2.22. dbmopen (Programming Perl)
dissolving locks by closing files: 16.2.1. File Locking (Programming Perl)
flock function: 29.2.39. flock (Programming Perl)
shared and exclusive locks: 16.2.1. File Locking (Programming Perl)
locking methods: 17.2.2.5. Locking methods (Programming Perl)
locking subroutines: 17.2.2.3. Locking subroutines (Programming Perl)
log( ): 5. Function Reference (Perl in a Nutshell)
log10( ): 2.12.2. Solution (Perl Cookbook)
log files
(see also logging)
web server: 20.12.1. Problem (Perl Cookbook)
processing: 20.13.1. Problem (Perl Cookbook)
log files, filehandles and: 11.2. Opening a Filehandle (Learning Perl)
11.4.1. Changing the Default Output Filehandle (Learning Perl)
log function: 29.2.90. log (Programming Perl)
-log option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
logarithm: B.9.1. Advanced Math Functions (Learning Perl)
29.2.90. log (Programming Perl)
logarithms: 2.12.1. Problem (Perl Cookbook)
log_base( ): 2.12.3. Discussion (Perl Cookbook)
LOGDIR variable: 3.3. Environment Variables (Perl in a Nutshell)
19.2. Environment Variables (Programming Perl)
Logfile::Apache module: 20.13.3. Discussion (Perl Cookbook)
logfiles, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
logging
customizing Apache logging requests: 21.9.1. Problem (Perl Cookbook)
port connection attempts: 17.20. Program: backsniff (Perl Cookbook)
server logs, processing: 20.13.3. Discussion (Perl Cookbook)
logical
AND (&&) operator: 3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
negation (!) operator: 3.5. Ideographic Unary Operators (Programming Perl)
operators: 3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
logical functionality in patterns: 6.18.1. Problem (Perl Cookbook)
logical operators: 10.9. Logical Operators (Learning Perl)
4.5.9. Logical Operators (Perl in a Nutshell)
1.5.5. Logical Operators (Programming Perl)
Glossary (Programming Perl)
or operator
use with list operators: 4.7. Global Declarations (Programming Perl)
overloading: 13.3. Overloadable Operators (Programming Perl)
Perl, doing alternation: 5.9.1. Letting Perl Do the Work (Programming Perl)
precedence of: 12.3.3. Syntactic Snafus with Indirect Objects (Programming Perl)
login( )
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Net::Netrc module: 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
POP3 server: 18.5.3. Discussion (Perl Cookbook)
login entries (.netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
login names
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
getgrent function: 29.2.44. getgrent (Programming Perl)
getgrgid function, returning: 29.2.45. getgrgid (Programming Perl)
getgrnam function, returning: 29.2.46. getgrnam (Programming Perl)
getlogin function for: 29.2.50. getlogin (Programming Perl)
login sessions: 15.. Introduction (Perl Cookbook)
long longs: 29.2.108. pack (Programming Perl)
longs: 29.2.108. pack (Programming Perl)
look command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
lookahead: 5.10.1. Lookaround Assertions (Programming Perl)
Glossary (Programming Perl)
lookaround: 5.10.1. Lookaround Assertions (Programming Perl)
lookbehind: 5.10.1. Lookaround Assertions (Programming Perl)
Glossary (Programming Perl)
looks_like_number( ): 2.1.3. Discussion (Perl Cookbook)
lookup( ) (Net::Netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
loop blocks: 10.8.1. The last Operator (Learning Perl)
10.8.2. The next Operator (Learning Perl)
labels for: 10.8.4. Labeled Blocks (Learning Perl)
loop controls: 10.8. Loop Controls (Learning Perl)
loop variables: 4.5.3. Discussion (Perl Cookbook)
looping (code structure): 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
looping (data structure): 4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
loops: 2.10. The while Control Structure (Learning Perl)
4.3.1. Conditionals and Loops (Perl in a Nutshell)
1.6.2. Iterative (Looping) Constructs (Programming Perl)
4.4. Loop Statements (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
24.3. Programming with Style (Programming Perl)
Glossary (Programming Perl)
comments and blank lines, discarding before processing: 5.9.1. Letting Perl Do the Work (Programming Perl)
control operators for: 4.4.4. Loop Control (Programming Perl)
control statements in: Glossary (Programming Perl)
endless, stopping: 2.10. The while Control Structure (Learning Perl)
eval function within: 24.2.1. Time Efficiency (Programming Perl)
extracting slices, multidimensional arrays: 9.1.4. Slices (Programming Perl)
for loops: 1.6.2.2. The for statement (Programming Perl)
foreach loops: 1.6.2.3. The foreach statement (Programming Perl)
\G assertion, using in: 5.6.5. Where You Left Off: The \G Assertion (Programming Perl)
infinite: 4.4.2. for Loops (Programming Perl)
iteration through: 4.4.2. for Loops (Programming Perl)
Glossary (Programming Perl)
labels for: 4.4.4. Loop Control (Programming Perl)
Glossary (Programming Perl)
last operator: 4.4.2. for Loops (Programming Perl)
29.2.81. last (Programming Perl)
next and last operators: 1.6.2.4. Breaking out: next and last (Programming Perl)
next operator: 29.2.101. next (Programming Perl)
redo operator and: 29.2.126. redo (Programming Perl)
reset function and: 29.2.130. reset (Programming Perl)
s/// (substitution) operator, using on arrays: 5.2.3.1. Modifying strings en passant (Programming Perl)
using for: 4.4.2. for Loops (Programming Perl)
using in (global substitutions): 5.2.3.2. When a global substitution just isn't global enough (Programming Perl)
using until: 4.4.1. while and until Statements (Programming Perl)
using while: 4.4.1. while and until Statements (Programming Perl)
while loops: 1.6.2.1. The while and until statements (Programming Perl)
low-level programming languages: 1.2.1. Why Didn't Larry Just Use Some Other Language? (Learning Perl)
low-level socket access functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
lower( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
lowercase
case shifting and: 9.6.5. Case Shifting (Learning Perl)
vs. capitalization in variable names: 2.5.1. Choosing Good Variable Names (Learning Perl)
lowercase, converting to: 2.6.2. String Literals (Programming Perl)
lowercase, converting to uppercase: 1.13.1. Problem (Perl Cookbook)
-lp option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
lpa( ) (Net::Netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
lport manpage, function portability information: 29.2. Perl Functions in Alphabetical Order (Programming Perl)
ls( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
-ls option
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
lst program: 9.13. Program: lst (Perl Cookbook)
lstat( ): 5. Function Reference (Perl in a Nutshell)
lstat function: 11.6.1. The stat and lstat Functions (Learning Perl)
29.2.91. lstat (Programming Perl)
29.2.91. lstat (Programming Perl)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
underscore filehandle and: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
< (left angle bracket)
in debugger commands: 20.2.6. Actions and Command Execution (Programming Perl)
file-access modes: 7.. I/O Operations (Perl Cookbook)
7.1.3. Discussion (Perl Cookbook)
for filename globbing: 2.11.3. Filename Globbing Operator (Programming Perl)
in filenames: 29.2.104. open (Programming Perl)
<=> (comparison)operator: 3.12. Equality Operators (Programming Perl)
<< for here documents: 2.6.6. "Here" Documents (Programming Perl)
<<= (assignment) operator: 3.17. Assignment Operators (Programming Perl)
less than operator: 3.11. Relational Operators (Programming Perl)
<= (less than or equal) operator: 1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
3.11. Relational Operators (Programming Perl)
for line input: 2.11.2. Line Input (Angle) Operator (Programming Perl)
<&= and <& open modes: 7.9.2. Solution (Perl Cookbook)
<FH> line input operator: 7.. I/O Operations (Perl Cookbook)
<=> numerical comparison operator: 4.15.2. Solution (Perl Cookbook)
lt (less-than) operator: 4.5.4.1. Relational operators (Perl in a Nutshell)
< less-than sign: 11.2. Opening a Filehandle (Learning Perl)
<endrange>Win32 modules
Win32::ODBC module: 24.1. ODBC Methods and Properties (Perl in a Nutshell)
<> (angle brackets): 1.. Introduction (Perl Cookbook)
globbing: 9.6.2. Solution (Perl Cookbook)
line input operator: 7.14.2. Solution (Perl Cookbook)
reading strings from binary files: 8.14.2. Solution (Perl Cookbook)
<=> (spaceship operator): 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
<Perl\\>: 11.6. <Perl> Sections (Perl in a Nutshell)
lvaluable functions: 1.1.3. Discussion (Perl Cookbook)
lvalue: 2.3. Built-in Data Types (Programming Perl)
lvalue attribute: 8.3. attributes (Perl in a Nutshell)
lvalues: 2.4. Variables (Programming Perl)
Glossary (Programming Perl)
assignment operators and: 3.17. Assignment Operators (Programming Perl)
lvalue attribute, subroutines: 6.5. Subroutine Attributes (Programming Perl)
6.5.2. The lvalue Attribute (Programming Perl)
methods, declaring to indicate return of: 12.7.6. New Tricks (Programming Perl)
modifiers and: 4.8.1. Scoped Variable Declarations (Programming Perl)
operators and: 1.5.3. Assignment Operators (Programming Perl)
pattern-matching operators, use on: 5.2. Pattern-Matching Operators (Programming Perl)
LWP (library for web access in Perl): 20. The LWP Library (Perl in a Nutshell)
HTML modules: 20.4. The HTML Modules (Perl in a Nutshell)
HTML::Element: 20.4.3. HTML::Element (Perl in a Nutshell)
HTML::FormatPS: 20.4.5. HTML::FormatPS (Perl in a Nutshell)
HTML::FormatText: 20.4.6. HTML::FormatText (Perl in a Nutshell)
HTML::Parser: 20.4. The HTML Modules (Perl in a Nutshell)
20.4.1. HTML::Parser (Perl in a Nutshell)
HTML::TreeBuilder: 20.4.4. HTML::TreeBuilder (Perl in a Nutshell)
HTTP modules
HTTP::Cookies: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
HTTP::Cookies::Netscape: 20.3.6.1. HTTP::Cookies::Netscape (Perl in a Nutshell)
HTTP::Daemon: 20.3.7. HTTP::Daemon (Perl in a Nutshell)
HTTP::Daemon::ClientConn: 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
HTTP::Date: 20.3.5. HTTP::Date (Perl in a Nutshell)
HTTP::Headers: 20.3.3. HTTP::Headers (Perl in a Nutshell)
HTTP::Message: 20.3.8. HTTP::Message (Perl in a Nutshell)
HTTP::Request: 20.1. LWP Overview (Perl in a Nutshell)
20.3.1. HTTP::Request (Perl in a Nutshell)
HTTP::Response: 20.1. LWP Overview (Perl in a Nutshell)
20.3.2. HTTP::Response (Perl in a Nutshell)
HTTP::Status: 20.3.4. HTTP::Status (Perl in a Nutshell)
LWP modules
LWP::Debug module: 20.2. The LWP Modules (Perl in a Nutshell)
LWP::MediaTypes module: 20.2. The LWP Modules (Perl in a Nutshell)
LWP::Protocol module: 20.2. The LWP Modules (Perl in a Nutshell)
LWP::RobotUA module: 20.2. The LWP Modules (Perl in a Nutshell)
20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
LWP::Simple module: 20.2. The LWP Modules (Perl in a Nutshell)
20.2.2. LWP::Simple (Perl in a Nutshell)
LWP::UserAgent module: 20.1. LWP Overview (Perl in a Nutshell)
20.2. The LWP Modules (Perl in a Nutshell)
20.2.3. LWP::UserAgent (Perl in a Nutshell)
URI modules: 20.5. The URI Module (Perl in a Nutshell)
URI::Escape: 20.5. The URI Module (Perl in a Nutshell)
URI::Heuristic: 20.5. The URI Module (Perl in a Nutshell)
URI::URL: 20.5.3. URI::URL (Perl in a Nutshell)
LWP module: B.13.2. Sockets (Learning Perl)
LWP modules: 20.. Introduction (Perl Cookbook)
extracting HTML tags: 20.6.1. Problem (Perl Cookbook)
LWP::RobotUA module: 20.11.2. Solution (Perl Cookbook)
LWP::Simple module: 20.1.2. Solution (Perl Cookbook)
automating HTML forms: 20.2.3. Discussion (Perl Cookbook)
finding stale hyperlinks: 20.7.2. Solution (Perl Cookbook)
mirroring web pages: 20.10.2. Solution (Perl Cookbook)
LWP::UserAgent module: 20.1.3. Discussion (Perl Cookbook)
automating HTML forms: 20.2.2. Solution (Perl Cookbook)
using cookies: 20.14.2. Solution (Perl Cookbook)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

m command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
m command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-M (modification age) file test operator: 3.10. Named Unary and File Test Operators (Programming Perl)
-M file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
m?? (match) operator: 5.2.2. The m// Operator (Matching) (Programming Perl)
20.2.5. Locating Code (Programming Perl)
m// (matching) operator: 5.2.2. The m// Operator (Matching) (Programming Perl)
20.2.5. Locating Code (Programming Perl)
m?? operator, reset function and: 29.2.130. reset (Programming Perl)
/m option: 17.5.2. Matching Multiple-line Text (Learning Perl)
/m pattern modifier: 5.2.1. Pattern Modifiers (Programming Perl)
5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
m pattern match modifier: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
4.6.8. Extended Regular Expressions (Perl in a Nutshell)
/m pattern-matching modifier: 6.. Pattern-Matching Modifiers (Perl Cookbook)
multiple lines: 6.6.2. Solution (Perl Cookbook)
-m (use module)command-line switch: 19.1.3. Switches (Programming Perl)
macdef entries (.netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
machine entries (.netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
Macintosh operating system
command-line interface in versions: 1.3.1. How to Do It (Programming Perl)
File::Spec::Mac module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
invoking Perl application on: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
quoting on: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
magic: Glossary (Programming Perl)
magic ARGV: 8.25. Program: tctee (Perl Cookbook)
16.6.3. Discussion (Perl Cookbook)
magic open: 8.25. Program: tctee (Perl Cookbook)
16.6.3. Discussion (Perl Cookbook)
magic variables, creating: 13.15.1. Problem (Perl Cookbook)
magical autodecrement and autoincrement: 13.3. Overloadable Operators (Programming Perl)
magical autoincrement: 3.3. Autoincrement and Autodecrement (Programming Perl)
magical autoincrement operator: 3.15. Range Operator (Programming Perl)
magical counter variables: 14.1.2. Magical Counter Variables (Programming Perl)
mail
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
sending, portability and: 25.5. Interprocess Communication (IPC) (Programming Perl)
MAIL command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session (Perl in a Nutshell)
Mail modules: 16. Email Connectivity (Perl in a Nutshell)
16.2. The Mail Modules (Perl in a Nutshell)
Mail::Address module: 16.2.6. Parse Email Addresses with Mail::Address (Perl in a Nutshell)
Mail::Audit module: 16.2.9. Mail Filtering with Mail::Audit (Perl in a Nutshell)
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
Mail::Internet module: 16.2.4. Handle Messages with Mail::Internet (Perl in a Nutshell)
Mail::Mailer module: 16.2.1. Send Email with Mail::Mailer (Perl in a Nutshell)
Mail::RBL module: 16.2.8. Checking Blacklisted Hosts with Mail::RBL (Perl in a Nutshell)
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
mail( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
Mail Transport Agent (MTA): 18.5.3. Discussion (Perl Cookbook)
Mail User Agents (MUAs): 18.3.3. Discussion (Perl Cookbook)
mailing lists for Perl: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
mailing lists, Perl-related: 1.4.3. Mailing Lists (Perl in a Nutshell)
Mail::Mailer module: 18.3.2. Solution (Perl Cookbook)
MailTools collection: 16. Email Connectivity (Perl in a Nutshell)
main namespace: 7.1. Namespaces and Packages (Perl in a Nutshell)
main package: 2.5.1. Name Lookups (Programming Perl)
10. Packages (Programming Perl)
main program: 1.4.2. What's Inside That Program? (Learning Perl)
MainLoop statement (Perl/Tk): 21. Perl/Tk (Perl in a Nutshell)
maintaining state (CGI): 10.3. Maintaining State (Perl in a Nutshell)
maintenance considerations: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
maintenance programmers
partial-evaluation operators and: 10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
writing intelligible code for: 2.6.2. Operator Precedence and Associativity (Learning Perl)
10.1.1. The else Clause with unless (Learning Perl)
make command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
make dist: 13.9. Trivial make dist (Learning Perl Objects, References and Modules)
13.9. Trivial make dist (Learning Perl Objects, References and Modules)
make install: 13.8. Trivial make install (Learning Perl Objects, References and Modules)
make test: 13.7. Trivial make test (Learning Perl Objects, References and Modules)
14. Essential Testing (Learning Perl Objects, References and Modules)
14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
make utility: 2.4.2. Module Installation (Perl in a Nutshell)
make utility, exit status and: 11.3. Fatal Errors with die (Learning Perl)
Makefile: Glossary (Programming Perl)
creating for Perl extensions: 32.1.17. Module Installation Support (Programming Perl)
Makefile.PL: 21.3.2. Creating Extensions (Programming Perl)
22.2. Using CPAN Modules (Programming Perl)
22.3. Creating CPAN Modules (Programming Perl)
controlling distribution: 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
PREFIX=option: 13.6. Alternate Installation Locations (PREFIX=...) (Learning Perl Objects, References and Modules)
13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
test harness: 13.7. Trivial make test (Learning Perl Objects, References and Modules)
14.1. What the Test Harness Does (Learning Perl Objects, References and Modules)
14.1. What the Test Harness Does (Learning Perl Objects, References and Modules)
14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
testing and: 15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
Makefiles: 2.4.2. Module Installation (Perl in a Nutshell)
MakeMaker: 22.3. Creating CPAN Modules (Programming Perl)
22.3. Creating CPAN Modules (Programming Perl)
MakeMaker utility: 2.4.3.1. Using MakeMaker (Perl in a Nutshell)
MakeMask( ) (Win32::FileSecurity): 22.6. Win32::FileSecurity (Perl in a Nutshell)
malloc errors: 28.2. Special Variables in Alphabetical Order (Programming Perl)
malloc function: 19.2. Environment Variables (Programming Perl)
man command: 0.4. Online Documentation (Programming Perl)
11. Modules (Programming Perl)
20.2.7. Miscellaneous Commands (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
man pages, translating pod to: 4.13.3. Pod Utilities (Perl in a Nutshell)
MANIFEST file: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
21.3.2. Creating Extensions (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
manpages: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
0.4. Online Documentation (Programming Perl)
Glossary (Programming Perl)
CPAN doc subdirectory, containing: 22. CPAN (Programming Perl)
Pod::Man module: 32.1.16. Documentation Support (Programming Perl)
Perl-related: 2.5.2. The Perl Manpages (Perl in a Nutshell)
map( ): 5. Function Reference (Perl in a Nutshell)
4.16.3. Discussion (Perl Cookbook)
building SQL queries programmatically: 14.13.3. Discussion (Perl Cookbook)
printing hashes: 5.6.2. Solution (Perl Cookbook)
map function: 1.8. List Processing (Programming Perl)
24.3. Programming with Style (Programming Perl)
29.2.93. map (Programming Perl)
map operator
5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
(see also Schwartzian Transform)
functionality: 5.4. The map and grep Operators (Learning Perl Objects, References and Modules)
indirection and: 5.6. Applying a Bit of Indirection (Learning Perl Objects, References and Modules)
perlfunc manpage and: B.10.1. map and grep (Learning Perl)
scalar context: 5.5. Using map (Learning Perl Objects, References and Modules)
selecting complex data: 5.7. Selecting and Altering Complex Data (Learning Perl Objects, References and Modules)
mapping keys, pseudohashes: 12.7.1. Field Declarations with use fields (Programming Perl)
mark( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
mark stack: 18.3. Executing Your Code (Programming Perl)
marked( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
marked_articles( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
markGravity( ) (Text widget): 21.11.4. Marks (Perl in a Nutshell)
mark_list( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
markNames( ) (Text widget): 21.11.4. Marks (Perl in a Nutshell)
mark_range( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
marks, with Text widgets: 21.11.4. Marks (Perl in a Nutshell)
markSet( ) (Text widget): 21.11.4. Marks (Perl in a Nutshell)
markUnset( ) (Text widget): 21.11.4. Marks (Perl in a Nutshell)
marshalling modules: 32.10. Data::Dumper (Programming Perl)
$MATCH: 28.2. Special Variables in Alphabetical Order (Programming Perl)
match (??) operator, reset function and: 29.2.130. reset (Programming Perl)
match (m//) operator: 24.1.1. Universal Blunders (Programming Perl)
29.2.92. m// (Programming Perl)
pos function and: 29.2.112. pos (Programming Perl)
match operator (see m// operator)
match-time pattern interpolation: 5.10.3.4. Match-time pattern interpolation (Programming Perl)
$MATCH ($&) variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
match variables: 9.5. The Match Variables (Learning Perl)
matching
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
Soundex matching: 1.22.1. Problem (Perl Cookbook)
with =~ binding operator: 9.3. The Binding Operator, =~ (Learning Perl)
with dot wildcard character: 7.2.1. About Metacharacters (Learning Perl)
with /i modifier: 9.2.1. Case-insensitive Matching with /i (Learning Perl)
with m// operator: 9.1. Matches with m// (Learning Perl)
with /s modifier: 9.2.2. Matching Any Character with /s (Learning Perl)
with s/// substitution operator: 9.6. Substitutions with s/// (Learning Perl)
matching patterns: 5. Pattern Matching (Programming Perl)
5. Pattern Matching (Programming Perl)
(see also patterns)
math library, C language: 21.3.4. Using Functions from an External C Library (Programming Perl)
Math modules: 8.142. Math::BigFloat (Perl in a Nutshell)
Math::BigFloat module: 8.142. Math::BigFloat (Perl in a Nutshell)
Math::BigInt module: 8.143. Math::BigInt (Perl in a Nutshell)
Math::BigInt::Calc module: 8.144. Math::BigInt::Calc (Perl in a Nutshell)
Math::BigRat module: 8.145. Math::BigRat (Perl in a Nutshell)
Math::Complex module: 8.146. Math::Complex (Perl in a Nutshell)
Math::Trig module: 8.147. Math::Trig (Perl in a Nutshell)
math, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Math::BigFloat module: B.9.3. Large and High-Precision Numbers (Learning Perl)
Math::BigInt module: B.9.3. Large and High-Precision Numbers (Learning Perl)
Math::Complex module: B.9.2. Imaginary and Complex Numbers (Learning Perl)
mathematical functions: B.9.1. Advanced Math Functions (Learning Perl)
mathematical functions, overloading: 13.3. Overloadable Operators (Programming Perl)
mathematics: B.9. Mathematics (Learning Perl)
operators: 3. Unary and Binary Operators (Programming Perl)
operators in Perl: 1.5. Operators (Programming Perl)
Math::Random module: 2.8.2. Solution (Perl Cookbook)
Math::Trig module: 2.10.2. Solution (Perl Cookbook)
2.14.3. Discussion (Perl Cookbook)
32.1.1. Data Types (Programming Perl)
Math::TrulyRandom module: 2.8.2. Solution (Perl Cookbook)
matrix multiplication: 2.13.1. Problem (Perl Cookbook)
maximal matching: 5.3.1. Metasymbol Tables (Programming Perl)
5.5. Quantifiers (Programming Perl)
Boolean connectives in patterns: 6.18.3. Discussion (Perl Cookbook)
quantifiers: 6.15.3. Discussion (Perl Cookbook)
maximum and minimum item matches, specifying: 1.7.1. Quantifiers (Programming Perl)
maxsize( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
max_size( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
maxTraceLen option (debugger): 20.3.3. Debugger Options (Programming Perl)
MaxWindow( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
md5( ) (Digest::MD5 module): 8.58. Digest::MD5 (Perl in a Nutshell)
md5_base64 (Digest::MD5 module): 8.58. Digest::MD5 (Perl in a Nutshell)
md5_hex (Digest::MD5 module): 8.58. Digest::MD5 (Perl in a Nutshell)
mdtm( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
member data: 12.4.2. Initializers (Programming Perl)
member variables: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
memEQ_clause function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
memoizing technique: 4.20. Program: permute (Perl Cookbook)
memory: 4.2.5. Variables (Perl in a Nutshell)
Glossary (Programming Perl)
deallocation: 11.. Anonymous Data (Perl Cookbook)
efficiency of: 24.2.2. Space Efficiency (Programming Perl)
encodings and: 8.20.3. Discussion (Perl Cookbook)
event-based XML parsing: 22.3.1. Problem (Perl Cookbook)
garbage collection: 13.2.3. Discussion (Perl Cookbook)
8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
circular data structures and: 13.13.1. Problem (Perl Cookbook)
management, destructors and: 12.6. Instance Destructors (Programming Perl)
preallocating for hashes: 5.14.1. Problem (Perl Cookbook)
requirements for hash merging technique: 5.11.3. Discussion (Perl Cookbook)
running out of: 28.2. Special Variables in Alphabetical Order (Programming Perl)
shared memory segment ID: 29.2.151. shmget (Programming Perl)
shared, System V IPC: 16.4. System V IPC (Programming Perl)
controlled access to: 16.4. System V IPC (Programming Perl)
statistics on, displaying: 19.2. Environment Variables (Programming Perl)
memory addresses: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.8. References to Hashes (Learning Perl Objects, References and Modules)
memory management: 4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
memory parentheses: 8.4. Memory Parentheses (Learning Perl)
memory, persistence of: 9.5.1. The Persistence of Memory (Learning Perl)
memory variables: 8.4.2. Memory Variables (Learning Perl)
menu( ) (Menubutton): 21.14.2. Menubutton Methods (Perl in a Nutshell)
-menu option
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
21.14.1. Menu Item Options (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Menu widget (Perl/Tk): 21.15. The Menu Widget (Perl in a Nutshell)
Menubutton widget (Perl/Tk): 21.14. The Menubutton Widget (Perl in a Nutshell)
Menubutton widget, Tk: 15.14.2. Solution (Perl Cookbook)
-menuitems option
Menu widget: 21.15. The Menu Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
21.14. The Menubutton Widget (Perl in a Nutshell)
merging
DBM files: 14.4.1. Problem (Perl Cookbook)
hashes: 5.11.1. Problem (Perl Cookbook)
message, ,script embedded in: 19.1.3. Switches (Programming Perl)
message digests, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
message_exists( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
message( ) (HTTP::Response): 20.3.2. HTTP::Response (Perl in a Nutshell)
message_list( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
message-oriented protocols: 15. Sockets (Perl in a Nutshell)
messages
functions for: 29.2.95. msgctl (Programming Perl)
IPC::Msg module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
passing with UDP: 16.5.3. Message Passing (Programming Perl)
printing on entry and exit from subroutines: 20.3.3. Debugger Options (Programming Perl)
receiving on sockets: 29.2.125. recv (Programming Perl)
sending on sockets: 29.2.145. send (Programming Perl)
System V IPC: 16.4. System V IPC (Programming Perl)
meta-variables: 10.5. Using Class Variables (Learning Perl Objects, References and Modules)
metacharacters: 7.2.1. About Metacharacters (Learning Perl)
5.1. The Regular Expression Bestiary (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
Glossary (Programming Perl)
escaping with backslash (\): 5.3. Metacharacters and Metasymbols (Programming Perl)
escaping with quotemeta: 29.2.118. quotemeta (Programming Perl)
in exec arguments: 29.2.33. exec (Programming Perl)
in patterns: 5.3. Metacharacters and Metasymbols (Programming Perl)
shell, in pipe commands: 29.2.104. open (Programming Perl)
structural: 5.1. The Regular Expression Bestiary (Programming Perl)
metacharacters for regular expressions: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
anchors: 4.6.5. Anchors (Perl in a Nutshell)
character classes: 4.6.4. Character Classes (Perl in a Nutshell)
escaped sequences: 4.6.3. Escaped Sequences (Perl in a Nutshell)
quantifiers: 4.6.6. Quantifiers (Perl in a Nutshell)
metasymbols: Glossary (Programming Perl)
alphanumeric, in patterns: 5.3.1. Metasymbol Tables (Programming Perl)
extension syntax for: 5.3.1. Metasymbol Tables (Programming Perl)
in patterns: 5.3. Metacharacters and Metasymbols (Programming Perl)
5.3.2. Specific Characters (Programming Perl)
method attribute: 8.3. attributes (Perl in a Nutshell)
12.7.6. New Tricks (Programming Perl)
<form\\> tag: 9.1.1. Transferring the Form Data (Perl in a Nutshell)
method attribute (subroutines): 6.5. Subroutine Attributes (Programming Perl)
method( ) (HTTP::Request): 20.3.1. HTTP::Request (Perl in a Nutshell)
Method (overload::Method): 13.7. Public Overload Functions (Programming Perl)
methods: 13.. Under the Hood (Perl Cookbook)
13.. Methods (Perl Cookbook)
13.3.3. Discussion (Perl Cookbook)
13.8.3. The File::Spec Module (Learning Perl)
7.3. Object-Oriented Perl (Perl in a Nutshell)
9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
8.3.4. Using Object Methods (Programming Perl)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
abstract methods: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
adding to an existing class: 12.5.2. Accessing Overridden Methods (Programming Perl)
array-tying: 14.2.1. Array-Tying Methods (Programming Perl)
autoloading: 12.5.4. Method Autoloading (Programming Perl)
called by tied variables: 14. Tied Variables (Programming Perl)
class data, working like accessors: 12.8. Managing Class Data (Programming Perl)
classes implementing tied arrays: 14.2. Tying Arrays (Programming Perl)
classes implementing tied filehandles: 14.4. Tying Filehandles (Programming Perl)
classes implementing tied hashes: 14.3. Tying Hashes (Programming Perl)
declarations
lvalues, indicating return of: 12.7.6. New Tricks (Programming Perl)
vs. functions: 13.10.3. Discussion (Perl Cookbook)
generating with AUTOLOAD: 13.. Methods (Perl Cookbook)
13.12.1. Problem (Perl Cookbook)
getters doubling as setters: 9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
hash-tying: 14.3.1. Hash-Tying Methods (Programming Perl)
HTTP: 19.. Behind the Scenes (Perl Cookbook)
19.1.3. Discussion (Perl Cookbook)
indirect notation: 13.. A Warning on Indirect Object Notation (Perl Cookbook)
inheritance and: 8.4. Calling a Second Method to Simplify Things (Learning Perl Objects, References and Modules)
8.4. Calling a Second Method to Simplify Things (Learning Perl Objects, References and Modules)
instance vs. class methods: 7.4. Object Syntax (Perl in a Nutshell)
instances and: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
invocation arrow: 8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
8.10. Where We Are So Far... (Learning Perl Objects, References and Modules)
10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
invoking: 12.3. Method Invocation (Programming Perl)
explicitly or implicitly: 12.3. Method Invocation (Programming Perl)
using indirect objects: 12.3.2. Method Invocation Using Indirect Objects (Programming Perl)
subroutine calls vs.: 12.4.1. Inheritable Constructors (Programming Perl)
using arrow operator: 12.3.1. Method Invocation Using the Arrow Operator (Programming Perl)
invoking indirectly: 13.8.1. Problem (Perl Cookbook)
names for: 24.3. Programming with Style (Programming Perl)
object methods
locking: 17.2.2.5. Locking methods (Programming Perl)
overridden: 13.11.1. Problem (Perl Cookbook)
overriding: 8.6. Overriding the Methods (Learning Perl Objects, References and Modules)
12.5.2. Accessing Overridden Methods (Programming Perl)
parameters and: 8.3. The Extra Parameter of Method Invocation (Learning Perl Objects, References and Modules)
8.3. The Extra Parameter of Method Invocation (Learning Perl Objects, References and Modules)
9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
Perl classes inheritance of: 12.7. Managing Instance Data (Programming Perl)
private and public: 13.. Methods (Perl Cookbook)
private methods, ignoring inheritance with: 12.5.5. Private Methods (Programming Perl)
references to: 11.8.1. Problem (Perl Cookbook)
8.3.7. Closures (Programming Perl)
remote: 18.12.3. Discussion (Perl Cookbook)
restricting: 9.14. Restricting a Method to Class-Only or Instance-Only (Learning Perl Objects, References and Modules)
searching for
class inheritance: 12.5. Class Inheritance (Programming Perl)
inheritance through @ISA array: 12.5.1. Inheritance Through @ISA (Programming Perl)
subroutines as: 12.2. Perl's Object System (Programming Perl)
subroutines vs.: 6. Subroutines (Programming Perl)
12.3. Method Invocation (Programming Perl)
superclasses: 10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
Thread class: 17.2.1. The Thread Module (Programming Perl)
tying scalars: 14.1.1. Scalar-Tying Methods (Programming Perl)
UINVERSAL class
adding to: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
in UNIVERSAL class: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
UNIVERSAL class and: 11.1. UNIVERSAL Methods (Learning Perl Objects, References and Modules)
widget (Perl/Tk): 21.1.1. Widget Methods (Perl in a Nutshell)
working with classes: 9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
XML::SAX::Base: 22.3.3. Discussion (Perl Cookbook)
m//g operator
Perl versions, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
MHCONTEXTFD environment variable: 7.9.3. Discussion (Perl Cookbook)
Microsoft
SOAP, and: 14.1. What Is SOAP? (Perl in a Nutshell)
Windows 95, Perl functionality on: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
Microsoft Windows
ActiveState Perl distribution, installing: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
CPAN modules, installing on: 22.2.1. Decompressing and Unpacking CPAN Modules (Programming Perl)
fileglobbing, File::DosGlob module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::Win32 module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
fork operation, cloning interpreter objects: 17.1. The Process Model (Programming Perl)
modules for: 32.1.20. Microsoft-Related Modules (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
porting information (perlwin32): 16. Interprocess Communication (Programming Perl)
registry, manipulating: 14.6. Tie Modules on CPAN (Programming Perl)
shell, setting alternative for Perl use: 19.2. Environment Variables (Programming Perl)
signal number 0 on: 16.1.1. Signaling Process Groups (Programming Perl)
system calls using wide-character APIs: 15.1. Building Character (Programming Perl)
Windows NT, quoting on: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
Win32::Pipe module: 16.3.4. Named Pipes (Programming Perl)
MIDI, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
MIME (Multimedia Internet Mail Extensions): 18.9.3. Discussion (Perl Cookbook)
18.10.3. Discussion (Perl Cookbook)
MIME, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
MIME-Tools module: 18.10.2. Solution (Perl Cookbook)
MIME::Base64 module: 8.148. MIME::Base64 (Perl in a Nutshell)
MIME::Lite module: 18.9.2. Solution (Perl Cookbook)
MIME::QuotedPrint module: 8.149. MIME::QuotedPrint (Perl in a Nutshell)
Mingw32: 2.3.2. Installing on Win32 (Perl in a Nutshell)
2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
minimal matching: 4.6.6. Quantifiers (Perl in a Nutshell)
1.7.2. Minimal Matching (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
5.5. Quantifiers (Programming Perl)
Boolean connectives in patterns: 6.18.3. Discussion (Perl Cookbook)
quantifiers: 6.15.3. Discussion (Perl Cookbook)
minsize( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
minus (-) operator: 3.5. Ideographic Unary Operators (Programming Perl)
minus sign (-), modifiers and: 6.18.3. Discussion (Perl Cookbook)
minutes (see date and time values)
mirror( )
LWP::Simple module: 20.2.2. LWP::Simple (Perl in a Nutshell)
LWP::UserAgent module: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
mirror( ): 20.10.2. Solution (Perl Cookbook)
miscellaneous functions: 29.1. Perl Functions by Category (Programming Perl)
mkdir( ): 5. Function Reference (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
mkdir function: 13.4. Making and Removing Directories (Learning Perl)
29.2.94. mkdir (Programming Perl)
Mkdir( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
mkfifo function: 16.3.4. Named Pipes (Programming Perl)
MLDBM module: 11.14.2. Solution (Perl Cookbook)
14.. Introduction (Perl Cookbook)
14.6.2. Solution (Perl Cookbook)
14.6. Tie Modules on CPAN (Programming Perl)
Data::Dumper module, using with: 32.10. Data::Dumper (Programming Perl)
persistent data: 14.7.2. Solution (Perl Cookbook)
mmap syscall: 16.4. System V IPC (Programming Perl)
-mod option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
moddn( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
$mode: 11.6.1. The stat and lstat Functions (Learning Perl)
modems, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
modes, opening files in: 29.2.104. open (Programming Perl)
modification time, file: 29.2.165. stat (Programming Perl)
29.2.193. utime (Programming Perl)
modifiers
pattern
cloistered: 5.7.3. Cloistered Pattern Modifiers (Programming Perl)
with s/// (substitution) operator: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
patterns
with tr/// (transliteration) operator: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
statements
quantifiers vs.: 5.1. The Regular Expression Bestiary (Programming Perl)
statements, simple: 4.1. Simple Statements (Programming Perl)
modifiers, conditional: 4.3.1.4. Modifiers (Perl in a Nutshell)
modify( ), LDAP server: 18.8.3. Discussion (Perl Cookbook)
modify( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
modifying files (see file contents)
mod_include module: 11.5. Server-Side Includes with mod_perl (Perl in a Nutshell)
mod_perl: 21.. Introduction (Perl Cookbook)
accessing form parameters: 21.6.1. Problem (Perl Cookbook)
Apache handlers
receiving uploaded files: 21.7.1. Problem (Perl Cookbook)
sharing information between: 21.13.1. Problem (Perl Cookbook)
Apache logging requests, customizing: 21.9.1. Problem (Perl Cookbook)
applications, benchmarking: 21.15.1. Problem (Perl Cookbook)
authentication: 21.1.1. Problem (Perl Cookbook)
communicating with PHP: 21.11.1. Problem (Perl Cookbook)
cookies
accessing values: 21.3.1. Problem (Perl Cookbook)
setting: 21.2.1. Problem (Perl Cookbook)
documentation: 21.. More Documentation (Perl Cookbook)
interrogating headers: 21.5.1. Problem (Perl Cookbook)
migrating from CGI: 21.12.1. Problem (Perl Cookbook)
redirecting browsers: 21.4.1. Problem (Perl Cookbook)
reloading changed modules: 21.14.1. Problem (Perl Cookbook)
speeding database access: 21.8.1. Problem (Perl Cookbook)
templating with HTML::Mason: 21.16.1. Problem (Perl Cookbook)
autohandlers: 21.16.3.4. Autohandlers (Perl Cookbook)
configuration: 21.16.3.1. Configuration (Perl Cookbook)
dhandlers: 21.16.3.5. Dhandlers (Perl Cookbook)
Mason syntax: 21.16.3.2. Basic Mason syntax (Perl Cookbook)
objects: 21.16.3.3. Objects (Perl Cookbook)
templating with Template Toolkit: 21.17.1. Problem (Perl Cookbook)
configuration: 21.17.3.1. Configuration (Perl Cookbook)
data structures: 21.17.3.4. Data structures (Perl Cookbook)
other templates: 21.17.3.6. Including other templates (Perl Cookbook)
parameters: 21.17.3.7. Parameters (Perl Cookbook)
Perl code: 21.17.3.3. Perl code (Perl Cookbook)
plug-ins: 21.17.3.8. Plug-ins (Perl Cookbook)
subroutines: 21.17.3.5. Subroutines (Perl Cookbook)
syntax: 21.17.3.2. Syntax (Perl Cookbook)
URLs, transparently storing information in: 21.10.1. Problem (Perl Cookbook)
mod_perl 2: 21.. mod_perl 2 (Perl Cookbook)
mod_perl module: 11. Web Server Programmingwith mod_perl (Perl in a Nutshell)
18.3. Executing Your Code (Programming Perl)
21.4. Embedding Perl (Using Perl from C) (Programming Perl)
installing: 11.2. Installing mod_perl (Perl in a Nutshell)
running CGI scripts with: 11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
SSI with: 11.5. Server-Side Includes with mod_perl (Perl in a Nutshell)
mod_perl software: B.24. Embedding (Learning Perl)
modules: 12.. Modules (Perl Cookbook)
4.11.1. Omitting the Ampersand (Learning Perl)
13.8. Using Simple Modules (Learning Perl)
B.4.2. Modules (Learning Perl)
B.33. And More... (Learning Perl)
12. Using Modules (Learning Perl Objects, References and Modules)
0.1. The Pursuit of Happiness (Programming Perl)
1.2.1.4. Simplicities (Programming Perl)
10. Packages (Programming Perl)
10.2. Autoloading (Programming Perl)
11. Modules (Programming Perl)
announcing: 15.5. Announcing the Module (Learning Perl Objects, References and Modules)
automatic setup and cleanup: 12.7.1. Problem (Perl Cookbook)
backend: 18.4. Compiler Backends (Programming Perl)
backend, calling: 18.4. Compiler Backends (Programming Perl)
built-in functions, overriding: 11.3. Overriding Built-in Functions (Programming Perl)
class system and: 12.5.1. Inheritance Through @ISA (Programming Perl)
classes, storing in for privacy: 12.5.5. Private Methods (Programming Perl)
classes vs.: 10. Packages (Programming Perl)
core modules: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
CPAN: 12.21.1. Problem (Perl Cookbook)
22.1. The CPAN modules Directory (Programming Perl)
building: 22.2.2. Building CPAN Modules (Programming Perl)
categories of: 22.1. The CPAN modules Directory (Programming Perl)
creating: 22.3. Creating CPAN Modules (Programming Perl)
decompressing and unpacking: 22.2.1. Decompressing and Unpacking CPAN Modules (Programming Perl)
installing into Perl library: 22.2.3. Installing CPAN Modules into the Perl Library (Programming Perl)
mail, sending: 25.5. Interprocess Communication (IPC) (Programming Perl)
making available to programs: 22.2. Using CPAN Modules (Programming Perl)
portability of: 25.7. Standard Modules (Programming Perl)
CPAN, collection of: 1.2.1.4. Simplicities (Programming Perl)
CPAN directory for: 22. CPAN (Programming Perl)
CPAN, storing in: 10. Packages (Programming Perl)
creating: 11.2. Creating Modules (Programming Perl)
privacy and the Exporter: 11.2.1. Module Privacy and the Exporter (Programming Perl)
symbol exportation, preventing: 11.2.1.3. Managing unknown symbols (Programming Perl)
version checking: 11.2.1.2. Version checking (Programming Perl)
designing interface for: 12.1.1. Problem (Perl Cookbook)
directories of: 12.8.1. Problem (Perl Cookbook)
distributions and: 13.1. Starting with h2xs (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
documenting with pod: 12.20.1. Problem (Perl Cookbook)
sorting =head1 sections: 15.22. Program: tkshufflepod (Perl Cookbook)
errors
reporting like built-ins: 12.14.1. Problem (Perl Cookbook)
trapping in use and require statements: 12.2.1. Problem (Perl Cookbook)
exporting names to other modules: 29.2.74. import (Programming Perl)
finding versions and descriptions of: 12.23. Program: Finding Versions and Descriptions of Installed Modules (Perl Cookbook)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
importing: 32.1.17. Module Installation Support (Programming Perl)
importing from: 10.14.3. Discussion (Perl Cookbook)
lib pragma for: B.6.3. The lib Pragma (Learning Perl)
loading: 12.10.1. Problem (Perl Cookbook)
reloading changed modules with mod_perl: 21.14.1. Problem (Perl Cookbook)
at runtime: 12.3.1. Problem (Perl Cookbook)
mod_perl: 21.. More Documentation (Perl Cookbook)
names for: 24.3. Programming with Style (Programming Perl)
overriding built-in functions: 12.12.1. Problem (Perl Cookbook)
overview: 12. Using Modules (Learning Perl Objects, References and Modules)
preparing for distribution: 12.9.1. Problem (Perl Cookbook)
private variables: 12.4.1. Problem (Perl Cookbook)
splitting into separate files: 10.2. Autoloading (Programming Perl)
standard: 32. Standard Modules (Programming Perl)
base classes and convenience: 32.1.14. Convenient Classes (Programming Perl)
command-line processing: 32.1.3. Option, Argument, Parameter, and Configuration File Processing (Programming Perl)
for data types: 32.1.1. Data Types (Programming Perl)
DBM file management libraries, loading: 32.1.10. DBM Interfaces (Programming Perl)
development support: 32.1.18. Development Support (Programming Perl)
documentation support: 32.1.16. Documentation Support (Programming Perl)
files, cross-platform methods of access: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
internationalization and locales: 32.1.6. Internationalization and Locale (Programming Perl)
module installation support: 32.1.17. Module Installation Support (Programming Perl)
networking and interprocess communication: 32.1.8. Networking and Interprocess Communication (Programming Perl)
object-oriented file, directory, and IPC access: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
operating system interfaces, manipulating: 32.1.7. Operating System Interfaces (Programming Perl)
Perl compiler and code generator: 32.1.19. Perl Compiler and Code Generator (Programming Perl)
Perl language extensions and externals: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
security, dealing with: 32.1.12. Authentication, Security, and Encryption (Programming Perl)
text, manipulating with: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
user interfaces, providing: 32.1.11. User Interfaces (Programming Perl)
warnings and exceptions: 32.1.15. Warnings and Exceptions (Programming Perl)
template for: 12.22. Example: Module Template (Perl Cookbook)
testing: 21.3.2. Creating Extensions (Programming Perl)
21.3.3. XSUB Input and Output (Programming Perl)
22.3. Creating CPAN Modules (Programming Perl)
thread modules: 17.2.3. Other Thread Modules (Programming Perl)
thread safety and: 17.2. The Thread Model (Programming Perl)
tie modules on CPAN: 14.6. Tie Modules on CPAN (Programming Perl)
user-defined, capitalization in names: 2.5. Names (Programming Perl)
using only some functions from: 13.8.2. Using Only Some Functions from a Module (Learning Perl)
writing in C: 12.18.1. Problem (Perl Cookbook)
modules, Perl: 1.1. What's Perl Good For? (Perl in a Nutshell)
7. Packages,Modules, and Objects (Perl in a Nutshell)
7.2. Modules (Perl in a Nutshell)
categories: 2.4.1. Locating Modules (Perl in a Nutshell)
compiling into shared objects: 3.4. The Perl Compiler (Perl in a Nutshell)
obtaining and installing: 2.4. Getting and Installing Modules (Perl in a Nutshell)
obtaining from CPAN: 2.2. How Is CPAN Organized? (Perl in a Nutshell)
standard, list of: 8. Standard Modules (Perl in a Nutshell)
modulus (%) operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
3.7. Multiplicative Operators (Programming Perl)
modulus operator (%): 2.2.5. Numeric Operators (Learning Perl)
used with grep operator: 17.2. Picking Items from a List with grep (Learning Perl)
money, sprintf function for: 15.3.1. Using sprintf with "Money Numbers" (Learning Perl)
months (see date and time values)
more than sign (see >)
MoreResults( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
24.1. ODBC Methods and Properties (Perl in a Nutshell)
mortgages, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
mounted volume: 13.3. Links and Files (Learning Perl)
MouseButtons( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
move( ): 9.3.3. Discussion (Perl Cookbook)
move( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
MS-DOS operating system, invoking Perl applications on: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
msgctl( ): 5. Function Reference (Perl in a Nutshell)
msgctl function: 29.2.95. msgctl (Programming Perl)
msgget( ): 5. Function Reference (Perl in a Nutshell)
msgget function: 29.2.96. msgget (Programming Perl)
msgrcv( ): 5. Function Reference (Perl in a Nutshell)
msgrcv function: 29.2.97. msgrcv (Programming Perl)
msgsnd( ): 5. Function Reference (Perl in a Nutshell)
msgsnd function: 29.2.98. msgsnd (Programming Perl)
MTA (Mail Transport Agent): 18.5.3. Discussion (Perl Cookbook)
$mtime file statistic: 29.2.165. stat (Programming Perl)
mtime field, inode structure: 9.. Introduction (Perl Cookbook)
$mtime (timestamp): 11.6.1. The stat and lstat Functions (Learning Perl)
changing: 13.7. Changing Timestamps (Learning Perl)
MUAs (Mail User Agents): 18.3.3. Discussion (Perl Cookbook)
mulitple inheritance, SUPER pseudopackage, working with: 12.5.2. Accessing Overridden Methods (Programming Perl)
multidimensional
arrays: 4.. Introduction (Perl Cookbook)
associative array emulation syntax: 9.4.3. Discussion (Perl Cookbook)
multidimensional arrays: 1.2.1.3. Complexities (Programming Perl)
9.1. Arrays of Arrays (Programming Perl)
Glossary (Programming Perl)
multidimensional hashes: 9.4. Hashes of Hashes (Programming Perl)
accessing and printing: 9.4.3. Access and Printing of a Hash of Hashes (Programming Perl)
generation of: 9.4.2. Generation of a Hash of Hashes (Programming Perl)
multihomed servers: 17.16.1. Problem (Perl Cookbook)
multiline fieldholder: 4.12. Formats (Perl in a Nutshell)
multiline string quoting: B.8.2. Here documents (Learning Perl)
Multimedia Internet Mail Extensions (see MIME)
multiple inheritance: 13.. Inheritance (Perl Cookbook)
12.5. Class Inheritance (Programming Perl)
Glossary (Programming Perl)
AUTOLOAD subroutine and: 12.5.4. Method Autoloading (Programming Perl)
methods, invoking all overridden base class: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
multiplication: 1.5.1. Some Binary Arithmetic Operators (Programming Perl)
of matrices: 2.13.1. Problem (Perl Cookbook)
strings, repeat operator: 1.5.2. String Operators (Programming Perl)
x operator: 2.13.3. Discussion (Perl Cookbook)
multiplication (*) operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
multiplication operator (*): 2.2.5. Numeric Operators (Learning Perl)
multiplicative operators: 1.5.2. String Operators (Programming Perl)
3.7. Multiplicative Operators (Programming Perl)
multiprocessing
processer access, unpredictability of: 23.2. Handling Timing Glitches (Programming Perl)
thread model: 17.2. The Thread Model (Programming Perl)
multirefinplace( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
multithreading: 3.5. Threads (Perl in a Nutshell)
17. Threads (Programming Perl)
Munoz, Luis: 16. Email Connectivity (Perl in a Nutshell)
mutators, copying and: 13.4. The Copy Constructor (=) (Programming Perl)
mutex objects: 22.9. Win32::Mutex (Perl in a Nutshell)
mux_input( ): 17.19.2. Solution (Perl Cookbook)
mv command (Unix): 13.2. Renaming Files (Learning Perl)
my( ): 4.7.4. Private and Local Variables (Perl in a Nutshell)
5. Function Reference (Perl in a Nutshell)
my declarations: 2.5. Names (Programming Perl)
4. Statements and Declarations (Programming Perl)
29.2.99. my (Programming Perl)
closures and: 8.3.7. Closures (Programming Perl)
context rules and: 2.7.1. Scalar and List Context (Programming Perl)
local, using instead of: 24.1.2. Frequently Ignored Advice (Programming Perl)
local vs.: 4.8.4. Dynamically Scoped Variables: local (Programming Perl)
my function: 4.4.3. foreach Loops (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
4.8.2. Lexically Scoped Variables: my (Programming Perl)
my operator: 10.2.3. Discussion (Perl Cookbook)
4.9. Notes on Lexical (my) Variables (Learning Perl)
creating lexical variables with: 4.6. Private Variables in Subroutines (Learning Perl)
using instead of local operator: 4.7.1. The Difference Between local and my (Learning Perl)
my variables: 2.3. Using do (Learning Perl Objects, References and Modules)
2.8. Scope of a Package Directive (Learning Perl Objects, References and Modules)
myconfig (Config module): 8.44. Config (Perl in a Nutshell)
MyConfig.pm: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

\n: 25.1. Newlines (Programming Perl)
(see also newlines)
-n command-line option, writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
n command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
n index
Entry widget: 21.8.1. Text Indexes (Perl in a Nutshell)
Listbox widget: 21.10.1. Listbox Indexes (Perl in a Nutshell)
Menu widget: 21.15.1. Menu Indexes (Perl in a Nutshell)
Text widget: 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
-n (loop) command-line switch: 19.1.3. Switches (Programming Perl)
\n (newline) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
\n shortcut: 1.4.2. What's Inside That Program? (Learning Perl)
within a single-quoted string: 2.3.1. Single-Quoted String Literals (Learning Perl)
Nagle Algorithm: 17.3.3. Discussion (Perl Cookbook)
naked block control structure: 10.4. The Naked Block Control Structure (Learning Perl)
name( ) (Mail::Address): 16.2.7. Mail::Address Reference (Perl in a Nutshell)
name-value pairs, passing subroutines by named parameter: 10.7.3. Discussion (Perl Cookbook)
named
character: 2.6.2. String Literals (Programming Perl)
character, metasymbol for: 5.3.2. Specific Characters (Programming Perl)
characters, inserting: 15.2. Effects of Character Semantics (Programming Perl)
parameters (CGI): 10.4. Named Parameters (Perl in a Nutshell)
pipes: 16.3.4. Named Pipes (Programming Perl)
16.11.1. Problem (Perl Cookbook)
Glossary (Programming Perl)
sigrand program: 16.23. Program: sigrand (Perl Cookbook)
unary operators: 2.11.3. Filename Globbing Operator (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
listing of: 3.10. Named Unary and File Test Operators (Programming Perl)
names: 2.5. Names (Programming Perl)
arrays: 2.4. Variables (Programming Perl)
attributes, subroutines: 6.5.1. The locked and method Attributes (Programming Perl)
capitalization conventions: 2.5. Names (Programming Perl)
classes, distinguishing from subroutines: 12.3.4. Package-Quoted Classes (Programming Perl)
commands: 1.2.2. Verbs (Programming Perl)
Glossary (Programming Perl)
constructors: 12.4.2. Initializers (Programming Perl)
file: 2.6.8. Other Literal Tokens (Programming Perl)
for files==>filenames: 29.2.128. rename (Programming Perl)
format (see format names)
formats associated with filehandles: 7. Formats (Programming Perl)
functions: 1.2.2. Verbs (Programming Perl)
getting from network addresses: 29.2.47. gethostbyaddr (Programming Perl)
group names: 29.2.46. getgrnam (Programming Perl)
hashes: 2.4. Variables (Programming Perl)
hashes and: 5.1.1. Why Use a Hash? (Learning Perl)
hashes, storing in: 1.2.1.2. Pluralities (Programming Perl)
hostnames, translating to network addresses: 29.2.48. gethostbyname (Programming Perl)
identifiers vs.: 2.5. Names (Programming Perl)
labels and filehandles: 2.5. Names (Programming Perl)
login (see login names)
lookups of: 2.5.1. Name Lookups (Programming Perl)
methods, tied variables: 14. Tied Variables (Programming Perl)
modules: 11.1. Using Modules (Programming Perl)
capitalization in: 11.1. Using Modules (Programming Perl)
modules/packages: 24.3. Programming with Style (Programming Perl)
network addresses, getting from: 29.2.51. getnetbyaddr (Programming Perl)
of hashes: 5.2. Hash Element Access (Learning Perl)
of variables
choosing: 2.5.1. Choosing Good Variable Names (Learning Perl)
enclosed in curly braces: 2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
packages: 10. Packages (Programming Perl)
parameters, not requiring: 6.2.1. Tricks with Parameter Lists (Programming Perl)
ports, getting from number: 29.2.64. getservbyname (Programming Perl)
program (see $0 variable)
protocols, getting from port numbers: 29.2.65. getservbyport (Programming Perl)
protocols, translating to/from numbers: 29.2.58. getprotobyname (Programming Perl)
scope, confining to: 4.8.1. Scoped Variable Declarations (Programming Perl)
signals: 16.1. Signals (Programming Perl)
subroutines: 6.1. Syntax (Programming Perl)
capitalization in: 6.1. Syntax (Programming Perl)
symbol tables: 10.1. Symbol Tables (Programming Perl)
temporary files, generating: 23.2.3. Temporary Files (Programming Perl)
translating to network addresses: 29.2.52. getnetbyname (Programming Perl)
typeglobs: 2.10. Typeglobs and Filehandles (Programming Perl)
users: 29.2.62. getpwnam (Programming Perl)
variable: 24.3. Programming with Style (Programming Perl)
variables: 1.2.1. Variable Syntax (Programming Perl)
2.4. Variables (Programming Perl)
names of current subroutines. determining: 10.4.1. Problem (Perl Cookbook)
namespace (see packages)
encapsulation based on: 14.6. Tie Modules on CPAN (Programming Perl)
modules and: 11.2.1. Module Privacy and the Exporter (Programming Perl)
namespace( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
namespaces: 4.2.5. Variables (Perl in a Nutshell)
7.1. Namespaces and Packages (Perl in a Nutshell)
2.5. Names (Programming Perl)
Glossary (Programming Perl)
access, restricting with Safe module: 23.3.1.1. Restricting namespace access (Programming Perl)
for packages: 1.2.1.4. Simplicities (Programming Perl)
packages as separators: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
packages for: B.3. Packages (Learning Perl)
problems with collisions: 2.6. The Problem of Namespace Collisions (Learning Perl Objects, References and Modules)
12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
XML: 22.. Namespaces (Perl Cookbook)
naming
loop labels: 4.3.1.5. Loop control (Perl in a Nutshell)
packages: 7.1. Namespaces and Packages (Perl in a Nutshell)
socket: 29.2.5. bind (Programming Perl)
statement block labels: 4.3. Statements (Perl in a Nutshell)
variables: 4.2.5.2. Hashes (Perl in a Nutshell)
natural languages: 1.2. Natural and Artificial Languages (Programming Perl)
environment variables controlling Perl handling of: 19.2. Environment Variables (Programming Perl)
natural logarithms: 2.12.2. Solution (Perl Cookbook)
navigating Web with robots: 20.11.1. Problem (Perl Cookbook)
NDBM files: 14.. Introduction (Perl Cookbook)
NDBM_File module: 8.150. NDBM_File (Perl in a Nutshell)
32.1.10. DBM Interfaces (Programming Perl)
ne (not equal to) operator: 4.5.4.2. Equality operators (Perl in a Nutshell)
ne operator: 24.1.1. Universal Blunders (Programming Perl)
nearest( ) (Listbox): 21.10.2. Listbox Methods (Perl in a Nutshell)
neat( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
neat_list( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
negating shortcuts: 8.1.2. Negating the Shortcuts (Learning Perl)
negation
arithmetic (-)operator: 3.5. Ideographic Unary Operators (Programming Perl)
bitwise (~) operator: 3.5. Ideographic Unary Operators (Programming Perl)
character classes: 5.4.1. Custom Character Classes (Programming Perl)
5.4.2. Classic Perl Character Class Shortcuts (Programming Perl)
logical (!) operator: 3.5. Ideographic Unary Operators (Programming Perl)
of character class: 1.7.1. Quantifiers (Programming Perl)
POSIX character classes: 5.4.4. POSIX-Style Character Classes (Programming Perl)
negation (not) operator (!): 2.7.1. Boolean Values (Learning Perl)
10.1. The unless Control Structure (Learning Perl)
10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
overloading: 13.3. Overloadable Operators (Programming Perl)
negative array indices: 3.2. Special Array Indices (Learning Perl)
negative array subscripts, counting from end of array: 24.1.5. Previous Perl Traps (Programming Perl)
negative lookahead assertions: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
5.10.1. Lookaround Assertions (Programming Perl)
negative subscripts in Perl: 2.3. Built-in Data Types (Programming Perl)
nested
arrays: 9.1. Arrays of Arrays (Programming Perl)
data structures: 1.2.1.3. Complexities (Programming Perl)
3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
3.6. Nested Data Structures (Learning Perl Objects, References and Modules)
4.3. Reference Counting and Nested Data Structures (Learning Perl Objects, References and Modules)
printed: 20.2.4. Display (Programming Perl)
destruction: 12.6. Instance Destructors (Programming Perl)
element references: 3.7. Simplifying Nested Element References with Arrows (Learning Perl Objects, References and Modules)
elements, XML: 22.. Namespaces (Perl Cookbook)
HTML tags: 20.6.3. Discussion (Perl Cookbook)
lists: 9.1. Arrays of Arrays (Programming Perl)
object destruction: 10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
pattern matching: 6.17.1. Problem (Perl Cookbook)
subroutines: 10.16.1. Problem (Perl Cookbook)
8.3.7.2. Nested subroutines (Programming Perl)
Net modules: 8.151. Net::Cmd (Perl in a Nutshell)
16. Email Connectivity (Perl in a Nutshell)
Net::Cmd module: 8.151. Net::Cmd (Perl in a Nutshell)
Net::Config module: 8.152. Net::Config (Perl in a Nutshell)
Net::Domain module: 8.153. Net::Domain (Perl in a Nutshell)
Net::FTP module\: 18.2. Net::FTP (Perl in a Nutshell)
Net::hostent module: 8.155. Net::hostent (Perl in a Nutshell)
Net::netent module: 8.156. Net::netent (Perl in a Nutshell)
Net::Netrc module: 8.157. Net::Netrc (Perl in a Nutshell)
18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
Net::News module: 17.2. Net::NNTP (Perl in a Nutshell)
Net::NNTP module: 8.158. Net::NNTP (Perl in a Nutshell)
Net::Ping module: 8.159. Net::Ping (Perl in a Nutshell)
Net::POP3 module: 8.160. Net::POP3 (Perl in a Nutshell)
16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
Net::protoent module: 8.161. Net::protoent (Perl in a Nutshell)
Net::servent module: 8.162. Net::servent (Perl in a Nutshell)
Net::SMTP module: 8.163. Net::SMTP (Perl in a Nutshell)
16.1.1. Send Email with Net::SMTP (Perl in a Nutshell)
Net::SNPP and Net::Time modules: 16. Email Connectivity (Perl in a Nutshell)
Net::Time module: 8.164. Net::Time (Perl in a Nutshell)
Net::DNS module: 18.1.3. Discussion (Perl Cookbook)
18.16. Program: expn and vrfy (Perl Cookbook)
Net::FTP module: 18.2.2. Solution (Perl Cookbook)
Net::hostent module: 13.5.3. Discussion (Perl Cookbook)
29.2.49. gethostent (Programming Perl)
32.1.8. Networking and Interprocess Communication (Programming Perl)
Class::Struct, using to create objects and accesors: 32.6. Class::Struct (Programming Perl)
Net::LDAP: 19. Lightweight Directory Access with Net::LDAP (Perl in a Nutshell)
directory, adding entries to: 19.3. Adding an Entry to the Directory with Net::LDAP (Perl in a Nutshell)
methods: 19.4. Net::LDAP Methods (Perl in a Nutshell)
searching LDAP: 19.2. Searching an LDAP Directory with Net::LDAP (Perl in a Nutshell)
Net::LDAP module: 18.8.2. Solution (Perl Cookbook)
netloc( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
netlock program: 7.24. Program: netlock (Perl Cookbook)
Net::netent module: 29.2.51. getnetbyaddr (Programming Perl)
32.1.8. Networking and Interprocess Communication (Programming Perl)
netnews: 22.1. The CPAN modules Directory (Programming Perl)
(see also Usenet)
Net::NNTP module: 18.4.2. Solution (Perl Cookbook)
Net::Ping module: 18.7.2. Solution (Perl Cookbook)
32.1.8. Networking and Interprocess Communication (Programming Perl)
Net::POP3 module: 18.5.2. Solution (Perl Cookbook)
Net::proto module: 29.2.59. getprotobynumber (Programming Perl)
Net::protoent module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
.netrc file: 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
netresource data structure: 22.11. Win32::NetResource (Perl in a Nutshell)
Netscape history.db file: 14.19. Program: ggh—Grep Netscape Global History (Perl Cookbook)
:netscape method group: 10.2. Importing Method Groups (Perl in a Nutshell)
Net::servent module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
NetShareAdd( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
NetShareCheck( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
NetShareDel( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
NetShareGetInfo( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
NetShareSetInfo( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
Net::SMTP module: B.5.8. The Net::SMTP Module (Learning Perl)
Net::Telnet module: 18.6.2. Solution (Perl Cookbook)
Network News Transfer Protocol (NNTP): 17. Usenet News (Perl in a Nutshell)
networking: B.13. Networking and IPC (Learning Perl)
clients: 16.5.1. Networking Clients (Programming Perl)
connections (between client and server): Glossary (Programming Perl)
email: 16. Email Connectivity (Perl in a Nutshell)
fetching information, function for: 5.1. Perl Functions by Category (Perl in a Nutshell)
modules for: 32.1.8. Networking and Interprocess Communication (Programming Perl)
modules implementing network protocols: 22.1. The CPAN modules Directory (Programming Perl)
network addresses
translating to names: 29.2.51. getnetbyaddr (Programming Perl)
network addresses, translating into names: 29.2.47. gethostbyaddr (Programming Perl)
network filesystems (see NFS)
network information, functions for retrieving: 29.1. Perl Functions by Category (Programming Perl)
server administration: 22.10. Win32::NetAdmin (Perl in a Nutshell)
servers: 16.5.2. Networking Servers (Programming Perl)
services, Perl module for interacting with: 22.1. The CPAN modules Directory (Programming Perl)
sockets: 15. Sockets (Perl in a Nutshell)
built-in functions for: 15.1. Built-in Socket Functions (Perl in a Nutshell)
IO::Socket module: 15.2. The IO::Socket Module (Perl in a Nutshell)
IO::Socket::INET subclass: 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
IO::Socket::UNIX subclass: 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
Usenet news: 17. Usenet News (Perl in a Nutshell)
Win32 network modules: 32.1.20. Microsoft-Related Modules (Programming Perl)
networking modules: 16.5. Sockets (Programming Perl)
networks file (see /etc/networks file)
new( )
Data::Dumper: 8.50. Data::Dumper (Perl in a Nutshell)
Digest::MD5 module: 8.58. Digest::MD5 (Perl in a Nutshell)
DirHandle module: 8.59. DirHandle (Perl in a Nutshell)
HTML::Element module: 20.4.3. HTML::Element (Perl in a Nutshell)
HTTP::Cookies module: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
HTTP::Cookies::Netscape module: 20.3.6.1. HTTP::Cookies::Netscape (Perl in a Nutshell)
HTTP::Daemon module: 20.3.7. HTTP::Daemon (Perl in a Nutshell)
HTTP::Headers module: 20.3.3. HTTP::Headers (Perl in a Nutshell)
HTTP::Request module: 20.3.1. HTTP::Request (Perl in a Nutshell)
HTTP::Response module: 20.3.2. HTTP::Response (Perl in a Nutshell)
LWP::RobotUA module: 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
Mail::Address module: 16.2.7. Mail::Address Reference (Perl in a Nutshell)
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
Mail::Internet module: 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
Mail::Mailer module: 16.2.1. Send Email with Mail::Mailer (Perl in a Nutshell)
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Net::LDAP: 19.4. Net::LDAP Methods (Perl in a Nutshell)
Net::NNTP module: 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
Net::SMTP module: 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
News::Newsrc module: 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
SOAP::Lite: 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify (Perl in a Nutshell)
Win32::Console module: 22.2. Win32::Console (Perl in a Nutshell)
Win32::Internet module: 22.7. Win32::Internet (Perl in a Nutshell)
22.7.1. General Internet Methods (Perl in a Nutshell)
Win32::OLE module: 23.1. Creating Objects (Perl in a Nutshell)
Win32::OLE::Enum module: 23.3.1. Win32::OLE::Enum Methods (Perl in a Nutshell)
Win32::OLE::Variant module: 23.4. Win32::OLE::Variant (Perl in a Nutshell)
Win32::Pipe module: 22.13. Win32::Pipe (Perl in a Nutshell)
XML::Parser module: 13.2. XML::Parser Methods (Perl in a Nutshell)
new( ): 7.22.3. Discussion (Perl Cookbook)
.new files, renaming from .old files: 13.2. Renaming Files (Learning Perl)
new method: 17.2.1.1. Thread creation (Programming Perl)
29.2.100. new (Programming Perl)
creating objects: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
indirect object notation: 10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
Math::BigInt module: 12.4. A More Typical Object-Oriented Module: Math::BigInt (Learning Perl Objects, References and Modules)
new_from_fd( ): 7.9.2. Solution (Perl Cookbook)
newgroups( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
newline: 2.2. Molecules (Programming Perl)
newlines (see also line breaks, whitespace)
blank lines, truth values and: 1.6.2.1. The while and until statements (Programming Perl)
chomp function, deleting with: 29.2.11. chomp (Programming Perl)
dot (.) metacharacter, matching: 5.3.3. Wildcard Metasymbols (Programming Perl)
in filenames, security risks of: 23.1.2. Cleaning Up Your Environment (Programming Perl)
Perl program portability and: 25.1. Newlines (Programming Perl)
print function and: 6.4. Output to Standard Output (Learning Perl)
removing: 1.4. Filehandles (Programming Perl)
in string literals: 2.6.2. String Literals (Programming Perl)
strings containing, matches against: 5.2.1. Pattern Modifiers (Programming Perl)
trailing
chomp operator for removing: 2.9. The chomp Operator (Learning Perl)
die function and: 11.3. Fatal Errors with die (Learning Perl)
newnews( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
news: 17. Usenet News (Perl in a Nutshell)
Net::News module: 17.2. Net::NNTP (Perl in a Nutshell)
News::Newsrc module: 17.3. The News::Newsrc Module (Perl in a Nutshell)
NNTP protocol: 17.1. The NNTP Protocol (Perl in a Nutshell)
newsgroups: 0.6.2. Usenet Newsgroups (Programming Perl)
listing available: 17.1. The NNTP Protocol (Perl in a Nutshell)
Perl-related: 1.4.1. The comp.lang.perl.* Newsgroups (Perl in a Nutshell)
newsgroups for Perl: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
newsgroups( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
News::Newsrc module: 17.3. The News::Newsrc Module (Perl in a Nutshell)
.newsrc file: 17.3. The News::Newsrc Module (Perl in a Nutshell)
next
used in a do while: 4.5. Bare Blocks (Programming Perl)
4.3.1.5. Loop control (Perl in a Nutshell)
24.1.3. C Traps (Programming Perl)
next operator: 10.8.2. The next Operator (Learning Perl)
1.6.2.4. Breaking out: next and last (Programming Perl)
4.4.1. while and until Statements (Programming Perl)
4.4.4. Loop Control (Programming Perl)
4.4.4. Loop Control (Programming Perl)
29.2.101. next (Programming Perl)
exiting once-through blocks with: 4.5. Bare Blocks (Programming Perl)
next if construct: 24.2.1. Time Efficiency (Programming Perl)
Next( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods (Perl in a Nutshell)
next_labeled_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
next_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
NFA (non-deterministic finite automata): 6.. The Tricky Bits (Perl Cookbook)
NFA (nondeterministic finite-state automaton): 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
NFC( ): 1.9.3. Discussion (Perl Cookbook)
NFD( ): 1.9.2. Solution (Perl Cookbook)
NFKC( ): 1.9.3. Discussion (Perl Cookbook)
NFKD( ): 1.9.3. Discussion (Perl Cookbook)
NFS (network filesystems): Glossary (Programming Perl)
limitations of: 16.5. Sockets (Programming Perl)
$nlink file statistic: 29.2.165. stat (Programming Perl)
$nlink (number of links): 11.6.1. The stat and lstat Functions (Learning Perl)
nlst( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
\N{name} (named character value) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
\NNN metasymbol: 5.3.2. Specific Characters (Programming Perl)
NNTP (Network News Transfer Protocol): 17. Usenet News (Perl in a Nutshell)
nntppost( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
nntpstat( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
no( ): 5. Function Reference (Perl in a Nutshell)
no declaration: 11.1. Using Modules (Programming Perl)
29.2.102. no (Programming Perl)
no declarations: 4.7. Global Declarations (Programming Perl)
4.9. Pragmas (Programming Perl)
14.1.3. Magically Banishing $_ (Programming Perl)
noecho input mode: 15.10.2. Solution (Perl Cookbook)
NOFILE constant: 7.7.3. Discussion (Perl Cookbook)
nomethod overloading key: 13.5. When an Overload Handler Is Missing (nomethod and fallback) (Programming Perl)
non-blocking I/O: 7.20.1. Problem (Perl Cookbook)
non-deterministic finite automata (NFA): 6.. The Tricky Bits (Perl Cookbook)
non-greedy matching: 4.6.6. Quantifiers (Perl in a Nutshell)
non-greedy pattern matching: 6.. The Tricky Bits (Perl Cookbook)
vs. greedy pattern matching: 6.15.1. Problem (Perl Cookbook)
non-numeric strings, converting to numbers: 2.. Introduction (Perl Cookbook)
nonbacktracking subpatterns: 5.10.2. Nonbacktracking Subpatterns (Programming Perl)
nondecimal integer literals: 2.2.4. Nondecimal Integer Literals (Learning Perl)
nondeterministic finite-state automaton (NFA): 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
none index (Menu widget): 21.15.1. Menu Indexes (Perl in a Nutshell)
noninteractive mode, putting debugger in: 20.4. Unattended Execution (Programming Perl)
nonpaired delimiters: 9.1. Matches with m// (Learning Perl)
NonStop option (PERLDB_OPTS): 6.4. Customizing the Debugger (Perl in a Nutshell)
no_proxy( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
not (!) operator: 3.5. Ideographic Unary Operators (Programming Perl)
not equal to (!=) operator: 3.12. Equality Operators (Programming Perl)
NOT functionality in regular expressions: 6.18.1. Problem (Perl Cookbook)
not operator (see negation operator)
Notation handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
notational convenience, tied arrays: 14.2.2. Notational Convenience (Programming Perl)
notes, Apache requests: 21.11.3. Discussion (Perl Cookbook)
noTTY option (PERLDB_OPTS): 6.4. Customizing the Debugger (Perl in a Nutshell)
nounder_demo program: 13.15.4. Tie Example: Outlaw $_ (Perl Cookbook)
nouns: 1.2. Natural and Artificial Languages (Programming Perl)
packages, handling of: 1.2.1.4. Simplicities (Programming Perl)
novice programmers, common mistakes of: 24.1. Common Goofs for Novices (Programming Perl)
no_visits( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
$now variable: 14.4. Using Backquotes to Capture Output (Learning Perl)
n2perm( ): 4.20. Program: permute (Perl Cookbook)
nph( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
$NR variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
nstore( ): 11.13.3. Discussion (Perl Cookbook)
NTFS file permissions: 22.6. Win32::FileSecurity (Perl in a Nutshell)
NUL character: 2.3. Strings (Learning Perl)
DBM hashes and: 16.1.2. Using a DBM Hash (Learning Perl)
null
filehandle ;angle operator and: 2.11.2. Line Input (Angle) Operator (Programming Perl)
list: 2.8. List Values and Arrays (Programming Perl)
values: Glossary (Programming Perl)
null device, Unix: 14.4.2. Creative Filehandles (Programming Perl)
null list, assigning to arrays: 2.8.2. Array Length (Programming Perl)
null values ("" or 0): 1.2.1.1. Singularities (Programming Perl)
number width: 25.2. Endianness and Number Width (Programming Perl)
numbered variables: 28.2. Special Variables in Alphabetical Order (Programming Perl)
numbers: 1.4.1. Problem (Perl Cookbook)
2.. Introduction (Perl Cookbook)
2.2. Numbers (Learning Perl)
2.2. Numbers (Learning Perl)
4.2.1. Numbers (Perl in a Nutshell)
1.2.1. Variable Syntax (Programming Perl)
adding commas to: 2.16.1. Problem (Perl Cookbook)
arrays, storing in: 1.2.1.2. Pluralities (Programming Perl)
bitwise operators, working with: 3.13. Bitwise Operators (Programming Perl)
comma-separated: 8.2. General Quantifiers (Learning Perl)
command (see command history, debugger and)
commas, inserting into: 7.1. Format Variables (Programming Perl)
comparison operators for: 2.6.3. Comparison Operators (Learning Perl)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
complex (imaginary): 2.14.1. Problem (Perl Cookbook)
complex/imaginary and: B.9.2. Imaginary and Complex Numbers (Learning Perl)
converted automatically to strings: 2.3.4. Automatic Conversion Between Numbers and Strings (Learning Perl)
converting between characters and values: 1.4.1. Problem (Perl Cookbook)
converting binary, octal, and hexadecimal: 2.15.1. Problem (Perl Cookbook)
converting nonnumeric variables to: 13.3. Overloadable Operators (Programming Perl)
\D (nondigit) character class: 4.6.4. Character Classes (Perl in a Nutshell)
d for digit=\d (for digit): 1.7. Regular Expressions (Programming Perl)
decimal places, controlling: 13.14.5. Example: Overloaded FixNum Class (Perl Cookbook)
digits in names: 2.5. Names (Programming Perl)
fixed-precision numeric fields: 4.12. Formats (Perl in a Nutshell)
floating-point (see floating-point numbers)
Glossary (Programming Perl)
comparing: 2.3.1. Problem (Perl Cookbook)
rounding: 2.2.1. Problem (Perl Cookbook)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
hexadecimal: 2.6.1. Numeric Literals (Programming Perl)
29.2.73. hex (Programming Perl)
hexadecimal, converting to: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
high-precision/large: B.9.3. Large and High-Precision Numbers (Learning Perl)
integers (see integers)
justifying by decimal point: 7. Formats (Programming Perl)
large, underscore and: 2.6.1. Numeric Literals (Programming Perl)
logarithms: 2.12.1. Problem (Perl Cookbook)
matrix multiplication: 2.13.1. Problem (Perl Cookbook)
octal: 2.6.1. Numeric Literals (Programming Perl)
29.2.103. oct (Programming Perl)
operating on integer series: 2.4.1. Problem (Perl Cookbook)
for pages: 28.2. Special Variables in Alphabetical Order (Programming Perl)
plural words based on: 2.17.1. Problem (Perl Cookbook)
port, getting name for: 29.2.64. getservbyname (Programming Perl)
ports, getting protocol names from: 29.2.65. getservbyport (Programming Perl)
primes, calculating: 2.18. Program: Calculating Prime Factors (Perl Cookbook)
protocol: 29.2.59. getprotobynumber (Programming Perl)
random: 2.. Introduction (Perl Cookbook)
29.2.119. rand (Programming Perl)
29.2.164. srand (Programming Perl)
biasing: 2.9.1. Problem (Perl Cookbook)
generating: 2.6.1. Problem (Perl Cookbook)
Roman numerals: 2.5.1. Problem (Perl Cookbook)
scalars as: 2.. Introduction (Perl Cookbook)
sorting: 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
7.1. Review of Sorting (Learning Perl Objects, References and Modules)
spaceship operator for comparing: 15.4. Advanced Sorting (Learning Perl)
sprintf function for: 15.3.1. Using sprintf with "Money Numbers" (Learning Perl)
strings as valid numbers: 2.1.1. Problem (Perl Cookbook)
strings, converting to: 2.6. Scalar Values (Programming Perl)
testing equality: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
trigonometry: 2.10.1. Problem (Perl Cookbook)
truncating with int: 29.2.76. int (Programming Perl)
truth values of: 1.6.1. What Is Truth? (Programming Perl)
typing in Perl: 2.6. Scalar Values (Programming Perl)
width of: 25.2. Endianness and Number Width (Programming Perl)
numeric comparison operators: 2.6.3. Comparison Operators (Learning Perl)
numeric context: 2.7.1. Scalar and List Context (Programming Perl)
Glossary (Programming Perl)
numeric literals: 2.6.1. Numeric Literals (Programming Perl)
numeric operators: 2.2.5. Numeric Operators (Learning Perl)
numeric user-ID (see user-ID, numeric)
numerical comparison (<=>) operator: 4.15.2. Solution (Perl Cookbook)
NV (internal double value): 21.2. Internal Data Types (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

o command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
O command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-o (effective UID) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-O file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
O_ flags: 7.1.3. Discussion (Perl Cookbook)
7.20.2. Solution (Perl Cookbook)
/o modifier
recompilation, suppressing with: 5.9.2. Variable Interpolation (Programming Perl)
O module: 8.165. O (Perl in a Nutshell)
18.4. Compiler Backends (Programming Perl)
18.6. Code Development Tools (Programming Perl)
32.1.19. Perl Compiler and Code Generator (Programming Perl)
-O option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-o option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
/o pattern modifier: 5.2.1. Pattern Modifiers (Programming Perl)
5.2.1. Pattern Modifiers (Programming Perl)
5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
o pattern match modifier: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
/o pattern-matching modifier: 6.10.2. Solution (Perl Cookbook)
-O (real UID) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
OASIS group: 22.. Schemas (Perl Cookbook)
object
classes: 10. Packages (Programming Perl)
methods: 8.3.4. Using Object Methods (Programming Perl)
object attributes: 13.3.1. Problem (Perl Cookbook)
object methods: 13.. Some Notes on Object Terminology (Perl Cookbook)
locking: 17.2.2.5. Locking methods (Programming Perl)
Thread objects: 17.2.1. The Thread Module (Programming Perl)
object-oriented modules: 11.1. Using Modules (Programming Perl)
method calls, allowing: 11.2. Creating Modules (Programming Perl)
object-oriented (OO) programming: B.20.2. Object-Oriented Programming (Learning Perl)
object-oriented programming: 13.. Under the Hood (Perl Cookbook)
13.. Some Notes on Object Terminology (Perl Cookbook)
7.3. Object-Oriented Perl (Perl in a Nutshell)
8. Introduction to Objects (Learning Perl Objects, References and Modules)
10. Packages (Programming Perl)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
abstraction in: 12.3. Method Invocation (Programming Perl)
modules for file, directory, and IPC access: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
portable filename operations: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
references in Perl, emulating: 10. Packages (Programming Perl)
objects: 13.. Under the Hood (Perl Cookbook)
7.3. Object-Oriented Perl (Perl in a Nutshell)
1.2.1.3. Complexities (Programming Perl)
12. Objects (Programming Perl)
Glossary (Programming Perl)
bless operator and: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
as blessed references: 9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
blessing: 3.2. The Arrow Operator (Programming Perl)
29.2.7. bless (Programming Perl)
class data, managing: 12.8. Managing Class Data (Programming Perl)
cloning parent objects: 13.6.1. Problem (Perl Cookbook)
closures as: 11.7.1. Problem (Perl Cookbook)
constructing: 13.. Methods (Perl Cookbook)
13.1.1. Problem (Perl Cookbook)
constructors: 8.2.3. Object Constructors (Programming Perl)
12.4. Object Construction (Programming Perl)
inheritable: 12.4.1. Inheritable Constructors (Programming Perl)
initializers: 12.4.2. Initializers (Programming Perl)
creating: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
destroying: 13.. Methods (Perl Cookbook)
13.2.1. Problem (Perl Cookbook)
destruction of: 10. Object Destruction (Learning Perl Objects, References and Modules)
destruction of (global), controlling: 19.2. Environment Variables (Programming Perl)
determining subclass membership: 13.9.1. Problem (Perl Cookbook)
encapsulation of: 9.11. Don't Look Inside the Box (Learning Perl Objects, References and Modules)
filehandles and: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
indirect (see indirect objects)
inheritance, through @ISA array: 12.5.1. Inheritance Through @ISA (Programming Perl)
instance data, managing: 12.7. Managing Instance Data (Programming Perl)
12.7.1. Field Declarations with use fields (Programming Perl)
generating accesors with closures: 12.7.4. Generating Accessors with Closures (Programming Perl)
generating accessors with autoloading: 12.7.3. Generating Accessors with Autoloading (Programming Perl)
generating classes with Class::Struct: 12.7.2. Generating Classes with Class::Struct (Programming Perl)
new features, Perl 5.6: 12.7.6. New Tricks (Programming Perl)
private objects, using closures for: 12.7.5. Using Closures for Private Objects (Programming Perl)
instance destructors: 12.6. Instance Destructors (Programming Perl)
garbage collection with: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
instance vs. class methods: 7.4. Object Syntax (Perl in a Nutshell)
instances and: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
managing class data: 13.4.1. Problem (Perl Cookbook)
managing instance data: 13.3.1. Problem (Perl Cookbook)
methods, references to: 8.3.7. Closures (Programming Perl)
8.3.7. Closures (Programming Perl)
(see also closures)
Perl object system: 12.2. Perl's Object System (Programming Perl)
references to, in scalars: 1.2.1.1. Singularities (Programming Perl)
storing within other objects vs. inheritance: 12.6. Instance Destructors (Programming Perl)
stringifying: 8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
structure considerations: 9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
testing with isa and can methods: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
tied objects: 13.15.1. Problem (Perl Cookbook)
tied variables, underlying: 14. Tied Variables (Programming Perl)
breaking reference to: 14.5. A Subtle Untying Trap (Programming Perl)
Objects style (XML::Parser): 13.4. XML::Parser Styles (Perl in a Nutshell)
obtaining Perl modules: 2.2. How Is CPAN Organized? (Perl in a Nutshell)
2.4. Getting and Installing Modules (Perl in a Nutshell)
obtaining Perl source code: 2. Installing Perl (Perl in a Nutshell)
oct( ): 5. Function Reference (Perl in a Nutshell)
2.15.2. Solution (Perl Cookbook)
2.6.1. Numeric Literals (Programming Perl)
29.2.103. oct (Programming Perl)
octal
characters: 2.6.1. Numeric Literals (Programming Perl)
literals: 2.2.4. Nondecimal Integer Literals (Learning Perl)
numbers
converting: 2.15.1. Problem (Perl Cookbook)
values, working with symbolic file permissions instead: 9.11.1. Problem (Perl Cookbook)
29.2.103. oct (Programming Perl)
characters, representing: 15.1. Building Character (Programming Perl)
characters, specifying with: 5.3.2. Specific Characters (Programming Perl)
specifying $/ as: 19.1.3. Switches (Programming Perl)
octets (see also bytes)
15.1. Building Character (Programming Perl)
treating Unicode strings as: 1.10.1. Problem (Perl Cookbook)
ODBC Extension: 24. ODBC Extension for Win32 (Perl in a Nutshell)
ODBM_File module: 8.166. ODBM_File (Perl in a Nutshell)
offsets: Glossary (Programming Perl)
for m// successes: 29.2.112. pos (Programming Perl)
read function and: 29.2.120. read (Programming Perl)
seek function: 29.2.138. seek (Programming Perl)
-offvalue option
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
$OFMT ($#) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$OFS ($,) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
ok function (Test::Simple): 14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
-ok option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
-okay option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
.old files, renaming to .new files: 13.2. Renaming Files (Learning Perl)
OLE automation: 23. OLE Automation (Perl in a Nutshell)
OLE, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
on_action( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
on_debug( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
one-liners: 1.3.1. How to Do It (Programming Perl)
Glossary (Programming Perl)
on_fault( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
on_nonserialized( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
O_NONBLOCK option: 7.20.2. Solution (Perl Cookbook)
-onvalue option
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
OO (object-oriented) modules
exporting: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
exporting and: 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
non-OO versus: 12.5. The Differences Between OO and Non-OO Modules (Learning Perl Objects, References and Modules)
Test::More module: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
OO (object-oriented) programming: B.20.2. Object-Oriented Programming (Learning Perl)
OOP (object-oriented programming)
File::Spec module: 12.3. Sample Object-Oriented Interface: File::Spec (Learning Perl Objects, References and Modules)
inheritance structures and: A.7.2. Exercise 2 (Section 8.11.2) (Learning Perl Objects, References and Modules)
overview: 8. Introduction to Objects (Learning Perl Objects, References and Modules)
versus non-OOP: 12.5. The Differences Between OO and Non-OO Modules (Learning Perl Objects, References and Modules)
Opcode module: 8.167. Opcode (Perl in a Nutshell)
32.1.12. Authentication, Security, and Encryption (Programming Perl)
opcodes: 18.2. Compiling Your Code (Programming Perl)
18.3. Executing Your Code (Programming Perl)
21.1. How Perl Works (Programming Perl)
open( ): 5. Function Reference (Perl in a Nutshell)
DirHandle module: 8.59. DirHandle (Perl in a Nutshell)
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
Mail::Mailer module: 16.2.1. Send Email with Mail::Mailer (Perl in a Nutshell)
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
PerlIO: 4.9.1. Perl 5.8 and PerlIO (Perl in a Nutshell)
Win32::Mutex module: 22.9. Win32::Mutex (Perl in a Nutshell)
Win32::Semaphore module: 22.16. Win32::Semaphore (Perl in a Nutshell)
16.10.3. Discussion (Perl Cookbook)
(see also processes)
caching open filehandles: 7.7.2. Solution (Perl Cookbook)
creating temporary files: 7.11.3. Discussion (Perl Cookbook)
file access modes: 7.. I/O Operations (Perl Cookbook)
file descriptors, creating aliases for: 7.10.3. Discussion (Perl Cookbook)
filehandles: 7.1.2. Solution (Perl Cookbook)
storing in variables: 7.5.2. Solution (Perl Cookbook)
filtering output: 16.5.2. Solution (Perl Cookbook)
magic open: 8.25. Program: tctee (Perl Cookbook)
reading from other programs: 16.4.2. Solution (Perl Cookbook)
unusual filenames: 7.2.2. Solution (Perl Cookbook)
16.3. Fixed-length Random-access Databases (Learning Perl)
1.4. Filehandles (Programming Perl)
16.3.1. Anonymous Pipes (Programming Perl)
29.2.104. open (Programming Perl)
converting file descriptor to filehandle: 16.2.2. Passing Filehandles (Programming Perl)
$. and: 29.2.16. close (Programming Perl)
fileno function and: 29.2.38. fileno (Programming Perl)
fork-open: 29.2.104. open (Programming Perl)
forking open: 16.3.2. Talking to Yourself (Programming Perl)
modes in three-argument form: 29.2.104. open (Programming Perl)
piped
list argument form, avoiding shell with: 23.3.2. Code Masquerading as Data (Programming Perl)
piped (two-argument form): 29.2.104. open (Programming Perl)
for pipes, security risks posed by: 23.1.2. Cleaning Up Your Environment (Programming Perl)
pipes, opening with: 16.3.1. Anonymous Pipes (Programming Perl)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
Open2, Open3 library modules: 16.3.3. Bidirectional Communication (Programming Perl)
open operator: 11.2. Opening a Filehandle (Learning Perl)
open pragma: 8.19.2. Solution (Perl Cookbook)
open source software: Glossary (Programming Perl)
Open( ) (Win32::Registry): 22.15. Win32::Registry (Perl in a Nutshell)
opendir( ): 5. Function Reference (Perl in a Nutshell)
9.5.2. Solution (Perl Cookbook)
globbing: 9.6.3. Discussion (Perl Cookbook)
readdir( ): 9.. Introduction (Perl Cookbook)
29.2.105. opendir (Programming Perl)
12.4. Directory Handles (Learning Perl)
opening
file descriptors: 7.9.1. Problem (Perl Cookbook)
files: 7.1.1. Problem (Perl Cookbook)
files via low-level system call: 29.2.171. sysopen (Programming Perl)
sockets: 29.2.157. socket (Programming Perl)
OpenLDAP: 19. Lightweight Directory Access with Net::LDAP (Perl in a Nutshell)
OpenRequest( ) (Win32::Internet): 22.7.3. HTTP Functions (Perl in a Nutshell)
OpenSSL libraries: 20.16.3. Discussion (Perl Cookbook)
OpenURL( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
operand stack: 18.3. Executing Your Code (Programming Perl)
operating system: 0.1. The Pursuit of Happiness (Programming Perl)
operating system name: 28.2. Special Variables in Alphabetical Order (Programming Perl)
operating systems: Glossary (Programming Perl)
#! technique, simulating on non-Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
command interpreters for: 19.1. Command Processing (Programming Perl)
flock support on: 16.2.1. File Locking (Programming Perl)
fork operator, support for: 16.2.2. Passing Filehandles (Programming Perl)
GUIs, relying on: 25.4. System Interaction (Programming Perl)
interfaces to, manipulating: 32.1.7. Operating System Interfaces (Programming Perl)
invoking interpreters with #! line: 19.1. Command Processing (Programming Perl)
module names, translating to directory names: 11.1. Using Modules (Programming Perl)
newlines, variations in: 25.1. Newlines (Programming Perl)
perl interpreter, starting on: 1.3.1. How to Do It (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Perl ports to: 22. CPAN (Programming Perl)
Perl program portability: 25. Portable Perl (Programming Perl)
signal reliability on: 16.1.2. Reaping Zombies (Programming Perl)
signals and default behaviors of: 16.1. Signals (Programming Perl)
sockets, support for: 16.5. Sockets (Programming Perl)
threading libraries: 17.2. The Thread Model (Programming Perl)
operations, contexts, evaluation in: 2.7.1. Scalar and List Context (Programming Perl)
operator: 2.8. Getting User Input (Learning Perl)
context and: 3.9. <STDIN> in List Context (Learning Perl)
defined function and: 2.12. The defined Function (Learning Perl)
while loop shortcut and: 6.1. Input from Standard Input (Learning Perl)
operator precedence (see precedence)
operators: 4.5. Operators (Perl in a Nutshell)
1.5. Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
Glossary (Programming Perl)
access, restricting with Safe module: 23.3.1.2. Restricting operator access (Programming Perl)
assignment operators: 1.5.3. Assignment Operators (Programming Perl)
associativity and: 2.6.2. Operator Precedence and Associativity (Learning Perl)
associativity of: 3. Unary and Binary Operators (Programming Perl)
C language, missing in Perl: 3.21. C Operators Missing from Perl (Programming Perl)
comparison: 2.6.3. Comparison Operators (Learning Perl)
15.4. Advanced Sorting (Learning Perl)
line input: 7.. I/O Operations (Perl Cookbook)
8.. Basic Operations (Perl Cookbook)
logical operators: 1.5.5. Logical Operators (Programming Perl)
matching and substitution: 5. Pattern Matching (Programming Perl)
numeric: 2.2.5. Numeric Operators (Learning Perl)
overload module for: B.22. Operator Overloading (Learning Perl)
overloadable: 13.3. Overloadable Operators (Programming Perl)
Glossary (Programming Perl)
arithmetic operators: 13.3. Overloadable Operators (Programming Perl)
assignment operators: 13.3. Overloadable Operators (Programming Perl)
bitwise operators: 13.3. Overloadable Operators (Programming Perl)
circular references, problems with: 13.3. Overloadable Operators (Programming Perl)
comparison operators: 13.3. Overloadable Operators (Programming Perl)
conversion operators: 13.3. Overloadable Operators (Programming Perl)
dereference operators: 13.3. Overloadable Operators (Programming Perl)
iterative operator: 13.3. Overloadable Operators (Programming Perl)
logical negation operator: 13.3. Overloadable Operators (Programming Perl)
overloading: 13.14.1. Problem (Perl Cookbook)
3. Unary and Binary Operators (Programming Perl)
13. Overloading (Programming Perl)
32.1.1. Data Types (Programming Perl)
pattern-matching: 5.2. Pattern-Matching Operators (Programming Perl)
modifiers for: 5.2.1. Pattern Modifiers (Programming Perl)
perlfunc manpage and: B.8. Other Operators and Functions (Learning Perl)
perlop manpage and: B.8. Other Operators and Functions (Learning Perl)
positions or lengths, switching to character positions: 15.2. Effects of Character Semantics (Programming Perl)
precedence and: 2.6.2. Operator Precedence and Associativity (Learning Perl)
precedence of: 1.5.1. Some Binary Arithmetic Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
C precedence, retaining in Perl: 3. Unary and Binary Operators (Programming Perl)
quotes, syntactical similarity to: 1.2.1.1. Singularities (Programming Perl)
quoting operators: 2.6.3. Pick Your Own Quotes (Programming Perl)
scalar context, supplying to parameters: 1.2.1.1. Singularities (Programming Perl)
string operators: 1.5.2. String Operators (Programming Perl)
verbs as: 1.2.2. Verbs (Programming Perl)
operators, for loop control: 4.4.4. Loop Control (Programming Perl)
ops module: 8.168. ops (Perl in a Nutshell)
32.1.12. Authentication, Security, and Encryption (Programming Perl)
optimizing
in the Perl compiler: 18.2. Compiling Your Code (Programming Perl)
performance and: 24.2. Efficiency (Programming Perl)
option modifiers: 9.2. Option Modifiers (Learning Perl)
option processing, Perl modules for: 32.1.3. Option, Argument, Parameter, and Configuration File Processing (Programming Perl)
option processing, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Optionmenu widget (Perl/Tk): 21.16. The Optionmenu Widget (Perl in a Nutshell)
options (see switches, command-line)
19.1.3. Switches (Programming Perl)
-options option (Optionmenu): 21.16. The Optionmenu Widget (Perl in a Nutshell)
OR (||) operator: 3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
4.5.9. Logical Operators (Perl in a Nutshell)
list operators and: 4.7. Global Declarations (Programming Perl)
10.9. Logical Operators (Learning Perl)
10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
die function and: 11.3. Fatal Errors with die (Learning Perl)
OR (|) operator, bitwise: 4.5.10. Bitwise Operators (Perl in a Nutshell)
OR functionality in regular expressions: 6.18.1. Problem (Perl Cookbook)
OR logical operator: 1.5.5. Logical Operators (Programming Perl)
or operator: 3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
5.9.1. Letting Perl Do the Work (Programming Perl)
24.3. Programming with Style (Programming Perl)
| (bitwise): 3.13. Bitwise Operators (Programming Perl)
list operators, use with: 4.7. Global Declarations (Programming Perl)
precedence, or vs. ||: 12.3.3. Syntactic Snafus with Indirect Objects (Programming Perl)
or operator, vs. || operator: 1.2.3. Discussion (Perl Cookbook)
or (OR) operator: 4.5.9. Logical Operators (Perl in a Nutshell)
oraperl package: 12.2. Design of DBI (Perl in a Nutshell)
ord( ): 5. Function Reference (Perl in a Nutshell)
1.4.3. Discussion (Perl Cookbook)
15.2. Effects of Character Semantics (Programming Perl)
29.2.106. ord (Programming Perl)
order (see precedence)
of function precedence: 29. Functions (Programming Perl)
ordered lists: 3. Introduction to References (Learning Perl Objects, References and Modules)
-orient option
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
ornaments option (debugger): 20.3.3. Debugger Options (Programming Perl)
$ORS ($\) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
OS/2 operating system
invoking Perl applications on: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
OSBC
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
$OS_ERROR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$OS_ERROR ($!) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$OSNAME (see $^O variable)
28.2. Special Variables in Alphabetical Order (Programming Perl)
$OSNAME ($^O) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
our( ): 5. Function Reference (Perl in a Nutshell)
our declarations: 2.5.1. Name Lookups (Programming Perl)
4. Statements and Declarations (Programming Perl)
29.2.107. our (Programming Perl)
context rules and: 2.7.1. Scalar and List Context (Programming Perl)
global variables, lexically scoped: 4.8.3. Lexically Scoped Global Declarations: our (Programming Perl)
our function: 4.8.1. Scoped Variable Declarations (Programming Perl)
4.8.2. Lexically Scoped Variables: my (Programming Perl)
29.2.107. our (Programming Perl)
our variables: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
out of memory errors: 28.2. Special Variables in Alphabetical Order (Programming Perl)
outer( ): 10.16.3. Discussion (Perl Cookbook)
outlaw $_ program: 13.15.4. Tie Example: Outlaw $_ (Perl Cookbook)
outline programs: 11.16. Program: Outlines (Perl Cookbook)
output: 6.4. Output to Standard Output (Learning Perl)
5.1. Perl Functions by Category (Perl in a Nutshell)
29.2.38. fileno (Programming Perl)
(see also STDOUT filehandle)
array and hash, changing style (debugger): 20.3.3. Debugger Options (Programming Perl)
buffered: 6.4. Output to Standard Output (Learning Perl)
capturing using backquotes: 14.4. Using Backquotes to Capture Output (Learning Perl)
checking file descriptors for: 29.2.141. select (ready file descriptors) (Programming Perl)
controlling decimal places: 13.14.5. Example: Overloaded FixNum Class (Perl Cookbook)
controlling for other programs: 16.8.1. Problem (Perl Cookbook)
currently selected channel: Glossary (Programming Perl)
debugger, setting: 20.4. Unattended Execution (Programming Perl)
field separator (see $, variable)
files, open mode for: 29.2.104. open (Programming Perl)
filtering: 16.5.1. Problem (Perl Cookbook)
flushing: 7.19.1. Problem (Perl Cookbook)
format output accumulator: 29.2.42. formline (Programming Perl)
formats for: 4.12. Formats (Perl in a Nutshell)
formatted with printf function: 6.5. Formatted Output with printf (Learning Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
gathering from programs: 16.1.1. Problem (Perl Cookbook)
ioctl function: 29.2.77. ioctl (Programming Perl)
pipes: 16.3. Pipes (Programming Perl)
16.3. Pipes (Programming Perl)
bidirectional: 16.3.3. Bidirectional Communication (Programming Perl)
filtering: 16.3.2. Talking to Yourself (Programming Perl)
STDOUT as pipe to another program: 16.3.1. Anonymous Pipes (Programming Perl)
tridirectional: 16.3.3. Bidirectional Communication (Programming Perl)
random access I/O: 8.12.1. Problem (Perl Cookbook)
record separator (see $\ variable)
selecting filehandles for: 29.2.140. select (output filehandle) (Programming Perl)
writing to other programs: 16.4.1. Problem (Perl Cookbook)
XSUBs: 21.3.3. XSUB Input and Output (Programming Perl)
output( ): 5.17. Program: dutree (Perl Cookbook)
output filehandles: 1.4. Filehandles (Programming Perl)
output filehandles;STDOUT: 1.4. Filehandles (Programming Perl)
output record formats, declaring: 7. Formats (Programming Perl)
$OUTPUT_AUTOFLUSH: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$OUTPUT_AUTOFLUSH ($|) variable: 4.4.6. Filehandle Special Variables (Perl in a Nutshell)
OutputCP( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
output_fh( ): 22.7.3. Discussion (Perl Cookbook)
$OUTPUT_FIELD_SEPARATOR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$OUTPUT_FIELD_SEPARATOR ($,) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
output_file( ): 22.7.3. Discussion (Perl Cookbook)
$OUTPUT_RECORD_SEPARATOR: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$OUTPUT_RECORD_SEPARATOR ($\\\\) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
outputxml( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
=over command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
overloading mathematical functions: 13.3. Overloadable Operators (Programming Perl)
overload handlers: 13.2. Overload Handlers (Programming Perl)
overload module: B.22. Operator Overloading (Learning Perl)
8.169. overload (Perl in a Nutshell)
overloaded functions: 2.7.1. Scalar and List Context (Programming Perl)
Overloaded (overload::Overloaded): 13.7. Public Overload Functions (Programming Perl)
overloaded string constants, translating text with: 5.10.4. Defining Your Own Assertions (Programming Perl)
overloading: 3. Unary and Binary Operators (Programming Perl)
13. Overloading (Programming Perl)
Glossary (Programming Perl)
autogeneration of: 13.3. Overloadable Operators (Programming Perl)
circular references, avoiding: 13.3. Overloadable Operators (Programming Perl)
constants: 13.6. Overloading Constants (Programming Perl)
copy constructor (=): 13.4. The Copy Constructor (=) (Programming Perl)
diagnostics: 13.10. Overloading Diagnostics (Programming Perl)
functions for: 13.7. Public Overload Functions (Programming Perl)
inheritance and: 13.8. Inheritance and Overloading (Programming Perl)
nonmethod and fallback: 13.5. When an Overload Handler Is Missing (nomethod and fallback) (Programming Perl)
overload module: 32.1.1. Data Types (Programming Perl)
overload pragma: 13.1. The overload Pragma (Programming Perl)
overloadable operators: 13.3. Overloadable Operators (Programming Perl)
at run time: 13.9. Run-Time Overloading (Programming Perl)
sorting and: 13.3. Overloadable Operators (Programming Perl)
stringifying: 14.4.1. Filehandle-Tying Methods (Programming Perl)
overloading, autogeneration of: 13.3. Overloadable Operators (Programming Perl)
overloading operators: 13.14.1. Problem (Perl Cookbook)
overridden methods: 13.11.1. Problem (Perl Cookbook)
overridden methods, base class, invoking all: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
overridedirect( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
overriding
base class methods: 12.5.2. Accessing Overridden Methods (Programming Perl)
built-in functions: 12.12.1. Problem (Perl Cookbook)
functions: 11.3. Overriding Built-in Functions (Programming Perl)
methods: 8.6. Overriding the Methods (Learning Perl Objects, References and Modules)
signal handlers: 16.16.1. Problem (Perl Cookbook)
superclass methods: 10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
UNIVERSAL class methods: 11.1. UNIVERSAL Methods (Learning Perl Objects, References and Modules)
overview_fmt( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
overwriting existing files, race conditions and: 23.2.2. Handling Race Conditions (Programming Perl)
ownership, file: 29.2.13. chown (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

-P (C preprocessor) command-line switch: 19.1.3. Switches (Programming Perl)
-p command-line option: 16.4.1. In-place Editing from the Command Line (Learning Perl)
modifying files with: 7.16.2. Solution (Perl Cookbook)
writing filters: 7.14.3.2. Command-line options (Perl Cookbook)
p command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
\P (doesn't match property): 15.2. Effects of Character Semantics (Programming Perl)
-p file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
16.3.4. Named Pipes (Programming Perl)
\p (matches property): 15.2. Effects of Character Semantics (Programming Perl)
-p (named pipe) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-p option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-p (print while looping) command-line switch: 19.1.3. Switches (Programming Perl)
pack ( ): 25.2. Endianness and Number Width (Programming Perl)
1.4.3. Discussion (Perl Cookbook)
8.13.2. Solution (Perl Cookbook)
with Tk resize events: 15.16.2. Solution (Perl Cookbook)
16.2. Manipulating Data with pack and unpack (Learning Perl)
29.2.108. pack (Programming Perl)
template characters for: 29.2.108. pack (Programming Perl)
unpack function, Unicode characters and: 15.2. Effects of Character Semantics (Programming Perl)
pack geometry manager (Perl/Tk): 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
package( ): 5. Function Reference (Perl in a Nutshell)
_ _PACKAGE_ _ constant: 4.4.4. Global Special Constants (Perl in a Nutshell)
package declaration: 4.8. Scoped Declarations (Programming Perl)
10. Packages (Programming Perl)
29.2.109. package (Programming Perl)
package statement: 12.. Introduction (Perl Cookbook)
7.1. Namespaces and Packages (Perl in a Nutshell)
__PACKAGE__ symbol: 10.4.3. Discussion (Perl Cookbook)
12.6.3. Discussion (Perl Cookbook)
package variables
wrapping declaration in block scope: 12.8. Managing Class Data (Programming Perl)
storing class data in: 12.8. Managing Class Data (Programming Perl)
package variables (see also global variables)
2.5.1. Name Lookups (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
declaring: 29.2.107. our (Programming Perl)
threads, no protection in: 17.2.2. Data Access (Programming Perl)
packages: 12.. Introduction (Perl Cookbook)
B.3. Packages (Learning Perl)
7.1. Namespaces and Packages (Perl in a Nutshell)
12. Using Modules (Learning Perl Objects, References and Modules)
1.2.1.4. Simplicities (Programming Perl)
2.5. Names (Programming Perl)
2.5. Names (Programming Perl)
10. Packages (Programming Perl)
10.2. Autoloading (Programming Perl)
Glossary (Programming Perl)
adding methods to existing: 12.5.2. Accessing Overridden Methods (Programming Perl)
binding variables to: 29.2.191. untie (Programming Perl)
bless function arguments: 12.4. Object Construction (Programming Perl)
blessing objects into: 29.2.7. bless (Programming Perl)
current package: Glossary (Programming Perl)
delimiters for: 10. Packages (Programming Perl)
determining current calling: 12.6.1. Problem (Perl Cookbook)
global variables: 2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
identifiers: 10. Packages (Programming Perl)
importing semantics to: 29.2.192. use (Programming Perl)
in @ISA array, inheritance through: 12.5.1. Inheritance Through @ISA (Programming Perl)
@ISA variable and: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
lexicals and: 2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
main program in: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
methods and subroutines, resolving for: 12.3. Method Invocation (Programming Perl)
names for: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
24.3. Programming with Style (Programming Perl)
as namespace separators: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
naming considerations: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
overriding built-in functions: 12.12.1. Problem (Perl Cookbook)
private variables: 12.4.1. Problem (Perl Cookbook)
quoting: 12.3.4. Package-Quoted Classes (Programming Perl)
referring to indirectly: 12.16.1. Problem (Perl Cookbook)
scope of directives: 2.8. Scope of a Package Directive (Learning Perl Objects, References and Modules)
2.8. Scope of a Package Directive (Learning Perl Objects, References and Modules)
splitting for autoloading: 32.1.17. Module Installation Support (Programming Perl)
symbol tables
displaying: 20.3.3. Debugger Options (Programming Perl)
symbol tables for: 10.1. Symbol Tables (Programming Perl)
tying variables to: 29.2.178. tie (Programming Perl)
packed sockaddr: 29.2.54. getpeername (Programming Perl)
packet-oriented communication: 15. Sockets (Perl in a Nutshell)
packForget( ) (pack geometry manager): 21.2.1.1. pack methods (Perl in a Nutshell)
packInfo( ) (pack geometry manager): 21.2.1.1. pack methods (Perl in a Nutshell)
packPropogate( ) (pack geometry manager): 21.2.1.1. pack methods (Perl in a Nutshell)
packSlaves( ) (pack geometry manager): 21.2.1.1. pack methods (Perl in a Nutshell)
-padbottom option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
-padleft option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
-padright option form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
pads: 2.5. Names (Programming Perl)
-padtop option form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
-padx option form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
-padx, -pady options: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
grid geometry manager: 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
pack geometry manager: 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
-pady option form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
page numbers: 28.2. Special Variables in Alphabetical Order (Programming Perl)
pager option (debugger): 20.3.3. Debugger Options (Programming Perl)
pages: 28.2. Special Variables in Alphabetical Order (Programming Perl)
PalmPilot, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
paragraph mode: 19.1.3. Switches (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
paragraph separator character: 2.2. Molecules (Programming Perl)
paragraph tags (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
paragraphs
counting in files: 8.2.1. Problem (Perl Cookbook)
in pod documentation: 12.20.3. Discussion (Perl Cookbook)
reading files backwards by: 8.4.1. Problem (Perl Cookbook)
reformatting: 1.17.1. Problem (Perl Cookbook)
param( ): 19.1.3. Discussion (Perl Cookbook)
param( ) (CGI.pm): 10. The CGI.pm Module (Perl in a Nutshell)
10.7. CGI.pm Reference (Perl in a Nutshell)
parameter lists: 4.5. Arguments (Learning Perl)
empty: 4.8.2. Empty Parameter Lists (Learning Perl)
variable-length: 4.8. Variable-length Parameter Lists (Learning Perl)
parameters (see also arguments)
28.2. Special Variables in Alphabetical Order (Programming Perl)
@_: 8.9. What to Do with @_ (Learning Perl Objects, References and Modules)
adding to methods: 9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
9.7. Adding Parameters to a Method (Learning Perl Objects, References and Modules)
callbacks and: 6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
hash references as: 3.9.2. Exercise 2 [30 min] (Learning Perl Objects, References and Modules)
instance methods and: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
instances as: 9.2. Invoking an Instance Method (Learning Perl Objects, References and Modules)
method invocation and: 8.3. The Extra Parameter of Method Invocation (Learning Perl Objects, References and Modules)
8.3. The Extra Parameter of Method Invocation (Learning Perl Objects, References and Modules)
passing to superclasses: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
returning updated values: 9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
scalar context, providing for: 1.2.1.1. Singularities (Programming Perl)
shifting: 8.4. Calling a Second Method to Simplify Things (Learning Perl Objects, References and Modules)
8.9. What to Do with @_ (Learning Perl Objects, References and Modules)
subroutines
changing in place: 6.2.1. Tricks with Parameter Lists (Programming Perl)
working with: 6.2.1. Tricks with Parameter Lists (Programming Perl)
params function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
params( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
( ) (parentheses);grouping operator: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
parent-child relationships: 10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
parent classes: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
accessing overridden methods: 13.11.1. Problem (Perl Cookbook)
cloning objects: 13.6.1. Problem (Perl Cookbook)
parent( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
parent processes (see processes)
parent processes, managing: 14. Process Management (Learning Perl)
parentheses
file tests and: 11.6. File Tests (Learning Perl)
grouping patterns with: 7.2.3. Grouping in Patterns (Learning Perl)
indicating precedence: 2.6.2. Operator Precedence and Associativity (Learning Perl)
optional use of: 3.4.1. The pop and push Operators (Learning Perl)
with print function: 6.4. Output to Standard Output (Learning Perl)
with memory function: 8.4. Memory Parentheses (Learning Perl)
around function arguments: 5. Function Reference (Perl in a Nutshell)
operator precedence and: 4.5. Operators (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
(?...) extended regular expression syntax: 4.6.8. Extended Regular Expressions (Perl in a Nutshell)
1.. Introduction (Perl Cookbook)
autouse pragma: 12.3.3. Discussion (Perl Cookbook)
prototyping functions: 10.11.3.1. Omitting parentheses (Perl Cookbook)
substitution: 6.1.3. Discussion (Perl Cookbook)
parse( )
HTML::Parser module: 20.4.1. HTML::Parser (Perl in a Nutshell)
Mail::Address module: 16.2.7. Mail::Address Reference (Perl in a Nutshell)
XML::Parser module: 13.2. XML::Parser Methods (Perl in a Nutshell)
HTML tables, extracting data: 20.19.3. Discussion (Perl Cookbook)
parse trees: 18.1. The Life Cycle of a Perl Program (Programming Perl)
18.2. Compiling Your Code (Programming Perl)
internal, keeping: 18.4. Compiler Backends (Programming Perl)
original, reconstituting and splicing into current parse tree: 18.5.1. The Bytecode Generator (Programming Perl)
reconstruction of: 18.1. The Life Cycle of a Perl Program (Programming Perl)
parse_csv subroutines: 1.20.3. Discussion (Perl Cookbook)
ParseDate( ): 3.7.2. Solution (Perl Cookbook)
3.11. Program: hopdelta (Perl Cookbook)
parse_date( ) (HTTP::Date): 20.3.5. HTTP::Date (Perl in a Nutshell)
parse_file( ) (HTML::Parser): 20.4.1. HTML::Parser (Perl in a Nutshell)
parsefile( ) (XML::Parser module): 13.2. XML::Parser Methods (Perl in a Nutshell)
parse_head( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
parse_start( ) (XML::Parser module): 13.2. XML::Parser Methods (Perl in a Nutshell)
parsestring( ) (XML::Parser module): 13.2. XML::Parser Methods (Perl in a Nutshell)
parsing: 21.1. How Perl Works (Programming Perl)
comma-separated data: 1.20.1. Problem (Perl Cookbook)
command-line arguments: 15.1.1. Problem (Perl Cookbook)
commas into numbers: 2.16.1. Problem (Perl Cookbook)
date and time from strings: 3.7.1. Problem (Perl Cookbook)
double-quote interpolation and regular expressions: 5.2. Pattern-Matching Operators (Programming Perl)
email addresses: 16.2.6. Parse Email Addresses with Mail::Address (Perl in a Nutshell)
event-based: 13.3. Expat Handlers (Perl in a Nutshell)
file specifications: 12.1. Sample Function-Oriented Interface: File::Basename (Learning Perl Objects, References and Modules)
filenames: 9.10.1. Problem (Perl Cookbook)
HTML: 20.18.1. Problem (Perl Cookbook)
HTML tags: 20.6.1. Problem (Perl Cookbook)
in the Perl compiler: 18.2. Compiling Your Code (Programming Perl)
shifting style: 2.1. The Cure for the Common Code (Learning Perl Objects, References and Modules)
3.1. Performing the Same Task on Many Arrays (Learning Perl Objects, References and Modules)
text, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
web server log file: 20.12.1. Problem (Perl Cookbook)
XML
into data structures: 22.1.1. Problem (Perl Cookbook)
into DOM tree: 22.2.1. Problem (Perl Cookbook)
into SAX events: 22.3.1. Problem (Perl Cookbook)
partial-evaluation operators: 10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
pass( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
PASS command (POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
passing
arrays and hashes by reference: 10.5.1. Problem (Perl Cookbook)
by named parameter: 10.7.1. Problem (Perl Cookbook)
passing arguments to subroutines: 4.7.2. Passing Arguments (Perl in a Nutshell)
passing by reference: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
6.2. Semantics (Programming Perl)
Glossary (Programming Perl)
prototypes declaring function calls as: 8.1. What Is a Reference? (Programming Perl)
passing by value: Glossary (Programming Perl)
passing by value, copying @_ values to my list: 6.2.1. Tricks with Parameter Lists (Programming Perl)
passing references: 6.3. Passing References (Programming Perl)
passing references to subroutines: 4.7.3. Passing References (Perl in a Nutshell)
password( )
Net::Netrc module: 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
password databases (Unix): B.7.1. Direct System Database Access (Learning Perl)
password entries (.netrc): 18.3. FTP Configuration with Net::Netrc (Perl in a Nutshell)
Password( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
password_field( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
passwords: 29.2.164. srand (Programming Perl)
crypt function and: 29.2.20. crypt (Programming Perl)
passwd file: 29.2.61. getpwent (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
randomly generating: 2.6.3. Discussion (Perl Cookbook)
reading without echo: 15.10.1. Problem (Perl Cookbook)
15.10.1. Problem (Perl Cookbook)
pasv( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
pasv_wait( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
pasv_xfer( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
pasv_xfer_unique( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
patches for Perl source code: 2.3.1.2. Patches (Perl in a Nutshell)
path( )
Mail::Address module: 16.2.7. Mail::Address Reference (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
PATH environment variable: 14.3. The Environment Variables (Learning Perl)
2.5. require and @INC (Learning Perl Objects, References and Modules)
1.3.1. How to Do It (Programming Perl)
19.1.3. Switches (Programming Perl)
19.2. Environment Variables (Programming Perl)
security and: 23.1.2. Cleaning Up Your Environment (Programming Perl)
path for library searches, %INC: 28.2. Special Variables in Alphabetical Order (Programming Perl)
PATH variable: 3.3. Environment Variables (Perl in a Nutshell)
PATHEXT variable: 3.3. Environment Variables (Perl in a Nutshell)
path_info( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
PATH_INFO variable: 9.3. Extra Path Information (Perl in a Nutshell)
pathnames module installed on Windows system: 11.1. Using Modules (Programming Perl)
paths, searching for installed modules/libraries: 12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
paths, XML: 22.. Paths (Perl Cookbook)
path_translated( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
PATH_TRANSLATED variable: 9.3. Extra Path Information (Perl in a Nutshell)
pattern-binding operator: 1.7. Regular Expressions (Programming Perl)
pattern match operator (m//): 9.1. Matches with m// (Learning Perl)
pattern matching (see regular expressions)
pattern matching functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
pattern matching operators: 4.5.7. Pattern Match Operators (Perl in a Nutshell)
4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
pattern separators, reading data with: 6.7.1. Problem (Perl Cookbook)
pattern space: 28.2. Special Variables in Alphabetical Order (Programming Perl)
patterns: 7.1. What Are Regular Expressions? (Learning Perl)
7.1. What Are Regular Expressions? (Learning Perl)
7.2. Using Simple Patterns (Learning Perl)
autosplitting via -a switch: 19.1.3. Switches (Programming Perl)
debugger, commands for matching: 20.2.5. Locating Code (Programming Perl)
fancy patterns: 5.10.1. Lookaround Assertions (Programming Perl)
manpages for: 8.5.2. And There's More (Learning Perl)
replacements, changes in Perl versions: 24.1.5. Previous Perl Traps (Programming Perl)
split operator and: 9.7. The split Operator (Learning Perl)
test program for: 7.3. A Pattern Test Program (Learning Perl)
patterns (and regular expressions): 1.7. Regular Expressions (Programming Perl)
5. Pattern Matching (Programming Perl)
29.2.92. m// (Programming Perl)
alphanumeric metasymbols: 5.3.1. Metasymbol Tables (Programming Perl)
assertions, defining your own: 5.10.4. Defining Your Own Assertions (Programming Perl)
assertions in: 5.1. The Regular Expression Bestiary (Programming Perl)
backreferences: 1.7.4. Backreferences (Programming Perl)
5.7.1. Capturing (Programming Perl)
capturing in: 5.7. Capturing and Clustering (Programming Perl)
character classes: 1.7. Regular Expressions (Programming Perl)
5.4. Character Classes (Programming Perl)
characters in: 5.1. The Regular Expression Bestiary (Programming Perl)
clustering in: 5.7.2. Clustering (Programming Perl)
conditional interpolation in: 5.10.3.5. Conditional interpolation (Programming Perl)
controlling matching: 5.9. Staying in Control (Programming Perl)
Perl flow control, deciding pattern execution: 5.9.1. Letting Perl Do the Work (Programming Perl)
regex compiler: 5.9.3. The Regex Compiler (Programming Perl)
extension syntax: 5.3.1. Metasymbol Tables (Programming Perl)
extensions
lookaround assertions: 5.10.1. Lookaround Assertions (Programming Perl)
finding duplicate words in paragraphs: 5.2.1. Pattern Modifiers (Programming Perl)
functions for matching: 29.1. Perl Functions by Category (Programming Perl)
generated: 5.10.3.1. Generated patterns (Programming Perl)
greedy matching: 1.7.1. Quantifiers (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
grep function and: 29.2.72. grep (Programming Perl)
match-time code evaluation: 5.10.3.3. Match-time code evaluation (Programming Perl)
match-time pattern interpolation: 5.10.3.4. Match-time pattern interpolation (Programming Perl)
matching
operators for: 1.7. Regular Expressions (Programming Perl)
5.2. Pattern-Matching Operators (Programming Perl)
special variables for: 5.2. Pattern-Matching Operators (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
substrings corresponding to subpatterns: 5.2. Pattern-Matching Operators (Programming Perl)
matching precedence: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
metacharacters and metasymbols in: 5.3. Metacharacters and Metasymbols (Programming Perl)
metasymbols in: 5.3.2. Specific Characters (Programming Perl)
minimal matching: 1.7.2. Minimal Matching (Programming Perl)
modifiers cloistering: 5.7.3. Cloistered Pattern Modifiers (Programming Perl)
modifiers for: 5.2.1. Pattern Modifiers (Programming Perl)
Perl code, interjecting into: 5.10.3. Programmatic Patterns (Programming Perl)
positions for matching: 5.6. Positions (Programming Perl)
programming style for: 5.10.3. Programmatic Patterns (Programming Perl)
quantifiers in: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
5.5. Quantifiers (Programming Perl)
5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
quotes in: 2.6.3. Pick Your Own Quotes (Programming Perl)
re pragma, altering default behavior of: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
recursive matching: 5.10.3.4. Match-time pattern interpolation (Programming Perl)
security concerns: 23.3.2. Code Masquerading as Data (Programming Perl)
split function: 29.2.161. split (Programming Perl)
split function and: 5.2. Pattern-Matching Operators (Programming Perl)
study function: 29.2.166. study (Programming Perl)
substitution evaluation: 5.10.3.2. Substitution evaluations (Programming Perl)
terminating delimiter for: 5.2. Pattern-Matching Operators (Programming Perl)
Unicode properties, matching on: 15.2. Effects of Character Semantics (Programming Perl)
for untainting data: 23.1.1. Detecting and Laundering Tainted Data (Programming Perl)
PAUSE: 22.3. Creating CPAN Modules (Programming Perl)
PAUSE (Perl Authors Upload Server) ID: 15.2. Getting Prepared (Learning Perl Objects, References and Modules)
15.4. Uploading Your Distribution (Learning Perl Objects, References and Modules)
PauseService( ) (Win32::Service): 22.17. Win32::Service (Perl in a Nutshell)
pausing scripts: 29.2.156. sleep (Programming Perl)
PDL (Perl Data Language): 2.13.2. Solution (Perl Cookbook)
22.1. The CPAN modules Directory (Programming Perl)
modules, matrix multiplication: 2.13.2. Solution (Perl Cookbook)
PeekInput( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
Peer option (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
peeraddr( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods (Perl in a Nutshell)
PeerAddr option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
peerhost( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods (Perl in a Nutshell)
peerpath (IO::Socket::UNIX): 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
peerport( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods (Perl in a Nutshell)
PeerPort option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
percent sign (%): 29.2.189. unpack (Programming Perl)
dereferencing with: 4.8.2. Dereferencing (Perl in a Nutshell)
hashes: 5.. Introduction (Perl Cookbook)
indicating conversion: 6.5. Formatted Output with printf (Learning Perl)
indicating entire hash: 5.2.1. The Hash as a Whole (Learning Perl)
modulus operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
printing: 6.5. Formatted Output with printf (Learning Perl)
prototype symbol (hash): 4.7.5. Prototypes (Perl in a Nutshell)
%SIG hash: 16.15.2. Solution (Perl Cookbook)
%= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
%SIG: 4.10. Signals (Perl in a Nutshell)
performance: 0.1. The Pursuit of Happiness (Programming Perl)
backreferences and: 1.11.3. Discussion (Perl Cookbook)
CGI programs: 9. CGI Overview (Perl in a Nutshell)
CGI scripts, with mod_perl: 11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
database access, speeding with mod_perl: 21.8.1. Problem (Perl Cookbook)
event-based XML parsing: 22.3.1. Problem (Perl Cookbook)
measuring: 29.2.181. times (Programming Perl)
Perl programs, efficiency in: 24.2. Efficiency (Programming Perl)
presizing hashes: 5.14.3. Discussion (Perl Cookbook)
web server, improving: 21.12.1. Problem (Perl Cookbook)
performance, slowed by automatic match variables: 9.5.2. The Automatic Match Variables (Learning Perl)
period: 4.5.6. Assignment Operators (Perl in a Nutshell)
1.7.1. Quantifiers (Programming Perl)
#!perl: 1.4.2. What's Inside That Program? (Learning Perl)
perl-bin directory: 11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
perl command
-d option: 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
-I option: 2.5.3. Extending @INC with -I (Learning Perl Objects, References and Modules)
13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
-M option: 13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
-V command line option: 2.5. require and @INC (Learning Perl Objects, References and Modules)
-V:make: 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
-w option: 10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
A.3.1. Exercise 1 (Section 4.9.1) (Learning Perl Objects, References and Modules)
PREFIX= option (Makefile.PL): 13.6. Alternate Installation Locations (PREFIX=...) (Learning Perl Objects, References and Modules)
13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
Perl Data Language (see PDL)
Perl Data Language (PDL) module: 9.1.4. Slices (Programming Perl)
PERL_DEBUG_MSTATS variable: 3.3. Environment Variables (Perl in a Nutshell)
PERL_DESTRUCT_LEVEL variable: 3.3. Environment Variables (Perl in a Nutshell)
12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
perl executable: 3. The Perl Executable (Perl in a Nutshell)
Perl, history of: 27.1. History Made Practical (Programming Perl)
Perl identifiers: 2.5. Scalar Variables (Learning Perl)
Perl interpreter: 1.3.1. How to Do It (Programming Perl)
18.1. The Life Cycle of a Perl Program (Programming Perl)
-a switch: 19.1.3. Switches (Programming Perl)
-c switch: 19.1.3. Switches (Programming Perl)
-d switch: 19.1.3. Switches (Programming Perl)
20. The Perl Debugger (Programming Perl)
-e switch: 1.3.1. How to Do It (Programming Perl)
19.1.3. Switches (Programming Perl)
-F switch: 19.1.3. Switches (Programming Perl)
19.1.3. Switches (Programming Perl)
-h switch: 19.1.3. Switches (Programming Perl)
-- switch: 19.1.3. Switches (Programming Perl)
-I switch: 19.1. Command Processing (Programming Perl)
19.1.3. Switches (Programming Perl)
-l switch: 19.1.3. Switches (Programming Perl)
-m switch: 19.1.3. Switches (Programming Perl)
-n switch: 19.1.3. Switches (Programming Perl)
-p switch: 19.1.3. Switches (Programming Perl)
-s switch: 19.1.3. Switches (Programming Perl)
20. The Perl Debugger (Programming Perl)
switches: 19.1.3. Switches (Programming Perl)
-T switch: 19.1.3. Switches (Programming Perl)
-u switch: 19.1.3. Switches (Programming Perl)
-v switch: 19.1.3. Switches (Programming Perl)
-w switch: 1.3.1. How to Do It (Programming Perl)
19.1.3. Switches (Programming Perl)
-x switch: 19.1. Command Processing (Programming Perl)
19.1.3. Switches (Programming Perl)
-0 switch: 19.1. Command Processing (Programming Perl)
19.1.3. Switches (Programming Perl)
perl interpreter program
-a switch: 28.2. Special Variables in Alphabetical Order (Programming Perl)
-d switch: 20.6. The Perl Profiler (Programming Perl)
sticky bit: 24.2.1. Time Efficiency (Programming Perl)
-T switch: 16.5.2. Networking Servers (Programming Perl)
23.1. Handling Insecure Data (Programming Perl)
-w switch: 33. Diagnostic Messages (Programming Perl)
Perl Journal: 1.4.7. The Perl Journal (Perl in a Nutshell)
Perl language: 1. Introduction to Perl (Perl in a Nutshell)
bugs in, reporting: 6.6. The perlbug Program (Perl in a Nutshell)
development of: 1.2. Perl Development (Perl in a Nutshell)
documentation: 2.5. Documentation (Perl in a Nutshell)
4.13. Pod (Perl in a Nutshell)
= (equals sign), and: 4.1. Program Structure (Perl in a Nutshell)
utilities for: 4.13.3. Pod Utilities (Perl in a Nutshell)
example scripts: 2.3.1.1. Perl examples (Perl in a Nutshell)
installing source code: 2.3. Installing Perl (Perl in a Nutshell)
multithreading, and: 3.5. Threads (Perl in a Nutshell)
obtaining source from CPAN: 2. Installing Perl (Perl in a Nutshell)
resources: 1.4. Perl Resources (Perl in a Nutshell)
signals, handling: 4.10. Signals (Perl in a Nutshell)
uses of: 1.1. What's Perl Good For? (Perl in a Nutshell)
v. 5.8, I/O: 4.9.1. Perl 5.8 and PerlIO (Perl in a Nutshell)
Perl library: 22.2.3. Installing CPAN Modules into the Perl Library (Programming Perl)
PERL_MAILERS variable: 16.2.1. Send Email with Mail::Mailer (Perl in a Nutshell)
PERL_MODULE_EXT variable: 3.4. The Perl Compiler (Perl in a Nutshell)
Perl Monastery: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
Perl Mongers: 1.4.6. Perl Mongers (www.perl.org) (Perl in a Nutshell)
Perl Package Manager (PPM): 2.4.3.2. Using the Perl Package Manager (Perl in a Nutshell)
perl-packrats mailing list: 15.1. The Comprehensive Perl Archive Network (Learning Perl Objects, References and Modules)
perl (Perl interpreter): 3. The Perl Executable (Perl in a Nutshell)
command-line options: 3.2. Command-Line Options (Perl in a Nutshell)
command processing: 3.1. Command Processing (Perl in a Nutshell)
Perl profiler (DProf): 6.5. The Perl Profiler (Perl in a Nutshell)
PERL_SCRIPT_EXT variable: 3.4. The Perl Compiler (Perl in a Nutshell)
perl-script handler: 11.3. mod_perl Handlers (Perl in a Nutshell)
11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
$PERL_VERSION ($]) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
Perl virtual machine: 18.3. Executing Your Code (Programming Perl)
18.3. Executing Your Code (Programming Perl)
perlapi manpage: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
perlboot manpage, object-oriented programming and: B.20.2. Object-Oriented Programming (Learning Perl)
perlbug program: 6.6. The perlbug Program (Perl in a Nutshell)
perlbug utility: 1.3.4. What If I Find a Bug in Perl? (Learning Perl)
perlcall manpage: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
perlcc: 28.2. Special Variables in Alphabetical Order (Programming Perl)
perlcc command: 18.4. Compiler Backends (Programming Perl)
pbyscript resulting from: 18.5.1. The Bytecode Generator (Programming Perl)
perlcc utility: 3.4. The Perl Compiler (Perl in a Nutshell)
perldata manpage, here documents and: B.8.2. Here documents (Learning Perl)
$PERLDB: 28.2. Special Variables in Alphabetical Order (Programming Perl)
PERL5DB environment variable: 19.2. Environment Variables (Programming Perl)
debugger, customizing with: 20.3.2. Customizing with Init Files (Programming Perl)
.perldb file: 6.4. Customizing the Debugger (Perl in a Nutshell)
$PERLDB ($^P) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
PERLDB_OPTS environment variable
AutoTrace option, tracing compile-phase statements: 20.1. Using the Debugger (Programming Perl)
debugger customization via: 20.3. Debugger Customization (Programming Perl)
PERLDB_OPTS variable: 6.4. Customizing the Debugger (Perl in a Nutshell)
perldebug manpage: B.15. Debugging (Learning Perl)
PERL_DEBUG_MSTATS environment variable: 19.2. Environment Variables (Programming Perl)
PERL_DESTRUCT_LEVEL environment variable: 19.2. Environment Variables (Programming Perl)
perldiag manpage: 1.4.2. What's Inside That Program? (Learning Perl)
errors and: 17.1. Trapping Errors with eval (Learning Perl)
warnings explained in: 2.4. Perl's Built-in Warnings (Learning Perl)
perldoc command: 1.5. A Whirlwind Tour of Perl (Learning Perl)
4.13.3. Pod Utilities (Perl in a Nutshell)
8. Standard Modules (Perl in a Nutshell)
0.4. Online Documentation (Programming Perl)
11. Modules (Programming Perl)
debugger invoking: 20.2.7. Miscellaneous Commands (Programming Perl)
perldoc manpage: B.1. Further Documentation (Learning Perl)
perldsc manpage, data structures and: B.20.1. Complex Data Structures (Learning Perl)
perlembed manpage: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
eval_sv function, demonstrating: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
perlfaq manpage: 10.5. The elsif Clause (Learning Perl)
B.1. Further Documentation (Learning Perl)
perlfork documentation: 16. Interprocess Communication (Programming Perl)
perlfork manpage: B.31. Threads and Forking (Learning Perl)
perlform manpage, formats and: B.12. Formats (Learning Perl)
perlfunc manpage: 10.4. The Naked Block Control Structure (Learning Perl)
format letters and: 16.2. Manipulating Data with pack and unpack (Learning Perl)
grep operator and: B.10.1. map and grep (Learning Perl)
map operator and: B.10.1. map and grep (Learning Perl)
mathematical functions and: B.9.1. Advanced Math Functions (Learning Perl)
operators and: B.8. Other Operators and Functions (Learning Perl)
splice operator and: B.10.2. The splice Operator (Learning Perl)
System V IPC and: B.13.1. System V IPC (Learning Perl)
vec operator and: B.11. Bits and Pieces (Learning Perl)
PerlHandler directive (mod_perl): 11.3. mod_perl Handlers (Perl in a Nutshell)
PerlIO modules: 4.9.1. Perl 5.8 and PerlIO (Perl in a Nutshell)
8.170. PerlIO (Perl in a Nutshell)
PerlIO::Scalar: 8.171. PerlIO::Scalar (Perl in a Nutshell)
PerlIO::Via: 8.172. PerlIO::Via (Perl in a Nutshell)
perlipc manpage: 14.6. Getting Down and Dirty with Fork (Learning Perl)
perlipc module, System V IPC and: B.13.1. System V IPC (Learning Perl)
perllexwarn manpage: 2.4. Perl's Built-in Warnings (Learning Perl)
PERL5LIB environment variable: 12.8.3. Discussion (Perl Cookbook)
2.5.2. Extending @INC with PERL5LIB (Learning Perl Objects, References and Modules)
19.2. Environment Variables (Programming Perl)
PERLLIB variable: 3.3. Environment Variables (Perl in a Nutshell)
perllocale manpage: B.30. Locales and Unicode (Learning Perl)
29.2.82. lc (Programming Perl)
perllol manpage, data structures and: B.20.1. Complex Data Structures (Learning Perl)
perlmenu module: 15.12.3. Description (Perl Cookbook)
perlmod manpage
syntax extensions and: B.19. Syntax Extensions (Learning Perl)
writing modules and: B.4.4. Writing Your Own Modules (Learning Perl)
perlmodinstall manpage: B.4.3. Finding and Installing Modules (Learning Perl)
22.2. Using CPAN Modules (Programming Perl)
perlmodlib manpage
pragmas and: B.6. Pragmas (Learning Perl)
writing modules and: B.4.4. Writing Your Own Modules (Learning Perl)
PerlModule directive (mod_perl): 11.4. Running CGI Scripts with mod_perl (Perl in a Nutshell)
perlobj manpage, object-oriented programming and: B.20.2. Object-Oriented Programming (Learning Perl)
perlop manpage
bitwise operators and: 11.6.4. Using Bitstrings (Learning Perl)
operators and: B.8. Other Operators and Functions (Learning Perl)
perlopentut manpage, filehandles and: B.29. More Ways to Open Filehandles (Learning Perl)
PERL5OPT environment variable: 19.2. Environment Variables (Programming Perl)
PERL5OPT variable: 3.3. Environment Variables (Perl in a Nutshell)
perlpod manpage: B.28. Embedded Documentation (Learning Perl)
perlport documentation: 16. Interprocess Communication (Programming Perl)
perlport manpage, standard input/output and: 11.1. What Is a Filehandle? (Learning Perl)
perlre manpage: 8.5.2. And There's More (Learning Perl)
B.2. Regular expressions (Learning Perl)
perlref manpage, references and: B.20. References (Learning Perl)
perlreftut manpage, references and: B.20. References (Learning Perl)
perlrequick manpage: 8.5.2. And There's More (Learning Perl)
B.2. Regular expressions (Learning Perl)
perlretut manpage: 8.5.2. And There's More (Learning Perl)
B.2. Regular expressions (Learning Perl)
perlrun manpage, command-line options and: 16.4.1. In-place Editing from the Command Line (Learning Perl)
B.17. Command-Line Options (Learning Perl)
perlsec manpage: B.14. Security (Learning Perl)
PERL5SHELL environment variable: 19.2. Environment Variables (Programming Perl)
PERL5SHELL variable: 3.3. Environment Variables (Perl in a Nutshell)
perl_stringify function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
perlsyn manpage: 10.7. The for Control Structure (Learning Perl)
continue block and: 10.8.2. The next Operator (Learning Perl)
syntax extensions and: B.19. Syntax Extensions (Learning Perl)
perlthrtut manpage: B.31. Threads and Forking (Learning Perl)
perltie manpage, tied variables and: B.21. Tied Variables (Learning Perl)
Perl/Tk: 21. Perl/Tk (Perl in a Nutshell)
24.2.6. User Efficiency (Programming Perl)
callbacks: 21.1.3. Callbacks (Perl in a Nutshell)
colors and fonts: 21.1.4. Colors and Fonts (Perl in a Nutshell)
geometry managers: 21.2. Geometry Managers (Perl in a Nutshell)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
scrollbars: 21.1.2. Scrollbars (Perl in a Nutshell)
widgets: 21.1. Widgets (Perl in a Nutshell)
Button widget: 21.4. The Button Widget (Perl in a Nutshell)
Canvas widget: 21.12. The Canvas Widget (Perl in a Nutshell)
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
common configuration options: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
Entry widget: 21.8. The Entry Widget (Perl in a Nutshell)
Frame widget: 21.17. The Frame Widget (Perl in a Nutshell)
Label widget: 21.7. The Label Widget (Perl in a Nutshell)
Listbox widget: 21.10. The Listbox Widget (Perl in a Nutshell)
Menu widget: 21.15. The Menu Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
Text widget: 21.11. The Text Widget (Perl in a Nutshell)
toplevel widget: 21.18. The Toplevel Widget (Perl in a Nutshell)
widgets methods: 21.1.1. Widget Methods (Perl in a Nutshell)
perltoc manpage: B.1. Further Documentation (Learning Perl)
PERL_UNICODE environment variable: 8.21.3. Discussion (Perl Cookbook)
perlvar manpage, builtin variables and: B.18. Built in Variables (Learning Perl)
$PERL_VERSION: 28.2. Special Variables in Alphabetical Order (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
perlwin32 documentation: 16. Interprocess Communication (Programming Perl)
permissions: 29.2.171. sysopen (Programming Perl)
29.2.186. umask (Programming Perl)
CGI scripts: 19.3.3.2. Make sure the script has permissions to do what it's trying to do (Perl Cookbook)
changing: 13.5. Modifying Permissions (Learning Perl)
file permission operators, interpreting: 3.10. Named Unary and File Test Operators (Programming Perl)
libraries: 19.3.3.3. Is the script valid Perl? (Perl Cookbook)
symbolic file, instead of octal values: 9.11.1. Problem (Perl Cookbook)
testing files for trustworthiness: 8.17.1. Problem (Perl Cookbook)
Unix and: 13.1. Removing Files (Learning Perl)
users, granting limited: 23.1. Handling Insecure Data (Programming Perl)
permutations, generating all possible: 4.20. Program: permute (Perl Cookbook)
permute program: 4.20. Program: permute (Perl Cookbook)
persistent
data structures: 11.14.1. Problem (Perl Cookbook)
database data: 14.7.1. Problem (Perl Cookbook)
private subroutine variables: 10.3.1. Problem (Perl Cookbook)
persistent data structures, providing via tie: 14.6. Tie Modules on CPAN (Programming Perl)
persistent Perl interpreter: 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
personal identification number (PIN): 6.19.3. Discussion (Perl Cookbook)
PF_ constants: 17.. Introduction (Perl Cookbook)
.ph filename extension: 12.17.3. Discussion (Perl Cookbook)
PHP, communicating with mod_perl: 21.11.1. Problem (Perl Cookbook)
phrase( ) (Mail::Address): 16.2.6. Parse Email Addresses with Mail::Address (Perl in a Nutshell)
16.2.7. Mail::Address Reference (Perl in a Nutshell)
pi: 29.2.4. atan2 (Programming Perl)
picture lines: 7. Formats (Programming Perl)
29.2.41. format (Programming Perl)
pid (see processes)
PID (process ID): 28.2. Special Variables in Alphabetical Order (Programming Perl)
$PID ($$) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
PIN (personal identification number): 6.19.3. Discussion (Perl Cookbook)
ping( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
pinging machines: 18.7.1. Problem (Perl Cookbook)
pipe( ): 5. Function Reference (Perl in a Nutshell)
pipe( ): 16.. Process Creation (Perl Cookbook)
16.10.2. Solution (Perl Cookbook)
pipe function: 29.2.110. pipe (Programming Perl)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
pipelines
multistage, for input: 16.3.1. Anonymous Pipes (Programming Perl)
multistage, for output: 16.3.1. Anonymous Pipes (Programming Perl)
pipes
closing: 29.2.16. close (Programming Perl)
double-ended, opening with tied filehandle: 14.4.2. Creative Filehandles (Programming Perl)
in interprocess communication: 16.3. Pipes (Programming Perl)
named pipes: 16.3.4. Named Pipes (Programming Perl)
process talking to itself: 16.3.2. Talking to Yourself (Programming Perl)
IO::Pipe module: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
named: Glossary (Programming Perl)
open function, security risks posed by: 23.1.2. Cleaning Up Your Environment (Programming Perl)
read-only filehandles, opening: 29.2.104. open (Programming Perl)
.pl (Perl Library) extension: 2.3. Using do (Learning Perl Objects, References and Modules)
place geometry manager (Perl/Tk): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
placeForget( ) (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
placeholders (DBI): 12.2.4. Placeholders and Statement Handles (Perl in a Nutshell)
placeInfo( ) (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
places( ): 13.14.5. Example: Overloaded FixNum Class (Perl Cookbook)
placeSlaves( ) (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
plain old documentation (see pod)
plain-old documentation format: B.28. Embedded Documentation (Learning Perl)
platforms supporting Perl: 1.3. Which Platforms Support Perl? (Perl in a Nutshell)
pl2bat.bat: 3. The Perl Executable (Perl in a Nutshell)
pluralities: 1.2.1.2. Pluralities (Programming Perl)
pluralizing words: 2.17.1. Problem (Perl Cookbook)
+ (plus) ;unary operator: 3.5. Ideographic Unary Operators (Programming Perl)
plus (+)
2: 4.5.5. Autoincrement and Autodecrement (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
unary operator: 4.5.2. Unary Operators (Perl in a Nutshell)
+= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
plus sign (+), as quantifier: 7.2.2. Simple Quantifiers (Learning Perl)
plus sign (+), file-access modes: 7.1.3. Discussion (Perl Cookbook)
.plx (Perl Executable) extension: 2.3. Using do (Learning Perl Objects, References and Modules)
.plx file extension: 1.4.1. A Simple Program (Learning Perl)
.pm (Perl Module) extension: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
.pm file extension: 10. Packages (Programming Perl)
.pm filename extension: 12.. Modules (Perl Cookbook)
.pm files: 7.1. What Are Regular Expressions? (Learning Perl)
loading associated files with: 11.1. Using Modules (Programming Perl)
pnotes
Apache requests, sharing information between handlers: 21.13.2. Solution (Perl Cookbook)
URLs, storing information in: 21.10.2. Solution (Perl Cookbook)
pod
converting into other languages: 12.20.3. Discussion (Perl Cookbook)
directives: 26.1.2. Pod Directives (Programming Perl)
Glossary (Programming Perl)
documentation: 12.20.1. Problem (Perl Cookbook)
sorting =head1 sections: 15.22. Program: tkshufflepod (Perl Cookbook)
embedding in Perl: 2.2. Molecules (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
=pod command (pod): 4.13.1. Paragraph Tags (Perl in a Nutshell)
pod documentation: 2.5. Documentation (Perl in a Nutshell)
4.13. Pod (Perl in a Nutshell)
= to signify in programs: 4.1. Program Structure (Perl in a Nutshell)
utilities for: 4.13.3. Pod Utilities (Perl in a Nutshell)
pod format: B.28. Embedded Documentation (Learning Perl)
26. Plain Old Documentation (Programming Perl)
Pod::Functions module: 8.173. Pod::Functions (Perl in a Nutshell)
Pod::Html module: 8.174. Pod::Html (Perl in a Nutshell)
pod modules: 26.2. Pod Translators and Modules (Programming Perl)
Pod::Text module: 8.176. Pod::Text (Perl in a Nutshell)
pod translators: 26.1. Pod in a Nutshell (Programming Perl)
26.2. Pod Translators and Modules (Programming Perl)
Pod::Checker module: 32.1.16. Documentation Support (Programming Perl)
pod2fm utility: 4.13.3. Pod Utilities (Perl in a Nutshell)
Pod::Functions module: 32.1.16. Documentation Support (Programming Perl)
pod2html: 12.20.3. Discussion (Perl Cookbook)
Pod::Html module: 32.1.16. Documentation Support (Programming Perl)
pod2html utility: 4.13.3. Pod Utilities (Perl in a Nutshell)
8.174. Pod::Html (Perl in a Nutshell)
Pod::InputObjects module: 32.1.16. Documentation Support (Programming Perl)
pod2latex utility: 4.13.3. Pod Utilities (Perl in a Nutshell)
pod2man: 12.20.3. Discussion (Perl Cookbook)
Pod::Man module: 32.1.16. Documentation Support (Programming Perl)
pod2man utility: 4.13.3. Pod Utilities (Perl in a Nutshell)
Pod::ParseLink module: 8.175. Pod::ParseLink (Perl in a Nutshell)
Pod::Parser module: 32.1.16. Documentation Support (Programming Perl)
Pod::Select module: 32.1.16. Documentation Support (Programming Perl)
Pod::Text module: 32.1.16. Documentation Support (Programming Perl)
pod2text tools: 12.20.3. Discussion (Perl Cookbook)
pod2text utility: 4.13.3. Pod Utilities (Perl in a Nutshell)
8.176. Pod::Text (Perl in a Nutshell)
Pod::Text::Termcap module: 32.1.16. Documentation Support (Programming Perl)
Pod::Usage module: 32.1.16. Documentation Support (Programming Perl)
POE framework, writing multitasking server with: 17.15.1. Problem (Perl Cookbook)
POE (Perl Object Environment): 22.1. The CPAN modules Directory (Programming Perl)
POE::Component::Server::TCP module: 17.15.2. Solution (Perl Cookbook)
poetry in Perl: 27.2. Perl Poetry (Programming Perl)
pointers: 2.3. Built-in Data Types (Programming Perl)
references, unable to convert to: 2.6. Scalar Values (Programming Perl)
to strings: 29.2.108. pack (Programming Perl)
pointers (C language): 8. References (Programming Perl)
pointers (C programming language): B.20. References (Learning Perl)
poll function: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
polluting your namespace: 11.2.1. Module Privacy and the Exporter (Programming Perl)
polymorphism: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Glossary (Programming Perl)
pop( ): 5. Function Reference (Perl in a Nutshell)
pop( ), circular lists: 4.17.2. Solution (Perl Cookbook)
pop function: 9. Data Structures (Programming Perl)
29.2.111. pop (Programming Perl)
POP method: 14.2.1. Array-Tying Methods (Programming Perl)
pop operator: 3.4.1. The pop and push Operators (Learning Perl)
POP (Post Office Protocol): 18.5.3. Discussion (Perl Cookbook)
fetching and summarizing messages: 18.15. Program: rfrm (Perl Cookbook)
logging in: 18.5.3. Discussion (Perl Cookbook)
POP3 protocol, interface to: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
16.2.8. Checking Blacklisted Hosts with Mail::RBL (Perl in a Nutshell)
POP3 servers: 18.5.1. Problem (Perl Cookbook)
popen function (C language): 21.4. Embedding Perl (Using Perl from C) (Programming Perl)
popstat( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
popup_menu( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
port( )
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
URI::URL module: 20.5.3. URI::URL (Perl in a Nutshell)
port connection attempts, logging: 17.20. Program: backsniff (Perl Cookbook)
portability: 1.1.2. Why Are There So Many Footnotes? (Learning Perl)
1.2.2. Is Perl Easy or Hard? (Learning Perl)
closing filehandles: 7.. I/O Operations (Perl Cookbook)
encodings in XML: 22.. XML Declaration (Perl Cookbook)
of files and filesystems: 25.3. Files and Filesystems (Programming Perl)
functions, information on: 29.2. Perl Functions in Alphabetical Order (Programming Perl)
modules and: 13.8.3. The File::Spec Module (Learning Perl)
scripts using gethostent function: 29.2.49. gethostent (Programming Perl)
of signals: 25.4. System Interaction (Programming Perl)
portability, Perl programs: 25. Portable Perl (Programming Perl)
Portable Operating System Interface (see POSIX)
porting, information on: 16. Interprocess Communication (Programming Perl)
porting, efficiency of: 24.2.5. Porter Efficiency (Programming Perl)
ports: Glossary (Programming Perl)
name/number translations for: 29.2.64. getservbyname (Programming Perl)
Perl, to operating systems: 22. CPAN (Programming Perl)
pos( ): 5. Function Reference (Perl in a Nutshell)
6.14.3. Discussion (Perl Cookbook)
5.6.4. Progressive Matching (Programming Perl)
5.6.5. Where You Left Off: The \G Assertion (Programming Perl)
29.2.112. pos (Programming Perl)
HTML::Parser: 20.4.3. HTML::Element (Perl in a Nutshell)
positional assertions: 5.6.5. Where You Left Off: The \G Assertion (Programming Perl)
ordering of matching, changing with: 5.8. Alternation (Programming Perl)
positionfrom( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
positions: 5.6. Positions (Programming Perl)
beginnings of strings, matching: 5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
ends of strings, matching: 5.6.2. Endings: The \z, \Z, and $ Assertions (Programming Perl)
operators switching to character positions: 15.2. Effects of Character Semantics (Programming Perl)
position just after previous match, specifying: 5.6.5. Where You Left Off: The \G Assertion (Programming Perl)
precedence in pattern matching: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
substr function, manipulating with: 5.6. Positions (Programming Perl)
word boundaries, matching: 5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
positive lookahead assertions: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
5.10.1. Lookaround Assertions (Programming Perl)
POSIX classes: 5.4. Character Classes (Programming Perl)
POSIX module: B.5.9. The POSIX Module (Learning Perl)
8.177. POSIX (Perl in a Nutshell)
32.1.7. Operating System Interfaces (Programming Perl)
blocking signals: 16.20.2. Solution (Perl Cookbook)
getattr function: 29.2.43. getc (Programming Perl)
getting exported functions and variables with: 11.1. Using Modules (Programming Perl)
math functions and: B.9.1. Advanced Math Functions (Learning Perl)
signal blocking with: 16.1.4. Blocking Signals (Programming Perl)
strftime function: 29.2.88. localtime (Programming Perl)
today's date: 3.1.3. Discussion (Perl Cookbook)
trigonometric functions: 2.11.2. Solution (Perl Cookbook)
POSIX (Portable Operating System Interface): 0.3. Platform Notes (Perl Cookbook)
termios interface: 15.8.1. Problem (Perl Cookbook)
time( ): 3.. Introduction (Perl Cookbook)
POSIX-style character classes: 5.4.4. POSIX-Style Character Classes (Programming Perl)
POSIX::close( ): 7.9.2. Solution (Perl Cookbook)
7.9.3. Discussion (Perl Cookbook)
POSIX::setsid( ): 17.17.3. Discussion (Perl Cookbook)
POSIX::strtod( ): 2.1.3. Discussion (Perl Cookbook)
POSIX::uname( ): 17.8.2. Solution (Perl Cookbook)
possible matches, specifying set of: 5.8. Alternation (Programming Perl)
post command (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
post-incremented (post-decremented) variables: 1.5.4. Unary Arithmetic Operators (Programming Perl)
post( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
post( ) (Menu widget): 21.15.2. Menu Methods (Perl in a Nutshell)
POST method: 19.. Behind the Scenes (Perl Cookbook)
19.1.3. Discussion (Perl Cookbook)
20.2.2. Solution (Perl Cookbook)
POST method (CGI): 9.1.1. Transferring the Form Data (Perl in a Nutshell)
20.3.1. HTTP::Request (Perl in a Nutshell)
post( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
Post Office Protocol (see POP)
Post Office Protocol (POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
postcascade( ) (Menu widget): 21.15.2. Menu Methods (Perl in a Nutshell)
-postcommand option (Menu): 21.15. The Menu Widget (Perl in a Nutshell)
postincrement and postdecrement operators: 3. Unary and Binary Operators (Programming Perl)
postincrements/postdecrements: 10.6.1. The Value of Autoincrement (Learning Perl)
posting news articles: 17.1. The NNTP Protocol (Perl in a Nutshell)
posting Usenet messages: 18.4.1. Problem (Perl Cookbook)
$POSTMATCH: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$POSTMATCH ($') variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
postok( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
postscript( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
PostScript, converting HTML parse tree to: 20.4.5. HTML::FormatPS (Perl in a Nutshell)
Postscript, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
pound sign: 3. The Perl Executable (Perl in a Nutshell)
pound sign (#) in comments: 1.4.2. What's Inside That Program? (Learning Perl)
pound sign (#), with printf( ): 2.15.3. Discussion (Perl Cookbook)
PPM (Perl Package Manager): 2.4.3.2. Using the Perl Package Manager (Perl in a Nutshell)
22.2. Using CPAN Modules (Programming Perl)
22.2. Using CPAN Modules (Programming Perl)
Practical Extraction and Report Language (see Perl)
pragmas: 12.. Modules (Perl Cookbook)
4.10. The use strict Pragma (Learning Perl)
B.6. Pragmas (Learning Perl)
1.2.1.4. Simplicities (Programming Perl)
4.7. Global Declarations (Programming Perl)
4.9. Pragmas (Programming Perl)
10. Packages (Programming Perl)
19.1.3. Switches (Programming Perl)
29.2.192. use (Programming Perl)
integer: 2.2.1. All Numbers Are the Same Format Internally (Learning Perl)
lexically scoped: 4.9. Pragmas (Programming Perl)
modules and: 11.1. Using Modules (Programming Perl)
names, capitalization in: 2.5. Names (Programming Perl)
use charnames: 2.6.2. String Literals (Programming Perl)
pre-extending arrays: 24.2.1. Time Efficiency (Programming Perl)
pre-incremented (pre-decremented) variables: 1.5.4. Unary Arithmetic Operators (Programming Perl)
preallocating memory for hashes: 5.14.1. Problem (Perl Cookbook)
precedence: 2.6.2. Operator Precedence and Associativity (Learning Perl)
8.5. Precedence (Learning Perl)
29. Functions (Programming Perl)
Glossary (Programming Perl)
diagnostic messages: 33. Diagnostic Messages (Programming Perl)
key/value pair (hashes): 2.9. Hashes (Programming Perl)
logical operators: 1.5.5. Logical Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
12.3.3. Syntactic Snafus with Indirect Objects (Programming Perl)
modifiers vs. commas: 4.8.1. Scoped Variable Declarations (Programming Perl)
operator, table of: 3. Unary and Binary Operators (Programming Perl)
partial-evaluation operators and: 10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
Perl versions, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
regular expression matching: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
table of: 2.6.2. Operator Precedence and Associativity (Learning Perl)
unary operators, higher than binary: 3.10. Named Unary and File Test Operators (Programming Perl)
precedence, operator: 4.5. Operators (Perl in a Nutshell)
predeclaring subroutines: 12.5.4. Method Autoloading (Programming Perl)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
predefined Perl variables: 4.4. Special Variables (Perl in a Nutshell)
prefix operators: 1.5. Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
metacharacters working as: 5.3. Metacharacters and Metasymbols (Programming Perl)
prefixes, explicit: 2.6. The Problem of Namespace Collisions (Learning Perl Objects, References and Modules)
preincrements/predecrements: 10.6.1. The Value of Autoincrement (Learning Perl)
$PREMATCH: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$PREMATCH ($`) variable: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
prepare( ) (DBI): 12.2.3. Database Handles and Statement Handles (Perl in a Nutshell)
12.3. DBI Methods (Perl in a Nutshell)
prepending, directories to @INC: 19.1.3. Switches (Programming Perl)
prepending elements to arrays: 29.2.190. unshift (Programming Perl)
preprocessing Perl: 24.5.2. Generating Perl in Other Languages (Programming Perl)
Glossary (Programming Perl)
preprocessor (C language): Glossary (Programming Perl)
PREREQ_PM setting (Makefiles): 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
prev_labeled( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
prev_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
prime numbers, calculating: 2.18. Program: Calculating Prime Factors (Perl Cookbook)
print( ): 5. Function Reference (Perl in a Nutshell)
Socket module: 15.1.2. Client Connections (Perl in a Nutshell)
email attachments: 18.9.3. Discussion (Perl Cookbook)
filehandles
outputting to multiple: 7.8.3. Discussion (Perl Cookbook)
storing in variables: 7.5.3. Discussion (Perl Cookbook)
2.6. Output with print (Learning Perl)
1.4. Filehandles (Programming Perl)
1.8. List Processing (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.113. print (Programming Perl)
databases records and: 16.3. Fixed-length Random-access Databases (Learning Perl)
filehandles and: 11.4. Using Filehandles (Learning Perl)
implementing to tied filehandle: 14.4.1. Filehandle-Tying Methods (Programming Perl)
newlines and: 6.4. Output to Standard Output (Learning Perl)
optional parentheses and: 6.4. Output to Standard Output (Learning Perl)
output and: 6.4. Output to Standard Output (Learning Perl)
print statements, comma error in: 24.1.1. Universal Blunders (Programming Perl)
printf( ): 5. Function Reference (Perl in a Nutshell)
1.4.3. Discussion (Perl Cookbook)
floating-point numbers, rounding: 2.2.2. Solution (Perl Cookbook)
storing filehandles in variables: 7.5.3. Discussion (Perl Cookbook)
6.5. Formatted Output with printf (Learning Perl)
3.16. Conditional Operator (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.114. printf (Programming Perl)
29.2.162. sprintf (Programming Perl)
filehandles and: 11.4. Using Filehandles (Learning Perl)
using on tied filehandle: 14.4.1. Filehandle-Tying Methods (Programming Perl)
print_header( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
printing
arrays of hashes: 9.3.3. Access and Printing of an Array of Hashes (Programming Perl)
data structures: 11.11.1. Problem (Perl Cookbook)
date and time information: 3.8.1. Problem (Perl Cookbook)
hashes: 5.6.1. Problem (Perl Cookbook)
hashes of arrays: 9.2.3. Access and Printing of a Hash of Arrays (Programming Perl)
lists with commas: 4.2.1. Problem (Perl Cookbook)
multidimensional arrays: 9.1.3. Access and Printing (Programming Perl)
9.2. Hashes of Arrays (Programming Perl)
9.4. Hashes of Hashes (Programming Perl)
multidimensional hashes: 9.4.3. Access and Printing of a Hash of Hashes (Programming Perl)
9.6.1. Composition, Access, and Printing of More Elaborate Records (Programming Perl)
nested data structures: 20.2.4. Display (Programming Perl)
to multiple filehandles simultaneously: 7.8.1. Problem (Perl Cookbook)
typeglob contents: 20.3.3. Debugger Options (Programming Perl)
PrintRet option (debugger): 20.3.3. Debugger Options (Programming Perl)
priority, process: 29.2.57. getpriority (Programming Perl)
29.2.147. setpriority (Programming Perl)
privacy: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
Perl modules and: 11.2.1. Module Privacy and the Exporter (Programming Perl)
private
function to variable: 12.5.1. Problem (Perl Cookbook)
methods: 13.. Methods (Perl Cookbook)
module variables: 12.4.1. Problem (Perl Cookbook)
subroutine variables: 10.2.1. Problem (Perl Cookbook)
private methods, ignoring inheritance with: 12.5.5. Private Methods (Programming Perl)
private objects, closures, using for: 12.7.5. Using Closures for Private Objects (Programming Perl)
private variables (see also local variables)
4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
29.2.99. my (Programming Perl)
Proc handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
procedureal programming style: 5.10.3. Programmatic Patterns (Programming Perl)
procedures: 1.2.2. Verbs (Programming Perl)
process group: 29.2.55. getpgrp (Programming Perl)
29.2.146. setpgrp (Programming Perl)
process groups: 16.1. Signals (Programming Perl)
process ID (pid)
getting process group from: 29.2.55. getpgrp (Programming Perl)
returning: 29.2.56. getppid (Programming Perl)
returning with fork: 29.2.40. fork (Programming Perl)
waitpid function: 29.2.197. waitpid (Programming Perl)
process management: 22.13. Win32::Pipe (Perl in a Nutshell)
22.14. Win32::Process (Perl in a Nutshell)
processes: 16.. Introduction (Perl Cookbook)
as filehandles: 14.5. Processes as Filehandles (Learning Perl)
catching Ctrl-C: 16.18.1. Problem (Perl Cookbook)
checking for existence: 16.1.1. Signaling Process Groups (Programming Perl)
communicating between: 16.10.1. Problem (Perl Cookbook)
controlling input/output: 16.8.1. Problem (Perl Cookbook)
creating: 16.. Process Creation (Perl Cookbook)
filtering output: 16.5.1. Problem (Perl Cookbook)
fork function: 29.2.40. fork (Programming Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
gathering output: 16.1.1. Problem (Perl Cookbook)
getting group for: 29.2.146. setpgrp (Programming Perl)
groups: 7.25. Program: lockarea (Perl Cookbook)
16.14.3. Discussion (Perl Cookbook)
ID (pid): 29.2.104. open (Programming Perl)
imitating files with named pipes: 16.11.1. Problem (Perl Cookbook)
interprocess communication: 16. Interprocess Communication (Programming Perl)
between processes on same machine: 16. Interprocess Communication (Programming Perl)
files: 16.2. Files (Programming Perl)
on the Internet: 16. Interprocess Communication (Programming Perl)
sockets: 16.5. Sockets (Programming Perl)
System V IPC: 16.4. System V IPC (Programming Perl)
killing: 29.2.80. kill (Programming Perl)
large XML files, processing: 22.8.1. Problem (Perl Cookbook)
managing: 14. Process Management (Learning Perl)
multitasking environments, CPU access: 23.2. Handling Timing Glitches (Programming Perl)
multitasking servers, writing: 17.14.1. Problem (Perl Cookbook)
with POE: 17.15.1. Problem (Perl Cookbook)
preprocessing input: 16.6.1. Problem (Perl Cookbook)
priority, setting: 29.2.147. setpriority (Programming Perl)
process model, threads: 17.1. The Process Model (Programming Perl)
programs
reading from and writing to: 16.4.1. Problem (Perl Cookbook)
reading STDERR from: 16.7.1. Problem (Perl Cookbook)
replacing: 16.3.1. Problem (Perl Cookbook)
running multiple: 16.2.1. Problem (Perl Cookbook)
recursively processing files in directories: 9.7.1. Problem (Perl Cookbook)
returning priority of: 29.2.57. getpriority (Programming Perl)
sharing variables among: 16.12.1. Problem (Perl Cookbook)
signal handlers: 16.15.1. Problem (Perl Cookbook)
overriding: 16.16.1. Problem (Perl Cookbook)
writing: 16.17.1. Problem (Perl Cookbook)
signaling process groups: 16.1.1. Signaling Process Groups (Programming Perl)
signals: 16.. Signals (Perl Cookbook)
blocking: 16.20.1. Problem (Perl Cookbook)
listing available: 16.13.1. Problem (Perl Cookbook)
sending: 16.14.1. Problem (Perl Cookbook)
turning into errors: 16.22.1. Problem (Perl Cookbook)
standard input, output, and error in: 1.4. Filehandles (Programming Perl)
timing out operations: 16.21.1. Problem (Perl Cookbook)
umask for: 29.2.186. umask (Programming Perl)
variables for: 28.2. Special Variables in Alphabetical Order (Programming Perl)
waiting for: 29.2.196. wait (Programming Perl)
XML processing instructions: 22.. Processing Instructions (Perl Cookbook)
XSLT, processing: 22.7.1. Problem (Perl Cookbook)
zombie: 16.1.2. Reaping Zombies (Programming Perl)
zombies: 16.. Process Creation (Perl Cookbook)
avoiding: 16.19.1. Problem (Perl Cookbook)
$PROCESS_ID: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$PROCESS_ID ($$) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
processing shell commands: 19.1. Command Processing (Programming Perl)
processor (see CPU)
product_tokens( ) (HTTP::Daemon): 20.3.7. HTTP::Daemon (Perl in a Nutshell)
profiler, Perl: 20.6. The Perl Profiler (Programming Perl)
profiler, Perl (DProf): 6.5. The Perl Profiler (Perl in a Nutshell)
profiling, Devel::DProf module: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
-prog option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
program arguments, shell vs. Perl: 24.1.4. Shell Traps (Programming Perl)
program flow control functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
program name
of perl executable: 28.2. Special Variables in Alphabetical Order (Programming Perl)
of perl script: 28.2. Special Variables in Alphabetical Order (Programming Perl)
program structure: 4.1. Program Structure (Perl in a Nutshell)
programming: 1.4. How Do I Make a Perl Program? (Learning Perl)
10.1.1. The else Clause with unless (Learning Perl)
automatic match variables and: 9.5.2. The Automatic Match Variables (Learning Perl)
text editor for: 1.4. How Do I Make a Perl Program? (Learning Perl)
programming languages
C, operators and: 10.9.2. The Ternary Operator, ?: (Learning Perl)
converting to Perl: B.25. Converting Other Languages to Perl (Learning Perl)
low-level vs. high-level: 1.2.1. Why Didn't Larry Just Use Some Other Language? (Learning Perl)
Perl modules for interfacing with or emulating: 22.1. The CPAN modules Directory (Programming Perl)
structured: 10.8. Loop Controls (Learning Perl)
programming, Perl: 24. Common Practices (Programming Perl)
common mistakes by novices
Perl traps, previous versions: 24.1.5. Previous Perl Traps (Programming Perl)
common mistakes of novices: 24.1. Common Goofs for Novices (Programming Perl)
efficiency: 24.2. Efficiency (Programming Perl)
file-manipulating programs, writing portable: 25.3. Files and Filesystems (Programming Perl)
fluent: 24.4. Fluent Perl (Programming Perl)
portability: 25. Portable Perl (Programming Perl)
program generation: 24.5. Program Generation (Programming Perl)
generating Perl in other languages: 24.5.2. Generating Perl in Other Languages (Programming Perl)
program generators
other languages in Perl: 24.5.1. Generating Other Languages in Perl (Programming Perl)
source filters: 24.5.3. Source Filters (Programming Perl)
programming with style: 24.3. Programming with Style (Programming Perl)
programming style, patterns: 5.10.3. Programmatic Patterns (Programming Perl)
$PROGRAM_NAME: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$PROGRAM_NAME ($0) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
programs: 8. Introduction to Objects (Learning Perl Objects, References and Modules)
(see also OOP)
behaviors of: 6. Subroutine References (Learning Perl Objects, References and Modules)
CGI (see CGI programming)
command-line arguments, parsing: 15.1.1. Problem (Perl Cookbook)
compile phase: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
controlling debugger from: 20.1. Using the Debugger (Programming Perl)
controlling input/output of: 16.8.1. Problem (Perl Cookbook)
controlling with Expect: 15.13.1. Problem (Perl Cookbook)
core dump of: 29.2.29. dump (Programming Perl)
example of in a nutshell: 1.5. A Whirlwind Tour of Perl (Learning Perl)
executing: 29.2.174. system (Programming Perl)
Glossary (Programming Perl)
exit status and: 11.3. Fatal Errors with die (Learning Perl)
exiting: 1.1. Getting Started (Programming Perl)
29.2.35. exit (Programming Perl)
filtering output: 16.5.1. Problem (Perl Cookbook)
gathering output from: 16.1.1. Problem (Perl Cookbook)
last operator for exiting early: 10.8.1. The last Operator (Learning Perl)
name of
die function and: 11.3. Fatal Errors with die (Learning Perl)
warn function and: 11.3.1. Warning Messages with warn (Learning Perl)
object destruction and: 10. Object Destruction (Learning Perl Objects, References and Modules)
one-liners: Glossary (Programming Perl)
preprocessing input: 16.6.1. Problem (Perl Cookbook)
reading from and writing to: 16.4.1. Problem (Perl Cookbook)
reading STDERR from: 16.7.1. Problem (Perl Cookbook)
replacing: 16.3.1. Problem (Perl Cookbook)
run phase: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
running multiple: 16.2.1. Problem (Perl Cookbook)
running over the Web: 1.4.3. But How Do I Compile Perl? (Learning Perl)
sharing code: 2.1. The Cure for the Common Code (Learning Perl Objects, References and Modules)
simulating telnet from: 18.6.1. Problem (Perl Cookbook)
stepping through with debugger: 20.2.1. Stepping and Running (Programming Perl)
testing if running interactively: 15.2.1. Problem (Perl Cookbook)
whitespace: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
4.7. Autovivification (Learning Perl Objects, References and Modules)
programs, calculating and printing student grade averages: 1.3. An Average Example (Programming Perl)
progressive matching: 6.5.3. Discussion (Perl Cookbook)
5.6.5. Where You Left Off: The \G Assertion (Programming Perl)
projects, large, benefits of strict pragma in: 1.2.1.4. Simplicities (Programming Perl)
properties: 12.4.2. Initializers (Programming Perl)
case, Unicode: 15.2. Effects of Character Semantics (Programming Perl)
Unicode: 5.4. Character Classes (Programming Perl)
Unicode database of: 15.2. Effects of Character Semantics (Programming Perl)
properties, instances and: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
Proto option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
protocol( )
Frame widget module: 21.18.1. Toplevel Methods (Perl in a Nutshell)
HTTP::Message module: 20.3.8. HTTP::Message (Perl in a Nutshell)
IO::Socket module: 15.2.3. IO::Socket Methods (Perl in a Nutshell)
protocols
Internet: 18.. Introduction (Perl Cookbook)
socket: 17.. Introduction (Perl Cookbook)
protocols, name/number translations: 29.2.58. getprotobyname (Programming Perl)
protocols_allowed( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
rotocols_forbidden( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
proto_ge( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
prototype( ): 5. Function Reference (Perl in a Nutshell)
prototypes: 10.11.1. Problem (Perl Cookbook)
13.. Methods (Perl Cookbook)
4.11.1. Omitting the Ampersand (Learning Perl)
6.4. Prototypes (Programming Perl)
Glossary (Programming Perl)
& (ampersand), omitting from subroutine names: 6.4. Prototypes (Programming Perl)
built-in functions, emulating: 6.4. Prototypes (Programming Perl)
careful use of: 6.4.2. Care with Prototypes (Programming Perl)
closures, giving to: 8.3.7.1. Closures as function templates (Programming Perl)
implicit pass-by-reference in: 8.1. What Is a Reference? (Programming Perl)
inlining constant functions: 6.4.1. Inlining Constant Functions (Programming Perl)
prototypes for subroutines: 4.7. Subroutines (Perl in a Nutshell)
4.7.5. Prototypes (Perl in a Nutshell)
prototyping: 6.4. Prototypes (Programming Perl)
proxy( )
LWP::UserAgent: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
SOAP::Lite: 14.2. SOAP::Lite (Perl in a Nutshell)
proxy, submitting forms through: 20.2.3. Discussion (Perl Cookbook)
pseudo-operators, overloading and: 13.3. Overloadable Operators (Programming Perl)
pseudocommands, piping: 16.3.2. Talking to Yourself (Programming Perl)
pseudohashes: 8.3.5. Pseudohashes (Programming Perl)
implementing classes with: 29.2.99. my (Programming Perl)
inheritance and: 12.7.1. Field Declarations with use fields (Programming Perl)
simulating with overload function: 13.3. Overloadable Operators (Programming Perl)
use fields pragma, using with: 12.7.1. Field Declarations with use fields (Programming Perl)
pseudoliterals (see input operators)
psgrep program: 1.24. Program: psgrep (Perl Cookbook)
public methods: 13.. Methods (Perl Cookbook)
pumpkins and pumpkings: Glossary (Programming Perl)
punctuation characters, and word boundary matching: 5.6.3. Boundaries: The \b and \B Assertions (Programming Perl)
punctuation variables, English module, handling with: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
push( ): 5. Function Reference (Perl in a Nutshell)
4.10.2. Solution (Perl Cookbook)
11.2.2. Solution (Perl Cookbook)
circular lists: 4.17.2. Solution (Perl Cookbook)
Tie::IxHash module and: 5.7.3. Discussion (Perl Cookbook)
2.5.1. Extending @INC (Learning Perl Objects, References and Modules)
9. Data Structures (Programming Perl)
29.2.116. push (Programming Perl)
pop function: 2.3. Built-in Data Types (Programming Perl)
push operator: 3.4.1. The pop and push Operators (Learning Perl)
push-pop (PP) codes: 18.3. Executing Your Code (Programming Perl)
push_content( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
init_header( ) (HTTP::Headers): 20.3.3. HTTP::Headers (Perl in a Nutshell)
put( )
DB_File module: 8.52. DB_File (Perl in a Nutshell)
LWP::UserAgent: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
Net::FTP: 18.2. Net::FTP (Perl in a Nutshell)
PUT requests (CGI): 20.3.1. HTTP::Request (Perl in a Nutshell)
put_unique( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
PV (internal string value): 21.2. Internal Data Types (Programming Perl)
pwd command (Unix): 24.2.1. Time Efficiency (Programming Perl)
pwd( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
Pwd( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
Python: 2.2. Molecules (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

\` quote (disable) character: 4.6.4. Character Classes (Perl in a Nutshell)
q command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
q command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
q// operator: 1.. Introduction (Perl Cookbook)
-q option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
q// (pattern match) operator: 13.6. Overloading Constants (Programming Perl)
` string metacharacter: 1.18.3. Discussion (Perl Cookbook)
qq// operator: 1.. Introduction (Perl Cookbook)
qr// operator
comments in regular expressions: 6.4.3. Discussion (Perl Cookbook)
interpolated matches: 6.10.3. Discussion (Perl Cookbook)
2.7.4. Interpolative Context (Programming Perl)
5.2. Pattern-Matching Operators (Programming Perl)
5.9.2.2. The qr// quote regex operator (Programming Perl)
modifiers for: 5.2.1. Pattern Modifiers (Programming Perl)
Qt, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
qty( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
qualify_to_ref( ): 7.6.2. Solution (Perl Cookbook)
quant method (XML::Parser::ContentModel): 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
quantifiers: 7.2.2. Simple Quantifiers (Learning Perl)
8.2. General Quantifiers (Learning Perl)
1.7. Regular Expressions (Programming Perl)
1.7.1. Quantifiers (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
atoms and: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
greedy: 5.5. Quantifiers (Programming Perl)
greedy/non-greedy: 17.5.1. Non-greedy Quantifiers (Learning Perl)
in matches, using with dot (.) metacharacter: 5.3.3. Wildcard Metasymbols (Programming Perl)
in matching: 5.5. Quantifiers (Programming Perl)
character classes and: 5.4.1. Custom Character Classes (Programming Perl)
in matching: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
minimal and maximal: 5.3.1. Metasymbol Tables (Programming Perl)
minimal and maximal: 5.5. Quantifiers (Programming Perl)
for regular expressions: 4.6.6. Quantifiers (Perl in a Nutshell)
quarantining suspicious code: 23.3. Handling Insecure Code (Programming Perl)
query( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
QueryDataAvailable( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
query_form( ): 20.2.3. Discussion (Perl Cookbook)
QueryInfo( ) (Win32::Internet): 22.7.3. HTTP Functions (Perl in a Nutshell)
QueryKey( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
QueryObjectType( ) (Win32::OLE): 23.2.1. Win32::OLE Methods (Perl in a Nutshell)
QueryOption( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
QUERY_STRING variable: 9.1.1. Transferring the Form Data (Perl in a Nutshell)
QueryValue( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
? (question mark) regex extensions
(?=): 5.10.1. Lookaround Assertions (Programming Perl)
(?!): 5.10.1. Lookaround Assertions (Programming Perl)
(?>): 5.10.2. Nonbacktracking Subpatterns (Programming Perl)
(?<=): 5.10.1. Lookaround Assertions (Programming Perl)
(?<!): 5.10.1. Lookaround Assertions (Programming Perl)
question mark (?)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
?: (conditional) operator: 4.5.11.2. Conditional operator (Perl in a Nutshell)
?...? pattern match operator: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
?...? Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
question mark (?) as quantifier: 7.2.2. Simple Quantifiers (Learning Perl)
queues: 9. Data Structures (Programming Perl)
queues, Thread::Queue module: 17.2.3.1. Queues (Programming Perl)
quick reference to Perl: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
quit( )
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Net::NNTP module: 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
Net::POP3 module: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
Net::SMTP module: 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
QUIT command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session (Perl in a Nutshell)
quit signals, handler for: 16.1. Signals (Programming Perl)
quitting
infinite loop: 4.4.2. for Loops (Programming Perl)
Perl debugger: 20.2.7. Miscellaneous Commands (Programming Perl)
" (double quote): 1.. Introduction (Perl Cookbook)
escaping: 14.10.1. Problem (Perl Cookbook)
quot( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
$" variable: 3.5. Interpolating Arrays into Strings (Learning Perl)
quotation marks: 8.5. Braces, Brackets, and Quoting (Programming Perl)
(see also " (double quotes) and ' (single quotes) under Symbols)
in braces: 2.6.2. String Literals (Programming Perl)
double ("): 5.2. Pattern-Matching Operators (Programming Perl)
false values: Glossary (Programming Perl)
in formline arguments: 29.2.42. formline (Programming Perl)
interpolative context: 2.7.4. Interpolative Context (Programming Perl)
leaving out: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
line-oriented quoting: 2.6.6. "Here" Documents (Programming Perl)
on non-Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
quoting operators: 2.6.3. Pick Your Own Quotes (Programming Perl)
strings, changing style of string display: 20.3.3. Debugger Options (Programming Perl)
strings and: 2.6.2. String Literals (Programming Perl)
" (double quotes): 2.6.2. String Literals (Programming Perl)
5.2. Pattern-Matching Operators (Programming Perl)
5.2. Pattern-Matching Operators (Programming Perl)
8.5. Braces, Brackets, and Quoting (Programming Perl)
conversion operator, stringification: 13.3. Overloadable Operators (Programming Perl)
in formline arguments: 29.2.42. formline (Programming Perl)
in replacement string: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
translation escape processing: 5.9.2.1. When backslashes happen (Programming Perl)
quote( ): 14.10.2. Solution (Perl Cookbook)
quote( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
quote operators: 3.1. Terms and List Operators (Leftward) (Programming Perl)
quoted execution operator (see ` (backtick) operator)
quotemeta( ): 5. Function Reference (Perl in a Nutshell)
1.18.3. Discussion (Perl Cookbook)
29.2.118. quotemeta (Programming Perl)
quotes, use in strings: 1.2.1.1. Singularities (Programming Perl)
quotewords( ): 1.20.3. Discussion (Perl Cookbook)
quoting
multiline string: B.8.2. Here documents (Learning Perl)
packages: 12.3.4. Package-Quoted Classes (Programming Perl)
qw shortcut form of: 3.3.1. The qw Shortcut (Learning Perl)
quoting, line oriented: 2.6.6. "Here" Documents (Programming Perl)
quoting mechanisms: 1.2.1.1. Singularities (Programming Perl)
quoting schemes: 4.2.2. String Interpolation (Perl in a Nutshell)
"short-circuit" logical operators: 10.9. Logical Operators (Learning Perl)
qw( ): 4.1.2. Solution (Perl Cookbook)
qw( ) list: 12.2. Selecting What to Import (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
qw operator: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
qw (quote words): 2.8. List Values and Arrays (Programming Perl)
qw shortcut: 3.3.1. The qw Shortcut (Learning Perl)
qx// operator: 29.2.124. readpipe (Programming Perl)
2.7.4. Interpolative Context (Programming Perl)
2.11.1. Command Input (Backtick) Operator (Programming Perl)
2.11.1. Command Input (Backtick) Operator (Programming Perl)
(see also ` (backtick) operator)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

r command
CPAN.pm: 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
Perl debugger: 6.2. Debugger Commands (Perl in a Nutshell)
R command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-r file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
-r option
dprofpp: 6.5. The Perl Profiler (Perl in a Nutshell)
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
perlbug: 6.6. The perlbug Program (Perl in a Nutshell)
-r (readable by effective uid/gid) file test: 1.5.7. Some File Test Operators (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
-R (readable by real uid/gid file test: 3.10. Named Unary and File Test Operators (Programming Perl)
\r (carriage return) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
race conditions: 19.4.3. Discussion (Perl Cookbook)
file locking and: 16.2.1. File Locking (Programming Perl)
handling: 23.2.2. Handling Race Conditions (Programming Perl)
rad2deg( ): 2.10.3. Discussion (Perl Cookbook)
radians, vs. degrees: 2.10.1. Problem (Perl Cookbook)
radiobutton( ) (Menubutton): 21.14.2. Menubutton Methods (Perl in a Nutshell)
Radiobutton widget (Perl/Tk): 21.6. The Radiobutton Widget (Perl in a Nutshell)
radiobuttons: 15.14.3. Discussion (Perl Cookbook)
radio_group( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
raise( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
raise to the power of operator (**=): 2.5.3. Binary Assignment Operators (Learning Perl)
rand( ): 5. Function Reference (Perl in a Nutshell)
2.6.2. Solution (Perl Cookbook)
8.6.2. Solution (Perl Cookbook)
3.1. Terms and List Operators (Leftward) (Programming Perl)
29.2.119. rand (Programming Perl)
random
email signatures: 16.23. Program: sigrand (Perl Cookbook)
lines in files
ordering of: 8.7.1. Problem (Perl Cookbook)
selecting: 8.6.1. Problem (Perl Cookbook)
numbers: 2.. Introduction (Perl Cookbook)
29.2.119. rand (Programming Perl)
29.2.164. srand (Programming Perl)
producing as handles or scalars: 14.4.2. Creative Filehandles (Programming Perl)
biasing: 2.9.1. Problem (Perl Cookbook)
generating: 2.6.1. Problem (Perl Cookbook)
random-access files, updating: 8.13.1. Problem (Perl Cookbook)
random-access I/O: 8.12.1. Problem (Perl Cookbook)
randomizing arrays: 4.18.1. Problem (Perl Cookbook)
range (.. and ...) operator: 3.15. Range Operator (Programming Perl)
range (..) operator: 4.5.11.1. Range operator (Perl in a Nutshell)
range (...) operator: 4.5.11.1. Range operator (Perl in a Nutshell)
Range header: 20.17.2. Solution (Perl Cookbook)
range operator (..): 3.3. List Literals (Learning Perl)
ranges
character sets, specifying in: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
characters: 5.4.1. Custom Character Classes (Programming Perl)
raw I/O layer: 8.. I/O Layers (Perl Cookbook)
8.11.3. Discussion (Perl Cookbook)
raw_cookie( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
RC_ mnemonics (HTTP::Status): 20.3.4. HTTP::Status (Perl in a Nutshell)
RCPT command (SMTP): 16.1.2. The SMTP Protocol and the SMTP Session (Perl in a Nutshell)
$rdev file statistic: 29.2.165. stat (Programming Perl)
re-initialization expressions, loops: 4.4.2. for Loops (Programming Perl)
re module: 8.178. re (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
read( ): 5. Function Reference (Perl in a Nutshell)
DirHandle module: 8.59. DirHandle (Perl in a Nutshell)
fixed-length records: 8.. Advanced Operations (Perl Cookbook)
8.15.2. Solution (Perl Cookbook)
I/O layers: 8.. Advanced Operations (Perl Cookbook)
random-access files: 8.12.4. See Also (Perl Cookbook)
14.4.1. Filehandle-Tying Methods (Programming Perl)
29.2.120. read (Programming Perl)
database records and: 16.3. Fixed-length Random-access Databases (Learning Perl)
Read( ) (Win32::EventLog): 22.4. Win32::Eventlog (Perl in a Nutshell)
readable file test operator: 1.5.7. Some File Test Operators (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
readable( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
ReadAttr( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
read_buffer( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
ReadChar( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
readdir( ): 5. Function Reference (Perl in a Nutshell)
9.5.2. Solution (Perl Cookbook)
globbing: 9.6.3. Discussion (Perl Cookbook)
29.2.121. readdir (Programming Perl)
12.4. Directory Handles (Learning Perl)
ReadEntireFile( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
reader( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
ReadFile( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
reading
data via low-level system call: 29.2.172. sysread (Programming Perl)
files, and open mode: 29.2.104. open (Programming Perl)
records: 7.. I/O Operations (Perl Cookbook)
with pattern separators: 6.7.1. Problem (Perl Cookbook)
shared memory segment ID: 29.2.152. shmread (Programming Perl)
Usenet messages: 18.4.1. Problem (Perl Cookbook)
reading and writing
determining whether data can be read or written: 17.3.2. Solution (Perl Cookbook)
hash records to text files: 11.10.1. Problem (Perl Cookbook)
RSS files: 22.9.1. Problem (Perl Cookbook)
reading email messages
Mail::Audit: 16.2.9. Mail Filtering with Mail::Audit (Perl in a Nutshell)
Mail::RBL: 16.2.8. Checking Blacklisted Hosts with Mail::RBL (Perl in a Nutshell)
reading news articles: 17.1. The NNTP Protocol (Perl in a Nutshell)
readline( ): 5. Function Reference (Perl in a Nutshell)
readline function: 2.11.2. Line Input (Angle) Operator (Programming Perl)
READLINE method: 14.4.1. Filehandle-Tying Methods (Programming Perl)
ReadLine module, disabling support to debugger: 20.4. Unattended Execution (Programming Perl)
readline operator: 12.3. An Alternate Syntax for Globbing (Learning Perl)
ReadLine option (PERLDB_OPTS): 6.4. Customizing the Debugger (Perl in a Nutshell)
readline packages: 32.1.11. User Interfaces (Programming Perl)
readlink( ): 5. Function Reference (Perl in a Nutshell)
readlink function: 29.2.123. readlink (Programming Perl)
readme command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
README file: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
ReadParse( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
readpipe( ): 5. Function Reference (Perl in a Nutshell)
ReadRect( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
Read( ) (Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
ready file descriptors: 29.2.141. select (ready file descriptors) (Programming Perl)
real GID (see $( variable)
real UID (see $< variable)
real values, testing for with defined function: 29.2.23. defined (Programming Perl)
$REAL_GROUP_ID: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$REAL_GROUP_ID ($( ) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$REAL_USER_ID: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$REAL_USER_ID ($<) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
reaping zombie processes: 16.1.2. Reaping Zombies (Programming Perl)
servers: 16.5.2. Networking Servers (Programming Perl)
reason( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
recallCommand option (debugger): 20.3.3. Debugger Options (Programming Perl)
recipient( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
recompile command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
recompiling patterns, limiting with /o modifier: 5.2.1. Pattern Modifiers (Programming Perl)
record delimiter (see $/ variable)
record mode: 28.2. Special Variables in Alphabetical Order (Programming Perl)
records: 11.. Records (Perl Cookbook)
binary tree structures: 11.17. Program: Binary Trees (Perl Cookbook)
closures as objects: 11.7.1. Problem (Perl Cookbook)
comma-separated (see CSV)
constructing: 11.9.1. Problem (Perl Cookbook)
counting in files: 8.2.1. Problem (Perl Cookbook)
fixed-length: 8.. Advanced Operations (Perl Cookbook)
reading: 8.15.1. Problem (Perl Cookbook)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
input, separator for (see $/ variable)
lastlog file: 8.26. Program: laston (Perl Cookbook)
output, separator for (see $\ variable)
random-access I/O: 8.12.1. Problem (Perl Cookbook)
reading: 7.. I/O Operations (Perl Cookbook)
with pattern separators: 6.7.1. Problem (Perl Cookbook)
reading and writing to text files: 11.10.1. Problem (Perl Cookbook)
variable-length: 8.9.1. Problem (Perl Cookbook)
of various data structures: 9.6. More Elaborate Records (Programming Perl)
composing, accessing, and printing: 9.6.1. Composition, Access, and Printing of More Elaborate Records (Programming Perl)
generating hash of: 9.6.3. Generation of a Hash of Complex Records (Programming Perl)
wtmp file: 8.24. Program: tailwtmp (Perl Cookbook)
records, functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
records, variable-length: 7. Formats (Programming Perl)
recursion of subroutines: 6.2.3. Scoping Issues (Programming Perl)
recursive directory listing: 12.5. Recursive Directory Listing (Learning Perl)
recursive lexical pad stacks: 18.3. Executing Your Code (Programming Perl)
recursive matching: 5.10.3.4. Match-time pattern interpolation (Programming Perl)
recursively defined data: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
recursively processing files in directories: 9.7.1. Problem (Perl Cookbook)
recursivity, locks: 17.2.2.1. Synchronizing access with lock (Programming Perl)
recv( ): 5. Function Reference (Perl in a Nutshell)
Socket module: 15.1. Built-in Socket Functions (Perl in a Nutshell)
TCP, communicating over: 17.3.2. Solution (Perl Cookbook)
29.2.125. recv (Programming Perl)
redirect( ): 19.7.3. Discussion (Perl Cookbook)
redirect( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
redo( ): 5. Function Reference (Perl in a Nutshell)
4.3.1.5. Loop control (Perl in a Nutshell)
10.8.3. The redo Operator (Learning Perl)
4.4.4. Loop Control (Programming Perl)
4.4.4. Loop Control (Programming Perl)
29.2.126. redo (Programming Perl)
redundancy in Perl: 1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
ref( ): 4.8.2. Dereferencing (Perl in a Nutshell)
5. Function Reference (Perl in a Nutshell)
11.. References (Perl Cookbook)
13.. Under the Hood (Perl Cookbook)
12.4. Object Construction (Programming Perl)
29.2.127. ref (Programming Perl)
9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
9.14. Restricting a Method to Class-Only or Instance-Only (Learning Perl Objects, References and Modules)
8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
reference counting
closures and: 6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
defined: 4.1. More than One Reference to Data (Learning Perl Objects, References and Modules)
garbage collection and: 4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
memory management and: 4.4. When Reference Counting Goes Bad (Learning Perl Objects, References and Modules)
nested data structures and: 4.3. Reference Counting and Nested Data Structures (Learning Perl Objects, References and Modules)
subroutine reference example: 6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
weak references and: 10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
references: 11.. References (Perl Cookbook)
3.4. List Assignment (Learning Perl)
B.20. References (Learning Perl)
4.8.1. Creating References (Perl in a Nutshell)
3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
1.2.1.1. Singularities (Programming Perl)
8. References (Programming Perl)
to filehandles: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
8.2.4. Handle References (Programming Perl)
29.2.104. open (Programming Perl)
to anonymous data: 8.2.2. Anonymous Data (Programming Perl)
to arrays: 11.1.1. Problem (Perl Cookbook)
arrays of scalar references: 11.6.1. Problem (Perl Cookbook)
autovivification: 11.. Anonymous Data (Perl Cookbook)
bless operator: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
blessing: 12.4. Object Construction (Programming Perl)
braces, brackets and quoting in: 8.5. Braces, Brackets, and Quoting (Programming Perl)
casting to other pointer types: 2.6. Scalar Values (Programming Perl)
checking for: 29.2.127. ref (Programming Perl)
circular
in overloading: 13.3. Overloadable Operators (Programming Perl)
circular, and memory: 8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
closures as objects: 11.7.1. Problem (Perl Cookbook)
creating: 8.2. Creating References (Programming Perl)
with backslash operator: 8.2.1. The Backslash Operator (Programming Perl)
to data structures: 8.1. What Is a Reference? (Programming Perl)
defining: 8.1. What Is a Reference? (Programming Perl)
destruction and: 10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
destruction of, controlling: 19.2. Environment Variables (Programming Perl)
to functions: 11.4.1. Problem (Perl Cookbook)
storing in data structures: 9.5. Hashes of Functions (Programming Perl)
hard: 3.2. The Arrow Operator (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also hard references)
as hash keys: 13.15.7. Tie Example: Hash That Allows Lookups by Key or Value (Perl Cookbook)
hash keys, providing as: 32.1.14. Convenient Classes (Programming Perl)
as hash values: 5.13.2. Solution (Perl Cookbook)
to hashes: 11.3.1. Problem (Perl Cookbook)
9.1.5. Common Mistakes (Programming Perl)
multidimensional hashes: 9.6. More Elaborate Records (Programming Perl)
hashes of arrays: 11.2.1. Problem (Perl Cookbook)
11.2.1. Problem (Perl Cookbook)
hierarchical data and: 7.5. Recursively Defined Data (Learning Perl Objects, References and Modules)
indirection: 8. References (Programming Perl)
instances and: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
9.5. Inheriting the Constructor (Learning Perl Objects, References and Modules)
9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
iterating over arrays by: 4.6.1. Problem (Perl Cookbook)
locking: 17.2.2.1. Synchronizing access with lock (Programming Perl)
to methods: 11.8.1. Problem (Perl Cookbook)
in multidimsional arrays: 9.1.1. Creating and Accessing a Two-Dimensional Array (Programming Perl)
named subroutines: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
object destruction and: 10. Object Destruction (Learning Perl Objects, References and Modules)
object-oriented programming and: 10. Packages (Programming Perl)
for objects: 12.2. Perl's Object System (Programming Perl)
objects as: 12.4. Object Construction (Programming Perl)
overview: 3. Introduction to References (Learning Perl Objects, References and Modules)
to packages, indirect: 12.16.1. Problem (Perl Cookbook)
passing: 6.3. Passing References (Programming Perl)
passing arrays and hashes by: 10.5.1. Problem (Perl Cookbook)
passing by: 6.2. Semantics (Programming Perl)
passing to subroutines: 4.7.3. Passing References (Perl in a Nutshell)
Perl, C pointers vs.: 3.21. C Operators Missing from Perl (Programming Perl)
reference count: 11.. References (Perl Cookbook)
references and: 2.5.1. Name Lookups (Programming Perl)
return values: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
returning subroutines by: 10.9.1. Problem (Perl Cookbook)
as scalars: A.3.1. Exercise 1 (Section 4.9.1) (Learning Perl Objects, References and Modules)
scoping and: 4. References and Scoping (Learning Perl Objects, References and Modules)
self-referential structures: 13.13.1. Problem (Perl Cookbook)
to signal handlers (user-defined): 16.1. Signals (Programming Perl)
stringifying: 8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
8.5.1. References Don't Work as Hash Keys (Programming Perl)
9.1.3. Access and Printing (Programming Perl)
9.1.5. Common Mistakes (Programming Perl)
to subroutines: 6.1. Syntax (Programming Perl)
retrieving from or passing to: 10.1. Symbol Tables (Programming Perl)
to symbol table entries: 10.1. Symbol Tables (Programming Perl)
in symbol tables to other symbol tables: 10.1. Symbol Tables (Programming Perl)
symbolic: 1.12.2. Solution (Perl Cookbook)
12.16.2. Solution (Perl Cookbook)
8.4. Symbolic References (Programming Perl)
to tied arrays: 14.2.1. Array-Tying Methods (Programming Perl)
to tied scalar variables: 14.1.1. Scalar-Tying Methods (Programming Perl)
to tied variable objects, breaking: 14.5. A Subtle Untying Trap (Programming Perl)
truth value of: 1.6.1. What Is Truth? (Programming Perl)
typed: 11.. References (Perl Cookbook)
weak: 8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
weak, coping with circular data structures using: 11.15.1. Problem (Perl Cookbook)
weak references: 10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
weakening or breaking: 12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
referents: 8.1. What Is a Reference? (Programming Perl)
objects as: 12.2. Perl's Object System (Programming Perl)
referer( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
refile( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
reftype function: 12.4. Object Construction (Programming Perl)
regex (see patterns)
-regex option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
regexes (see patterns)
Regexp::Common module: 2.1.3. Discussion (Perl Cookbook)
6.17.3. Discussion (Perl Cookbook)
regexps (see patterns)
register_function( ): 22.7.3. Discussion (Perl Cookbook)
Registry access and management: 22.15. Win32::Registry (Perl in a Nutshell)
registry (Microsoft Windows), manipulating: 14.6. Tie Modules on CPAN (Programming Perl)
32.1.20. Microsoft-Related Modules (Programming Perl)
Registry (Windows): B.7.1. Direct System Database Access (Learning Perl)
regular expression engines: 17.5. More Powerful Regular Expressions (Learning Perl)
resources for further information: B.2. Regular expressions (Learning Perl)
regular expression memories: 8.4. Memory Parentheses (Learning Perl)
regular expressions (see also patterns)
7. Concepts of Regular Expressions (Learning Perl)
17.5. More Powerful Regular Expressions (Learning Perl)
4.6. Regular Expressions (Perl in a Nutshell)
5. Pattern Matching (Programming Perl)
anchors: 4.6.5. Anchors (Perl in a Nutshell)
backtracking: 6.. The Tricky Bits (Perl Cookbook)
6.16.3. Discussion (Perl Cookbook)
character classes: 4.6.4. Character Classes (Perl in a Nutshell)
character classes, confusing with array subscripts: 2.6.5. Interpolating Array Values (Programming Perl)
characters, matching instead of bytes: 15.2. Effects of Character Semantics (Programming Perl)
checking strings for valid numbers: 2.1.1. Problem (Perl Cookbook)
commas in numbers: 2.16.3. Discussion (Perl Cookbook)
commenting: 6.4.1. Problem (Perl Cookbook)
copying and substituting: 6.1.1. Problem (Perl Cookbook)
doubled words: 6.16.1. Problem (Perl Cookbook)
eager matching: 6.. The Tricky Bits (Perl Cookbook)
email addresses: 6.19.1. Problem (Perl Cookbook)
escaped sequences: 4.6.3. Escaped Sequences (Perl in a Nutshell)
extended, syntax for: 4.6.8. Extended Regular Expressions (Perl in a Nutshell)
extracting ranges of lines: 6.8.1. Problem (Perl Cookbook)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
fuzzy matching: 6.13.1. Problem (Perl Cookbook)
\G anchor: 6.14.3. Discussion (Perl Cookbook)
globbing filenames: 9.6.1. Problem (Perl Cookbook)
greedy vs. non-greedy matching: 6.. The Tricky Bits (Perl Cookbook)
6.15.1. Problem (Perl Cookbook)
honoring locale settings: 6.12.1. Problem (Perl Cookbook)
logical functionality in: 6.18.1. Problem (Perl Cookbook)
matching
abbreviations: 6.20.1. Problem (Perl Cookbook)
letters: 6.2.1. Problem (Perl Cookbook)
within multiple lines: 6.6.1. Problem (Perl Cookbook)
nested patterns: 6.17.1. Problem (Perl Cookbook)
Nth occurrence: 6.5.1. Problem (Perl Cookbook)
shell globs as: 6.9.1. Problem (Perl Cookbook)
from where last pattern ended: 6.14.1. Problem (Perl Cookbook)
words: 6.3.1. Problem (Perl Cookbook)
metacharacters: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
parsing HTML: 20.18.2. Solution (Perl Cookbook)
pattern match variables: 4.6.7. Pattern Match Variables (Perl in a Nutshell)
pattern-matching modifiers: 6.. Pattern-Matching Modifiers (Perl Cookbook)
Boolean connectives: 6.18.3. Discussion (Perl Cookbook)
pattern matching operators: 4.5.7. Pattern Match Operators (Perl in a Nutshell)
4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
progressive matching: 6.5.3. Discussion (Perl Cookbook)
quantifiers: 4.6.6. Quantifiers (Perl in a Nutshell)
resources for further reading: B.2. Regular expressions (Learning Perl)
special (predefined) variables: 4.4.5. Regular Expression Special Variables (Perl in a Nutshell)
tcgrep program: 6.22. Program: tcgrep (Perl Cookbook)
testing for invalid patterns: 6.11.1. Problem (Perl Cookbook)
urlify program: 6.21. Program: urlify (Perl Cookbook)
useful, list of: 6.23. Regular Expression Grab Bag (Perl Cookbook)
using: 9. Using Regular Expressions (Learning Perl)
regular files, testing for: 1.5.7. Some File Test Operators (Programming Perl)
rel( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
relational databases: B.7.3. Relational Database Access (Learning Perl)
hashes, tying to: 14.6. Tie Modules on CPAN (Programming Perl)
relational operators: 4.5.4.1. Relational operators (Perl in a Nutshell)
1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
3.11. Relational Operators (Programming Perl)
nonassociation of: 3.11. Relational Operators (Programming Perl)
RelaxNG schema: 22.. Schemas (Perl Cookbook)
release( )
Win32::Mutex module: 22.9. Win32::Mutex (Perl in a Nutshell)
Win32::Semaphore module: 22.16. Win32::Semaphore (Perl in a Nutshell)
-relheight, -relwidth options (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
-relief option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
reload command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
-relx, -rely options (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
remote_host( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
remote_user( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
remove_header( ) (HTTP::Headers): 20.3.3. HTTP::Headers (Perl in a Nutshell)
remove_sig( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
removing (see also deleting)
directories: 13.4. Making and Removing Directories (Learning Perl)
files: 13.1. Removing Files (Learning Perl)
rename( ): 5. Function Reference (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
9.9.2. Solution (Perl Cookbook)
modifying files with temporary files: 7.15.2. Solution (Perl Cookbook)
13.2. Renaming Files (Learning Perl)
29.2.128. rename (Programming Perl)
rename script, example: 9.9.3. Discussion (Perl Cookbook)
Rename( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
rep program: 15.12.3. Description (Perl Cookbook)
-repeatdelay option
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
-repeatinterval option
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
repetition (x) operator: 1.5.2. String Operators (Programming Perl)
1.5.2. String Operators (Programming Perl)
3.7. Multiplicative Operators (Programming Perl)
replacement, matched substrings (see s/// (substitution) operator)
replacement strings, building with /e modifier, building with: 5.10.3.2. Substitution evaluations (Programming Perl)
replacing array elements: 29.2.160. splice (Programming Perl)
reply( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
report( ), processing server logs: 20.13.3. Discussion (Perl Cookbook)
Report( ) (Win32::EventLog): 22.4. Win32::Eventlog (Perl in a Nutshell)
reporting bugs in Perl: 6.6. The perlbug Program (Perl in a Nutshell)
reports, formats for: B.12. Formats (Learning Perl)
reports, generating: 7. Formats (Programming Perl)
Representational State Transfer (REST): 18.. Introduction (Perl Cookbook)
request( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
Request( ) (Win32::Internet): 22.7.3. HTTP Functions (Perl in a Nutshell)
request_method( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
requests, HTTP
HTTP::Request module: 20.1. LWP Overview (Perl in a Nutshell)
20.3.1. HTTP::Request (Perl in a Nutshell)
UserAgent object for: 20.1. LWP Overview (Perl in a Nutshell)
20.2. The LWP Modules (Perl in a Nutshell)
20.2.3. LWP::UserAgent (Perl in a Nutshell)
require: 4.7. Global Declarations (Programming Perl)
require declarations, and tie function 14. Tied Variables (Programming Perl)
require directives: 7.2. Modules (Perl in a Nutshell)
require function: 11.1. Using Modules (Programming Perl)
require operator: 10.. Introduction (Perl Cookbook)
12.. Modules (Perl Cookbook)
4.7. Global Declarations (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
29.2.129. require (Programming Perl)
functionality: 2.4. Using require (Learning Perl Objects, References and Modules)
2.4. Using require (Learning Perl Objects, References and Modules)
@INC and: 2.5. require and @INC (Learning Perl Objects, References and Modules)
syntax errors and: 2.4. Using require (Learning Perl Objects, References and Modules)
trapping errors in: 12.2.1. Problem (Perl Cookbook)
use operation and: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
12.6. What use Is Doing (Learning Perl Objects, References and Modules)
require_version method (Exporter): 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
REs (see patterns)
reserved words: 2.5. Names (Programming Perl)
barewords, possible conflict with: 2.6.4. Or Leave the Quotes Out Entirely (Programming Perl)
Reset( ), Win32::OLE::Enum module: 23.3.1. Win32::OLE::Enum Methods (Perl in a Nutshell)
reset function: 29.2.130. reset (Programming Perl)
resizable( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
Resize( ), thumbnailing images: 15.19.3. Discussion (Perl Cookbook)
-resolution option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
Resolve( ) (Win32::Shortcut): 22.18. Win32::Shortcut (Perl in a Nutshell)
resources for further reading: 1.4. Perl Resources (Perl in a Nutshell)
auxiliary lock files: 16.1.2. Using a DBM Hash (Learning Perl)
bitwise operators: 11.6.4. Using Bitstrings (Learning Perl)
file tests: 11.6. File Tests (Learning Perl)
Perl
object-oriented programming and: B.20.2. Object-Oriented Programming (Learning Perl)
using with the Web: B.16. The Common Gateway Interface (CGI) (Learning Perl)
Programming Perl: 1.2.1. Why Didn't Larry Just Use Some Other Language? (Learning Perl)
regular expressions: 17.5.1. Non-greedy Quantifiers (Learning Perl)
B.2. Regular expressions (Learning Perl)
Tk: B.32. Graphical User Interfaces (GUIs) (Learning Perl)
resources, managing shared: 22.11. Win32::NetResource (Perl in a Nutshell)
responses, HTTP: 20.3.2. HTTP::Response (Perl in a Nutshell)
REST (Representational State Transfer): 18.. Introduction (Perl Cookbook)
restarting servers on demand: 17.18.1. Problem (Perl Cookbook)
restrictions: 4.10. The use strict Pragma (Learning Perl)
Resume( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
ResumeService( ) (Win32::Service): 22.17. Win32::Service (Perl in a Nutshell)
retr( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
retrieve( ): 11.13.2. Solution (Perl Cookbook)
retrieving email messages: 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
return( ): 5. Function Reference (Perl in a Nutshell)
return context, subroutines: 10.6.1. Problem (Perl Cookbook)
return function: 29.2.131. return (Programming Perl)
return operator: 4.11. The return Operator (Learning Perl)
return operators: 4.4.4. Loop Control (Programming Perl)
return stack: 18.3. Executing Your Code (Programming Perl)
return statement: 10.10.2. Solution (Perl Cookbook)
4.7.2. Passing Arguments (Perl in a Nutshell)
return values
(see also parameters)
currently executing subroutine, displaying in debugger: 20.2.1. Stepping and Running (Programming Perl)
coderefs as: 6.8.1. Exercise [30 min] (Learning Perl Objects, References and Modules)
hash references: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
required files: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
subroutines
6.2. Semantics (Programming Perl)
9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
bless operator and: 9.4. How to Build a Horse (Learning Perl Objects, References and Modules)
returning by reference: 10.9.1. Problem (Perl Cookbook)
returning failure: 10.10.1. Problem (Perl Cookbook)
skipping selected: 10.8.1. Problem (Perl Cookbook)
subroutine references: 6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
undef example: 7.6. Building Recursively Defined Data (Learning Perl Objects, References and Modules)
updated parameters: 9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
return_clause function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
Reuse option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
reused addresses, displaying contents of: 20.3.3. Debugger Options (Programming Perl)
reusing code: 24.3. Programming with Style (Programming Perl)
reval method, running suspicious code with: 23.3.1.1. Restricting namespace access (Programming Perl)
reverse( ): 5. Function Reference (Perl in a Nutshell)
1.7.2. Solution (Perl Cookbook)
4.11.2. Solution (Perl Cookbook)
inverting hashes: 5.9.2. Solution (Perl Cookbook)
disallowing as sort subroutine name: 24.1.5. Previous Perl Traps (Programming Perl)
1.8. List Processing (Programming Perl)
29.2.132. reverse (Programming Perl)
3.7.1. The reverse Operator (Learning Perl)
15.4. Advanced Sorting (Learning Perl)
reversing
array elements: 4.11.1. Problem (Perl Cookbook)
hashes: 5.9.2. Solution (Perl Cookbook)
words or characters in strings: 1.7.1. Problem (Perl Cookbook)
reversing print and printf statements (tied filehandles): 14.4. Tying Filehandles (Programming Perl)
revert( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies (Perl in a Nutshell)
revhash_demo program: 13.15.7. Tie Example: Hash That Allows Lookups by Key or Value (Perl Cookbook)
revision (see version)
revnum( ): 4.15.3. Discussion (Perl Cookbook)
rewind( ) (DirHandle module): 8.59. DirHandle (Perl in a Nutshell)
rewinddir( ): 5. Function Reference (Perl in a Nutshell)
9.5.3. Discussion (Perl Cookbook)
29.2.133. rewinddir (Programming Perl)
RFC 1617, LDAP data storage: 19.1. How Data Is Stored in LDAP (Perl in a Nutshell)
rfrm program: 18.15. Program: rfrm (Perl Cookbook)
Rich Site Summary (see RSS)
right angle bracket (>), file-access modes: 7.. I/O Operations (Perl Cookbook)
7.1.3. Discussion (Perl Cookbook)
right justification: 7.1. Format Variables (Programming Perl)
-right option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
right-shift (>>) operator: 3.9. Shift Operators (Programming Perl)
-rightspring option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
rindex( ): 5. Function Reference (Perl in a Nutshell)
rindex function: 15.1. Finding a Substring with index (Learning Perl)
29.2.134. rindex (Programming Perl)
rm command (Unix): 13.1. Removing Files (Learning Perl)
rmdir( ): 5. Function Reference (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
9.8.3. Discussion (Perl Cookbook)
<
29.2.135. rmdir (Programming Perl)
13.4. Making and Removing Directories (Learning Perl)
Rmdir( ) (Win32::Internet): 22.7.2. FTP Functions (Perl in a Nutshell)
rmtree( ): 9.8.2. Solution (Perl Cookbook)
13.4. Making and Removing Directories (Learning Perl)
Robot User Agent: 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
robots for Web traversal: 20.11.1. Problem (Perl Cookbook)
rollback( ): 14.15.2. Solution (Perl Cookbook)
rollback( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
roman( ): 2.5.3. Discussion (Perl Cookbook)
Roman module: 2.5.2. Solution (Perl Cookbook)
Roman numerals: 2.5.1. Problem (Perl Cookbook)
root directory, redefining: 29.2.15. chroot (Programming Perl)
root user: Glossary (Programming Perl)
rot13 encryption: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
rounding floating-point numbers: 2.2.1. Problem (Perl Cookbook)
routines (see subroutines)
-row option (grid manager): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
rows( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
-rowspan option (grid manager): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
-rp option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
RPCs (remote procedure calls): 14.1. What Is SOAP? (Perl in a Nutshell)
RS (awk variable) (see $INPUT_RECORD_SEPARATOR)
-rs option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
RSS (Rich Site Summary): 22.9.1. Problem (Perl Cookbook)
files, reading and writing: 22.9.1. Problem (Perl Cookbook)
RSTART (awk variable): 28.2. Special Variables in Alphabetical Order (Programming Perl)
RTF, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
rules( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
-run option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
run phase: 18.1. The Life Cycle of a Perl Program (Programming Perl)
BEGIN keyword and: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
storage allocation: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
run phase vs. run time: 18.2. Compiling Your Code (Programming Perl)
running (see executing)
RunSQL( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
runtime: 1.4.3. But How Do I Compile Perl? (Learning Perl)
loading modules at: 12.3.1. Problem (Perl Cookbook)
scoping: 10.13.3.3. Using local( ) on parts of aggregates (Perl Cookbook)
RV (internal reference value): 21.2. Internal Data Types (Programming Perl)
rvalue: 2.3. Built-in Data Types (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

\s (whitespace) character class: 4.6.4. Character Classes (Perl in a Nutshell)
s command (debugger): 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
s command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
%s conversion: 6.5. Formatted Output with printf (Learning Perl)
-S file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
3.10. Named Unary and File Test Operators (Programming Perl)
s for whitespace=\s (for whitespace): 1.7. Regular Expressions (Programming Perl)
/s modifier: 9.2.2. Matching Any Character with /s (Learning Perl)
s/// substitution operator and: 9.6.3. Option Modifiers (Learning Perl)
s/// operator: 1.1.3. Discussion (Perl Cookbook)
stripping whitespace with: 1.16.2. Solution (Perl Cookbook)
-s option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-s option (perlbug): 6.6. The perlbug Program (Perl in a Nutshell)
/s pattern modifier: 5.2.1. Pattern Modifiers (Programming Perl)
5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
6.. Pattern-Matching Modifiers (Perl Cookbook)
multiple lines: 6.6.2. Solution (Perl Cookbook)
s pattern match modifier: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
4.6.8. Extended Regular Expressions (Perl in a Nutshell)
-S (search for script) command-line switch: 19.1.3. Switches (Programming Perl)
\s shortcut: 8.1.1. Character Class Shortcuts (Learning Perl)
s/// (substitution) operator: 4.6. Regular Expressions (Perl in a Nutshell)
4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
2.7.4. Interpolative Context (Programming Perl)
5. Pattern Matching (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
Glossary (Programming Perl)
=~ and !~ binding operators, using with: 5.2. Pattern-Matching Operators (Programming Perl)
modifiers for: 5.2.1. Pattern Modifiers (Programming Perl)
pattern modifiers used with: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
double-quote interpolation, providing: 5.2. Pattern-Matching Operators (Programming Perl)
-s (switch) command-line switch: 19.1.3. Switches (Programming Perl)
20. The Perl Debugger (Programming Perl)
safe compartments for insecure code: 23.3.1. Safe Compartments (Programming Perl)
Safe module: 8.179. Safe (Perl in a Nutshell)
23.3.1. Safe Compartments (Programming Perl)
32.1.12. Authentication, Security, and Encryption (Programming Perl)
insecure code, handling
restricting operator access: 23.3.1.2. Restricting operator access (Programming Perl)
insecure code, handling with: 23.3.1. Safe Compartments (Programming Perl)
-sav option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
Save( )
Win32::Registry module: 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
Win32::Shortcut module: 22.18. Win32::Shortcut (Perl in a Nutshell)
save( ), HTML forms: 19.12.2. Solution (Perl Cookbook)
save stack: 18.3. Executing Your Code (Programming Perl)
save_as( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
save_parameters( ), HTML forms: 19.12.2. Solution (Perl Cookbook)
saving, data structures: 9.7. Saving Data Structures (Programming Perl)
SAX (Simple API for XML): 22.3.1. Problem (Perl Cookbook)
events, parsing XML into: 22.3.1. Problem (Perl Cookbook)
scalar( ): 4.2.6. Scalar and List Contexts (Perl in a Nutshell)
5. Function Reference (Perl in a Nutshell)
scalar context: 3.8. Scalar and List Context (Learning Perl)
4.2.6. Scalar and List Contexts (Perl in a Nutshell)
2.7.1. Scalar and List Context (Programming Perl)
Glossary (Programming Perl)
Boolean values and: 2.7.2. Boolean Context (Programming Perl)
Glossary (Programming Perl)
comma operator in: 3.18. Comma Operators (Programming Perl)
24.1.5. Previous Perl Traps (Programming Perl)
conditional operator in: 3.16. Conditional Operator (Programming Perl)
expressions in (see EXPRs)
forcing: 3.8.3. Forcing Scalar Context (Learning Perl)
29.2.137. scalar (Programming Perl)
functions in: 29. Functions (Programming Perl)
/g pattern modifier, use in: 5.2.2. The m// Operator (Matching) (Programming Perl)
hash variables, evaluating in: 2.9. Hashes (Programming Perl)
keys function, calling in: 14.3.1. Hash-Tying Methods (Programming Perl)
list assignment in: 2.8.1. List Assignment (Programming Perl)
3.17. Assignment Operators (Programming Perl)
lvalues in: 4.8.1. Scoped Variable Declarations (Programming Perl)
m// (match) operator in: 5.2.2. The m// Operator (Matching) (Programming Perl)
operations behaving differently in: 24.1.2. Frequently Ignored Advice (Programming Perl)
range (..) operator in: 3.15. Range Operator (Programming Perl)
recognizing in debugger: 20.1. Using the Debugger (Programming Perl)
subroutines, calling and evaluating in: 6.2. Semantics (Programming Perl)
subtypes of: 2.7.1. Scalar and List Context (Programming Perl)
void context: 2.7.3. Void Context (Programming Perl)
scalar multiplication operator: 2.13.3. Discussion (Perl Cookbook)
scalar operator, list version: 10.8.3. Discussion (Perl Cookbook)
scalar prototype symbol ($): 4.7.5. Prototypes (Perl in a Nutshell)
scalar pseudofunction: 29.2.137. scalar (Programming Perl)
scalar reverse function: 15.2. Effects of Character Semantics (Programming Perl)
scalar values: 2.6. Scalar Values (Programming Perl)
2.6. Scalar Values (Programming Perl)
here documents: 2.6.6. "Here" Documents (Programming Perl)
interpolating array values: 2.6.5. Interpolating Array Values (Programming Perl)
numeric literals: 2.6.1. Numeric Literals (Programming Perl)
operators fo: 3. Unary and Binary Operators (Programming Perl)
string literals: 2.6.2. String Literals (Programming Perl)
v-string literals: 2.6.7. V-String Literals (Programming Perl)
scalar variables
in angle brackets: 2.11.2. Line Input (Angle) Operator (Programming Perl)
autoincrements/autodecrements for: 10.6. Autoincrement and Autodecrement (Learning Perl)
in double-quote context: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
stat function and: 11.6.1. The stat and lstat Functions (Learning Perl)
scalars: 1.. Introduction (Perl Cookbook)
2.1. What Is Scalar Data? (Learning Perl)
1.2.1. Variable Syntax (Programming Perl)
1.2.1.1. Singularities (Programming Perl)
2.3. Built-in Data Types (Programming Perl)
2.4. Variables (Programming Perl)
Glossary (Programming Perl)
anonymous: 6.4. Closures (Learning Perl Objects, References and Modules)
arrays of: 4.2.5.1. Arrays (Perl in a Nutshell)
arrays of scalar references: 11.6.1. Problem (Perl Cookbook)
characters, length of: 29.2.84. length (Programming Perl)
complex data structures, representing as: 1.2.1.3. Complexities (Programming Perl)
constants: 10.1. Symbol Tables (Programming Perl)
10.1. Symbol Tables (Programming Perl)
(see also constants)
curly braces and: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
detecting scalar context: 10.6.1. Problem (Perl Cookbook)
exchanging values between: 1.3.1. Problem (Perl Cookbook)
filehandles and: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
functions for manipulating: 5.1. Perl Functions by Category (Perl in a Nutshell)
29.1. Perl Functions by Category (Programming Perl)
hard references as: 8.1. What Is a Reference? (Programming Perl)
hash references and: 4.6. Creating an Anonymous Hash (Learning Perl Objects, References and Modules)
indirect object syntax: 10.3. Indirect Object Notation (Learning Perl Objects, References and Modules)
isa method and: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
list of (see arrays)
lists, converting to: 1.2.1.3. Complexities (Programming Perl)
lists of: 4.2.3. Here Documents (Perl in a Nutshell)
4.2.4. Lists (Perl in a Nutshell)
as numbers: 2.. Introduction (Perl Cookbook)
package names and: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
parameter and return lists, subroutines: 6.2. Semantics (Programming Perl)
pattern-matching operators, applying to: 5.2. Pattern-Matching Operators (Programming Perl)
Perl, converting to C types: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
references: 4.8.1. Creating References (Perl in a Nutshell)
1.2.1.1. Singularities (Programming Perl)
references and: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
A.3.1. Exercise 1 (Section 4.9.1) (Learning Perl Objects, References and Modules)
references to: 11.5.1. Problem (Perl Cookbook)
single values and: 3. Introduction to References (Learning Perl Objects, References and Modules)
SV (scalar value) in C: 21.2. Internal Data Types (Programming Perl)
truth, evaluating in: 1.6.1. What Is Truth? (Programming Perl)
tying: 14.1. Tying Scalars (Programming Perl)
base class definitions, providing: 32.1.14. Convenient Classes (Programming Perl)
magical counter variables: 14.1.2. Magical Counter Variables (Programming Perl)
methods for: 14.1.1. Scalar-Tying Methods (Programming Perl)
preventing unlocalized use of $_ variables: 14.1.3. Magically Banishing $_ (Programming Perl)
unordered set of (see hashes)
values of, assigning to variables: 2.5.2. Scalar Assignment (Learning Perl)
Scalar::Util module: 2.1.3. Discussion (Perl Cookbook)
11.15.3. Description (Perl Cookbook)
scale( ) (Canvas): 21.12.3. Canvas Methods (Perl in a Nutshell)
Scale widget (Perl/Tk): 21.13. The Scale Widget (Perl in a Nutshell)
scan( )
HTTP::Cookies module: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
HTTP::Headers module: 20.3.3. HTTP::Headers (Perl in a Nutshell)
scheduling and preemption policies, threads: 17.2. The Thread Model (Programming Perl)
schemas, XML: 22.. Schemas (Perl Cookbook)
scheme( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
schemes, URLs: 19.. Architecture (Perl Cookbook)
Schwartzian Transform
dictionary order: 7.8.3. Exercise 3 [10 min] (Learning Perl Objects, References and Modules)
performance: A.6.2. Exercise 2 (Section 7.8.2) (Learning Perl Objects, References and Modules)
sorting and: 7.4. The Schwartzian Transform (Learning Perl Objects, References and Modules)
scope: 2.5. Names (Programming Perl)
loop variable in foreach: 4.4.3. foreach Loops (Programming Perl)
variables in if statements: 4.3. if and unless Statements (Programming Perl)
variables in three-part for loops: 4.4.2. for Loops (Programming Perl)
variables in while loops: 4.4.1. while and until Statements (Programming Perl)
declarations and: 4.8. Scoped Declarations (Programming Perl)
do operator and: 2.3. Using do (Learning Perl Objects, References and Modules)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
global variables and: 6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
lexically scoped variables: 2.5. Names (Programming Perl)
private variables (see lexical variables)
references and: 4. References and Scoping (Learning Perl Objects, References and Modules)
subroutines: 6.2.3. Scoping Issues (Programming Perl)
in threads: 17.2.3.1. Queues (Programming Perl)
variables: 1.2.1. Variable Syntax (Programming Perl)
strict pragma and: 1.2.1.4. Simplicities (Programming Perl)
scope modifiers: 4.8.1. Scoped Variable Declarations (Programming Perl)
scope of subroutine variables: 10.2.3. Discussion (Perl Cookbook)
scope of variables: 4.9. Notes on Lexical (my) Variables (Learning Perl)
naked block control structure and: 10.4. The Naked Block Control Structure (Learning Perl)
scope operators: 4.8.1. Scoped Variable Declarations (Programming Perl)
scope, variable: 4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
functions for: 5.1. Perl Functions by Category (Perl in a Nutshell)
scoped variables (see lexical variables)
scopes: 4.2. Compound Statements (Programming Perl)
Glossary (Programming Perl)
dynamic: 4.8.4. Dynamically Scoped Variables: local (Programming Perl)
block: 4.8.2. Lexically Scoped Variables: my (Programming Perl)
blocks: 4.2. Compound Statements (Programming Perl)
dynamic: Glossary (Programming Perl)
file: 4.8.2. Lexically Scoped Variables: my (Programming Perl)
lexical scope: 4.8.2. Lexically Scoped Variables: my (Programming Perl)
my variables: 10. Packages (Programming Perl)
package declarations: 10. Packages (Programming Perl)
pattern-matching operations: 5.2. Pattern-Matching Operators (Programming Perl)
scope stack: 18.3. Executing Your Code (Programming Perl)
signal handling: 16.1. Signals (Programming Perl)
static (see scopes; lexical)
screen (see user interfaces)
screen appearance of command line: 20.3.3. Debugger Options (Programming Perl)
-screen option (toplevel): 21.18. The Toplevel Widget (Perl in a Nutshell)
script_name( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
scripts
alternate installation locations: 13.6. Alternate Installation Locations (PREFIX=...) (Learning Perl Objects, References and Modules)
building with -e switch: 19.1.3. Switches (Programming Perl)
CGI, taint mode and: 23.1. Handling Insecure Data (Programming Perl)
checking syntax of: 19.1.3. Switches (Programming Perl)
complex tests: 14.5. More Complex Tests (Multiple Test Scripts) (Learning Perl Objects, References and Modules)
debugging: 19.1.3. Switches (Programming Perl)
19.1.3. Switches (Programming Perl)
(see also debugging)
dumping core files: 19.1.3. Switches (Programming Perl)
embedding in messages: 19.1.3. Switches (Programming Perl)
end marker for: 2.6.8. Other Literal Tokens (Programming Perl)
executing: 29.2.174. system (Programming Perl)
insecure: 23.3. Handling Insecure Code (Programming Perl)
interpretation, shells vs. Perl: 24.1.4. Shell Traps (Programming Perl)
languages, checking for: 5.4.3.3. Unicode block properties (Programming Perl)
names of (see $0 variable)
pausing: 29.2.156. sleep (Programming Perl)
Perl
common mistakes of novices: 24.1. Common Goofs for Novices (Programming Perl)
CPAN directory of: 22. CPAN (Programming Perl)
idiomatic Perl, using: 24.4. Fluent Perl (Programming Perl)
performance of: 24.2. Efficiency (Programming Perl)
programming with style: 24.3. Programming with Style (Programming Perl)
searching for and compiling: 19.1. Command Processing (Programming Perl)
test scripts: 32.1.18. Development Support (Programming Perl)
running time of: 3.10. Named Unary and File Test Operators (Programming Perl)
searching for: 19.1.3. Switches (Programming Perl)
terminating with exec: 29.2.33. exec (Programming Perl)
scripts, CGI (see CGI programming)
scripts, Perl
perl interpreter, associating with: 1.3.1. How to Do It (Programming Perl)
Perl examples, obtaining: 2.3.1.1. Perl examples (Perl in a Nutshell)
Scroll( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
Scrollbar widget (Perl/Tk): 21.1.2.2. The Scrollbar widget (Perl in a Nutshell)
21.9. The Scrollbar Widget (Perl in a Nutshell)
scrollbars, widget (Perl/Tk): 21.1.2. Scrollbars (Perl in a Nutshell)
Scrolled( ) (Perl/Tk): 21.1.2.1. Using the Scrolled method (Perl in a Nutshell)
scrolling_list( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
-scrollregion option (Canvas): 21.12. The Canvas Widget (Perl in a Nutshell)
SDBM files: 14.. Introduction (Perl Cookbook)
SDBM_File module: 8.181. SDBM_File (Perl in a Nutshell)
32.1.10. DBM Interfaces (Programming Perl)
search( ), LDAP server: 18.8.3. Discussion (Perl Cookbook)
search and replace, global: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
Search::Dict module: 8.182. Search::Dict (Perl in a Nutshell)
search( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
search path: 2.5. require and @INC (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
%INC: 28.2. Special Variables in Alphabetical Order (Programming Perl)
search programs: 1.7. Regular Expressions (Programming Perl)
search( ) (Text widget): 21.11.2. Text Methods (Perl in a Nutshell)
Search::Dict module: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
searching
grep function for: 29.2.72. grep (Programming Perl)
linear, versus hashes: 24.2.1. Time Efficiency (Programming Perl)
Perl modules for text: 22.1. The CPAN modules Directory (Programming Perl)
rules for name searches: 2.5.1. Name Lookups (Programming Perl)
for scripts: 19.1.3. Switches (Programming Perl)
for substrings: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
29.2.75. index (Programming Perl)
29.2.134. rindex (Programming Perl)
searching against LDAP: 19.2. Searching an LDAP Directory with Net::LDAP (Perl in a Nutshell)
searching for patterns (see regular expressions)
seconds (see date and time values)
Secure Sockets Layer (SSL): 20.16.1. Problem (Perl Cookbook)
security: B.14. Security (Learning Perl)
0.1. The Pursuit of Happiness (Programming Perl)
23. Security (Programming Perl)
29.2.164. srand (Programming Perl)
CGI programs and: B.16. The Common Gateway Interface (CGI) (Learning Perl)
CGI scripts: 19.. Security (Perl Cookbook)
19.4.1. Problem (Perl Cookbook)
executing user commands: 19.5.1. Problem (Perl Cookbook)
code masquerading as data: 23.3.2. Code Masquerading as Data (Programming Perl)
connecting through firewalls: 17.21. Program: fwdport (Perl Cookbook)
cracking: Glossary (Programming Perl)
fetching secure web pages: 20.16.1. Problem (Perl Cookbook)
handling insecure data: 23.1. Handling Insecure Data (Programming Perl)
insecure code, handling: 23.3. Handling Insecure Code (Programming Perl)
safe compartments for: 23.3.1. Safe Compartments (Programming Perl)
insecure data, handling: 23.1. Handling Insecure Data (Programming Perl)
command and file access under reduced privileges: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
detecting and laundering tainted data: 23.1.1. Detecting and Laundering Tainted Data (Programming Perl)
environment, cleaning up: 23.1.2. Cleaning Up Your Environment (Programming Perl)
modules for: 32.1.12. Authentication, Security, and Encryption (Programming Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
reading passwords without echo: 15.10.1. Problem (Perl Cookbook)
testing files for trustworthiness: 8.17.1. Problem (Perl Cookbook)
timing glitches, handling: 23.2. Handling Timing Glitches (Programming Perl)
race conditions: 23.2.2. Handling Race Conditions (Programming Perl)
temporary files: 23.2.3. Temporary Files (Programming Perl)
Unix kernel security bugs: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
Win32::FileSecurity module: 32.1.20. Microsoft-Related Modules (Programming Perl)
security, of file test operators: 31.10. use filetest (Programming Perl)
sed: 1.7. Regular Expressions (Programming Perl)
5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
see( )
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
seed, random number: 29.2.164. srand (Programming Perl)
seek( ): 5. Function Reference (Perl in a Nutshell)
8.. Advanced Operations (Perl Cookbook)
8.5.3. Discussion (Perl Cookbook)
16.3. Fixed-length Random-access Databases (Learning Perl)
29.2.138. seek (Programming Perl)
29.2.176. tell (Programming Perl)
(see also tell function)
SEEK method: 14.4.1. Filehandle-Tying Methods (Programming Perl)
seek offset, filehandles: 7.. I/O Operations (Perl Cookbook)
seekable I/O objects: 32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
seekdir( ): 5. Function Reference (Perl in a Nutshell)
seekdir( ): 9.5.3. Discussion (Perl Cookbook)
seekdir function: 29.2.139. seekdir (Programming Perl)
Seen( ) (Data::Dumper)): 8.50. Data::Dumper (Perl in a Nutshell)
select( ): 5. Function Reference (Perl in a Nutshell)
Checkbutton widget: 21.5.1. Checkbutton Methods (Perl in a Nutshell)
Mail::Folder module: 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
Radiobutton widget: 21.6.1. Radiobutton Methods (Perl in a Nutshell)
3.10.2. Solution (Perl Cookbook)
determining whether data can be read or written: 17.3.2. Solution (Perl Cookbook)
reading from multiple filehandles: 7.22.2. Solution (Perl Cookbook)
17.3.3. Discussion (Perl Cookbook)
29.2.38. fileno (Programming Perl)
29.2.113. print (Programming Perl)
29.2.140. select (output filehandle) (Programming Perl)
29.2.141. select (ready file descriptors) (Programming Perl)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
for format variables: 7.1. Format Variables (Programming Perl)
7.1. Format Variables (Programming Perl)
select operator: 11.4.1. Changing the Default Output Filehandle (Learning Perl)
select syscall, multiplexing I/O between clients: 16.5.2. Networking Servers (Programming Perl)
Select( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
-selectbackground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-selectborderwidth option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-selectcolor option
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menu widget: 21.15. The Menu Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
-selectforeground option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
-selectimage option
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
selection( )
Entry widget: 21.8.2. Entry Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
select_label( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
-selectmode option (Listbox): 21.10. The Listbox Widget (Perl in a Nutshell)
SelectSaver module: 8.183. SelectSaver (Perl in a Nutshell)
32.1.5. Filehandle, Directory Handle, and Stream I/O Utilities (Programming Perl)
self-matching characters: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
self method, thread accessing own thread object: 17.2.1.5. Identifying threads (Programming Perl)
self-referential data structures: 13.13.1. Problem (Perl Cookbook)
self( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
self_and_super_path( ) (Class::ISA module): 8.42. Class::ISA (Perl in a Nutshell)
self_and_super_versions( ) (Class::ISA module): 8.42. Class::ISA (Perl in a Nutshell)
sel.first, sel.last indexes
Entry widget: 21.8.1. Text Indexes (Perl in a Nutshell)
Text widget: 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
SelfLoader core module: 11.3. AUTOLOAD as a Last Resort (Learning Perl Objects, References and Modules)
SelfLoader module: 12.10.2. Solution (Perl Cookbook)
8.184. SelfLoader (Perl in a Nutshell)
10.2. Autoloading (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
Devel::SelfStubber module, using with: 32.1.17. Module Installation Support (Programming Perl)
self_url( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
semantics: 29.2.192. use (Programming Perl)
semaphore files
shared memory: 16.4. System V IPC (Programming Perl)
System V IPC: 16.4. System V IPC (Programming Perl)
use in file locking: 16.2.1. File Locking (Programming Perl)
semaphores: Glossary (Programming Perl)
functions for: 29.2.142. semctl (Programming Perl)
implementing: 22.16. Win32::Semaphore (Perl in a Nutshell)
IPC::Semaphore module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
thread safety and: 17.2. The Thread Model (Programming Perl)
Thread::Semaphore module: 17.2.3.2. Semaphores (Programming Perl)
Win32::Semaphore module: 32.1.20. Microsoft-Related Modules (Programming Perl)
semctl( ): 5. Function Reference (Perl in a Nutshell)
semctl function: 29.2.142. semctl (Programming Perl)
semget( ): 5. Function Reference (Perl in a Nutshell)
semget function: 29.2.143. semget (Programming Perl)
[semi] (semicolon): 4.1. Simple Statements (Programming Perl)
errors, omitting trailing: 24.1.1. Universal Blunders (Programming Perl)
in debugger commands: 20.2. Debugger Commands (Programming Perl)
semicolon (;)
ending expressions: 1.4.2. What's Inside That Program? (Learning Perl)
ending Perl statements: 4.1. Program Structure (Perl in a Nutshell)
in for/foreach control structures: 10.7.1. The Secret Connection Between foreach and for (Learning Perl)
in prototype declarations: 4.7.5. Prototypes (Perl in a Nutshell)
return value expressions and: 4.6. Private Variables in Subroutines (Learning Perl)
semop( ): 5. Function Reference (Perl in a Nutshell)
semop function: 29.2.144. semop (Programming Perl)
send( ): 5. Function Reference (Perl in a Nutshell)
Socket: 15.1. Built-in Socket Functions (Perl in a Nutshell)
sendcommunicating over TCP: 17.3.2. Solution (Perl Cookbook)
send function: 29.2.145. send (Programming Perl)
send_basic_header( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
send_crlf( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
send_error( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
send_file( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
sending email messages: 16.1.1. Send Email with Net::SMTP (Perl in a Nutshell)
sendmail program: 18.3.2. Solution (Perl Cookbook)
send_redirect( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
SendRequest( ) (Win32::Internet): 22.7.3. HTTP Functions (Perl in a Nutshell)
send_response( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
send_status_line( ) (HTTP::Daemon::ClientConn): 20.3.7.1. HTTP::Daemon::ClientConn methods (Perl in a Nutshell)
separator( ) (Menubutton): 21.14.2. Menubutton Methods (Perl in a Nutshell)
separators
split operator, defining: 1.7. Regular Expressions (Programming Perl)
seq( ) (DB_File module): 8.52. DB_File (Perl in a Nutshell)
sequential matches: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
serial ports, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
serializer( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
serializing Perl data structures: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
server-push CGI scripting: 32.1.9. World Wide Web (Programming Perl)
server-side includes (SSI), mod_perl with: 11.5. Server-Side Includes with mod_perl (Perl in a Nutshell)
server-side socket connections: 15.1.3. Server Connections (Perl in a Nutshell)
15.2.2. Server-Side Sockets (Perl in a Nutshell)
servers
daemon servers: 17.17.1. Problem (Perl Cookbook)
database, using SQL without: 14.18.1. Problem (Perl Cookbook)
forking: 17.11.1. Problem (Perl Cookbook)
LDAP: 18.8.1. Problem (Perl Cookbook)
18.8.3. Discussion (Perl Cookbook)
search( ): 18.8.3. Discussion (Perl Cookbook)
multihomed: 17.16.1. Problem (Perl Cookbook)
multitasking, writing: 17.14.1. Problem (Perl Cookbook)
with POE: 17.15.1. Problem (Perl Cookbook)
non-forking: 17.13.1. Problem (Perl Cookbook)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
POP: 18.5.3. Discussion (Perl Cookbook)
fetching and summarizing messages: 18.15. Program: rfrm (Perl Cookbook)
preforking: 17.12.1. Problem (Perl Cookbook)
processing logs: 20.13.3. Discussion (Perl Cookbook)
restarting on demand: 17.18.1. Problem (Perl Cookbook)
SMTP: 18.16. Program: expn and vrfy (Perl Cookbook)
SOAP: 18.13.1. Problem (Perl Cookbook)
taint mode, importance of enabling for: 23.1. Handling Insecure Data (Programming Perl)
TCP, writing: 17.2.1. Problem (Perl Cookbook)
UDP, setting up: 17.5.1. Problem (Perl Cookbook)
web
common log format fields: 20.12.3. Discussion (Perl Cookbook)
performance, improving: 21.12.1. Problem (Perl Cookbook)
servers, networking: 16.5.2. Networking Servers (Programming Perl)
forking clones to handle incoming connections: 16.5.2. Networking Servers (Programming Perl)
servers, TCP: 16.5.1. Networking Clients (Programming Perl)
service control interface: 22.17. Win32::Service (Perl in a Nutshell)
service port name/number translations: 29.2.64. getservbyname (Programming Perl)
set( )
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
Scale widget: 21.13.1. Scale Methods (Perl in a Nutshell)
Scrollbar widget: 21.9.1. Scrollbar Methods (Perl in a Nutshell)
Set-Cookie2 header: 20.3.6. HTTP::Cookies (Perl in a Nutshell)
set-id program, dangerous operations, UID and GID setting to real: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
set-id programs: 23.1. Handling Insecure Data (Programming Perl)
Unix kernel bugs, security problems with: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
set theory: 4.8.1. Problem (Perl Cookbook)
SetAttributes( ) (Win32::File): 22.5. Win32::File (Perl in a Nutshell)
SetConnectOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
set_cookie( ) (HTTP::Cookies): 20.3.6. HTTP::Cookies (Perl in a Nutshell)
SetCursorName( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
setgid function: 16.3.2. Talking to Yourself (Programming Perl)
setgid program: 23.1. Handling Insecure Data (Programming Perl)
setgrent( ): 5. Function Reference (Perl in a Nutshell)
setgrent function: 29.2.44. getgrent (Programming Perl)
-setgrid option
Listbox widget: 21.10. The Listbox Widget (Perl in a Nutshell)
Text widget: 21.11. The Text Widget (Perl in a Nutshell)
SetHandler directive (mod_perl): 11.3. mod_perl Handlers (Perl in a Nutshell)
setHandlers( ), XML::Parser module: 13.2. XML::Parser Methods (Perl in a Nutshell)
sethostent( ): 5. Function Reference (Perl in a Nutshell)
sethostent function: 29.2.49. gethostent (Programming Perl)
setitimer( ): 3.9.3. Discussion (Perl Cookbook)
SetMaxBufSize( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
setnetent( ): 5. Function Reference (Perl in a Nutshell)
set_option( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
SetOption( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
setpgrp( ): 5. Function Reference (Perl in a Nutshell)
setpgrp function: 29.2.146. setpgrp (Programming Perl)
SetPos( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
setprgp function: 16.1.1. Signaling Process Groups (Programming Perl)
setpriority( ): 5. Function Reference (Perl in a Nutshell)
setpriority function: 29.2.147. setpriority (Programming Perl)
SetPriorityClass( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
setprotoent( ): 5. Function Reference (Perl in a Nutshell)
setprotoent function: 29.2.60. getprotoent (Programming Perl)
setpwent( ): 5. Function Reference (Perl in a Nutshell)
setpwent function: 29.2.61. getpwent (Programming Perl)
set_readonly( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
sets, intersection: 6.3. Passing References (Programming Perl)
Write(DATA) (Win32::Pipe): 22.13.1. Win32::Pipe Methods (Perl in a Nutshell)
setservent( ): 5. Function Reference (Perl in a Nutshell)
setservent function: 29.2.66. getservent (Programming Perl)
setsockopt( ): 5. Function Reference (Perl in a Nutshell)
setsockopt function: 29.2.148. setsockopt (Programming Perl)
SetStatusCallback( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
SetStmtCloseType( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
SetStmtOption( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
setters
AUTOLOAD method and: 11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
11.4. Using AUTOLOAD for Accessors (Learning Perl Objects, References and Modules)
creating: 9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
encapsulation and: 9.11. Don't Look Inside the Box (Learning Perl Objects, References and Modules)
getters doubling as: 9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
optimizing: 9.12. Faster Getters and Setters (Learning Perl Objects, References and Modules)
9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
restricting methods: 9.13. Getters That Double as Setters (Learning Perl Objects, References and Modules)
setting default I/O layers: 8.19.1. Problem (Perl Cookbook)
setuid function: 16.3.2. Talking to Yourself (Programming Perl)
setuid program: 23.1. Handling Insecure Data (Programming Perl)
SetValue( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
SetValueEx( ) (Win32::Registry): 22.15.1. Win32::Registry Methods (Perl in a Nutshell)
SGML (Standard Generalized Markup Language): 22.. Introduction (Perl Cookbook)
sh (Bourne shell): Glossary (Programming Perl)
shadow, password entries: 29.2.62. getpwnam (Programming Perl)
shallow copies: 11.12.3. Discussion (Perl Cookbook)
shar: 2.3.1. Installing on Unix (Perl in a Nutshell)
shared file locks: 16.2.1. File Locking (Programming Perl)
shared locks: 7.18.3. Discussion (Perl Cookbook)
shared memory, System V IPC: 16.4. System V IPC (Programming Perl)
controlled access to: 16.4. System V IPC (Programming Perl)
functions for: 29.2.150. shmctl (Programming Perl)
shared resources, managing: 22.11. Win32::NetResource (Perl in a Nutshell)
share_info hash: 22.11. Win32::NetResource (Perl in a Nutshell)
sharing variables among processes: 16.12.1. Problem (Perl Cookbook)
# (sharp)
for comments: 2.2. Molecules (Programming Perl)
/x pattern modifier, using with: 5.2.1. Pattern Modifiers (Programming Perl)
in formats: 7. Formats (Programming Perl)
quoting character, whitespace and: 2.6.3. Pick Your Own Quotes (Programming Perl)
#! (shebang) notation: 1.3.1. How to Do It (Programming Perl)
19.1. Command Processing (Programming Perl)
security problems caused by: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
simulating on non-Unix systems: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
shebang (#!): (see also #!)
0.5. Acknowledgments for the Second Edition (Perl in a Nutshell)
3. The Perl Executable (Perl in a Nutshell)
shell, avoiding: 14.1.1. Avoiding the Shell (Learning Perl)
shell escapes, executing commands without: 19.5.1. Problem (Perl Cookbook)
shell module: 32.1.7. Operating System Interfaces (Programming Perl)
shell wildcards for regular expression matching: 6.9.1. Problem (Perl Cookbook)
shells: Glossary (Programming Perl)
alternative for Perl, Windows systems: 19.2. Environment Variables (Programming Perl)
avoiding use of: 23.1.3. Accessing Commands and Files Under Reduced Privileges (Programming Perl)
avoiding with multi-argument piped open: 16.3.1. Anonymous Pipes (Programming Perl)
Bourne shell (sh): 19.1. Command Processing (Programming Perl)
bypassing with -| piping pseudocommand: 16.3.2. Talking to Yourself (Programming Perl)
commands in: Glossary (Programming Perl)
debugger commands and: 20.2.6. Actions and Command Execution (Programming Perl)
environment variables as security hazards: 23.1.2. Cleaning Up Your Environment (Programming Perl)
environment variables, using with: 19.2. Environment Variables (Programming Perl)
I/O streams, setting up: 1.4. Filehandles (Programming Perl)
pipe commands with shell metacharacters, passing to: 29.2.104. open (Programming Perl)
pipe commands with special characters, handling: 16.3.1. Anonymous Pipes (Programming Perl)
programming, Perl vs.: 24.1.4. Shell Traps (Programming Perl)
quotes, passing through: 19.1.3. Switches (Programming Perl)
security pitfalls with use, avoiding: 23.3.2. Code Masquerading as Data (Programming Perl)
spawning, characters for: 20.3.3. Debugger Options (Programming Perl)
shift( ): 5. Function Reference (Perl in a Nutshell)
circular lists: 4.17.2. Solution (Perl Cookbook)
9. Data Structures (Programming Perl)
29.2.149. shift (Programming Perl)
3.4.2. The shift and unshift Operators (Learning Perl)
1.6.2.1. The while and until statements (Programming Perl)
shift operators: 3.9. Shift Operators (Programming Perl)
3.9. Shift Operators (Programming Perl)
shifting
@_ array: 3.1. Performing the Same Task on Many Arrays (Learning Perl Objects, References and Modules)
argument parsing: 2.1. The Cure for the Common Code (Learning Perl Objects, References and Modules)
3.1. Performing the Same Task on Many Arrays (Learning Perl Objects, References and Modules)
arguments: 8.4. Calling a Second Method to Simplify Things (Learning Perl Objects, References and Modules)
8.9. What to Do with @_ (Learning Perl Objects, References and Modules)
closure variables: 6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
example eliminating: 3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
shmctl( ): 5. Function Reference (Perl in a Nutshell)
shmctl function: 29.2.150. shmctl (Programming Perl)
ShMem package: 16.4. System V IPC (Programming Perl)
shmget( ): 5. Function Reference (Perl in a Nutshell)
shmget function: 29.2.151. shmget (Programming Perl)
shmread( ): 5. Function Reference (Perl in a Nutshell)
shmread function: 29.2.152. shmread (Programming Perl)
shmwrite( ): 5. Function Reference (Perl in a Nutshell)
shmwrite function: 29.2.153. shmwrite (Programming Perl)
shopping cart applications: 19.11.1. Problem (Perl Cookbook)
short-circuit operators: 1.5.5. Logical Operators (Programming Perl)
3.14. C-Style Logical (Short-Circuit) Operators (Programming Perl)
overloading and: 13.3. Overloadable Operators (Programming Perl)
shortcut files: 22.18. Win32::Shortcut (Perl in a Nutshell)
shortcuts: 1.2.2. Is Perl Easy or Hard? (Learning Perl)
character class: 8.1.1. Character Class Shortcuts (Learning Perl)
negating: 8.1.2. Negating the Shortcuts (Learning Perl)
shortening arrays: 2.8.2. Array Length (Programming Perl)
shorts: 29.2.162. sprintf (Programming Perl)
-show option (Entry): 21.8. The Entry Widget (Perl in a Nutshell)
Showlex backend (Perl compiler): 3.4. The Perl Compiler (Perl in a Nutshell)
-showvalue option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
shuffle( )
arrays: 4.18.2. Solution (Perl Cookbook)
lines: 8.7.2. Solution (Perl Cookbook)
Shutdown( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
shutdown( ): 17.9.2. Solution (Perl Cookbook)
shutdown function: 29.2.154. shutdown (Programming Perl)
shutdown syscall: 16.5.1. Networking Clients (Programming Perl)
-side option (pack geometry manager): 21.2.1. The pack Geometry Manager (Perl in a Nutshell)
%SIG hash: 16.15.2. Solution (Perl Cookbook)
4.4.2. Global Special Arrays and Hashes (Perl in a Nutshell)
16.1. Signals (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
sigaction function: 16.1.2. Reaping Zombies (Programming Perl)
SIGALRM signal: 16.. Signals (Perl Cookbook)
16.21.2. Solution (Perl Cookbook)
29.2.3. alarm (Programming Perl)
SIGCHLD signal: 16.. Signals (Perl Cookbook)
16.19.2. Solution (Perl Cookbook)
SIGHUP signal: 16.. Signals (Perl Cookbook)
17.18.2. Solution (Perl Cookbook)
SIGINT: 14.7. Sending and Receiving Signals (Learning Perl)
SIGINT signal: 16.. Signals (Perl Cookbook)
16.18.2. Solution (Perl Cookbook)
signal handlers: 16.15.1. Problem (Perl Cookbook)
defining as strings: 10. Packages (Programming Perl)
overriding: 16.16.1. Problem (Perl Cookbook)
%SIG, Perl vs. C language: 24.1.3. C Traps (Programming Perl)
writing: 16.17.1. Problem (Perl Cookbook)
signal handling, sigtrap module: 32.1.7. Operating System Interfaces (Programming Perl)
signal level option (debugger): 20.3.3. Debugger Options (Programming Perl)
signals: 16.. Signals (Perl Cookbook)
16. Interprocess Communication (Programming Perl)
16.1. Signals (Programming Perl)
%SIG hash: 28.2. Special Variables in Alphabetical Order (Programming Perl)
blocking: 16.20.1. Problem (Perl Cookbook)
16.1.4. Blocking Signals (Programming Perl)
core dumps, triggering in C library: 16.1. Signals (Programming Perl)
handlers for (see signal handlers)
killing processes with: 29.2.80. kill (Programming Perl)
listing available: 16.13.1. Problem (Perl Cookbook)
portability of: 25.4. System Interaction (Programming Perl)
process groups: 7.25. Program: lockarea (Perl Cookbook)
16.14.3. Discussion (Perl Cookbook)
sending: 16.14.1. Problem (Perl Cookbook)
signaling process groups: 16.1.1. Signaling Process Groups (Programming Perl)
sources of: 16.1. Signals (Programming Perl)
threads, delivering to: 17.2. The Thread Model (Programming Perl)
Thread::Signal module: 17.2.3.3. Other standard threading modules (Programming Perl)
timing out slow operations: 16.1.3. Timing Out Slow Operations (Programming Perl)
trapping with sigtrap pragma: 16.1. Signals (Programming Perl)
turning into fatal errors: 16.22.1. Problem (Perl Cookbook)
zombie processes, reaping: 16.1.2. Reaping Zombies (Programming Perl)
signals, handling of: 4.10. Signals (Perl in a Nutshell)
signals, sending/receiving: 14.7. Sending and Receiving Signals (Learning Perl)
signatures, randomized: 16.23. Program: sigrand (Perl Cookbook)
SIGPIPE signal: 16.. Signals (Perl Cookbook)
16.4.3. Discussion (Perl Cookbook)
sigprocmask syscall: 16.20.2. Solution (Perl Cookbook)
16.1.4. Blocking Signals (Programming Perl)
SIGQUIT signal: 16.. Signals (Perl Cookbook)
sigrand program: 16.23. Program: sigrand (Perl Cookbook)
SIGTERM signal: 16.. Signals (Perl Cookbook)
sigtrap module: 8.186. sigtrap (Perl in a Nutshell)
sigtrap pragma: 16.22.2. Solution (Perl Cookbook)
16.1. Signals (Programming Perl)
16.1. Signals (Programming Perl)
SIGUSR1/SIGUSR2 signals: 16.. Signals (Perl Cookbook)
Simple API for XML (SAX): 22.3.1. Problem (Perl Cookbook)
simple difference: 4.9.3. Discussion (Perl Cookbook)
Simple Mail Transfer Protocol (SMTP): 18.3.3. Discussion (Perl Cookbook)
Simple Mail Transport Protocol (SMTP): 16.1.1. Send Email with Net::SMTP (Perl in a Nutshell)
Simple Object Access Protocol (see SOAP)
sin( ): 5. Function Reference (Perl in a Nutshell)
2.11.2. Solution (Perl Cookbook)
29.2.155. sin (Programming Perl)
single inheritance: 13.. Inheritance (Perl Cookbook)
12.5. Class Inheritance (Programming Perl)
single quote ('): 1.. Introduction (Perl Cookbook)
escaping: 14.10.1. Problem (Perl Cookbook)
single-quoted string literals: 2.3.1. Single-Quoted String Literals (Learning Perl)
suppressing interpolation: 1.2.1.1. Singularities (Programming Perl)
contractions in words, avoiding confusion with: 5.10.1. Lookaround Assertions (Programming Perl)
as package delimiters: 10. Packages (Programming Perl)
enclosing strings: 2.3.1. Single-Quoted String Literals (Learning Perl)
pattern recompilation and: 5.2.1. Pattern Modifiers (Programming Perl)
suppressing variable interpolation and translation escape processing: 5.9.2.1. When backslashes happen (Programming Perl)
singularities (see singularities)
size
arrays, changing: 4.3.1. Problem (Perl Cookbook)
hashes, preallocating for: 5.14.1. Problem (Perl Cookbook)
Tk window resize events: 15.16.1. Problem (Perl Cookbook)
window or terminal, determining: 15.4.1. Problem (Perl Cookbook)
sizefrom( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
Skip( ) (Win32::OLE::Enum): 23.3.1. Win32::OLE::Enum Methods (Perl in a Nutshell)
slash (/)
division operator: 4.5.3. Arithmetic Operators (Perl in a Nutshell)
encoding in URLs: 9.2. URL Encoding (Perl in a Nutshell)
/= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
/.../ pattern match operator: 4.6. Regular Expressions (Perl in a Nutshell)
/.../ Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
slash with dot (./): 1.4.1. A Simple Program (Learning Perl)
slave( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
sleep( ): 5. Function Reference (Perl in a Nutshell)
3.9.3. Discussion (Perl Cookbook)
3.10.1. Problem (Perl Cookbook)
29.2.156. sleep (Programming Perl)
select function instead of: 29.2.141. select (ready file descriptors) (Programming Perl)
slices: 17.6. Slices (Learning Perl)
slices of arrays or hashes: 2.4. Variables (Programming Perl)
slices of multidimensional arrays: 9.1.4. Slices (Programming Perl)
slider (Scale) widget: 21.13. The Scale Widget (Perl in a Nutshell)
-sliderlength option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
slurping files: Glossary (Programming Perl)
Perl, setting value for: 19.1.3. Switches (Programming Perl)
smoke tests: 15.6. Testing on Multiple Platforms (Learning Perl Objects, References and Modules)
SMTP protocol, interface to: 16.1.1. Send Email with Net::SMTP (Perl in a Nutshell)
SMTP servers, Net::SMTP module for: B.5.8. The Net::SMTP Module (Learning Perl)
SMTP (Simple Mail Transfer Protocol): 18.3.3. Discussion (Perl Cookbook)
server: 18.16. Program: expn and vrfy (Perl Cookbook)
smtpsend( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
SOAP 1.1 specification: 14.2. SOAP::Lite (Perl in a Nutshell)
SOAP (Simple Object Access Protocol): 18.. Introduction (Perl Cookbook)
14.1. What Is SOAP? (Perl in a Nutshell)
client: 18.14.1. Problem (Perl Cookbook)
implementations: 14.2. SOAP::Lite (Perl in a Nutshell)
server: 18.13.1. Problem (Perl Cookbook)
SOAP::Data: 14.3. SOAP::Data (Perl in a Nutshell)
SOAP::Fault: 14.5. SOAP::Fault (Perl in a Nutshell)
SOAP::Lite: 14.2. SOAP::Lite (Perl in a Nutshell)
methods: 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
SOAP::Lite module: 18.11.3. Discussion (Perl Cookbook)
18.13.2. Solution (Perl Cookbook)
SOAP::Serializer: 14.4. SOAP::Serializer (Perl in a Nutshell)
SOCK_ constants: 17.. Introduction (Perl Cookbook)
sockaddr( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods (Perl in a Nutshell)
sockaddr_in( ): 17.. Introduction (Perl Cookbook)
17.4.3. Discussion (Perl Cookbook)
sockaddr_in( ) (Socket): 15.1.3. Server Connections (Perl in a Nutshell)
15.1.4. Socket Module Functions (Perl in a Nutshell)
sockaddr_un( ): 17.. Introduction (Perl Cookbook)
Unix domain sockets: 17.6.2. Solution (Perl Cookbook)
sockaddr_un( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
sockdomain( ) (IO::Socket): 15.2.3. IO::Socket Methods (Perl in a Nutshell)
socket( ): 5. Function Reference (Perl in a Nutshell)
Socket module: 15.1. Built-in Socket Functions (Perl in a Nutshell)
socket( ): 17.. Introduction (Perl Cookbook)
Socket module: 8.187. Socket (Perl in a Nutshell)
16.5. Sockets (Programming Perl)
32.1.8. Networking and Interprocess Communication (Programming Perl)
inet_ntoa function: 29.2.47. gethostbyaddr (Programming Perl)
networking client, connecting to server: 16.5.1. Networking Clients (Programming Perl)
socket( ) (Socket): 15.1.1. Initializing a Socket (Perl in a Nutshell)
socketpair( ): 5. Function Reference (Perl in a Nutshell)
socketpair function: 29.2.158. socketpair (Programming Perl)
socketpair syscall: 16.3.3. Bidirectional Communication (Programming Perl)
sockets: 17.. Introduction (Perl Cookbook)
15. Sockets (Perl in a Nutshell)
accepting connections from clients: 29.2.2. accept (Programming Perl)
attaching address to: 29.2.5. bind (Programming Perl)
bidirectional clients: 17.10.1. Problem (Perl Cookbook)
built-in functions for: 15.1. Built-in Socket Functions (Perl in a Nutshell)
client-side connections: 15.1.2. Client Connections (Perl in a Nutshell)
15.2.1. Client-Side Sockets (Perl in a Nutshell)
closing: 29.2.16. close (Programming Perl)
closing after forking: 17.9.1. Problem (Perl Cookbook)
closing one side: 29.2.154. shutdown (Programming Perl)
connecting: 29.2.18. connect (Programming Perl)
connecting through firewalls: 17.21. Program: fwdport (Perl Cookbook)
daemon servers: 17.17.1. Problem (Perl Cookbook)
finding own name and address: 17.8.1. Problem (Perl Cookbook)
forking servers: 17.11.1. Problem (Perl Cookbook)
functions for: 29.2.67. getsockname (Programming Perl)
functions (Perl), dealing with: 16.5. Sockets (Programming Perl)
getting packed sockaddr address: 29.2.54. getpeername (Programming Perl)
identifying machine at end: 17.7.1. Problem (Perl Cookbook)
initializing: 15.1.1. Initializing a Socket (Perl in a Nutshell)
in interprocess communication: 16.5. Sockets (Programming Perl)
message passing: 16.5.3. Message Passing (Programming Perl)
networking clients: 16.5.1. Networking Clients (Programming Perl)
networking servers: 16.5.2. Networking Servers (Programming Perl)
IO::Socket module: 15.2. The IO::Socket Module (Perl in a Nutshell)
IO::Socket::INET subclass: 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
IO::Socket::UNIX subclass: 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
listen function for: 29.2.86. listen (Programming Perl)
logging port connection attempts: 17.20. Program: backsniff (Perl Cookbook)
low-level access functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
low-level access, functions for: 29.1. Perl Functions by Category (Programming Perl)
managing multiple input streams: 17.19.1. Problem (Perl Cookbook)
modules for: 32.1.8. Networking and Interprocess Communication (Programming Perl)
multihomed servers: 17.16.1. Problem (Perl Cookbook)
newlines, sending across: 25.1. Newlines (Programming Perl)
non-blocking: 17.2.3. Discussion (Perl Cookbook)
non-forking servers: 17.13.1. Problem (Perl Cookbook)
opening with socket function: 29.2.157. socket (Programming Perl)
preforking servers: 17.12.1. Problem (Perl Cookbook)
protocol associated with: 17.. Introduction (Perl Cookbook)
protocols and: 16. Interprocess Communication (Programming Perl)
receiving messages on: 29.2.125. recv (Programming Perl)
restarting servers on demand: 17.18.1. Problem (Perl Cookbook)
sending messages on: 29.2.145. send (Programming Perl)
server-side connections: 15.1.3. Server Connections (Perl in a Nutshell)
15.2.2. Server-Side Sockets (Perl in a Nutshell)
setting options: 29.2.148. setsockopt (Programming Perl)
shutting down connection: 29.2.154. shutdown (Programming Perl)
Socket module functions: 15.1.4. Socket Module Functions (Perl in a Nutshell)
TCP and: 16.5. Sockets (Programming Perl)
TCP protocol
communicating over: 17.3.1. Problem (Perl Cookbook)
writing clients: 17.1.1. Problem (Perl Cookbook)
writing servers: 17.2.1. Problem (Perl Cookbook)
UDP protocol
writing clients for: 17.4.1. Problem (Perl Cookbook)
writing servers for: 17.5.1. Problem (Perl Cookbook)
Unix domain: 17.. Introduction (Perl Cookbook)
17.6.1. Problem (Perl Cookbook)
Unix-domain sockets: 16.5. Sockets (Programming Perl)
sockets (TCP/IP): B.13.2. Sockets (Learning Perl)
sockhost( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods (Perl in a Nutshell)
sockopt( ) (IO::Socket): 15.2.3. IO::Socket Methods (Perl in a Nutshell)
sockport( ) (IO::Socket::INET): 15.2.4.1. IO::Socket::INET methods (Perl in a Nutshell)
socktype( ) (IO::Socket): 15.2.3. IO::Socket Methods (Perl in a Nutshell)
soft links: 13.3. Links and Files (Learning Perl)
13.3. Links and Files (Learning Perl)
sort variables: 28.2. Special Variables in Alphabetical Order (Programming Perl)
sort( ): 4.15.2. Solution (Perl Cookbook)
by computable field: 4.16.2. Solution (Perl Cookbook)
hashes: 5.10.2. Solution (Perl Cookbook)
sort function: 1.8. List Processing (Programming Perl)
sort module: 8.188. sort (Perl in a Nutshell)
sort subroutines, ,comparison operators in: 1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
sort subroutines (sort-definition subroutines): 15.4. Advanced Sorting (Learning Perl)
sortas="@parentheses">( )
conditional operator, use with: 3.16. Conditional Operator (Programming Perl)
sorting
advanced: 15.4. Advanced Sorting (Learning Perl)
array elements numerically: 4.15.1. Problem (Perl Cookbook)
arrays and lists by computable field: 4.16.1. Problem (Perl Cookbook)
arrays in hashes of: 9.2.3. Access and Printing of a Hash of Arrays (Programming Perl)
DBM files: 14.5.1. Problem (Perl Cookbook)
dictionary order: 7.8.3. Exercise 3 [10 min] (Learning Perl Objects, References and Modules)
directory contents: 9.. Introduction (Perl Cookbook)
9.13. Program: lst (Perl Cookbook)
du command output: 5.17. Program: dutree (Perl Cookbook)
efficient: 7.3. Sorting Efficiently (Learning Perl Objects, References and Modules)
glob operator: 7.8.1. Exercise 1 [15 min] (Learning Perl Objects, References and Modules)
hash elements: 5.10.1. Problem (Perl Cookbook)
hashes: 9.4.3. Access and Printing of a Hash of Hashes (Programming Perl)
with indices: 7.2. Sorting with Indices (Learning Perl Objects, References and Modules)
7.2. Sorting with Indices (Learning Perl Objects, References and Modules)
keys and values, hashes: 29.2.79. keys (Programming Perl)
lists: 29.2.159. sort (Programming Perl)
mail: 10.18. Program: Sorting Your Mail (Perl Cookbook)
overloading and: 13.3. Overloadable Operators (Programming Perl)
pod =head1 sections: 15.22. Program: tkshufflepod (Perl Cookbook)
randomizing array element order: 4.18.1. Problem (Perl Cookbook)
randomizing file line order: 8.7.1. Problem (Perl Cookbook)
review of: 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
7.1. Review of Sorting (Learning Perl Objects, References and Modules)
Schwartzian Transform: 7.4. The Schwartzian Transform (Learning Perl Objects, References and Modules)
sort blocks: 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
sort function: 29.2.159. sort (Programming Perl)
sort operator for: 3.7.2. The sort Operator (Learning Perl)
sorted list: A.3.2. Exercise 2 (Section 4.9.2) (Learning Perl Objects, References and Modules)
text into columns: 4.19. Program: words (Perl Cookbook)
soundex( ): 1.22.3. Discussion (Perl Cookbook)
Soundex matching: 1.22.1. Problem (Perl Cookbook)
source code
CPAN, for Perl distribution: 22. CPAN (Programming Perl)
development tools for: 18.6. Code Development Tools (Programming Perl)
filter for: 18.5.1. The Bytecode Generator (Programming Perl)
filters for: 24.5.3. Source Filters (Programming Perl)
foreign code, executing: 23. Security (Programming Perl)
window around breakpoint, examining: 20.1. Using the Debugger (Programming Perl)
source code for Perl, obtaining: 2. Installing Perl (Perl in a Nutshell)
source filters: 22.1. The CPAN modules Directory (Programming Perl)
s2p conversion program: B.25. Converting Other Languages to Perl (Learning Perl)
space: 2.2. Molecules (Programming Perl)
spaces: 8.1.1. Character Class Shortcuts (Learning Perl)
\s shortcut for: 8.1.1. Character Class Shortcuts (Learning Perl)
spaceship operator: 15.4. Advanced Sorting (Learning Perl)
7.1. Review of Sorting (Learning Perl Objects, References and Modules)
15.4. Advanced Sorting (Learning Perl)
3.12. Equality Operators (Programming Perl)
-spacing1, -spacing2, -spacing3 options (Text): 21.11. The Text Widget (Perl in a Nutshell)
special characters: 5.9.4. The Little Engine That /Could(n't)?/ (Programming Perl)
special variables: 28.1.6. Per-Package Special Functions (Programming Perl)
speed (see also performance)
24.2. Efficiency (Programming Perl)
splain: 8.56. diagnostics (Perl in a Nutshell)
splice( ): 5. Function Reference (Perl in a Nutshell)
4.12.2. Solution (Perl Cookbook)
29.2.160. splice (Programming Perl)
Perl versions, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
B.10.2. The splice Operator (Learning Perl)
splicing tied arrays: 14.2.1. Array-Tying Methods (Programming Perl)
split( ): 5. Function Reference (Perl in a Nutshell)
1.6.2. Solution (Perl Cookbook)
processing all words in file: 8.3.2. Solution (Perl Cookbook)
reading records with pattern separators: 6.7.2. Solution (Perl Cookbook)
using reverse( ) with: 1.7.2. Solution (Perl Cookbook)
variable-length text fields: 8.9.2. Solution (Perl Cookbook)
1.7. Regular Expressions (Programming Perl)
5.2. Pattern-Matching Operators (Programming Perl)
5.7.2. Clustering (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
29.2.161. split (Programming Perl)
variable-width fields, extracting with: Glossary (Programming Perl)
9.7. The split Operator (Learning Perl)
17.6. Slices (Learning Perl)
vs. join function: 9.8. The join Function (Learning Perl)
sports scores, sorting: 15.4.1. Sorting a Hash by Value (Learning Perl)
sprintf( ): 5. Function Reference (Perl in a Nutshell)
1.4.3. Discussion (Perl Cookbook)
floating-point numbers
comparing: 2.3.2. Solution (Perl Cookbook)
rounding: 2.2.2. Solution (Perl Cookbook)
15.3. Formatting Data with sprintf (Learning Perl)
14.4.1. Filehandle-Tying Methods (Programming Perl)
29.2.162. sprintf (Programming Perl)
Sql( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
SQL database: 20.9.3. Discussion (Perl Cookbook)
SQL queries
building programmatically: 14.13.1. Problem (Perl Cookbook)
without database server: 14.18.1. Problem (Perl Cookbook)
executing using DBI: 14.9.1. Problem (Perl Cookbook)
querying CSV files: 14.17.1. Problem (Perl Cookbook)
repeating efficiently: 14.12.1. Problem (Perl Cookbook)
saving results to Excel or CSV: 14.8.1. Problem (Perl Cookbook)
SQL statement placeholders: 12.2.4. Placeholders and Statement Handles (Perl in a Nutshell)
sqrt( ): 5. Function Reference (Perl in a Nutshell)
sqrt function: 10.4. The Naked Block Control Structure (Learning Perl)
14. Essential Testing (Learning Perl Objects, References and Modules)
29.2.163. sqrt (Programming Perl)
square brackets ([]): 1.. Introduction (Perl Cookbook)
creating anonymous arrays and hashes: 11.. References (Perl Cookbook)
in character classes: 8.1. Character Classes (Learning Perl)
in pattern test program results: 7.3. A Pattern Test Program (Learning Perl)
square root: B.9.1. Advanced Math Functions (Learning Perl)
srand( ): 5. Function Reference (Perl in a Nutshell)
2.7.2. Solution (Perl Cookbook)
29.2.164. srand (Programming Perl)
src directory (CPAN): 22. CPAN (Programming Perl)
SSI (server-side includes), mod_perl with: 11.5. Server-Side Includes with mod_perl (Perl in a Nutshell)
:ssl method group: 10.2. Importing Method Groups (Perl in a Nutshell)
SSL (Secure Sockets Layer): 20.16.1. Problem (Perl Cookbook)
stacks: 4.7. The local Operator (Learning Perl)
1.2.1.2.1. Arrays. (Programming Perl)
9. Data Structures (Programming Perl)
expression evaluation: 2.3. Built-in Data Types (Programming Perl)
backtracing with T command: 20.1. Using the Debugger (Programming Perl)
disciplines: 29.2.104. open (Programming Perl)
Perl, manipulating from C: 21.4.5. Fiddling with the Perl Stack from C (Programming Perl)
Perl virtuall machine: 18.3. Executing Your Code (Programming Perl)
subroutines, current calls: 29.2.8. caller (Programming Perl)
standard error stream: 11.1. What Is a Filehandle? (Learning Perl)
standard filehandles: 7.. Standard Filehandles (Perl Cookbook)
Standard Generalized Markup Language (SGML): 22.. Introduction (Perl Cookbook)
standard input: 2.8. Getting User Input (Learning Perl)
6. I/O Basics (Learning Perl)
scripts, passing by: 19.1. Command Processing (Programming Perl)
standard input stream: 11.1. What Is a Filehandle? (Learning Perl)
:standard method group: 10.2. Importing Method Groups (Perl in a Nutshell)
standard modules, table listing: 8. Standard Modules (Perl in a Nutshell)
standard output: 6.4. Output to Standard Output (Learning Perl)
6.4. Output to Standard Output (Learning Perl)
standard output stream: 11.1. What Is a Filehandle? (Learning Perl)
standard Unicode properties: 5.4.3.2. Standard Unicode properties (Programming Perl)
star (see asterisk)
star (*) as quantifier: 7.2.2. Simple Quantifiers (Learning Perl)
Star Wars, spaceship operator and: 15.4. Advanced Sorting (Learning Perl)
Start handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
startform( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
start_html( ) (CGI.pm): 10.5. Using JavaScript Features (Perl in a Nutshell)
10.7. CGI.pm Reference (Perl in a Nutshell)
starting position of matched string: 28.2. Special Variables in Alphabetical Order (Programming Perl)
start_multipart_form( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
StartService( ) (Win32::Service): 22.17. Win32::Service (Perl in a Nutshell)
starttag( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
start_tls( ) (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
stat buffer: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
stat( ): 5. Function Reference (Perl in a Nutshell)
8.17.2. Solution (Perl Cookbook)
9.. Introduction (Perl Cookbook)
timestamps: 9.1.2. Solution (Perl Cookbook)
11.6.1. The stat and lstat Functions (Learning Perl)
29.2.165. stat (Programming Perl)
32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
filehandles, calling on: 23.2.2. Handling Race Conditions (Programming Perl)
underscore filehandle and: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
stat(2) manpage: 11.6.1. The stat and lstat Functions (Learning Perl)
state( )
DBI module: 12.3. DBI Methods (Perl in a Nutshell)
Frame widget: 21.18.1. Toplevel Methods (Perl in a Nutshell)
state, maintaining (CGI): 10.3. Maintaining State (Perl in a Nutshell)
-state option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
statement handles (DBI methods): 12.2.3. Database Handles and Statement Handles (Perl in a Nutshell)
statements: 4.3. Statements (Perl in a Nutshell)
4. Statements and Declarations (Programming Perl)
compound: 4.2. Compound Statements (Programming Perl)
dangling: Glossary (Programming Perl)
global declarations and: 4.7. Global Declarations (Programming Perl)
if and unless: 4.3. if and unless Statements (Programming Perl)
labels for (see labels)
loop-control operators vs.: 4.4.4. Loop Control (Programming Perl)
loops (see loops)
Perl, evaluating from C: 21.4.4. Evaluating a Perl Statement from C (Programming Perl)
simple: 4.1. Simple Statements (Programming Perl)
static data members: 13.4.1. Problem (Perl Cookbook)
static linking: 21.3.1. XS and XSUBs (Programming Perl)
static local variables: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
static scoping (see lexical scope)
static variables: 6.2.3. Scoping Issues (Programming Perl)
statistics, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Stat::lsMode module: 9.11.2. Solution (Perl Cookbook)
status of exiting process: 28.2. Special Variables in Alphabetical Order (Programming Perl)
STDERR filehandle: 7.. Standard Filehandles (Perl Cookbook)
11.1. What Is a Filehandle? (Learning Perl)
11.5. Reopening a Standard Filehandle (Learning Perl)
4.4.3. Global Special Filehandles (Perl in a Nutshell)
4.9. Filehandles (Perl in a Nutshell)
14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
24.3. Programming with Style (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
29.2.38. fileno (Programming Perl)
controlling for other programs: 16.9.1. Problem (Perl Cookbook)
reading from programs: 16.7.1. Problem (Perl Cookbook)
STDIN: 1.4. Filehandles (Programming Perl)
STDIN filehandle: 7.. Standard Filehandles (Perl Cookbook)
11.1. What Is a Filehandle? (Learning Perl)
4.4.3. Global Special Filehandles (Perl in a Nutshell)
4.9. Filehandles (Perl in a Nutshell)
28.2. Special Variables in Alphabetical Order (Programming Perl)
29.2.38. fileno (Programming Perl)
preprocessing input: 16.6.2. Solution (Perl Cookbook)
reading single characters from: 29.2.43. getc (Programming Perl)
STDIN, STDOUT, and STDERR
reassigning to client connection: 16.5.2. Networking Servers (Programming Perl)
16.2.2. Passing Filehandles (Programming Perl)
passing filehandles to new programs through: 16.2.2. Passing Filehandles (Programming Perl)
stdio layer: 7.. I/O Operations (Perl Cookbook)
7.10.3. Discussion (Perl Cookbook)
STDOUT: 1.4. Filehandles (Programming Perl)
STDOUT filehandle: 7.. Standard Filehandles (Perl Cookbook)
7.. I/O Operations (Perl Cookbook)
11.1. What Is a Filehandle? (Learning Perl)
11.4.1. Changing the Default Output Filehandle (Learning Perl)
4.4.3. Global Special Filehandles (Perl in a Nutshell)
4.9. Filehandles (Perl in a Nutshell)
14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
28.2. Special Variables in Alphabetical Order (Programming Perl)
29.2.38. fileno (Programming Perl)
Glossary (Programming Perl)
filtering output: 16.5.3. Discussion (Perl Cookbook)
printing to: 29.2.113. print (Programming Perl)
stemming text, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
stepping through code: 20.2.1. Stepping and Running (Programming Perl)
sticky bit: 24.2.1. Time Efficiency (Programming Perl)
-sticky option (grid manager): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
sticky widgets, creating: 19.10.1. Problem (Perl Cookbook)
stopping (see also terminating)
infinite loop: 4.4.2. for Loops (Programming Perl)
StopService( ) (Win32::Service): 22.17. Win32::Service (Perl in a Nutshell)
stor( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
Storable module: 11.12.2. Solution (Perl Cookbook)
13.7.2. Solution (Perl Cookbook)
8.189. Storable (Perl in a Nutshell)
5.3. Storing Complex Data with Storable (Learning Perl Objects, References and Modules)
storage locations
for bytes (see also big endian little endian)
lvalues for: 1.5.3. Assignment Operators (Programming Perl)
Glossary (Programming Perl)
Glossary (Programming Perl)
(see also lvalues)
STORE( ): 13.15.3. Discussion (Perl Cookbook)
storing complex data values in DBM file: 14.6. Tie Modules on CPAN (Programming Perl)
storing data: 5.3. Storing Complex Data with Storable (Learning Perl Objects, References and Modules)
6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
A.9.1. Exercise (Section 10.7.1) (Learning Perl Objects, References and Modules)
stou( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
stream sockets: 17.. Introduction (Perl Cookbook)
17.11.3. Discussion (Perl Cookbook)
Stream style (XML::Parser): 13.4. XML::Parser Styles (Perl in a Nutshell)
strftime( ): 3.1.3. Discussion (Perl Cookbook)
3.8.2. Solution (Perl Cookbook)
strict module: 8.190. strict (Perl in a Nutshell)
1.2.1.4. Simplicities (Programming Perl)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
strict pragma: B.6.4. The strict Pragma (Learning Perl)
2.5.1. Name Lookups (Programming Perl)
4.9.2. Controlling the Use of Globals (Programming Perl)
8.4. Symbolic References (Programming Perl)
strict( ) (URI::URL): 20.5.3. URI::URL (Perl in a Nutshell)
string accumulator: 2.11. The undef Value (Learning Perl)
string comparison operators: 2.6.3. Comparison Operators (Learning Perl)
string concatenate operator (.): 2.5.3. Binary Assignment Operators (Learning Perl)
string context: 2.7.1. Scalar and List Context (Programming Perl)
string escapes (see backslash escapes)
string literals: 2.3. Strings (Learning Perl)
4.2.2. String Interpolation (Perl in a Nutshell)
2.6.2. String Literals (Programming Perl)
character classes: 4.6.4. Character Classes (Perl in a Nutshell)
comparing: 4.5.4.1. Relational operators (Perl in a Nutshell)
double-quoted (see double-quoted string literals)
newlines in: 2.6.2. String Literals (Programming Perl)
operators for: 4.5.11.4. String operator (Perl in a Nutshell)
v-strings (vector or version): 2.6.7. V-String Literals (Programming Perl)
string repetition operator (x): 2.3.3. String Operators (Learning Perl)
6.5.1. Arrays and printf (Learning Perl)
string repetition (x) operator: 4.5.11.4. String operator (Perl in a Nutshell)
String::Approx module: 1.22.3. Discussion (Perl Cookbook)
6.13.3. Discussion (Perl Cookbook)
stringification: 13.3. Overloadable Operators (Programming Perl)
modules for: 32.10. Data::Dumper (Programming Perl)
stringifying
data structures: 9.7. Saving Data Structures (Programming Perl)
objects: 8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
references: 8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
8.5.1. References Don't Work as Hash Keys (Programming Perl)
9.1.3. Access and Printing (Programming Perl)
9.1.5. Common Mistakes (Programming Perl)
stringifying operator, overloading: 14.4.1. Filehandle-Tying Methods (Programming Perl)
strings: 1.. Introduction (Perl Cookbook)
1.12.1. Problem (Perl Cookbook)
2.3. Strings (Learning Perl)
2.3. Strings (Learning Perl)
15. Strings and Sorting (Learning Perl)
14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
1.2.1. Variable Syntax (Programming Perl)
accessing substrings: 1.1.1. Problem (Perl Cookbook)
binary (see binary numbers)
bitwise operators, working with: 3.13. Bitwise Operators (Programming Perl)
boundary assertions: 1.7.3. Nailing Things Down (Programming Perl)
5.6.1. Beginnings: The \A and ^ Assertions (Programming Perl)
canonicalizing with Unicode combined characters: 1.9.1. Problem (Perl Cookbook)
capitalization of (see capitalization)
checking if valid numbers: 2.1.1. Problem (Perl Cookbook)
comparing: 3.11. Relational Operators (Programming Perl)
comparison operators: 1.5.6. Some Numeric and String Comparison Operators (Programming Perl)
as compilation units: 2.5.1. Name Lookups (Programming Perl)
concatenating: 3.8. Additive Operators (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
containing newlines, matches against: 5.2.1. Pattern Modifiers (Programming Perl)
context of: Glossary (Programming Perl)
converted automatically to numbers: 2.3.4. Automatic Conversion Between Numbers and Strings (Learning Perl)
converting
ASCII to and from HTML: 20.4.1. Problem (Perl Cookbook)
case: 1.13.1. Problem (Perl Cookbook)
characters and values: 1.4.1. Problem (Perl Cookbook)
non-numeric: 2.. Introduction (Perl Cookbook)
converting to list values: 29.2.189. unpack (Programming Perl)
converting to numbers
0x, 0b, and 0 prefixes, handling of: 2.6.1. Numeric Literals (Programming Perl)
copying and substituting: 6.1.1. Problem (Perl Cookbook)
display, changing in debugger: 20.3.3. Debugger Options (Programming Perl)
double-quoted
changes in Perl versions: 24.1.5. Previous Perl Traps (Programming Perl)
character interpolation in: 2.6.2. String Literals (Programming Perl)
doubled words, finding: 6.16.1. Problem (Perl Cookbook)
escaping characters: 1.18.1. Problem (Perl Cookbook)
eval function and: 24.2.1. Time Efficiency (Programming Perl)
extracting substrings: 29.2.168. substr (Programming Perl)
finding substrings within: 15.1. Finding a Substring with index (Learning Perl)
first character of: 28.2. Special Variables in Alphabetical Order (Programming Perl)
formats for: 29.2.162. sprintf (Programming Perl)
hash element indices: 5.. Introduction (Perl Cookbook)
headlines and titles, capitalizing: 1.14.1. Problem (Perl Cookbook)
hexadecimal (see hexadecimal numbers)
HTML text substitutions: 20.20. Program: htmlsub (Perl Cookbook)
index function: 29.2.75. index (Programming Perl)
interpolating functions and expressions within: 1.15.1. Problem (Perl Cookbook)
joining: 29.2.78. join (Programming Perl)
list values, converting to: 29.2.108. pack (Programming Perl)
matching
letters: 6.2.1. Problem (Perl Cookbook)
words: 6.3.1. Problem (Perl Cookbook)
modifying: 5.2.3.1. Modifying strings en passant (Programming Perl)
null-terminated, reading from binary files: 8.14.1. Problem (Perl Cookbook)
numbers, converting to: 2.6. Scalar Values (Programming Perl)
numeric operators with: 13.14.4. Example: Overloaded StrNum Class (Perl Cookbook)
octal (see octal numbers)
operators: 1.5.2. String Operators (Programming Perl)
24.1.1. Universal Blunders (Programming Perl)
operators for: 2.3.3. String Operators (Learning Perl)
comparison operators for: 2.6.3. Comparison Operators (Learning Perl)
parsing date and time information in: 3.7.1. Problem (Perl Cookbook)
plurals based on numbers: 2.17.1. Problem (Perl Cookbook)
printing: 29.2.113. print (Programming Perl)
printing values in: 8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
processing characters individually: 1.6.1. Problem (Perl Cookbook)
psgrep program: 1.24. Program: psgrep (Perl Cookbook)
quoted: 1.2.1.1. Singularities (Programming Perl)
range operator, working with: 3.15. Range Operator (Programming Perl)
references and: 8.5.1. References Don't Work as Hash Keys (Programming Perl)
reformatting paragraphs: 1.17.1. Problem (Perl Cookbook)
removing leading or trailing spaces: 1.19.1. Problem (Perl Cookbook)
removing or extracting HTML tags: 20.6.1. Problem (Perl Cookbook)
reversing elements of: 1.7.1. Problem (Perl Cookbook)
rindex function: 29.2.134. rindex (Programming Perl)
searching for and replacing substrings (s/// operator): 5.2.3. The s/// Operator (Substitution) (Programming Perl)
splitting into substrings: 29.2.161. split (Programming Perl)
study function and: 29.2.166. study (Programming Perl)
substituting specific words: 1.23. Program: fixstyle (Perl Cookbook)
text color, changing: 15.5.1. Problem (Perl Cookbook)
treating as files: 8.23.1. Problem (Perl Cookbook)
truth values of: 1.6.1. What Is Truth? (Programming Perl)
Unicode
support in Perl: 1.. Unicode Support in Perl (Perl Cookbook)
treating as octets: 1.10.1. Problem (Perl Cookbook)
treating as single characters: 1.8.1. Problem (Perl Cookbook)
universal character code: 1.. The Universal Character Code (Perl Cookbook)
vec function and: 29.2.195. vec (Programming Perl)
strings, alternate schemes for quoting: 4.2.2. String Interpolation (Perl in a Nutshell)
stripping (see deleting characters)
StrNum class (example): 13.14.4. Example: Overloaded StrNum Class (Perl Cookbook)
str2time( ) (HTTP::Date): 20.3.5. HTTP::Date (Perl in a Nutshell)
struct( ): 13.5.3. Discussion (Perl Cookbook)
struct( ) (Class::Struct module): 8.43. Class::Struct (Perl in a Nutshell)
Struct::Class module: 12.7. Managing Instance Data (Programming Perl)
struct_flock( ), lockarea program: 7.25. Program: lockarea (Perl Cookbook)
structs
emulating: 12.7.2. Generating Classes with Class::Struct (Programming Perl)
formatting: 29.2.108. pack (Programming Perl)
structs, classes as: 13.5.1. Problem (Perl Cookbook)
structural metacharacters in regular expressions: 5.1. The Regular Expression Bestiary (Programming Perl)
structural metasymbols: 5.3.1. Metasymbol Tables (Programming Perl)
structure of Perl programs: 4.1. Program Structure (Perl in a Nutshell)
StrVal (overload::StrVal): 13.7. Public Overload Functions (Programming Perl)
stub( ) (Devel::SelfStubber module): 8.55. Devel::SelfStubber (Perl in a Nutshell)
stubs for modules, generating: 32.1.17. Module Installation Support (Programming Perl)
study( ): 5. Function Reference (Perl in a Nutshell)
study function: 29.2.166. study (Programming Perl)
style, programming with: 24.3. Programming with Style (Programming Perl)
sub( ): 5. Function Reference (Perl in a Nutshell)
sub {}, loop controls and: 4.5. Bare Blocks (Programming Perl)
sub declaration: 8.2.2.3. The anonymous subroutine composer (Programming Perl)
29.2.167. sub (Programming Perl)
sub keyword: 10.. Introduction (Perl Cookbook)
4.2. Defining a Subroutine (Learning Perl)
6.1. Syntax (Programming Perl)
6.4. Prototypes (Programming Perl)
sub statement: 4.7. Subroutines (Perl in a Nutshell)
subarrays and subhashes
references to, in arrays: 1.2.1.2.1. Arrays. (Programming Perl)
subclasses: 12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
abstract methods and: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
attributes, overriding superclass ancestors: 12.7. Managing Instance Data (Programming Perl)
instance variables in: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
subclasses, determining membership: 13.9.1. Problem (Perl Cookbook)
sub_groups( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
subject( ) (Mail::Send): 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
subject, sorting mail by: 10.18. Program: Sorting Your Mail (Perl Cookbook)
submit( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
subnamespaces, for variables: 2.5. Names (Programming Perl)
subroutine call stack: 29.2.8. caller (Programming Perl)
subroutine calls, executing without stepping through: 20.2.1. Stepping and Running (Programming Perl)
subroutine references: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
subroutines: 10.. Introduction (Perl Cookbook)
4.1. System and User Functions (Learning Perl)
4.7. Subroutines (Perl in a Nutshell)
6.4. Closures (Learning Perl Objects, References and Modules)
1.2.1. Variable Syntax (Programming Perl)
6. Subroutines (Programming Perl)
6. Subroutines (Programming Perl)
12.2. Perl's Object System (Programming Perl)
arguments: 28.2. Special Variables in Alphabetical Order (Programming Perl)
aborting with exit: 29.2.35. exit (Programming Perl)
access arguments: 10.1.1. Problem (Perl Cookbook)
anonymous: B.20.3. Anonymous Subroutines and Closures (Learning Perl)
references to: 8.2.2.3. The anonymous subroutine composer (Programming Perl)
atrributes, getting and setting: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
autoloading: 10.2. Autoloading (Programming Perl)
12.5.4. Method Autoloading (Programming Perl)
32.1.17. Module Installation Support (Programming Perl)
barewords, confusing with: 24.1.5. Previous Perl Traps (Programming Perl)
built-in, overriding: 12.12.1. Problem (Perl Cookbook)
B::Xref module, cross-references with C: 18.6. Code Development Tools (Programming Perl)
calling: 4.3. Invoking a Subroutine (Learning Perl)
calling indirectly: 6.1. Syntax (Programming Perl)
calling, method invocations vs.: 12.4.1. Inheritable Constructors (Programming Perl)
classes with same names: 12.3.4. Package-Quoted Classes (Programming Perl)
constant: 10.1. Symbol Tables (Programming Perl)
constructors: 7.3. Object-Oriented Perl (Perl in a Nutshell)
currently running, name of: 10.4.1. Problem (Perl Cookbook)
custom import routines: 12.11. Custom Import Routines (Learning Perl Objects, References and Modules)
data, passing into and out of: 6.2. Semantics (Programming Perl)
debugger command for pattern match listings: 20.2.5. Locating Code (Programming Perl)
declaring: 4.7. Global Declarations (Programming Perl)
29.2.167. sub (Programming Perl)
declaring in package for AUTOLOAD management: 12.5.4. Method Autoloading (Programming Perl)
defining: 4.2. Defining a Subroutine (Learning Perl)
6.2. Semantics (Programming Perl)
definitions, loading from other files: 4.7. Global Declarations (Programming Perl)
do SUBROUTINE operator: 29.2.28. do (subroutine) (Programming Perl)
email sorter: 10.18. Program: Sorting Your Mail (Perl Cookbook)
errors, indicating: 6.2.2. Error Indications (Programming Perl)
exception handling: 10.12.1. Problem (Perl Cookbook)
executing: Glossary (Programming Perl)
extending: 10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
external, portability of: 25.6. External Subroutines (XS) (Programming Perl)
external (XSUBs): 21.3. Extending Perl (Using C from Perl) (Programming Perl)
importing: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
12.9. @EXPORT and @EXPORT_OK (Learning Perl Objects, References and Modules)
importing from another module: 6.1. Syntax (Programming Perl)
invoking: 4.3. Invoking a Subroutine (Learning Perl)
isa called as: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
lexical variables in: 4.6. Private Variables in Subroutines (Learning Perl)
lexically scoped: 29.2.99. my (Programming Perl)
localizing: 10.14.1. Problem (Perl Cookbook)
locking for threads: 17.2.2.3. Locking subroutines (Programming Perl)
locked attribute: 17.2.2.4. The locked attribute (Programming Perl)
lvalue attribute: 12.7.6. New Tricks (Programming Perl)
method resolution, steps for: 12.5. Class Inheritance (Programming Perl)
methods vs.: 12.3. Method Invocation (Programming Perl)
modules and: 12. Using Modules (Learning Perl Objects, References and Modules)
named, compiler/interpreter interaction: 18.7. Avant-Garde Compiler, Retro Interpreter (Programming Perl)
names for: 2.5. Names (Programming Perl)
2.5. Names (Programming Perl)
names of: 6.1. Syntax (Programming Perl)
nested: 8.3.7.2. Nested subroutines (Programming Perl)
nesting: 10.16.1. Problem (Perl Cookbook)
out of scope variables and: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
package names and: 2.7. Packages as Namespace Separators (Learning Perl Objects, References and Modules)
parameter lists, working with: 6.2.1. Tricks with Parameter Lists (Programming Perl)
passing arrays and hashes by reference: 10.5.1. Problem (Perl Cookbook)
passing by named parameter: 10.7.1. Problem (Perl Cookbook)
passing references in: 6.3. Passing References (Programming Perl)
performance and: 24.2.1. Time Efficiency (Programming Perl)
Perl, calling from C: 21.4.3. Calling a Perl Subroutine from C (Programming Perl)
persistent private variables: 10.3.1. Problem (Perl Cookbook)
private for modules: 12.4.1. Problem (Perl Cookbook)
private variables: 10.2.1. Problem (Perl Cookbook)
prototypes for functions: 10.11.1. Problem (Perl Cookbook)
prototyping, careful use of: 6.4.2. Care with Prototypes (Programming Perl)
redefining, inlining and: 6.4.1. Inlining Constant Functions (Programming Perl)
references to, retrieving from or passing to: 10.1. Symbol Tables (Programming Perl)
references to, in scalars: 1.2.1.1. Singularities (Programming Perl)
referencing: 6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
return context, detecting: 10.6.1. Problem (Perl Cookbook)
return function: 29.2.131. return (Programming Perl)
return values: 6.2. Semantics (Programming Perl)
returning by reference: 10.9.1. Problem (Perl Cookbook)
returning failure: 10.10.1. Problem (Perl Cookbook)
skipping selected: 10.8.1. Problem (Perl Cookbook)
returning references: 8.2.3. Object Constructors (Programming Perl)
saving global values: 10.13.1. Problem (Perl Cookbook)
scoping issues: 6.2.3. Scoping Issues (Programming Perl)
sorting, reverse disallowed as name for: 24.1.5. Previous Perl Traps (Programming Perl)
substituting with goto: 4.6. goto (Programming Perl)
29.2.71. goto (Programming Perl)
syntax errors and: 2.2. Inserting Code with eval (Learning Perl Objects, References and Modules)
timelocal: 29.2.88. localtime (Programming Perl)
trapping undefined function calls: 10.15.1. Problem (Perl Cookbook)
user-defined: 1.2.2. Verbs (Programming Perl)
writing switch statement: 10.17.1. Problem (Perl Cookbook)
subs module: 8.191. subs (Perl in a Nutshell)
32.1.13. Perl Language Extensions and Internals (Programming Perl)
subs pragma, overriding built-in functions with: 11.3. Overriding Built-in Functions (Programming Perl)
Subs style (XML::Parser): 13.4. XML::Parser Styles (Perl in a Nutshell)
subscribe( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
subscribed( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
$SUBSCRIPT_SEPARATOR: 2.9. Hashes (Programming Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
subscripting: 24.2.1. Time Efficiency (Programming Perl)
Glossary (Programming Perl)
negative: 2.3. Built-in Data Types (Programming Perl)
subscriptions( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
subscripts: 3.1. Accessing Elements of an Array (Learning Perl)
subscripts, arrays: 1.2.1.2.1. Arrays. (Programming Perl)
$SUBSCRIPT_SEPARATOR ($;) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
$SUBSEP ($;) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
subshells, environment variables, using with: 19.2. Environment Variables (Programming Perl)
substitute (s/) operator: 24.1.1. Universal Blunders (Programming Perl)
substitution
expanding filenames: 7.3.2. Solution (Perl Cookbook)
within strings: 6.1.1. Problem (Perl Cookbook)
substitution evaluations: 5.10.3.2. Substitution evaluations (Programming Perl)
substitution operator (see s/// operator)
5. Pattern Matching (Programming Perl)
substitution (s///) operator: 4.6. Regular Expressions (Perl in a Nutshell)
4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
2.7.4. Interpolative Context (Programming Perl)
5.2. Pattern-Matching Operators (Programming Perl)
substitution, shells versus Perl: 24.1.4. Shell Traps (Programming Perl)
substr( ): 5. Function Reference (Perl in a Nutshell)
1.1.2. Solution (Perl Cookbook)
operators to use with: 1.1.3. Discussion (Perl Cookbook)
pattern matching variables: 6.. Special Variables (Perl Cookbook)
24.2.1. Time Efficiency (Programming Perl)
29.2.168. substr (Programming Perl)
chop function and: 29.2.12. chop (Programming Perl)
manipulating string positions with: 5.6. Positions (Programming Perl)
15.2. Manipulating a Substring with substr (Learning Perl)
substrings: 1.1.1. Problem (Perl Cookbook)
15.1. Finding a Substring with index (Learning Perl)
Glossary (Programming Perl)
searching for and replacing with s/// operator: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
subtracting, from character sets: 5.4.3.4. Defining your own character properties (Programming Perl)
subtracting pattern modifiers from cloisters: 5.7.3. Cloistered Pattern Modifiers (Programming Perl)
subtraction (see also additive operators)
overloaded objects: 13.2. Overload Handlers (Programming Perl)
subtraction operator (-): 2.2.5. Numeric Operators (Learning Perl)
success code (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
SUPER pseudo-class: 8.8. The SUPER Way of Doing Things (Learning Perl Objects, References and Modules)
SUPER pseudoclass: 13.11.2. Solution (Perl Cookbook)
12.5.2. Accessing Overridden Methods (Programming Perl)
12.5.2. Accessing Overridden Methods (Programming Perl)
superclasses: 13.. Inheritance (Perl Cookbook)
13.. Some Notes on Object Terminology (Perl Cookbook)
8.8. The SUPER Way of Doing Things (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.2. Beating a Dead Horse (Learning Perl Objects, References and Modules)
10.4. Additional Instance Variables in Subclasses (Learning Perl Objects, References and Modules)
12.1. Brief Refresher on Object-Oriented Lingo (Programming Perl)
accessing overridden methods: 13.11.1. Problem (Perl Cookbook)
super_path( ) (Class::ISA module): 8.42. Class::ISA (Perl in a Nutshell)
superuser: Glossary (Programming Perl)
support for Perl: 1.3.2. How Can I Get Support for Perl? (Learning Perl)
supported( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
surface copies: 11.12.3. Discussion (Perl Cookbook)
surl script: 20.8.3. Discussion (Perl Cookbook)
Suspend( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
SV (internal scalar value): 21.2. Internal Data Types (Programming Perl)
SWIG: 21.3.1. XS and XSUBs (Programming Perl)
SWIG system, XSUBs, automatically generating: 21.3.1. XS and XSUBs (Programming Perl)
switch construct: 10.17.3. Discussion (Perl Cookbook)
Switch module: 10.17.2. Solution (Perl Cookbook)
8.192. Switch (Perl in a Nutshell)
switch statement: 19.7.3. Discussion (Perl Cookbook)
19.11.3. Discussion (Perl Cookbook)
4.5.1. Case Structures (Programming Perl)
24.2.1. Time Efficiency (Programming Perl)
Glossary (Programming Perl)
Perl vs. C programming: 24.1.3. C Traps (Programming Perl)
writing: 10.17.1. Problem (Perl Cookbook)
switch_clause function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
switches: 3.2. Command-Line Options (Perl in a Nutshell)
3.2. Command-Line Options (Perl in a Nutshell)
-w switch: 29. Functions (Programming Perl)
switches, command-line: 19.1. Command Processing (Programming Perl)
19.1.3. Switches (Programming Perl)
-e switches: 19.1. Command Processing (Programming Perl)
default, taking switches as: 19.2. Environment Variables (Programming Perl)
single character, processing with clustering: 32.1.3. Option, Argument, Parameter, and Configuration File Processing (Programming Perl)
Sx, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
sybperl package: 12.2. Design of DBI (Perl in a Nutshell)
Symbol module: 7.6.2. Solution (Perl Cookbook)
8.193. Symbol (Perl in a Nutshell)
symbol table entries, aliasing: 2.10. Typeglobs and Filehandles (Programming Perl)
symbol tables: 2.5. Names (Programming Perl)
2.5. Names (Programming Perl)
10.1. Symbol Tables (Programming Perl)
containing references to other symbol tables: 10.1. Symbol Tables (Programming Perl)
current package, determining use of: 10. Packages (Programming Perl)
displaying for packages: 20.3.3. Debugger Options (Programming Perl)
format name identifiers in: 29.2.41. format (Programming Perl)
in fully qualified names: 2.5. Names (Programming Perl)
local operator, making temporary changes with: 4.8.4. Dynamically Scoped Variables: local (Programming Perl)
packages: 29.2.109. package (Programming Perl)
references to: 8.2.5. Symbol Table References (Programming Perl)
Symbol module: 32.1.1. Data Types (Programming Perl)
symbolic references naming entries in: 8.1. What Is a Reference? (Programming Perl)
symbolic debugging: Glossary (Programming Perl)
Glossary (Programming Perl)
(see also debugging)
symbolic dereferences
checking with strict pragma: 4.9.2. Controlling the Use of Globals (Programming Perl)
symbolic links: 9.. Introduction (Perl Cookbook)
11.6. File Tests (Learning Perl)
11.6.1. The stat and lstat Functions (Learning Perl)
13.3. Links and Files (Learning Perl)
13.3. Links and Files (Learning Perl)
29.2.169. symlink (Programming Perl)
duplicating directory trees: 9.12. Program: symirror (Perl Cookbook)
getting filenames from: 29.2.123. readlink (Programming Perl)
lstat function and: 29.2.91. lstat (Programming Perl)
security risks in Unix: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
to packages: 12.16.1. Problem (Perl Cookbook)
symbolic references: 12.16.2. Solution (Perl Cookbook)
8.1. What Is a Reference? (Programming Perl)
8.4. Symbolic References (Programming Perl)
Glossary (Programming Perl)
Symbol::qualify( ): 12.6.3. Discussion (Perl Cookbook)
symbols: 12.8. Importing with Exporter (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
exporting from modules: 11.2. Creating Modules (Programming Perl)
exporting, preventing 11.2.1.3. Managing unknown symbols (Programming Perl)
importing into current package: 11.1. Using Modules (Programming Perl)
leaving off export list or deleting from import list: 11.2.1. Module Privacy and the Exporter (Programming Perl)
metasymbols, generic wildcards: 5.3.3. Wildcard Metasymbols (Programming Perl)
symirror program: 9.12. Program: symirror (Perl Cookbook)
symlink( ): 5. Function Reference (Perl in a Nutshell)
symlink function: 13.3. Links and Files (Learning Perl)
29.2.169. symlink (Programming Perl)
symmetric difference: 4.9.3. Discussion (Perl Cookbook)
sync( )
DB_File module: 8.52. DB_File (Perl in a Nutshell)
Mail::Folder: 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
synchronization: Glossary (Programming Perl)
data access in threads: 17.2.2.1. Synchronizing access with lock (Programming Perl)
syntactic sugar: Glossary (Programming Perl)
syntax: Glossary (Programming Perl)
syntax, checking: 19.1.3. Switches (Programming Perl)
syntax errors: 2.2. Inserting Code with eval (Learning Perl Objects, References and Modules)
2.4. Using require (Learning Perl Objects, References and Modules)
syntax extensions: B.19. Syntax Extensions (Learning Perl)
syntax, Perl: 2.3. Built-in Data Types (Programming Perl)
Sys::Syslog module: 8.195. Sys::Syslog (Perl in a Nutshell)
syscall( ): 5. Function Reference (Perl in a Nutshell)
syscall function: 29.2.3. alarm (Programming Perl)
29.2.170. syscall (Programming Perl)
syscalls: 7.. I/O Operations (Perl Cookbook)
Glossary (Programming Perl)
ioctl and fcntl returns: 29.2.77. ioctl (Programming Perl)
performance and: 24.2.1. Time Efficiency (Programming Perl)
Perl, C language vs.: 24.1.3. C Traps (Programming Perl)
restarting: 16.1.3. Timing Out Slow Operations (Programming Perl)
signal interruption of: 16.1.2. Reaping Zombies (Programming Perl)
Sys::Hostname module: B.5.10. The Sys::Hostname Module (Learning Perl)
8.194. Sys::Hostname (Perl in a Nutshell)
syslog, filehandle tying to: 14.6. Tie Modules on CPAN (Programming Perl)
sysopen( ): 5. Function Reference (Perl in a Nutshell)
filehandles: 7.1.2. Solution (Perl Cookbook)
non-blocking I/O: 7.20.2. Solution (Perl Cookbook)
unusual filenames: 7.2.2. Solution (Perl Cookbook)
file overwriting, controlling: 23.2.2. Handling Race Conditions (Programming Perl)
16.2.1. File Locking (Programming Perl)
16.3.4. Named Pipes (Programming Perl)
29.2.104. open (Programming Perl)
29.2.171. sysopen (Programming Perl)
sysread( ): 5. Function Reference (Perl in a Nutshell)
8.. Advanced Operations (Perl Cookbook)
14.4.1. Filehandle-Tying Methods (Programming Perl)
29.2.172. sysread (Programming Perl)
sysreadline( ): 7.23.2. Solution (Perl Cookbook)
sysseek( ): 5. Function Reference (Perl in a Nutshell)
8.. Advanced Operations (Perl Cookbook)
Sys::Syslog module: 17.20. Program: backsniff (Perl Cookbook)
32.1.7. Operating System Interfaces (Programming Perl)
system calls: 7.. I/O Operations (Perl Cookbook)
29.2.170. syscall (Programming Perl)
system databases: B.7.1. Direct System Database Access (Learning Perl)
system( ): 5. Function Reference (Perl in a Nutshell)
running multiple programs: 16.2.2. Solution (Perl Cookbook)
shell escapes: 19.5.2. Solution (Perl Cookbook)
14.1. The system Function (Learning Perl)
4.1. System and User Functions (Learning Perl)
29.2.174. system (Programming Perl)
list argument form, avoiding shell with: 23.3.2. Code Masquerading as Data (Programming Perl)
performance and: 24.2.1. Time Efficiency (Programming Perl)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
using vs. exec function: 14.2. The exec Function (Learning Perl)
system performance: 11.5. Creating Getters and Setters More Easily (Learning Perl Objects, References and Modules)
system time: 11.6.1. The stat and lstat Functions (Learning Perl)
System V interprocess communication functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
System V IPC: B.13.1. System V IPC (Learning Perl)
16.4. System V IPC (Programming Perl)
functions dealing with: 29.1. Perl Functions by Category (Programming Perl)
functions for semaphores: 29.2.142. semctl (Programming Perl)
IPC::SysV module: 32.1.8. Networking and Interprocess Communication (Programming Perl)
killing proces groups: 29.2.80. kill (Programming Perl)
messages, syscalls for: 29.2.95. msgctl (Programming Perl)
portability of: 25.5. Interprocess Communication (IPC) (Programming Perl)
shared memory, functions for: 29.2.150. shmctl (Programming Perl)
System V IPC syscalls: 16. Interprocess Communication (Programming Perl)
reliable signals, not supporting: 16.1.2. Reaping Zombies (Programming Perl)
$SYSTEM_FD_MAX: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$SYSTEM_FD_MAX ($^F) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
SysV IPC: 16.12.2. Solution (Perl Cookbook)
syswrite( ): 5. Function Reference (Perl in a Nutshell)
8.. Advanced Operations (Perl Cookbook)
14.4. Tying Filehandles (Programming Perl)
14.4.1. Filehandle-Tying Methods (Programming Perl)
29.2.175. syswrite (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

-t command-line option: 15.2.2. Solution (Perl Cookbook)
t command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
t directory: 14.1. What the Test Harness Does (Learning Perl Objects, References and Modules)
-T (text file) test operator: 3.10. Named Unary and File Test Operators (Programming Perl)
-t file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
-t option
dprofpp: 6.5. The Perl Profiler (Perl in a Nutshell)
form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
perlbug: 6.6. The perlbug Program (Perl in a Nutshell)
-T option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-T (taint checking) switch: 16.5. Sockets (Programming Perl)
16.5.2. Networking Servers (Programming Perl)
\t tab character assertion: 5.1. The Regular Expression Bestiary (Programming Perl)
-T (taint checking) command-line switch: 19.1.3. Switches (Programming Perl)
-t (tty) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
TableList( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
tables: 9.1. Arrays of Arrays (Programming Perl)
(see also multidimensional arrays)
tables, formatting with HTML shortcuts: 19.6.1. Problem (Perl Cookbook)
tabs (see also whitespace)
-tabs option (Text): 21.11. The Text Widget (Perl in a Nutshell)
tag( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
tagAdd( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagBind( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagCget( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagConfigure( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagDelete( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagLower( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagNames( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagNextrange( ): 21.11.3. Tags (Perl in a Nutshell)
tagRaise( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagRanges( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tagRemove( ) (Text widget): 21.11.3. Tags (Perl in a Nutshell)
tags, HTML (see HTML)
tags (HTML and XML), transforming text to: 5.10.4. Defining Your Own Assertions (Programming Perl)
tags, symbol sets, Exporter: 11.2.1.4. Tag-handling utility functions (Programming Perl)
tags, with Text widgets: 21.11.3. Tags (Perl in a Nutshell)
tailwtmp program: 8.24. Program: tailwtmp (Perl Cookbook)
taint
functions returning tainted data: 29.2. Perl Functions in Alphabetical Order (Programming Perl)
taint checking code: 23.3. Handling Insecure Code (Programming Perl)
taint checks: 23.1. Handling Insecure Data (Programming Perl)
taint mode
automatic enabling of: 23.1. Handling Insecure Data (Programming Perl)
enabling explicitly with -T switch: 23.1. Handling Insecure Data (Programming Perl)
programs needing to run with: 23.1. Handling Insecure Data (Programming Perl)
taint mode, using: 23. Security (Programming Perl)
tainted data, detecting and laundering: 23.1.1. Detecting and Laundering Tainted Data (Programming Perl)
taint checking: B.14. Security (Learning Perl)
16.5.2. Networking Servers (Programming Perl)
19.1.3. Switches (Programming Perl)
Glossary (Programming Perl)
taint mode: 19.4.3. Discussion (Perl Cookbook)
taintperl program: 24.1.5. Previous Perl Traps (Programming Perl)
"take a reference to" operator: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
3.8. References to Hashes (Learning Perl Objects, References and Modules)
6.1. Referencing a Named Subroutine (Learning Perl Objects, References and Modules)
-takefocus option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
tan( ): 2.11.2. Solution (Perl Cookbook)
tan function: 29.2.4. atan2 (Programming Perl)
tangent: 29.2.4. atan2 (Programming Perl)
tar: 2.3.1. Installing on Unix (Perl in a Nutshell)
Win32, for: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
tarballs (.tar.gz files): 22.2. Using CPAN Modules (Programming Perl)
(see also tar files)
tarring, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
tc( ): 1.14.2. Solution (Perl Cookbook)
tcapdemo program: 15.21.1. Description (Perl Cookbook)
tcgrep program: 6.22. Program: tcgrep (Perl Cookbook)
TCP: Glossary (Programming Perl)
over Internet-domain sockets: 16.5. Sockets (Programming Perl)
TCP clients/servers: 16.5.1. Networking Clients (Programming Perl)
TCP protocol
communicating over: 17.3.1. Problem (Perl Cookbook)
writing clients for: 17.1.1. Problem (Perl Cookbook)
writing servers for: 17.2.1. Problem (Perl Cookbook)
TCP/IP sockets: B.13.2. Sockets (Learning Perl)
TCP_NODELAY socket option: 17.3.3. Discussion (Perl Cookbook)
tctee program: 8.25. Program: tctee (Perl Cookbook)
tear-off menus: 15.14.3. Discussion (Perl Cookbook)
-tearoff option
Menu widget: 21.15. The Menu Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
tee program, Unix: 14.4.2. Creative Filehandles (Programming Perl)
tell( ): 5. Function Reference (Perl in a Nutshell)
8.. Advanced Operations (Perl Cookbook)
tell function: 29.2.176. tell (Programming Perl)
using on tied filehandle: 14.4.1. Filehandle-Tying Methods (Programming Perl)
telldir( ): 5. Function Reference (Perl in a Nutshell)
telldir function: 29.2.177. telldir (Programming Perl)
telnet, simulating from programs: 18.6.1. Problem (Perl Cookbook)
tempfile( ): 7.11.2. Solution (Perl Cookbook)
template( ): 20.9.2. Solution (Perl Cookbook)
template files: 13.2. Looking at the Templates (Learning Perl Objects, References and Modules)
Template Toolkit: 21.17.1. Problem (Perl Cookbook)
configuration: 21.17.3.1. Configuration (Perl Cookbook)
data structures: 21.17.3.4. Data structures (Perl Cookbook)
other templates: 21.17.3.6. Including other templates (Perl Cookbook)
parameters: 21.17.3.7. Parameters (Perl Cookbook)
Perl code: 21.17.3.3. Perl code (Perl Cookbook)
plug-ins: 21.17.3.8. Plug-ins (Perl Cookbook)
subroutines: 21.17.3.5. Subroutines (Perl Cookbook)
syntax: 21.17.3.2. Syntax (Perl Cookbook)
templates
HTML: 20.9.1. Problem (Perl Cookbook)
HTML::Mason: 21.16.1. Problem (Perl Cookbook)
autohandlers: 21.16.3.4. Autohandlers (Perl Cookbook)
configuration: 21.16.3.1. Configuration (Perl Cookbook)
dhandlers: 21.16.3.5. Dhandlers (Perl Cookbook)
Mason syntax: 21.16.3.2. Basic Mason syntax (Perl Cookbook)
objects: 21.16.3.3. Objects (Perl Cookbook)
for modules: 12.22. Example: Module Template (Perl Cookbook)
Template Toolkit: 21.17.1. Problem (Perl Cookbook)
configuration: 21.17.3.1. Configuration (Perl Cookbook)
data structures: 21.17.3.4. Data structures (Perl Cookbook)
other templates: 21.17.3.6. Including other templates (Perl Cookbook)
parameters: 21.17.3.7. Parameters (Perl Cookbook)
Perl code: 21.17.3.3. Perl code (Perl Cookbook)
plug-ins: 21.17.3.8. Plug-ins (Perl Cookbook)
subroutines: 21.17.3.5. Subroutines (Perl Cookbook)
syntax: 21.17.3.2. Syntax (Perl Cookbook)
templates, characters for pack/unpack: 29.2.108. pack (Programming Perl)
templates for outputting data: 4.12. Formats (Perl in a Nutshell)
templates, strings: 29.2.108. pack (Programming Perl)
temporary files
cleaning up: 14.7. Sending and Receiving Signals (Learning Perl)
B.26. Converting find Command Lines to Perl (Learning Perl)
data destruction and: 10. Object Destruction (Learning Perl Objects, References and Modules)
10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
10.1. Nested Object Destruction (Learning Perl Objects, References and Modules)
modifying files
with: 7.15.1. Problem (Perl Cookbook)
without: 7.17.1. Problem (Perl Cookbook)
security risks with: 23.2.3. Temporary Files (Programming Perl)
STDOUT and: 14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
temporary values: 2.3. Built-in Data Types (Programming Perl)
Tengwar script: 15.2. Effects of Character Semantics (Programming Perl)
Term::Cap module: 8.196. Term::Cap (Perl in a Nutshell)
Term::Complete module: 8.197. Term::Complete (Perl in a Nutshell)
Term::ReadLine module: 8.198. Term::ReadLine (Perl in a Nutshell)
Term::ANSIColor module: 15.5.2. Solution (Perl Cookbook)
Term::Cap module: 15.3.2. Solution (Perl Cookbook)
15.21.1. Description (Perl Cookbook)
32.1.11. User Interfaces (Programming Perl)
Term::Complete module: 32.1.11. User Interfaces (Programming Perl)
terminal (see user interfaces)
terminal, setting for debugging I/O: 20.4. Unattended Execution (Programming Perl)
terminating
infinite loop: 4.4.2. for Loops (Programming Perl)
processes: 29.2.80. kill (Programming Perl)
termios interface: 15.8.1. Problem (Perl Cookbook)
Term::ReadKey modlue: 29.2.43. getc (Programming Perl)
Term::ReadKey module: 1.17.3. Discussion (Perl Cookbook)
20.3.1. Editor Support for Debugging (Programming Perl)
checking for waiting input: 15.9.2. Solution (Perl Cookbook)
determining window size: 15.4.2. Solution (Perl Cookbook)
reading from keyboard: 15.6.2. Solution (Perl Cookbook)
reading passwords: 15.10.2. Solution (Perl Cookbook)
Term::ReadLine module: 15.11.2. Solution (Perl Cookbook)
20.3.1. Editor Support for Debugging (Programming Perl)
32.1.11. User Interfaces (Programming Perl)
Term::ReadLine::Gnu module: 15.11.2. Solution (Perl Cookbook)
Term::Rendezvous module: 20.4. Unattended Execution (Programming Perl)
terms: Glossary (Programming Perl)
precedence of: 3.1. Terms and List Operators (Leftward) (Programming Perl)
relationships among, expressing with operators: 3. Unary and Binary Operators (Programming Perl)
terms in Perl: 2.3. Built-in Data Types (Programming Perl)
ternary operator (?:): 10.9.2. The Ternary Operator, ?: (Learning Perl)
ternary operators (see trinary operator)
test command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
test command (Unix): 1.3.1. How to Do It (Programming Perl)
Test module: 32.1.18. Development Support (Programming Perl)
Test modules: 8.199. Test (Perl in a Nutshell)
Test::Builder module: 8.200. Test::Builder (Perl in a Nutshell)
Test::Harness module: 8.201. Test::Harness (Perl in a Nutshell)
Test::More module: 8.202. Test::More (Perl in a Nutshell)
Test::Simple module: 8.203. Test::Simple (Perl in a Nutshell)
test operators (files): 1.5.7. Some File Test Operators (Programming Perl)
Test::Harness module: 32.1.18. Development Support (Programming Perl)
testing
code coverage: 14. Essential Testing (Learning Perl Objects, References and Modules)
conditional tests: 14.4. Conditional Tests (Learning Perl Objects, References and Modules)
if defined: 29.2.23. defined (Programming Perl)
distributions and: 13. Writing a Distribution (Learning Perl Objects, References and Modules)
13.7. Trivial make test (Learning Perl Objects, References and Modules)
inequality: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
isa and can methods: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
Makefile.PL and: 15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
multiple test scripts: 14.5. More Complex Tests (Multiple Test Scripts) (Learning Perl Objects, References and Modules)
numeric equality: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
pound-sign comments and: 14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
smoke tests: 15.6. Testing on Multiple Platforms (Learning Perl Objects, References and Modules)
sqrt function: 14. Essential Testing (Learning Perl Objects, References and Modules)
for tainted data: 23.1.1. Detecting and Laundering Tainted Data (Programming Perl)
test harness: 13.7. Trivial make test (Learning Perl Objects, References and Modules)
14.1. What the Test Harness Does (Learning Perl Objects, References and Modules)
14.1. What the Test Harness Does (Learning Perl Objects, References and Modules)
14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
use operation: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
writing to STDOUT and STDERR: 14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
testing expression (of map or grep): 5.4. The map and grep Operators (Learning Perl Objects, References and Modules)
5.5. Using map (Learning Perl Objects, References and Modules)
testing modules: 22.3. Creating CPAN Modules (Programming Perl)
external testing: 22.3.2. External Testing (Programming Perl)
internal testing: 22.3.1. Internal Testing (Programming Perl)
Test::More module: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
14.6. Testing Things That Write to STDOUT and STDERR (Learning Perl Objects, References and Modules)
test.pl: 21.3.2. Creating Extensions (Programming Perl)
21.3.3. XSUB Input and Output (Programming Perl)
Test::Simple module: 14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
TEST_VERBOSE option (make test): 14.2. Writing Tests with Test::Simple (Learning Perl Objects, References and Modules)
text (see also strings)
adding to images: 15.20.1. Problem (Perl Cookbook)
changing color: 15.5.1. Problem (Perl Cookbook)
editors, support for Unicode fonts: 8.21.3. Discussion (Perl Cookbook)
lexical scope and: 2.5. Names (Programming Perl)
matching multiple lines of: 17.5.2. Matching Multiple-line Text (Learning Perl)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
pod data, converting to formatted ASCII: 32.1.16. Documentation Support (Programming Perl)
processing, Perl capabilities: 5. Pattern Matching (Programming Perl)
regular dollar sign in: 2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
Text::Wrap module for: B.5.11. The Text::Wrap Module (Learning Perl)
Unicode as international medium for: 15. Unicode (Programming Perl)
wrapping: 7.2.1. Accessing Formatting Internals (Programming Perl)
XML as: 22.. Introduction (Perl Cookbook)
text, translating to/from pod: 4.13.3. Pod Utilities (Perl in a Nutshell)
8.176. Pod::Text (Perl in a Nutshell)
text databases: 16.4. Variable-length (Text) Databases (Learning Perl)
text editors: 1.4. How Do I Make a Perl Program? (Learning Perl)
text editors, scripts, entering into: 1.3.1. How to Do It (Programming Perl)
text files, -T (file test) operator: 1.5.7. Some File Test Operators (Programming Perl)
text indexes (Entry widgets): 21.8.1. Text Indexes (Perl in a Nutshell)
text mode: 1.4. How Do I Make a Perl Program? (Learning Perl)
Text modules: 8.204. Text::Abbrev (Perl in a Nutshell)
Text::Abbrev module: 8.204. Text::Abbrev (Perl in a Nutshell)
Text::Balanced module: 8.205. Text::Balanced (Perl in a Nutshell)
Text::ParseWords module: 8.206. Text::ParseWords (Perl in a Nutshell)
Text::Soundex module: 8.207. Text::Soundex (Perl in a Nutshell)
Text::Tabs module: 8.208. Text::Tabs (Perl in a Nutshell)
Text::Wrap module: 8.209. Text::Wrap (Perl in a Nutshell)
-text option
Button widget: 21.4. The Button Widget (Perl in a Nutshell)
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Label widget: 21.7. The Label Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
text strings
cmp operator: 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
like function: 14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
ref operator and: 9.6. Making a Method Work with Either Classes or Instances (Learning Perl Objects, References and Modules)
sorting: 7.1. Review of Sorting (Learning Perl Objects, References and Modules)
Text widget (Perl/Tk): 21.11. The Text Widget (Perl in a Nutshell)
Text::Abbrev module: 6.20.2. Solution (Perl Cookbook)
6.20.3. Discussion (Perl Cookbook)
32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
textarea( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
Text::Balanced module: 6.17.2. Solution (Perl Cookbook)
6.17.3. Discussion (Perl Cookbook)
Text::CSV module: 1.20.3. Discussion (Perl Cookbook)
Text::CSV_File module: 1.20.3. Discussion (Perl Cookbook)
Text::Diff module: 8.22.3. Discussion (Perl Cookbook)
textfield( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
Text::Metaphone module: 1.22.2. Solution (Perl Cookbook)
Text::ParseWords module: 1.20.3. Discussion (Perl Cookbook)
32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
Text::Soundex module: 1.22.2. Solution (Perl Cookbook)
Text::Tabs module: 1.11.3. Discussion (Perl Cookbook)
Text::Template module: 20.9.2. Solution (Perl Cookbook)
-textvariable option
Button widget: 21.4. The Button Widget (Perl in a Nutshell)
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Entry widget: 21.8. The Entry Widget (Perl in a Nutshell)
Label widget: 21.7. The Label Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
Text::Wrap module: B.5.11. The Text::Wrap Module (Learning Perl)
Thread method: 17.2.1.1. Thread creation (Programming Perl)
thread model
control, passing between threads: 17.2.2.6. Condition variables (Programming Perl)
data access: 17.2.2. Data Access (Programming Perl)
Thread module: 8.210. Thread (Perl in a Nutshell)
17.2.1. The Thread Module (Programming Perl)
detach method, shutting down threads with: 17.2.1.4. The detach method (Programming Perl)
identifying threads: 17.2.1.5. Identifying threads (Programming Perl)
join method, catching exceptions from: 17.2.1.3. Catching exceptions from join (Programming Perl)
thread creation: 17.2.1.1. Thread creation (Programming Perl)
thread destruction: 17.2.1.2. Thread destruction (Programming Perl)
Thread::Queue module: 8.211. Thread::Queue (Perl in a Nutshell)
Thread::Semaphore module: 8.212. Thread::Semaphore (Perl in a Nutshell)
Thread::Signal module: 8.213. Thread::Signal (Perl in a Nutshell)
Thread::Specific module: 8.214. Thread::Specific (Perl in a Nutshell)
yielding the processor: 17.2.1.7. Yielding the processor (Programming Perl)
Thread::Queue module: 17.2.3.1. Queues (Programming Perl)
threads: B.31. Threads and Forking (Learning Perl)
3.5. Threads (Perl in a Nutshell)
17. Threads (Programming Perl)
29.2.89. lock (Programming Perl)
locked and method attributes, using: 12.7.6. New Tricks (Programming Perl)
locking: 29.2.89. lock (Programming Perl)
multiple, in single interpreter: 18.3. Executing Your Code (Programming Perl)
process model: 17.1. The Process Model (Programming Perl)
thread model: 17.2. The Thread Model (Programming Perl)
Thread::Semaphore module: 17.2. The Thread Model (Programming Perl)
17.2.2.6. Condition variables (Programming Perl)
17.2.3.2. Semaphores (Programming Perl)
Thread::Signal module: 17.2.3.3. Other standard threading modules (Programming Perl)
threads.pm: 17.14.2. Solution (Perl Cookbook)
three-way comparison operator (cmp): 15.4. Advanced Sorting (Learning Perl)
-tickinterval option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
tid method: 17.2.1.5. Identifying threads (Programming Perl)
tidy_body( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
tie( ): 5. Function Reference (Perl in a Nutshell)
13.15.2. Solution (Perl Cookbook)
DBM files
emptying: 14.2.2. Solution (Perl Cookbook)
making and using: 14.1.2. Solution (Perl Cookbook)
14. Tied Variables (Programming Perl)
29.2.178. tie (Programming Perl)
use or require declarations and: 14. Tied Variables (Programming Perl)
tie interface: 16.1.1. Opening and Closing DBM Hashes (Learning Perl)
Tie modules: 8.215. Tie::Array, Tie::StdArray (Perl in a Nutshell)
Tie::Array module: 8.215. Tie::Array, Tie::StdArray (Perl in a Nutshell)
Tie::Handle module: 8.217. Tie::Handle (Perl in a Nutshell)
Tie::Hash module: 8.218. Tie::Hash (Perl in a Nutshell)
Tie::RefHash module: 8.220. Tie::RefHash (Perl in a Nutshell)
Tie::Scalar module: 8.221. Tie::Scalar (Perl in a Nutshell)
Tie::StdArray module: 8.215. Tie::Array, Tie::StdArray (Perl in a Nutshell)
Tie::SubstrHash module: 8.222. Tie::SubstrHash (Perl in a Nutshell)
tie modules on CPAN: 14.6. Tie Modules on CPAN (Programming Perl)
TIEARRAY( ): 13.15.3. Discussion (Perl Cookbook)
Tie::Array module: 13.15.3. Discussion (Perl Cookbook)
14.2. Tying Arrays (Programming Perl)
32.1.14. Convenient Classes (Programming Perl)
SPLICE subroutine, using: 14.2.1. Array-Tying Methods (Programming Perl)
Tie::Counter module: 14.1.2. Magical Counter Variables (Programming Perl)
tied( ): 5. Function Reference (Perl in a Nutshell)
tied function: 14. Tied Variables (Programming Perl)
29.2.179. tied (Programming Perl)
tied variables: B.21. Tied Variables (Learning Perl)
Tie::DBI module: 14.6. Tie Modules on CPAN (Programming Perl)
Tie::DevNull module: 14.4.2. Creative Filehandles (Programming Perl)
Tie::DevRandom module: 14.4.2. Creative Filehandles (Programming Perl)
Tie::File module: 8.4.2. Solution (Perl Cookbook)
8.8.2. Solution (Perl Cookbook)
8.10.3. Discussion (Perl Cookbook)
files as arrays: 8.18.2. Solution (Perl Cookbook)
TIEHANDLE( ): 13.15.3. Discussion (Perl Cookbook)
Tie::Handle module: 13.15.3. Discussion (Perl Cookbook)
TIEHASH( ): 13.15.3. Discussion (Perl Cookbook)
Tie::Hash module: 13.15.3. Discussion (Perl Cookbook)
14.3. Tying Hashes (Programming Perl)
32.1.14. Convenient Classes (Programming Perl)
Tie::IxHash module: 5.7.2. Solution (Perl Cookbook)
Tie::Persistent module: 14.6. Tie Modules on CPAN (Programming Perl)
Tie::RefHash module: 5.13.2. Solution (Perl Cookbook)
32.1.14. Convenient Classes (Programming Perl)
TIESCALAR( ): 13.15.3. Discussion (Perl Cookbook)
Tie::Scalar module: 13.15.3. Discussion (Perl Cookbook)
14.1. Tying Scalars (Programming Perl)
32.1.14. Convenient Classes (Programming Perl)
Tie::SecureHash module: 12.7.5. Using Closures for Private Objects (Programming Perl)
14.6. Tie Modules on CPAN (Programming Perl)
Tie::StdArray module: 14.2. Tying Arrays (Programming Perl)
Tie::StdHash module: 14.3. Tying Hashes (Programming Perl)
Tie::StdScalar module: 14.1. Tying Scalars (Programming Perl)
Tie::SubstrHash module: 32.1.14. Convenient Classes (Programming Perl)
Tie::Syslog module: 14.6. Tie Modules on CPAN (Programming Perl)
Tie::Tee module: 14.4.2. Creative Filehandles (Programming Perl)
Tie::VecArray module: 14.6. Tie Modules on CPAN (Programming Perl)
Tie::Watch module: 14.6. Tie Modules on CPAN (Programming Perl)
tilde (~)
bitwise negation operator: 4.5.2. Unary Operators (Perl in a Nutshell)
suppressing output whitespace: 4.12. Formats (Perl in a Nutshell)
~~ to print strings in fields: 4.12. Formats (Perl in a Nutshell)
expanding in filenames: 7.3.1. Problem (Perl Cookbook)
home directory expansion of: 29.2.69. glob (Programming Perl)
tilde-prefix (~): 12.1. Moving Around the Directory Tree (Learning Perl)
tilde ("~"), as value for $^I variable: 16.4. Variable-length (Text) Databases (Learning Perl)
time( ): 5. Function Reference (Perl in a Nutshell)
3.. Introduction (Perl Cookbook)
high-res timers: 3.9.3. Discussion (Perl Cookbook)
11.6.2. The localtime Function (Learning Perl)
29.2.180. time (Programming Perl)
32.1.1. Data Types (Programming Perl)
time base ($^T): 28.2. Special Variables in Alphabetical Order (Programming Perl)
Time modules: 8.223. Time::gmtime (Perl in a Nutshell)
Time::gmtime module: 8.223. Time::gmtime (Perl in a Nutshell)
Time::HiRes module: 8.224. Time::HiRes (Perl in a Nutshell)
Time::Local module: 8.225. Time::Local (Perl in a Nutshell)
Time::localtime module: 8.226. Time::localtime (Perl in a Nutshell)
Time::tm module: 8.227. Time::tm (Perl in a Nutshell)
time zones (see date and time values)
TimeConvert( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
timegm( ): 3.. Introduction (Perl Cookbook)
3.2.2. Solution (Perl Cookbook)
Time::gmtime module: 3.. Introduction (Perl Cookbook)
3.3.2. Solution (Perl Cookbook)
32.1.7. Operating System Interfaces (Programming Perl)
Time::HiRes module: 3.9.2. Solution (Perl Cookbook)
3.10.2. Solution (Perl Cookbook)
time2iso( ) (HTTP::Date): 20.3.5. HTTP::Date (Perl in a Nutshell)
time2isoz( ) (HTTP::Date): 20.3.5. HTTP::Date (Perl in a Nutshell)
timelocal( ): 3.. Introduction (Perl Cookbook)
3.2.2. Solution (Perl Cookbook)
timelocal function: B.5.12. The Time::Local Module (Learning Perl)
Time::Local module: B.5.12. The Time::Local Module (Learning Perl)
timelocal subroutine: 29.2.88. localtime (Programming Perl)
Time::localtime module: 3.. Introduction (Perl Cookbook)
32.1.7. Operating System Interfaces (Programming Perl)
timeout( )
IO::Socket module: 15.2.3. IO::Socket Methods (Perl in a Nutshell)
LWP::UserAgent module: 20.2.3. LWP::UserAgent (Perl in a Nutshell)
Timeout option (IO::Socket::INET): 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
Timer::HiRes module: 29.2.3. alarm (Programming Perl)
timers, high-resolution: 3.9.1. Problem (Perl Cookbook)
times( ): 5. Function Reference (Perl in a Nutshell)
times function: 29.2.181. times (Programming Perl)
times, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
times, portability of: 25.8. Dates and Times (Programming Perl)
timestamps: 9.1.1. Problem (Perl Cookbook)
11.6.1. The stat and lstat Functions (Learning Perl)
6.8.1. Exercise [30 min] (Learning Perl Objects, References and Modules)
changing: 13.7. Changing Timestamps (Learning Perl)
number for, converting: 11.6.2. The localtime Function (Learning Perl)
time2str( ) (HTTP::Date): 20.3.5. HTTP::Date (Perl in a Nutshell)
Time::timelocal module: 3.3.2. Solution (Perl Cookbook)
Time::tm module: 3.. Introduction (Perl Cookbook)
32.1.7. Operating System Interfaces (Programming Perl)
timing
with alarms: 29.2.3. alarm (Programming Perl)
comparing for subroutines' execution: 20.6. The Perl Profiler (Programming Perl)
glitches, handling: 23.2. Handling Timing Glitches (Programming Perl)
temporary files: 23.2.3. Temporary Files (Programming Perl)
Unix kernel security bugs: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
glitches in
race conditions, handling: 23.2.2. Handling Race Conditions (Programming Perl)
running times of alternate code versions, comparing: 32.2. Benchmark (Programming Perl)
script running: 3.10. Named Unary and File Test Operators (Programming Perl)
timing out operations: 16.21.1. Problem (Perl Cookbook)
timing out slow operations: 16.1.3. Timing Out Slow Operations (Programming Perl)
title( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
Title( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
titlecase
\u and ucfirst function, using in conversions: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
ucfirst, translating to: 15.2. Effects of Character Semantics (Programming Perl)
Tk: 22.1. The CPAN modules Directory (Programming Perl)
24.2.6. User Efficiency (Programming Perl)
(see also Perl/Tk)
Tk extension to Perl: 21. Perl/Tk (Perl in a Nutshell)
callbacks: 21.1.3. Callbacks (Perl in a Nutshell)
colors and fonts: 21.1.4. Colors and Fonts (Perl in a Nutshell)
geometry managers: 21.2. Geometry Managers (Perl in a Nutshell)
scrollbars: 21.1.2. Scrollbars (Perl in a Nutshell)
widgets: 21.1. Widgets (Perl in a Nutshell)
Button widget: 21.4. The Button Widget (Perl in a Nutshell)
Canvas widget: 21.12. The Canvas Widget (Perl in a Nutshell)
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
common configuration options: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
Entry widget: 21.8. The Entry Widget (Perl in a Nutshell)
Frame widget: 21.17. The Frame Widget (Perl in a Nutshell)
Label widget: 21.7. The Label Widget (Perl in a Nutshell)
Listbox widget: 21.10. The Listbox Widget (Perl in a Nutshell)
Menu widget: 21.15. The Menu Widget (Perl in a Nutshell)
Menubutton widget: 21.14. The Menubutton Widget (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
Text widget: 21.11. The Text Widget (Perl in a Nutshell)
toplevel widget: 21.18. The Toplevel Widget (Perl in a Nutshell)
widgets methods: 21.1.1. Widget Methods (Perl in a Nutshell)
Tk module set: B.32. Graphical User Interfaces (GUIs) (Learning Perl)
Tk toolkit: 15.. Introduction (Perl Cookbook)
dialog boxes: 15.15.1. Problem (Perl Cookbook)
DOS shell window, removing: 15.17.1. Problem (Perl Cookbook)
menus: 15.14.1. Problem (Perl Cookbook)
resize events: 15.16.1. Problem (Perl Cookbook)
tkshufflepod program: 15.22. Program: tkshufflepod (Perl Cookbook)
tkRunning option (debugger): 20.3.3. Debugger Options (Programming Perl)
tkshufflepod program: 15.22. Program: tkshufflepod (Perl Cookbook)
to( )
Mail::Send module: 16.2.2. Better Header Control with Mail::Send (Perl in a Nutshell)
Net::SMTP module: 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
-to option (Scale): 21.13. The Scale Widget (Perl in a Nutshell)
TODO blocks: 14.4. Conditional Tests (Learning Perl Objects, References and Modules)
$TODO variable: 14.4. Conditional Tests (Learning Perl Objects, References and Modules)
toggle( ) (Checkbutton): 21.5.1. Checkbutton Methods (Perl in a Nutshell)
toggling trace mode (debugger): 20.2.3. Tracing (Programming Perl)
tokenization: 21.1. How Perl Works (Programming Perl)
(see also lexical analysis)
tokens: 2.2. Molecules (Programming Perl)
18.2. Compiling Your Code (Programming Perl)
ambiguous characters, problems with: 3.10. Named Unary and File Test Operators (Programming Perl)
parsing text into list of: 32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
top-level package: 2.5.1. Name Lookups (Programming Perl)
top( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
top-of-form processing: 7. Formats (Programming Perl)
29.2.140. select (output filehandle) (Programming Perl)
29.2.200. write (Programming Perl)
top-of-page processing: 28.2. Special Variables in Alphabetical Order (Programming Perl)
-top option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
topicalization: 1.2.1.4. Simplicities (Programming Perl)
toplevel widget (Perl/Tk): 21.18. The Toplevel Widget (Perl in a Nutshell)
-topspring option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
toString( ), XML documents: 22.2.3. Discussion (Perl Cookbook)
-tp option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
tr/// operator: 1.1.3. Discussion (Perl Cookbook)
B.8.1. Transliteration with tr/// (Learning Perl)
converting case with: 1.13.3. Discussion (Perl Cookbook)
tr// pattern match operator: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
tr/// (transliteration) operator: 5.2. Pattern-Matching Operators (Programming Perl)
5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
29.2.182. tr/// (Programming Perl)
29.2.201. y// (Programming Perl)
characters, transliterating with: 15.2. Effects of Character Semantics (Programming Perl)
=~ and !~ binding operators, using with: 5.2. Pattern-Matching Operators (Programming Perl)
modifiers for: 5.2.1. Pattern Modifiers (Programming Perl)
trace( ) (DBI): 12.3. DBI Methods (Perl in a Nutshell)
tracing, stack backtrace (debugger T command): 20.2.3. Tracing (Programming Perl)
20.1. Using the Debugger (Programming Perl)
trailing
growing files: 8.5.1. Problem (Perl Cookbook)
whitespace, removing: 1.19.1. Problem (Perl Cookbook)
trailing newlines (see newlines, trailing)
trailing spaces in string comparisons: 3.11. Relational Operators (Programming Perl)
Transact( ) (Win32::ODBC): 24.1. ODBC Methods and Properties (Perl in a Nutshell)
24.1. ODBC Methods and Properties (Perl in a Nutshell)
transformations, XML: 22.. Transformations (Perl Cookbook)
transient( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
translating between languages: 24.5.2. Generating Perl in Other Languages (Programming Perl)
translation: 29.2.182. tr/// (Programming Perl)
29.2.201. y// (Programming Perl)
transliteration escapes, processing by Perl regex compiler: 5.9.2.1. When backslashes happen (Programming Perl)
transport protocols: 15. Sockets (Perl in a Nutshell)
transport( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
trapping exceptions: 29.2.32. eval (Programming Perl)
trapping out-of-memory errors: 28.2. Special Variables in Alphabetical Order (Programming Perl)
trapping signals: 16.1. Signals (Programming Perl)
trapping undefined function calls: 10.15.1. Problem (Perl Cookbook)
traverse( ) (HTML::Parser): 20.4.3. HTML::Element (Perl in a Nutshell)
traversing hashes: 5.5.1. Problem (Perl Cookbook)
tree structures: 11.17. Program: Binary Trees (Perl Cookbook)
Tree style (XML::Parser): 13.4. XML::Parser Styles (Perl in a Nutshell)
trigonometry: 2.11.1. Problem (Perl Cookbook)
operating in degrees vs. radians: 2.10.1. Problem (Perl Cookbook)
trigonometry, Math::Trig module: 32.1.1. Data Types (Programming Perl)
trim( ): 2.1.3. Discussion (Perl Cookbook)
trinary operator: 3. Unary and Binary Operators (Programming Perl)
Glossary (Programming Perl)
?: as: 3.16. Conditional Operator (Programming Perl)
4.5.1. Case Structures (Programming Perl)
overloading, not working with: 13.1. The overload Pragma (Programming Perl)
trinary operators: 1.5. Operators (Programming Perl)
troff: Glossary (Programming Perl)
troubleshooting: 20. The Perl Debugger (Programming Perl)
(see also debugging)
C code: 24.1.3. C Traps (Programming Perl)
scripts, common mistakes of novices: 24.1. Common Goofs for Novices (Programming Perl)
shell code: 24.1.4. Shell Traps (Programming Perl)
multidimensional arrays: 9.1.5. Common Mistakes (Programming Perl)
-troughcolor option
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
Scrollbar widget: 21.9. The Scrollbar Widget (Perl in a Nutshell)
true values: 1.2.1.1. Singularities (Programming Perl)
Glossary (Programming Perl)
truncate( ): 5. Function Reference (Perl in a Nutshell)
8.. Advanced Operations (Perl Cookbook)
29.2.183. truncate (Programming Perl)
truncating: Glossary (Programming Perl)
truncating argument list: 20.3.3. Debugger Options (Programming Perl)
truncating arrays: 2.8.2. Array Length (Programming Perl)
truncating numbers: 29.2.76. int (Programming Perl)
truth conditions, if and unless statements, evaluating with: 1.6.1.1. The if and unless statements (Programming Perl)
truth values, evaluating for in Perl: 1.6.1. What Is Truth? (Programming Perl)
try block: 29.2.32. eval (Programming Perl)
-ts option, form geometry manager: 21.2.4. The form Geometry Manager (Perl in a Nutshell)
tty: 16.3.3. Bidirectional Communication (Programming Perl)
tty devices, testing for: 15.2.3. Discussion (Perl Cookbook)
TTY option (PERLDB_OPTS): 6.4. Customizing the Debugger (Perl in a Nutshell)
two-dimensional arrays
creating and accessing: 9.1.1. Creating and Accessing a Two-Dimensional Array (Programming Perl)
creating your own: 9.1.2. Growing Your Own (Programming Perl)
tying variables: 8.5.1. References Don't Work as Hash Keys (Programming Perl)
14. Tied Variables (Programming Perl)
arrays: 14.2. Tying Arrays (Programming Perl)
filehandles: 14.4. Tying Filehandles (Programming Perl)
hashes: 14.3. Tying Hashes (Programming Perl)
scalars: 14.1. Tying Scalars (Programming Perl)
untying trap: 14.5. A Subtle Untying Trap (Programming Perl)
type( )
Canvas widget: 21.12.3. Canvas Methods (Perl in a Nutshell)
Menu widget: 21.15.2. Menu Methods (Perl in a Nutshell)
Net::FTP module: 18.2. Net::FTP (Perl in a Nutshell)
Type option
IO::Socket::INET module: 15.2.4. IO::Socket::INET Reference (Perl in a Nutshell)
IO::Socket::UNIX module: 15.2.5. IO::Socket::UNIX Reference (Perl in a Nutshell)
Type( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods (Perl in a Nutshell)
typecasting operator (in C): 3.21. C Operators Missing from Perl (Programming Perl)
typed referents: 11.. References (Perl Cookbook)
typedefs (C language): 21.2. Internal Data Types (Programming Perl)
Glossary (Programming Perl)
typeglobs: 1.24. Program: psgrep (Perl Cookbook)
typeglob: 1.2.1. Variable Syntax (Programming Perl)
7.5.3. Discussion (Perl Cookbook)
2.5. Names (Programming Perl)
2.10. Typeglobs and Filehandles (Programming Perl)
8. References (Programming Perl)
8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
anonymous: 8.2.4. Handle References (Programming Perl)
anonymous
generating with Symbol module: 32.1.1. Data Types (Programming Perl)
assigning references to: 12.16.3. Discussion (Perl Cookbook)
autovivification of: 14.4.1. Filehandle-Tying Methods (Programming Perl)
filehandle references, creating: 8.2.4. Handle References (Programming Perl)
filehandles with, creating alias for: 7.10.3. Discussion (Perl Cookbook)
global values: 10.13.3.3. Using local( ) on parts of aggregates (Perl Cookbook)
IO::Handle object: 8.2.5. Symbol Table References (Programming Perl)
local function, using with: 29.2.87. local (Programming Perl)
printing contents of: 20.3.3. Debugger Options (Programming Perl)
prototype symbol (*): 1.2.1. Variable Syntax (Programming Perl)
references to typeglobs vs.: 8.2.4. Handle References (Programming Perl)
subroutines, resolving to: 12.3. Method Invocation (Programming Perl)
symbol table aliasing with: 10.1. Symbol Tables (Programming Perl)
in symbol table hashes: 10.1. Symbol Tables (Programming Perl)
variables, tying to classes via: 14. Tied Variables (Programming Perl)
typelookup( ) (SOAP::Lite): 14.2.1. SOAP::Lite Methods (Perl in a Nutshell)
typemap: 21.3.1. XS and XSUBs (Programming Perl)
types (see data types)
typing variables
scalars: 2.6. Scalar Values (Programming Perl)
subtypes, converting between: 2.6. Scalar Values (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

\U (uppercase) characters: 4.6.4. Character Classes (Perl in a Nutshell)
u command (CPAN.pm): 2.4.4. Installing Modules with the CPAN Module (Perl in a Nutshell)
-u (dump core) command-line switch: 19.1.3. Switches (Programming Perl)
\u escape: 5.2.3. The s/// Operator (Substitution) (Programming Perl)
-u file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
-u option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
-u (setuid) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
\u shortcut: 9.6.5. Case Shifting (Learning Perl)
\U string escape: 1.13.2. Solution (Perl Cookbook)
-U (unsafe) command-line switch: 19.1.3. Switches (Programming Perl)
ualarm( ): 3.9.3. Discussion (Perl Cookbook)
uc( ): 5. Function Reference (Perl in a Nutshell)
1.13.2. Solution (Perl Cookbook)
29.2.184. uc (Programming Perl)
15.2. Effects of Character Semantics (Programming Perl)
ucfirst( ): 5. Function Reference (Perl in a Nutshell)
1.13.2. Solution (Perl Cookbook)
29.2.185. ucfirst (Programming Perl)
15.2. Effects of Character Semantics (Programming Perl)
UDP: Glossary (Programming Perl)
passing messages with: 16.5.3. Message Passing (Programming Perl)
UDP packets: 16.5. Sockets (Programming Perl)
UDP (User Datagram Protocol)
writing clients for: 17.4.1. Problem (Perl Cookbook)
writing servers for: 17.5.1. Problem (Perl Cookbook)
uid (user-ID): 11.6.1. The stat and lstat Functions (Learning Perl)
$UID ($<) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
uidl( ) (Net::POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
umask( ): 5. Function Reference (Perl in a Nutshell)
umask function: 29.2.186. umask (Programming Perl)
Glossary (Programming Perl)
umask values: 7.1.3. Discussion (Perl Cookbook)
uname( ): 17.8.2. Solution (Perl Cookbook)
unary operators: 4.5.2. Unary Operators (Perl in a Nutshell)
1.5. Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
3. Unary and Binary Operators (Programming Perl)
arithmetic: 1.5.4. Unary Arithmetic Operators (Programming Perl)
Boolean: 1.5.7. Some File Test Operators (Programming Perl)
class handler, invoking: 13.1. The overload Pragma (Programming Perl)
functions, behaving as: 3.1. Terms and List Operators (Leftward) (Programming Perl)
ideographic: 3.5. Ideographic Unary Operators (Programming Perl)
list operators, distinguishing from: 3.10. Named Unary and File Test Operators (Programming Perl)
named: 2.11.3. Filename Globbing Operator (Programming Perl)
3.1. Terms and List Operators (Leftward) (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
listing of: 3.10. Named Unary and File Test Operators (Programming Perl)
prototyping functions as: 6.4.2. Care with Prototypes (Programming Perl)
unbind method (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
unbuffered input/output: 7.. I/O Operations (Perl Cookbook)
7.19.3. Discussion (Perl Cookbook)
8.. Advanced Operations (Perl Cookbook)
15.6.1. Problem (Perl Cookbook)
uncompress command: 2.3.1. Installing on Unix (Perl in a Nutshell)
uncompressing Perl source code: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
undef( ): 5. Function Reference (Perl in a Nutshell)
compared to delete( ): 5.4.3. Discussion (Perl Cookbook)
24.2.1. Time Efficiency (Programming Perl)
29.2.187. undef (Programming Perl)
arrays, freeing memory from: 2.8.2. Array Length (Programming Perl)
2.12. The defined Function (Learning Perl)
slices and: 17.6. Slices (Learning Perl)
undef value: 2.11. The undef Value (Learning Perl)
4.2.5. Variables (Perl in a Nutshell)
undefined scalars: 2.6. Scalar Values (Programming Perl)
undefined subroutines, calling with AUTOLOAD: 10.2. Autoloading (Programming Perl)
undefined values: 1.. Introduction (Perl Cookbook)
undelete_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
-underline option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
_(underscore)
global filehandle: 28.2. Special Variables in Alphabetical Order (Programming Perl)
underscore (_)
filehandle: 4.4.3. Global Special Filehandles (Perl in a Nutshell)
improving number legibility: 4.2.1. Numbers (Perl in a Nutshell)
in integer literals: 2.2.3. Integer Literals (Learning Perl)
in variable names: 4.10. The use strict Pragma (Learning Perl)
underscore (_), file stat cache: 9.. Introduction (Perl Cookbook)
underscore filehandle: 11.6.5. Using the Special Underscore Filehandle (Learning Perl)
Underscore module: 14.1.3. Magically Banishing $_ (Programming Perl)
unequal (see equality operators[semi] relational operators)
unescape_from( ) (Mail::Internet): 16.2.5. Mail::Internet Reference (Perl in a Nutshell)
Unicode: 1.. Unicode Support in Perl (Perl Cookbook)
B.30. Locales and Unicode (Learning Perl)
2.1. Atoms (Programming Perl)
15. Unicode (Programming Perl)
case translation tables: 15.2. Effects of Character Semantics (Programming Perl)
character database: 1.5.3. Discussion (Perl Cookbook)
combined characters, canonicalizing strings with: 1.9.1. Problem (Perl Cookbook)
converting Microsoft files to: 8.21.1. Problem (Perl Cookbook)
converting to characters: 29.2.14. chr (Programming Perl)
editors for: 15.2. Effects of Character Semantics (Programming Perl)
encodings, XML and: 22.. XML Declaration (Perl Cookbook)
information about: 5.4.3. Unicode Properties (Programming Perl)
line separator character: 2.2. Molecules (Programming Perl)
locales and: 29.2.82. lc (Programming Perl)
named characters, using: 1.5.1. Problem (Perl Cookbook)
paragraph separator character: 2.2. Molecules (Programming Perl)
Perl properties for: 5.4. Character Classes (Programming Perl)
properties: 5.4.3. Unicode Properties (Programming Perl)
bidirectional rendering: 5.4.3.2. Standard Unicode properties (Programming Perl)
block properties: 5.4.3.3. Unicode block properties (Programming Perl)
decomposition of characters: 5.4.3.2. Standard Unicode properties (Programming Perl)
Perl character class shortcuts and: 5.4.2. Classic Perl Character Class Shortcuts (Programming Perl)
Perl composites: 5.4.3.1. Perl's Unicode properties (Programming Perl)
standard: 5.4.3.2. Standard Unicode properties (Programming Perl)
syllabaries, classifying by vowel sounds: 5.4.3.2. Standard Unicode properties (Programming Perl)
properties database: 15.2. Effects of Character Semantics (Programming Perl)
reading and writing from filehandles: 8.20.1. Problem (Perl Cookbook)
smiley face: 29.2.14. chr (Programming Perl)
strings
treating as octets: 1.10.1. Problem (Perl Cookbook)
treating as single characters: 1.8.1. Problem (Perl Cookbook)
summary of, accessing: 15.2. Effects of Character Semantics (Programming Perl)
support for, turning on: 32.1.6. Internationalization and Locale (Programming Perl)
titlecase, converting strings to: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
Unicode Standard, Version 3.0: 15.2. Effects of Character Semantics (Programming Perl)
use in Perl, caveats on: 15.3. Caution, [ren2bold] Working (Programming Perl)
wildcard metasymbols, matching with: 5.3.3. Wildcard Metasymbols (Programming Perl)
Unicode characters: 1.7. Regular Expressions (Programming Perl)
in identifiers: 2.5. Names (Programming Perl)
smiley: 2.6.2. String Literals (Programming Perl)
Uniform Resource Locators (see URLs)
unimport( ): 13.15.4. Tie Example: Outlaw $_ (Perl Cookbook)
unimport method (Exporter): 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
uninitialized, variables: 1.2.1.1. Singularities (Programming Perl)
unions of lists: 4.8.1. Problem (Perl Cookbook)
computing: 4.9.1. Problem (Perl Cookbook)
unique list elements, extracting: 4.7.1. Problem (Perl Cookbook)
unique_name( ) (Net::FTP): 18.2. Net::FTP (Perl in a Nutshell)
universal character code: 1.. The Universal Character Code (Perl Cookbook)
UNIVERSAL class: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
inheritance and: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
methods, adding to: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
purpose of: 11.1. UNIVERSAL Methods (Learning Perl Objects, References and Modules)
utility methods: 11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
11.2. Testing Your Objects for Good Behavior (Learning Perl Objects, References and Modules)
UNIVERSAL module: 13.8.3. Discussion (Perl Cookbook)
8.228. UNIVERSAL (Perl in a Nutshell)
32.1.14. Convenient Classes (Programming Perl)
Universal Time: 11.6.2. The localtime Function (Learning Perl)
Unix: Glossary (Programming Perl)
domain sockets: 17.. Introduction (Perl Cookbook)
17.6.1. Problem (Perl Cookbook)
input/output and: 11.1. What Is a Filehandle? (Learning Perl)
I/O layers: 7.19.3. Discussion (Perl Cookbook)
model of files/directories and: 13.3. Links and Files (Learning Perl)
portability and: 1.1.2. Why Are There So Many Footnotes? (Learning Perl)
security bugs: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
truncating kernel interpretation of #! line: 19.1. Command Processing (Programming Perl)
utilities for
diamond operator and: 6.2. Input from the Diamond Operator (Learning Perl)
regular expressions and: 7. Concepts of Regular Expressions (Learning Perl)
Unix-domain sockets: 15. Sockets (Perl in a Nutshell)
unix layer: 7.. I/O Operations (Perl Cookbook)
7.19.3. Discussion (Perl Cookbook)
Unix, test command, test scripts and: 1.3.1. How to Do It (Programming Perl)
Unix password databases: B.7.1. Direct System Database Access (Learning Perl)
Unix signals, sending/receiving: 14.7. Sending and Receiving Signals (Learning Perl)
Unix, CPAN modules, installing on: 22.2.1. Decompressing and Unpacking CPAN Modules (Programming Perl)
Unix systems: 1.2.1.1. Singularities (Programming Perl)
#! (shebang) line: 3. The Perl Executable (Perl in a Nutshell)
command processing: 3.1. Command Processing (Perl in a Nutshell)
fileglobbing: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
File::Spec::Unix module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
installing Perl on: 2.3.1. Installing on Unix (Perl in a Nutshell)
sockets for: 32.1.8. Networking and Interprocess Communication (Programming Perl)
UnixDate( ): 3.7.3. Discussion (Perl Cookbook)
unless control structure: 10.1. The unless Control Structure (Learning Perl)
unless modifier: 10.3. Expression Modifiers (Learning Perl)
10.3. Expression Modifiers (Learning Perl)
4.3.1.4. Modifiers (Perl in a Nutshell)
4.1. Simple Statements (Programming Perl)
unless statement: 4.3.1. Conditionals and Loops (Perl in a Nutshell)
1.6.1.1. The if and unless statements (Programming Perl)
if statements, using instead of: 4.3. if and unless Statements (Programming Perl)
unlink( ): 5. Function Reference (Perl in a Nutshell)
removing directories and contents: 9.8.3. Discussion (Perl Cookbook)
29.2.188. unlink (Programming Perl)
13.1. Removing Files (Learning Perl)
2.7.2. Boolean Context (Programming Perl)
unmark( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
unmarked_articles( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
unmark_list( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
unmark_range( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
unordered lists (see hashes)
unpack: 25.2. Endianness and Number Width (Programming Perl)
1.1.2. Solution (Perl Cookbook)
1.4.3. Discussion (Perl Cookbook)
fixed-length records: 8.15.2. Solution (Perl Cookbook)
16.2. Manipulating Data with pack and unpack (Learning Perl)
29.2.189. unpack (Programming Perl)
fixed-width fields, use with: Glossary (Programming Perl)
template characters for: 29.2.108. pack (Programming Perl)
unpacking CPAN modules: 22.2.1. Decompressing and Unpacking CPAN Modules (Programming Perl)
unpacking Perl source code: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
unpack_sockaddr_in( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
unpack_sockaddr_un( ) (Socket): 15.1.4. Socket Module Functions (Perl in a Nutshell)
Unparsed handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
unpost( ) (Menu widget): 21.15.2. Menu Methods (Perl in a Nutshell)
unqualified, names, searching for: 2.5.1. Name Lookups (Programming Perl)
unquoted hash keys: 17.4. Unquoted Hash Keys (Learning Perl)
unread bytes, determining number: 7.21.1. Problem (Perl Cookbook)
unsafe operations: 19.1.3. Switches (Programming Perl)
unshift( ): 5. Function Reference (Perl in a Nutshell)
circular lists: 4.17.2. Solution (Perl Cookbook)
2.5.1. Extending @INC (Learning Perl Objects, References and Modules)
12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
9. Data Structures (Programming Perl)
29.2.190. unshift (Programming Perl)
3.4.2. The shift and unshift Operators (Learning Perl)
unsigned integers, lists of, storing: 29.2.195. vec (Programming Perl)
unsigned shorts: 29.2.162. sprintf (Programming Perl)
unsub_groups( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
unsubscribe( ) (News::Newsrc): 17.3.1. News::Newsrc Reference (Perl in a Nutshell)
untie( ): 5. Function Reference (Perl in a Nutshell)
untie function: 14. Tied Variables (Programming Perl)
14.5. A Subtle Untying Trap (Programming Perl)
29.2.21. dbmclose (Programming Perl)
29.2.191. untie (Programming Perl)
outstanding references, not eliminating: 14.1. Tying Scalars (Programming Perl)
until control structure: 10.2. The until Control Structure (Learning Perl)
until loops: 4.4.1. while and until Statements (Programming Perl)
until modifier: 10.3. Expression Modifiers (Learning Perl)
10.3. Expression Modifiers (Learning Perl)
4.3.1.4. Modifiers (Perl in a Nutshell)
4.1. Simple Statements (Programming Perl)
until statement: 4.3.1.1. while loops (Perl in a Nutshell)
untying trap: 14.5. A Subtle Untying Trap (Programming Perl)
unwinding hashes: 5.2.1. The Hash as a Whole (Learning Perl)
up method: 17.2.3.2. Semaphores (Programming Perl)
upcase function: 6.2.1. Tricks with Parameter Lists (Programming Perl)
update_message( ) (Mail::Folder): 16.2.3. Handle Folders with Mail::Folder (Perl in a Nutshell)
updating random-access files: 8.13.1. Problem (Perl Cookbook)
uppercase
case shifting and: 9.6.5. Case Shifting (Learning Perl)
vs. lowercase in variable names: 2.5.1. Choosing Good Variable Names (Learning Perl)
converting to: 2.6.2. String Literals (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
uppercase, converting to lowercase: 1.13.1. Problem (Perl Cookbook)
URI modules: 20.5. The URI Module (Perl in a Nutshell)
URI::Escape: 20.5. The URI Module (Perl in a Nutshell)
URI::Heuristic: 20.5. The URI Module (Perl in a Nutshell)
URI::URL: 20.5.3. URI::URL (Perl in a Nutshell)
URI::URL module: 20.1. LWP Overview (Perl in a Nutshell)
uri( ) (SOAP::Lite): 14.2. SOAP::Lite (Perl in a Nutshell)
uri_escape( ): 20.2.3. Discussion (Perl Cookbook)
URI::Escape module: 20.2.3. Discussion (Perl Cookbook)
URI::Heuristic module: 20.1.3. Discussion (Perl Cookbook)
20.7.3. Discussion (Perl Cookbook)
URIs (universal resource identifiers): 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
URI::URL module: 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
url( )
CGI.pm module: 10.7. CGI.pm Reference (Perl in a Nutshell)
HTTP::Daemon module: 20.3.7. HTTP::Daemon (Perl in a Nutshell)
HTTP::Request module: 20.3.1. HTTP::Request (Perl in a Nutshell)
url subroutine (URI::URL): 12.10. Exporting in a Primarily OO Module (Learning Perl Objects, References and Modules)
urlify program: 6.21. Program: urlify (Perl Cookbook)
urllist parameter, CPAN configuration table: 8.46.4. CD-ROM Support (Perl in a Nutshell)
URLs
code in this book: 0.3. Code Examples (Learning Perl)
CPAN: 1.3.1. What Is CPAN? (Learning Perl)
B.4.3. Finding and Installing Modules (Learning Perl)
Perl Monastery: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
search interfaces for Perl: 1.3.1. What Is CPAN? (Learning Perl)
URLs (uniform resource locators): 22.7.1. General Internet Methods (Perl in a Nutshell)
encoding: 9.2. URL Encoding (Perl in a Nutshell)
extra path information: 9.3. Extra Path Information (Perl in a Nutshell)
URI::URL module: 20.1. LWP Overview (Perl in a Nutshell)
20.5.3. URI::URL (Perl in a Nutshell)
use: 4.7. Global Declarations (Programming Perl)
global and lexical scoping of: 4.8. Scoped Declarations (Programming Perl)
use attributes pragma: 6.5. Subroutine Attributes (Programming Perl)
use autouse pragma: 12.3.1. Problem (Perl Cookbook)
use base: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
use base declarations: 12.5.1. Inheritance Through @ISA (Programming Perl)
pseudohash implementations, requirement with: 12.7.1. Field Declarations with use fields (Programming Perl)
use base pragma: 31.3. use base (Programming Perl)
use blib pragma: 31.4. use blib (Programming Perl)
use bytes pragma: 1.10.2. Solution (Perl Cookbook)
15.2. Effects of Character Semantics (Programming Perl)
use CGI: 12.11. Custom Import Routines (Learning Perl Objects, References and Modules)
use charnames pragma: 1.5.3. Discussion (Perl Cookbook)
15.2. Effects of Character Semantics (Programming Perl)
use command: 10. Packages (Programming Perl)
use constant pragma: 1.21.2. Solution (Perl Cookbook)
use declaration
modules: 11.1. Using Modules (Programming Perl)
use declarations: 1.2.1.4. Simplicities (Programming Perl)
4.7. Global Declarations (Programming Perl)
4.9. Pragmas (Programming Perl)
(see also pragmas)
tie function and: 14. Tied Variables (Programming Perl)
use strict: 24.1.2. Frequently Ignored Advice (Programming Perl)
use directives: B.4.3. Finding and Installing Modules (Learning Perl)
7. Packages,Modules, and Objects (Perl in a Nutshell)
7.2. Modules (Perl in a Nutshell)
pragmas and: B.6. Pragmas (Learning Perl)
use fields declarations: 12.5.1. Inheritance Through @ISA (Programming Perl)
use fields pragma
field declarations with: 12.7.1. Field Declarations with use fields (Programming Perl)
use filetest pragma: 3.10. Named Unary and File Test Operators (Programming Perl)
use lib: 12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
12.7. Setting the Path at the Right Time (Learning Perl Objects, References and Modules)
13.10. Using the Alternate Library Location (Learning Perl Objects, References and Modules)
use lib pragma: 12.8.3. Discussion (Perl Cookbook)
use locale pragma: 6.12.2. Solution (Perl Cookbook)
use operation: 12.6. What use Is Doing (Learning Perl Objects, References and Modules)
13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
14.3. Writing Tests with Test::More (Learning Perl Objects, References and Modules)
use operator: 10.. Introduction (Perl Cookbook)
use overload pragma: 13.14.1. Problem (Perl Cookbook)
13.1. The overload Pragma (Programming Perl)
use pragmas: 6.12.2. Solution (Perl Cookbook)
12.. Modules (Perl Cookbook)
trapping errors in: 12.2.1. Problem (Perl Cookbook)
use statement: 21.1. How Perl Works (Programming Perl)
use strict: 8.1. If We Could Talk to the Animals... (Learning Perl Objects, References and Modules)
8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
use strict pragma: 4.10. The use strict Pragma (Learning Perl)
B.6.4. The strict Pragma (Learning Perl)
use subs declarations: 12.5.4. Method Autoloading (Programming Perl)
use utf8 pragma: 5.3.3. Wildcard Metasymbols (Programming Perl)
use warnings pragma: 20. The Perl Debugger (Programming Perl)
use_alarm( ) (LWP::UserAgent): 20.2.3. LWP::UserAgent (Perl in a Nutshell)
use_named_parameters( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
Usenet news: 17. Usenet News (Perl in a Nutshell)
messages: 18.4.1. Problem (Perl Cookbook)
Net::News module: 17.2. Net::NNTP (Perl in a Nutshell)
News::Newsrc module: 17.3. The News::Newsrc Module (Perl in a Nutshell)
Perl-related: 1.4.1. The comp.lang.perl.* Newsgroups (Perl in a Nutshell)
Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
use( ): 5. Function Reference (Perl in a Nutshell)
USER command (POP3): 16.1.3. Retrieving Email with Net::POP3 (Perl in a Nutshell)
User Datagram Protocol (see UDP)
user-defined functions (see subroutines)
user-defined subroutines: 1.2.2. Verbs (Programming Perl)
1.2.2. Verbs (Programming Perl)
(see also subroutines)
user efficiency, Perl programming: 24.2.6. User Efficiency (Programming Perl)
user functions (see subroutines)
User::grent module: 8.229. User::grent (Perl in a Nutshell)
user-ID, numeric ($uid): 11.6.1. The stat and lstat Functions (Learning Perl)
changing file ownership and: 13.6. Changing Ownership (Learning Perl)
user-ID (uid): 11.6.1. The stat and lstat Functions (Learning Perl)
user interfaces: 15.. Introduction (Perl Cookbook)
adding text to images: 15.20.1. Problem (Perl Cookbook)
checking for waiting input: 15.9.1. Problem (Perl Cookbook)
clearing the screen: 15.3.1. Problem (Perl Cookbook)
controlling programs with Expect: 15.13.1. Problem (Perl Cookbook)
determining window size: 15.4.1. Problem (Perl Cookbook)
dialog boxes, creating with Tk: 15.15.1. Problem (Perl Cookbook)
DOS shell window, removing: 15.17.1. Problem (Perl Cookbook)
editing input: 15.11.1. Problem (Perl Cookbook)
full-screen mode: 15.. Introduction (Perl Cookbook)
graphing data: 15.18.1. Problem (Perl Cookbook)
15.23. Program: graphbox (Perl Cookbook)
managing screen: 15.12.1. Problem (Perl Cookbook)
manipulating terminal directly: 15.8.1. Problem (Perl Cookbook)
menus, creating with Tk: 15.14.1. Problem (Perl Cookbook)
modules providing: 32.1.11. User Interfaces (Programming Perl)
multiscreen CGI scripts: 19.11.1. Problem (Perl Cookbook)
reading from keyboard: 15.6.1. Problem (Perl Cookbook)
reading passwords without echo: 15.10.1. Problem (Perl Cookbook)
ringing terminal bell: 15.7.1. Problem (Perl Cookbook)
tcapdemo program: 15.21.1. Description (Perl Cookbook)
testing programs if running interactively: 15.2.1. Problem (Perl Cookbook)
text color: 15.5.1. Problem (Perl Cookbook)
thumbnailing images: 15.19.1. Problem (Perl Cookbook)
Tk resize events: 15.16.1. Problem (Perl Cookbook)
User::pwent module: 8.230. User::pwent (Perl in a Nutshell)
user_agent( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
UserAgent object: 20.1. LWP Overview (Perl in a Nutshell)
20.2. The LWP Modules (Perl in a Nutshell)
20.2.3. LWP::UserAgent (Perl in a Nutshell)
UserAgent( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
UserCreate( ) (Win32::NetAdmin): 22.10. Win32::NetAdmin (Perl in a Nutshell)
User::grent module: 29.2.44. getgrent (Programming Perl)
32.1.7. Operating System Interfaces (Programming Perl)
user_name( ) (CGI.pm): 10.7. CGI.pm Reference (Perl in a Nutshell)
username, passwd file entry from: 29.2.62. getpwnam (Programming Perl)
Username( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
User::pwent module: 4.16.3. Discussion (Perl Cookbook)
29.2.63. getpwuid (Programming Perl)
32.1.7. Operating System Interfaces (Programming Perl)
Class::Struct, using to create objects and accessors: 32.6. Class::Struct (Programming Perl)
users
authenticating, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
CPU times: 29.2.181. times (Programming Perl)
fetching information on: 5.1. Perl Functions by Category (Perl in a Nutshell)
granting limited privileges to: 23.1. Handling Insecure Data (Programming Perl)
groups of: Glossary (Programming Perl)
Glossary (Programming Perl)
(see also GID, groups)
information about, functions for getting: 29.1. Perl Functions by Category (Programming Perl)
userstats program: 14.1.3. Discussion (Perl Cookbook)
use_sleep( ) (LWP::RobotUA): 20.2.1. LWP::RobotUA Sections (Perl in a Nutshell)
usleep( ): 3.9.3. Discussion (Perl Cookbook)
/usr/bin/perl: 1.4.2. What's Inside That Program? (Learning Perl)
/usr/local/bin/perl: 1.4.2. What's Inside That Program? (Learning Perl)
utf8, globally switching interfaces to: 28.2. Special Variables in Alphabetical Order (Programming Perl)
UTF-8: 1.. Unicode Support in Perl (Perl Cookbook)
8.20.3. Discussion (Perl Cookbook)
2.1. Atoms (Programming Perl)
characters, ,converting to integers: 15.2. Effects of Character Semantics (Programming Perl)
variable-length character encoding: 15.1. Building Character (Programming Perl)
utf8 I/O layer: 8.. I/O Layers (Perl Cookbook)
utf8 module: 8.231. utf8 (Perl in a Nutshell)
32.1.6. Internationalization and Locale (Programming Perl)
utf8 (Perl version): 15.1. Building Character (Programming Perl)
utf8 pragma: 15.2. Effects of Character Semantics (Programming Perl)
utf8 strings, converting to/from byte strings: 15.1. Building Character (Programming Perl)
utilities
inside: B.4.3. Finding and Installing Modules (Learning Perl)
perlbug: 1.3.4. What If I Find a Bug in Perl? (Learning Perl)
Unix (see Unix, utilities for)
which_dbm: 16.1. DBM Files and DBM Hashes (Learning Perl)
utime( ): 5. Function Reference (Perl in a Nutshell)
utime( ), timestamps: 9.1.2. Solution (Perl Cookbook)
utime function: 13.7. Changing Timestamps (Learning Perl)
29.2.193. utime (Programming Perl)
utmp file (see /etc/utmp file)
UV (internal unsigned integer value): 21.2. Internal Data Types (Programming Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

v command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-V option
dprofpp: 6.5. The Perl Profiler (Perl in a Nutshell)
v-strings, in $^V: 28.2. Special Variables in Alphabetical Order (Programming Perl)
v-strings (vector or version): 2.6.7. V-String Literals (Programming Perl)
Glossary (Programming Perl)
-V (version) command-line switch: 19.1.3. Switches (Programming Perl)
validation( ): 22.5.3. Discussion (Perl Cookbook)
valof( ) (Win32::OLE): 23.2.2. Win32::OLE Functions (Perl in a Nutshell)
-value option
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
Value( ) (Win32::OLE::Variant): 23.4.1. Win32::OLE::Variant Methods (Perl in a Nutshell)
values
arrays (see arrays)
changing while copying: Glossary (Programming Perl)
comma-separated
initializing arrays with: 4.1.2. Solution (Perl Cookbook)
parsing: 1.20.1. Problem (Perl Cookbook)
converting strings between: 1.4.1. Problem (Perl Cookbook)
definedness: 1.. Introduction (Perl Cookbook)
1.2.3. Discussion (Perl Cookbook)
exchanging between scalar variables: 1.3.1. Problem (Perl Cookbook)
false: 1.. Introduction (Perl Cookbook)
hashes, sorting: 29.2.79. keys (Programming Perl)
list (see list values)
list, assigning to variables: 3.4. List Assignment (Learning Perl)
of short-circuit logical operators: 10.9.1. The Value of a Short-Circuit Operator (Learning Perl)
referencing: 8.1. What Is a Reference? (Programming Perl)
saving using local operator: 4.7. The local Operator (Learning Perl)
scalar (see scalar values)
scalar, assigning to variables: 2.5.2. Scalar Assignment (Learning Perl)
scope, confining to: 4.8.1. Scoped Variable Declarations (Programming Perl)
undefined, truth value of: 1.6.1. What Is Truth? (Programming Perl)
undefining: 29.2.187. undef (Programming Perl)
variables vs.: 1.2. Natural and Artificial Languages (Programming Perl)
values( ), traversing hashes: 5.5.3. Discussion (Perl Cookbook)
Values( ) (Data::Dumper)): 8.50. Data::Dumper (Perl in a Nutshell)
values function: 5.3.1. The keys and values Functions (Learning Perl)
14.3.1. Hash-Tying Methods (Programming Perl)
29.2.194. values (Programming Perl)
variable interpolation: 2.3.2. Double-Quoted String Literals (Learning Perl)
2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
2.6.2. String Literals (Programming Perl)
glob operator, using: 2.11.3. Filename Globbing Operator (Programming Perl)
variable-length parameter lists: 4.8. Variable-length Parameter Lists (Learning Perl)
variable-length records: 7. Formats (Programming Perl)
variable-length text databases: 16.4. Variable-length (Text) Databases (Learning Perl)
variable-length text fields: 8.9.1. Problem (Perl Cookbook)
variable-length UTF-8 characters: 15.1. Building Character (Programming Perl)
-variable option
Checkbutton widget: 21.5. The Checkbutton Widget (Perl in a Nutshell)
Menubutton widget: 21.14.1. Menu Item Options (Perl in a Nutshell)
Optionmenu widget: 21.16. The Optionmenu Widget (Perl in a Nutshell)
Radiobutton widget: 21.6. The Radiobutton Widget (Perl in a Nutshell)
Scale widget: 21.13. The Scale Widget (Perl in a Nutshell)
variables: 2.5. Scalar Variables (Learning Perl)
4.2.5. Variables (Perl in a Nutshell)
9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
2.3. Built-in Data Types (Programming Perl)
2.4. Variables (Programming Perl)
3.1. Terms and List Operators (Leftward) (Programming Perl)
8. References (Programming Perl)
8.3.1. Using a Variable as a Variable Name (Programming Perl)
altering: 2.5.3. Binary Assignment Operators (Learning Perl)
anonymous: 8.2.2. Anonymous Data (Programming Perl)
array: 2.6.5. Interpolating Array Values (Programming Perl)
assigning list values to: 3.4. List Assignment (Learning Perl)
assigning scalar values to: 2.5.2. Scalar Assignment (Learning Perl)
attributes, getting and setting: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
binding to packages: 29.2.191. untie (Programming Perl)
bless operator: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
builtin: 9.5.2. The Automatic Match Variables (Learning Perl)
B::Xref module, cross-references with C: 18.6. Code Development Tools (Programming Perl)
callbacks and: 6.4. Closures (Learning Perl Objects, References and Modules)
6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
class: 12.8. Managing Class Data (Programming Perl)
class variables: 10.5. Using Class Variables (Learning Perl Objects, References and Modules)
closure variables: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
condition variables: 17.2.2.6. Condition variables (Programming Perl)
constants: 1.21.1. Problem (Perl Cookbook)
control, in foreach loop: 4.4.3. foreach Loops (Programming Perl)
debugger, customizing: 20.3.2. Customizing with Init Files (Programming Perl)
declaration and scope: 4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
scoping functions: 5.1. Perl Functions by Category (Perl in a Nutshell)
declaring: 1.4.2. What's Inside That Program? (Learning Perl)
4. Statements and Declarations (Programming Perl)
4.8.1. Scoped Variable Declarations (Programming Perl)
declaring global: 4.8.3. Lexically Scoped Global Declarations: our (Programming Perl)
default values for: 1.2.1. Problem (Perl Cookbook)
dumping with V command: 10.1. Symbol Tables (Programming Perl)
environment: 14.3. The Environment Variables (Learning Perl)
28.2. Special Variables in Alphabetical Order (Programming Perl)
expanding in user input: 1.12.1. Problem (Perl Cookbook)
filehandles and: 11.7. References to Filehandles (Learning Perl Objects, References and Modules)
filehandles in: 7.5.1. Problem (Perl Cookbook)
format: 7.1. Format Variables (Programming Perl)
fully-qualified, accessing from outside package: 23.3.1.1. Restricting namespace access (Programming Perl)
functions private for: 12.5.1. Problem (Perl Cookbook)
global (see global)
global variables: 2.9. Packages and Lexicals (Learning Perl Objects, References and Modules)
6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
10. Object Destruction (Learning Perl Objects, References and Modules)
hash: 2.9. Hashes (Programming Perl)
initializing before calling subroutines: 6.2.3. Scoping Issues (Programming Perl)
interpolating
with double quotes: 5.2. Pattern-Matching Operators (Programming Perl)
into patterns: 5.2. Pattern-Matching Operators (Programming Perl)
interpolation: 1.2.1.1. Singularities (Programming Perl)
pattern matching, controlling with: 5.9.2. Variable Interpolation (Programming Perl)
lexical scoping: 29.2.99. my (Programming Perl)
local
common programming errors with: 24.1.1. Universal Blunders (Programming Perl)
my declarations, using instead of local function: 24.1.2. Frequently Ignored Advice (Programming Perl)
local vs. private: 4.2.7. Declarations and Scope (Perl in a Nutshell)
4.7.4. Private and Local Variables (Perl in a Nutshell)
localizing existing: 29.2.87. local (Programming Perl)
loop (iterator) variables: 4.5.3. Discussion (Perl Cookbook)
magic, creating: 13.15.1. Problem (Perl Cookbook)
match: 9.5. The Match Variables (Learning Perl)
member variables: 9.1. A Horse Is a Horse, of Course of Course—or Is It? (Learning Perl Objects, References and Modules)
9.8. More Interesting Instances (Learning Perl Objects, References and Modules)
memory addresses of: 3.2. Taking a Reference to an Array (Learning Perl Objects, References and Modules)
meta-variables: 10.5. Using Class Variables (Learning Perl Objects, References and Modules)
modules and: 12. Using Modules (Learning Perl Objects, References and Modules)
modules, exporting to programs: 11.2.1. Module Privacy and the Exporter (Programming Perl)
my (see my declarations)
8.3.6. Other Tricks You Can Do with Hard References (Programming Perl)
10. Packages (Programming Perl)
my variables: 2.3. Using do (Learning Perl Objects, References and Modules)
2.8. Scope of a Package Directive (Learning Perl Objects, References and Modules)
names for: 1.2.1. Variable Syntax (Programming Perl)
24.3. Programming with Style (Programming Perl)
names in nested symbol tables: 2.5. Names (Programming Perl)
names of enclosed in curly braces: 2.6.1. Interpolation of Scalar Variables into Strings (Learning Perl)
our (see our declarations)
our variables: 8.5. A Few Notes About @ISA (Learning Perl Objects, References and Modules)
out of scope: 6.4. Closures (Learning Perl Objects, References and Modules)
6.4. Closures (Learning Perl Objects, References and Modules)
6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
6.5. Returning a Subroutine from a Subroutine (Learning Perl Objects, References and Modules)
6.6. Closure Variables as Inputs (Learning Perl Objects, References and Modules)
6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
package, displaying: 20.2.4. Display (Programming Perl)
package, memory usage: 20.3.3. Debugger Options (Programming Perl)
package names: 8.2. Introducing the Method Invocation Arrow (Learning Perl Objects, References and Modules)
package variables: 2.5. Names (Programming Perl)
packages, associating with: 10. Packages (Programming Perl)
pattern match variables: 4.6.7. Pattern Match Variables (Perl in a Nutshell)
Perl vs. C, names of: 24.1.3. C Traps (Programming Perl)
persistent private, for subroutines: 10.3.1. Problem (Perl Cookbook)
private (see local variables)
private, for modules: 12.4.1. Problem (Perl Cookbook)
private, for subroutines: 10.2.1. Problem (Perl Cookbook)
reference removal and: 4.2. What if That Was the Name? (Learning Perl Objects, References and Modules)
4.2. What if That Was the Name? (Learning Perl Objects, References and Modules)
repeated substitutions, performing on: 5.2.3.1. Modifying strings en passant (Programming Perl)
as repository of values: 6. Subroutine References (Learning Perl Objects, References and Modules)
resetting values of: 29.2.130. reset (Programming Perl)
scalar and list context: 4.2.6. Scalar and List Contexts (Perl in a Nutshell)
scalars (see scalars)
scoped, lexical scope: 4.8.2. Lexically Scoped Variables: my (Programming Perl)
scoping, strict pragma, use of: 1.2.1.4. Simplicities (Programming Perl)
sharing among different processes: 16.12.1. Problem (Perl Cookbook)
shell programming, Perl vs.: 24.1.4. Shell Traps (Programming Perl)
special: 28.1.6. Per-Package Special Functions (Programming Perl)
special (predefined): 4.4. Special Variables (Perl in a Nutshell)
static local: 6.7. Closure Variables as Static Local Variables (Learning Perl Objects, References and Modules)
strings (see strings)
strings of, matching against known strings: 5.9.2. Variable Interpolation (Programming Perl)
taint and: 23.1. Handling Insecure Data (Programming Perl)
tied: B.21. Tied Variables (Learning Perl)
translating with: 5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
tying: 14. Tied Variables (Programming Perl)
29.2.178. tie (Programming Perl)
arrays: 14.2. Tying Arrays (Programming Perl)
filehandles: 14.4. Tying Filehandles (Programming Perl)
hashes: 14.3. Tying Hashes (Programming Perl)
scalars: 14.1. Tying Scalars (Programming Perl)
untying trap: 14.5. A Subtle Untying Trap (Programming Perl)
undef value and: 2.11. The undef Value (Learning Perl)
uninitialized: 1.2.1.1. Singularities (Programming Perl)
value of, saving: 4.7. The local Operator (Learning Perl)
values, assignment and: 1.5.3. Assignment Operators (Programming Perl)
values vs.: 1.2. Natural and Artificial Languages (Programming Perl)
watch points, placing on: 14.6. Tie Modules on CPAN (Programming Perl)
variadic functions in Perl: 6.2. Semantics (Programming Perl)
Variant data structure: 23.4. Win32::OLE::Variant (Perl in a Nutshell)
vars modle (obsolete): 32.1.13. Perl Language Extensions and Internals (Programming Perl)
vars module: 8.232. vars (Perl in a Nutshell)
vars pragma: B.6.5. The vars Pragma (Learning Perl)
vec( ): 5. Function Reference (Perl in a Nutshell)
vec function: 29.2.195. vec (Programming Perl)
vec operator: B.11. Bits and Pieces (Learning Perl)
vectors, strings as: 29.2.162. sprintf (Programming Perl)
29.2.195. vec (Programming Perl)
verbatim paragraphs (pod): 4.13. Pod (Perl in a Nutshell)
-verbose option (perlcc): 3.4. The Perl Compiler (Perl in a Nutshell)
verbosity
debugger, setting levels of: 20.3.3. Debugger Options (Programming Perl)
warnings, forcing in: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
verbs: 1.2.2. Verbs (Programming Perl)
verbs, packages, handling of: 1.2.1.4. Simplicities (Programming Perl)
verify( ) (Net::SMTP): 16.1.2.1. Net::SMTP methods (Perl in a Nutshell)
version
of Perl ($^V): 28.2. Special Variables in Alphabetical Order (Programming Perl)
module, checking for: 11.2.1.2. Version checking (Programming Perl)
of Perl
placing in #! line: 19.1. Command Processing (Programming Perl)
specifying: 19.1.2. Location of Perl (Programming Perl)
VERSION( ): 13.9.3. Discussion (Perl Cookbook)
VERSION method: 12.5.3. UNIVERSAL: The Ultimate Ancestor Class (Programming Perl)
version method (Net::LDAP): 19.4. Net::LDAP Methods (Perl in a Nutshell)
version numbers: 13.3. The Prototype Module Itself (Learning Perl Objects, References and Modules)
15.3. Preparing Your Distribution (Learning Perl Objects, References and Modules)
version, Perl: 28.2. Special Variables in Alphabetical Order (Programming Perl)
$VERSION variable: 13.9. Trivial make dist (Learning Perl Objects, References and Modules)
$VERSION variable (use pragma): 12.1.3. Discussion (Perl Cookbook)
Version( ) (Win32::Internet): 22.7.1. General Internet Methods (Perl in a Nutshell)
versions of Perl
changes between release 4 and 5: 24.1.5. Previous Perl Traps (Programming Perl)
obtaining current: 2.1. The CPAN Architecture (Perl in a Nutshell)
for Win32 systems: 2.3.2. Installing on Win32 (Perl in a Nutshell)
versions of Perl modules: 2.4.1. Locating Modules (Perl in a Nutshell)
vertical bar (|)
||= (assignment) operator: 1.2.2. Solution (Perl Cookbook)
4.5.6. Assignment Operators (Perl in a Nutshell)
|| operator
vs. or operator: 1.2.3. Discussion (Perl Cookbook)
separating multiple comparisons: 4.16.3. Discussion (Perl Cookbook)
format fieldholders: 4.12. Formats (Perl in a Nutshell)
OR bitwise operator: 4.5.10. Bitwise Operators (Perl in a Nutshell)
Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
regular expression metacharacter: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
|= (assignment) operator: 4.5.6. Assignment Operators (Perl in a Nutshell)
|| Perl debugger command: 6.2. Debugger Commands (Perl in a Nutshell)
vi editor
debugger, support for: 20.3.1. Editor Support for Debugging (Programming Perl)
regular expressions, use of: 1.7. Regular Expressions (Programming Perl)
vi text editor: 1.4. How Do I Make a Perl Program? (Learning Perl)
video, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
viewing data
Data::Dumper: 5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
with debugger: 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
virtual circuits (as TCP streams): 16.5. Sockets (Programming Perl)
virtual machine, Perl: 18.3. Executing Your Code (Programming Perl)
virtual web documents: 9.1.2. Creating Virtual Documents (Perl in a Nutshell)
visual bell: 15.7.3. Discussion (Perl Cookbook)
-visual option
Frame widget: 21.17. The Frame Widget (Perl in a Nutshell)
toplevel widget: 21.18. The Toplevel Widget (Perl in a Nutshell)
VMS operating system
File::Spec::VMS module: 32.1.4. Filenames, Filesystems, and File Locking (Programming Perl)
invoking Perl applications on: 19.1.1. #! and Quoting on Non-Unix Systems (Programming Perl)
vmsish module: 8.233. vmsish (Perl in a Nutshell)
void context: 4.4. Return Values (Learning Perl)
9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
1.5.4. Unary Arithmetic Operators (Programming Perl)
2.7.3. Void Context (Programming Perl)
2.8.1. List Assignment (Programming Perl)
29.2.198. wantarray (Programming Perl)
Glossary (Programming Perl)
recognizing in debugger: 20.1. Using the Debugger (Programming Perl)
vowel sounds, classifying syllabaries according to: 5.4.3.2. Standard Unicode properties (Programming Perl)
VRFY command: 18.16. Program: expn and vrfy (Perl Cookbook)
vrfy program: 18.16. Program: expn and vrfy (Perl Cookbook)
VRML, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Vromans, Johan: 1.3.3. Are There Any Other Kinds of Support? (Learning Perl)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

\w (word) character class: 4.6.4. Character Classes (Perl in a Nutshell)
\w characters: 8.3.1. Word Anchors (Learning Perl)
-w command-line switch: 19.1.3. Switches (Programming Perl)
w command (Perl debugger): 6.2. Debugger Commands (Perl in a Nutshell)
-W (writeable by real uid/gid) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-w file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
w forward character=\w (forward character): 1.7. Regular Expressions (Programming Perl)
\w shortcut: 8.1.1. Character Class Shortcuts (Learning Perl)
-w switch, Perl: 28.2. Special Variables in Alphabetical Order (Programming Perl)
wait( ): 5. Function Reference (Perl in a Nutshell)
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify (Perl in a Nutshell)
Win32::Mutex module: 22.9. Win32::Mutex (Perl in a Nutshell)
Win32::Semaphore module: 22.16. Win32::Semaphore (Perl in a Nutshell)
16.19.3. Discussion (Perl Cookbook)
29.2.196. wait (Programming Perl)
wait system call: 28.2. Special Variables in Alphabetical Order (Programming Perl)
Wait( ) (Win32::Process): 22.14.1. Win32::Process Methods (Perl in a Nutshell)
waitpid( ): 5. Function Reference (Perl in a Nutshell)
16.19.3. Discussion (Perl Cookbook)
14.6. Getting Down and Dirty with Fork (Learning Perl)
29.2.197. waitpid (Programming Perl)
Wall, Heidi: 6.2. Input from the Diamond Operator (Learning Perl)
Wall, Larry: 0.4. History of This Book (Learning Perl)
1.2. What Does "Perl" Stand For? (Learning Perl)
1.2. Perl Development (Perl in a Nutshell)
13.1. XML Parsing and Validation (Perl in a Nutshell)
wantarray( ): 5. Function Reference (Perl in a Nutshell)
10.6.2. Solution (Perl Cookbook)
4.4. Return Values (Learning Perl)
9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
9.10. Getting Your Deposit Back (Learning Perl Objects, References and Modules)
29.2.198. wantarray (Programming Perl)
warn( ): 4.9. Filehandles (Perl in a Nutshell)
5. Function Reference (Perl in a Nutshell)
HTML::Parser module: 20.4.4. HTML::TreeBuilder (Perl in a Nutshell)
dialog box for: 15.15.3. Discussion (Perl Cookbook)
11.3.1. Warning Messages with warn (Learning Perl)
29.2.199. warn (Programming Perl)
__WARN__ signal: 16.15.3. Discussion (Perl Cookbook)
$WARNING: 28.2. Special Variables in Alphabetical Order (Programming Perl)
warning messages: 19.1.3. Switches (Programming Perl)
29.2.199. warn (Programming Perl)
33. Diagnostic Messages (Programming Perl)
intercepting: 28.2. Special Variables in Alphabetical Order (Programming Perl)
-w switch, turning on with: 1.3.1. How to Do It (Programming Perl)
$WARNING ($^W) variable: 4.4.1. Global Special Variables (Perl in a Nutshell)
${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order (Programming Perl)
warnings: 2.4. Perl's Built-in Warnings (Learning Perl)
Glossary (Programming Perl)
lexical; ${^WARNING_BITS}: 28.2. Special Variables in Alphabetical Order (Programming Perl)
about undefined values: 4. Statements and Declarations (Programming Perl)
bad filehandles and: 11.2.2. Bad Filehandles (Learning Perl)
customizing: 12.15.1. Problem (Perl Cookbook)
disabling unconditionally and permanently: 19.1.3. Switches (Programming Perl)
enabling: 2.4. Using require (Learning Perl Objects, References and Modules)
A.3.1. Exercise 1 (Section 4.9.1) (Learning Perl Objects, References and Modules)
modules for: 32.1.15. Warnings and Exceptions (Programming Perl)
about remaining references to tied objects: 14.5. A Subtle Untying Trap (Programming Perl)
reporting like built-ins: 12.14.1. Problem (Perl Cookbook)
verbosity, forcing in: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
warn function for: 11.3.1. Warning Messages with warn (Learning Perl)
warnings module: 32.1.15. Warnings and Exceptions (Programming Perl)
warnings pragma: B.6.6. The warnings Pragma (Learning Perl)
4.9.1. Controlling Warnings (Programming Perl)
warnings::enabled( ): 12.15.2. Solution (Perl Cookbook)
warnings::register pragma: 12.15.3. Discussion (Perl Cookbook)
warnLevel option (debugger): 20.3.3. Debugger Options (Programming Perl)
watch expressions: 20.2.3. Tracing (Programming Perl)
Glossary (Programming Perl)
watch points, placing on Perl variables: 14.6. Tie Modules on CPAN (Programming Perl)
wc program: 8.2.2. Solution (Perl Cookbook)
W3C (World Wide Web Consortium): 22.. Schemas (Perl Cookbook)
weak references: 10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
8.5.2. Garbage Collection, Circular References, and Weak References (Programming Perl)
weaken( ): 11.15.3. Description (Perl Cookbook)
WeakRef module: 11.15.3. Description (Perl Cookbook)
10.6. Weakening the Argument (Learning Perl Objects, References and Modules)
12.6.1. Garbage Collection with DESTROY Methods (Programming Perl)
weather, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
Web
CGI programs and: B.16. The Common Gateway Interface (CGI) (Learning Perl)
running programs over: 1.4.3. But How Do I Compile Perl? (Learning Perl)
socket-support and: B.13.2. Sockets (Learning Perl)
web access, LWP library for: 20. The LWP Library (Perl in a Nutshell)
web architecture: 19.. Architecture (Perl Cookbook)
web automation: 20.. Introduction (Perl Cookbook)
converting ASCII to and from HTML: 20.4.1. Problem (Perl Cookbook)
extracting
table data: 20.19.1. Problem (Perl Cookbook)
URLs from HTML: 20.3.1. Problem (Perl Cookbook)
fetching
https:// web pages: 20.16.1. Problem (Perl Cookbook)
password-protected pages: 20.15.1. Problem (Perl Cookbook)
URLs: 20.1.1. Problem (Perl Cookbook)
finding stale or fresh links: 20.7.1. Problem (Perl Cookbook)
HTML
forms, submitting: 20.2.1. Problem (Perl Cookbook)
parsing: 20.18.1. Problem (Perl Cookbook)
removing or extracting tags: 20.6.1. Problem (Perl Cookbook)
templates: 20.9.1. Problem (Perl Cookbook)
text substitutions: 20.20. Program: htmlsub (Perl Cookbook)
htmlsub program: 20.20. Program: htmlsub (Perl Cookbook)
mirroring web pages: 20.10.1. Problem (Perl Cookbook)
resuming HTTP GET: 20.17.1. Problem (Perl Cookbook)
robots: 20.11.1. Problem (Perl Cookbook)
server logs
parsing: 20.12.1. Problem (Perl Cookbook)
processing: 20.13.1. Problem (Perl Cookbook)
using cookies: 20.14.1. Problem (Perl Cookbook)
web browsers (see browsers)
web client, creating: 20.2.2. LWP::Simple (Perl in a Nutshell)
web documents, virtual: 9.1.2. Creating Virtual Documents (Perl in a Nutshell)
web pages
https://: 20.16.1. Problem (Perl Cookbook)
modified, links in: 20.8.1. Problem (Perl Cookbook)
password-protected: 20.15.1. Problem (Perl Cookbook)
web, Perl modules for: 32.1.9. World Wide Web (Programming Perl)
web, references on: 19.. Web-Related Resources (Perl Cookbook)
web server programming: 11. Web Server Programmingwith mod_perl (Perl in a Nutshell)
web servers
log files, Common Log Format: 20.12.3. Discussion (Perl Cookbook)
logs
parsing: 20.12.1. Problem (Perl Cookbook)
processing: 20.13.1. Problem (Perl Cookbook)
performance, improving: 21.12.1. Problem (Perl Cookbook)
web services
SOAP client: 18.14.1. Problem (Perl Cookbook)
SOAP server: 18.13.1. Problem (Perl Cookbook)
XML-RPC server: 18.11.1. Problem (Perl Cookbook)
weekearly program: 8.13.3. Discussion (Perl Cookbook)
Week_Number( ): 3.6.2. Solution (Perl Cookbook)
weeks (see date and time values)
weighted_rand( ): 2.9.2. Solution (Perl Cookbook)
which_dbm utility: 16.1. DBM Files and DBM Hashes (Learning Perl)
while control structure: 2.10. The while Control Structure (Learning Perl)
for control structure and: 10.7. The for Control Structure (Learning Perl)
naked block control structure and: 10.4. The Naked Block Control Structure (Learning Perl)
shortcut for: 6.1. Input from Standard Input (Learning Perl)
until control structure for reversing: 10.2. The until Control Structure (Learning Perl)
using each function with: 5.3.2. The each Function (Learning Perl)
while loop
eof function in: 29.2.31. eof (Programming Perl)
traversing hashes: 5.5.2. Solution (Perl Cookbook)
4.3.1.1. while loops (Perl in a Nutshell)
1.6.2.1. The while and until statements (Programming Perl)
4.4.1. while and until Statements (Programming Perl)
angle operator and $_: 2.11.2. Line Input (Angle) Operator (Programming Perl)
while modifier: 10.3. Expression Modifiers (Learning Perl)
10.3. Expression Modifiers (Learning Perl)
15.3.1. Using sprintf with "Money Numbers" (Learning Perl)
4.3.1.4. Modifiers (Perl in a Nutshell)
4.1. Simple Statements (Programming Perl)
while statements: 1.5.5. Logical Operators (Programming Perl)
Boolean context, supplying: 2.7.2. Boolean Context (Programming Perl)
list assignment in: 2.8.1. List Assignment (Programming Perl)
whitespace: 1.4.2. What's Inside That Program? (Learning Perl)
3.3.1. The qw Shortcut (Learning Perl)
3.3. Dereferencing the Array Reference (Learning Perl Objects, References and Modules)
4.7. Autovivification (Learning Perl Objects, References and Modules)
1.7. Regular Expressions (Programming Perl)
2.2. Molecules (Programming Perl)
24.3. Programming with Style (Programming Perl)
29. Functions (Programming Perl)
Glossary (Programming Perl)
cononicalizing in a variable: 5.2.3.1. Modifying strings en passant (Programming Perl)
deleting leading or trailing: 1.19.1. Problem (Perl Cookbook)
encoding into URLs: 9.2. URL Encoding (Perl in a Nutshell)
expanding and compressing tabs: 1.11.1. Problem (Perl Cookbook)
extracting ranges of lines: 6.8.1. Problem (Perl Cookbook)
global replacements and: 9.6.1. Global Replacements with /g (Learning Perl)
greater-than sign and: 11.2. Opening a Filehandle (Learning Perl)
in format strings: 16.2. Manipulating Data with pack and unpack (Learning Perl)
in pod documentation: 12.20.3. Discussion (Perl Cookbook)
indenting here documents: 1.16.1. Problem (Perl Cookbook)
leading, removing in here documents: 2.6.6. "Here" Documents (Programming Perl)
matching
within multiple lines: 6.6.1. Problem (Perl Cookbook)
words: 6.3.1. Problem (Perl Cookbook)
in Perl programs: 4.1. Program Structure (Perl in a Nutshell)
quote characters, use in: 2.6.3. Pick Your Own Quotes (Programming Perl)
\S (non-whitespace) character class: 4.6.4. Character Classes (Perl in a Nutshell)
\s shortcut for: 8.1.1. Character Class Shortcuts (Learning Perl)
sorted text in columns and: 4.19. Program: words (Perl Cookbook)
sorting du command output: 5.17. Program: dutree (Perl Cookbook)
split operator and: 9.7. The split Operator (Learning Perl)
suppressing in formatted output: 4.12. Formats (Perl in a Nutshell)
/x modifier in pattern matching: 5.2.1. Pattern Modifiers (Programming Perl)
whitespace characters, in formats: 7. Formats (Programming Perl)
whitespaces, use as variable name or delimiter for quote construct, changes in: 24.1.5. Previous Perl Traps (Programming Perl)
who command (Unix): 14.4.1. Using Backquotes in a List Context (Learning Perl)
whoami( ): 10.4.3. Discussion (Perl Cookbook)
whowasi( ): 10.4.3. Discussion (Perl Cookbook)
wide character APIs
enabling Perl use of on target system: 19.1.3. Switches (Programming Perl)
system calls using: 15.1. Building Character (Programming Perl)
wide, syscalls: 28.2. Special Variables in Alphabetical Order (Programming Perl)
${^WIDE_SYSTEM_CALLS}: 28.2. Special Variables in Alphabetical Order (Programming Perl)
widgets (Perl/Tk): 21.1. Widgets (Perl in a Nutshell)
callbacks: 21.1.3. Callbacks (Perl in a Nutshell)
colors and fonts: 21.1.4. Colors and Fonts (Perl in a Nutshell)
common configuration options: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
geometry managers for: 21.2. Geometry Managers (Perl in a Nutshell)
scrollbars: 21.1.2. Scrollbars (Perl in a Nutshell)
widget methods: 21.1.1. Widget Methods (Perl in a Nutshell)
width
character representation: 15.1. Building Character (Programming Perl)
of numbers: 25.2. Endianness and Number Width (Programming Perl)
-width option: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
place geometry manager: 21.2.3. The place Geometry Manager (Perl in a Nutshell)
wildcard metasymbols: 5.3.3. Wildcard Metasymbols (Programming Perl)
character classes and: 5.4.1. Custom Character Classes (Programming Perl)
5.4.1. Custom Character Classes (Programming Perl)
wildcards for regular expressions: 4.6.2. Regular Expression Syntax (Perl in a Nutshell)
anchors: 4.6.5. Anchors (Perl in a Nutshell)
character classes: 4.6.4. Character Classes (Perl in a Nutshell)
escaped sequences: 4.6.3. Escaped Sequences (Perl in a Nutshell)
quantifiers: 4.6.6. Quantifiers (Perl in a Nutshell)
wildcards (shell) for regular expression matching: 6.9.1. Problem (Perl Cookbook)
`wimla,' diamond operator and: 6.2. Input from the Diamond Operator (Learning Perl)
Win32 modules: 22. Win32 Modules and Extensions (Perl in a Nutshell)
Win32:AbortSystemShutdown( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:BuildNumber( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::ChangeNotify module: 22.3. Win32::ChangeNotify (Perl in a Nutshell)
Win32::Clipboard module: 22.1. Win32::Clipboard (Perl in a Nutshell)
Win32::Console module: 22.2. Win32::Console (Perl in a Nutshell)
Win32::CopyFile( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:DomainName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::Eventlog module: 22.4. Win32::Eventlog (Perl in a Nutshell)
Win32:ExpandEnvironmentStrings( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::File module: 22.5. Win32::File (Perl in a Nutshell)
Win32::FileSecurity module: 22.6. Win32::FileSecurity (Perl in a Nutshell)
Win32:FormatMessage( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:FreeLibrary( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:FsType( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetArchName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetChipName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetCwd( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetFullPathName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetLastError( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetLongPathName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetNextAvailDrive( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetOSVersion( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetProcAddress( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetShortPathName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:GetTickCount( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:InitiateSystemShutdown( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::Internet module: 22.7. Win32::Internet (Perl in a Nutshell)
Win32::IPC module: 22.8. Win32::IPC (Perl in a Nutshell)
Win32:IsWin95( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:IsWinNT( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:LoadLibrary( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:LoginName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:LookupAccountName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:LookupAccountSID( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:MsgBox( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::Mutex module: 22.9. Win32::Mutex (Perl in a Nutshell)
Win32::NetAdmin module: 22.10. Win32::NetAdmin (Perl in a Nutshell)
Win32::NetResource module: 22.11. Win32::NetResource (Perl in a Nutshell)
Win32:NodeName( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::ODBC module: 24. ODBC Extension for Win32 (Perl in a Nutshell)
Win32::OLE modules: 23. OLE Automation (Perl in a Nutshell)
Win32::OLE::Const module: 23.5. Win32::OLE::Const (Perl in a Nutshell)
Win32::OLE::Enum module: 23.3. Win32::OLE::Enum (Perl in a Nutshell)
Win32:OLELastError( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::OLE::Variant module: 23.4. Win32::OLE::Variant (Perl in a Nutshell)
Win32::PerfLib module: 22.12. Win32::PerfLib (Perl in a Nutshell)
Win32::Pipe module: 22.13. Win32::Pipe (Perl in a Nutshell)
Win32::Process module: 22.14. Win32::Process (Perl in a Nutshell)
Win32:RegisterServer( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::Registry module: 22.15. Win32::Registry (Perl in a Nutshell)
Win32::Semaphore module: 22.16. Win32::Semaphore (Perl in a Nutshell)
Win32::Service module: 22.17. Win32::Service (Perl in a Nutshell)
Win32:SetCwd( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:SetLastError( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32::Shortcut module: 22.18. Win32::Shortcut (Perl in a Nutshell)
Win32:Sleep( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:Spawn( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32:UnregisterServer( ): 22.19. Win32 Extensions (Perl in a Nutshell)
Win32 systems
command processing: 3.1. Command Processing (Perl in a Nutshell)
installing Perl on: 2.3.2. Installing on Win32 (Perl in a Nutshell)
pl2bat.bat: 3. The Perl Executable (Perl in a Nutshell)
Win32API::File module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32API::Net module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32API::Registry module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::ChangeNotify module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Console module: 15.17.3. Description (Perl Cookbook)
32.1.20. Microsoft-Related Modules (Programming Perl)
window( ) (Text widget): 21.11.2. Text Methods (Perl in a Nutshell)
Window( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
Windows (see Microsoft Windows)
Windows 95, Perl functionality on: 2.3.2.2. Standard Perl distribution (Perl in a Nutshell)
Windows clipboard: 22.1. Win32::Clipboard (Perl in a Nutshell)
Windows Registry: B.7.1. Direct System Database Access (Learning Perl)
Winer, Dave: 14.1. What Is SOAP? (Perl in a Nutshell)
Win32::Event module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::EventLog module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::File module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::FileSecurity module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Internet module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::IPC module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Mutex module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::NetAdmin module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::NetResource module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::ODBC module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::OLE: 23. OLE Automation (Perl in a Nutshell)
Win32::OLE module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::OLE::Const: 23. OLE Automation (Perl in a Nutshell)
Win32::OLE::Const module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::OLE::Enum: 23. OLE Automation (Perl in a Nutshell)
Win32::OLE::Enum module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::OLE::NLS module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::OLE::Variant: 23. OLE Automation (Perl in a Nutshell)
methods: 23.4.1. Win32::OLE::Variant Methods (Perl in a Nutshell)
Win32::OLE::Variant module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::PerfLib module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Pipe module: 16.3.4. Named Pipes (Programming Perl)
Win32::Process module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Semaphore module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Service module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::Sound module: 32.1.20. Microsoft-Related Modules (Programming Perl)
Win32::TieRegistry module: 14.6. Tie Modules on CPAN (Programming Perl)
32.1.20. Microsoft-Related Modules (Programming Perl)
with( ) (Win32::OLE): 23.2.2. Win32::OLE Functions (Perl in a Nutshell)
withdraw( ) (Frame widget): 21.18.1. Toplevel Methods (Perl in a Nutshell)
WNetGetLastError( ) (Win32::NetResource): 22.11. Win32::NetResource (Perl in a Nutshell)
word-boundary anchors: 8.3.1. Word Anchors (Learning Perl)
word character: 1.7. Regular Expressions (Programming Perl)
word count, hashes and: 5.1.1. Why Use a Hash? (Learning Perl)
word lists: 2.8. List Values and Arrays (Programming Perl)
word processor, using instead of a text editor: 1.4. How Do I Make a Perl Program? (Learning Perl)
word-wrapping, Text::Wrap module for: B.5.11. The Text::Wrap Module (Learning Perl)
words: Glossary (Programming Perl)
b assertion=\b assertion: 1.7.3. Nailing Things Down (Programming Perl)
capturing: 5.2.2. The m// Operator (Matching) (Programming Perl)
double, finding: 6.16.1. Problem (Perl Cookbook)
fuzzy matching: 6.13.1. Problem (Perl Cookbook)
lists of, doing programmable command completion on: 32.1.11. User Interfaces (Programming Perl)
matching abbreviations: 6.20.1. Problem (Perl Cookbook)
pattern matching: 6.3.1. Problem (Perl Cookbook)
pluralizing, based on numbers: 2.17.1. Problem (Perl Cookbook)
processing all in file: 8.3.1. Problem (Perl Cookbook)
reversing: 1.7.1. Problem (Perl Cookbook)
sorting into columns: 4.19. Program: words (Perl Cookbook)
substitutions for specific: 1.23. Program: fixstyle (Perl Cookbook)
text color, changing: 15.5.1. Problem (Perl Cookbook)
wrapping paragraph text: 1.17.1. Problem (Perl Cookbook)
words program: 4.19. Program: words (Perl Cookbook)
words, \w shortcut for: 8.1.1. Character Class Shortcuts (Learning Perl)
wordstart, wordend modifiers (Text widget): 21.11.1. Text Indexes and Modifiers (Perl in a Nutshell)
working directory (see current directory)
chdir operator for changing: 12.1. Moving Around the Directory Tree (Learning Perl)
current, cwd function for determining: B.5.2. The Cwd Module (Learning Perl)
World Wide Web: 0.6.2. Usenet Newsgroups (Programming Perl)
World Wide Web Consortium (W3C): 22.. Schemas (Perl Cookbook)
World Wide Web (WWW) (see also web)
wrap function: B.5.11. The Text::Wrap Module (Learning Perl)
-wrap option (Text): 21.11. The Text Widget (Perl in a Nutshell)
-wraplength option (widgets): 21.3. Common Widget Configuration Options (Perl in a Nutshell)
wrappers: Glossary (Programming Perl)
C, around set-id scripts: 23.2.1. Unix Kernel Security Bugs (Programming Perl)
wrapping paragraph text: 1.17.1. Problem (Perl Cookbook)
wrapping text: 8.209. Text::Wrap (Perl in a Nutshell)
7.2.1. Accessing Formatting Internals (Programming Perl)
32.1.2. String Processing, Language Text Processing, Parsing, and Searching (Programming Perl)
Perl module for: 22.1. The CPAN modules Directory (Programming Perl)
writable file test operator: 1.5.7. Some File Test Operators (Programming Perl)
3.10. Named Unary and File Test Operators (Programming Perl)
write( ): 4.12. Formats (Perl in a Nutshell)
5. Function Reference (Perl in a Nutshell)
16.4.2. Solution (Perl Cookbook)
29.2.200. write (Programming Perl)
format function, declaring named sequence of picture lines: 29.2.41. format (Programming Perl)
Write( ) (Win32::Console module): 22.2. Win32::Console (Perl in a Nutshell)
WriteAttr( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
WriteChar( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
WriteInput( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
WriteMakefile subroutine (ExtUtils::MakeMaker): 13.5. Controlling the Distribution with Makefile.PL (Learning Perl Objects, References and Modules)
WriteRect( ) (Win32::Console): 22.2. Win32::Console (Perl in a Nutshell)
writing
data via low-level system call: 29.2.113. print (Programming Perl)
29.2.114. printf (Programming Perl)
29.2.175. syswrite (Programming Perl)
29.2.200. write (Programming Perl)
scripts (see scripts)
to shared memory segment ID: 29.2.153. shmwrite (Programming Perl)
signal handlers: 16.17.1. Problem (Perl Cookbook)
XML: 22.10.1. Problem (Perl Cookbook)
writing distributions: 13. Writing a Distribution (Learning Perl Objects, References and Modules)
writing to files, and open mode: 29.2.104. open (Programming Perl)
wtmp file, adding records to: 8.24. Program: tailwtmp (Perl Cookbook)
www.perl.com and www.perl.org sites: 1.4.5. www.perl.com (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x= (assignment) operator: 3.17. Assignment Operators (Programming Perl)
4.5.6. Assignment Operators (Perl in a Nutshell)
x command (debugger): 5.1. Using the Debugger to View Complex Data (Learning Perl Objects, References and Modules)
5.2. Viewing Complex Data with Data::Dumper (Learning Perl Objects, References and Modules)
x command (Perl debugger): 11.11.2. Solution (Perl Cookbook)
6.2. Debugger Commands (Perl in a Nutshell)
-x (executable by effective uid/gid) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-X (executable by real uid/gid) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
-x (extract program) command-line switch: 19.1. Command Processing (Programming Perl)
19.1.3. Switches (Programming Perl)
-X file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
x (grid geometry manager placeholder): 21.2.2. The grid Geometry Manager (Perl in a Nutshell)
X-headers (news articles): 17.1. The NNTP Protocol (Perl in a Nutshell)
\X metacharacter: 1.8.3. Discussion (Perl Cookbook)
x operator: 2.13.3. Discussion (Perl Cookbook)
1.5.2. String Operators (Programming Perl)
-x option (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
x pattern match modifier: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
4.6.8. Extended Regular Expressions (Perl in a Nutshell)
/x pattern modifier: 1.12.3. Discussion (Perl Cookbook)
5.2.1. Pattern Modifiers (Programming Perl)
5.2.1. Pattern Modifiers (Programming Perl)
5.2.2. The m// Operator (Matching) (Programming Perl)
5.2.3. The s/// Operator (Substitution) (Programming Perl)
comments in regular expressions: 6.4.3. Discussion (Perl Cookbook)
x (repetition operator): 1.5.2. String Operators (Programming Perl)
x string repetition: 2.3.3. String Operators (Learning Perl)
6.5.1. Arrays and printf (Learning Perl)
x (string repetition) operator: 4.5.11.4. String operator (Perl in a Nutshell)
-X (warning disabling) command-line switch: 19.1.3. Switches (Programming Perl)
\X wildcard metasymbol: 5.3.3. Wildcard Metasymbols (Programming Perl)
\x{263a} (wide hexadecimal value) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
\(hexadecimal value) sequence: 4.6.3. Escaped Sequences (Perl in a Nutshell)
xgtitle( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
xhdr command (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
xhdr( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
XML declaration: 22.. XML Declaration (Perl Cookbook)
XML documents
changing elements or text: 22.4.1. Problem (Perl Cookbook)
finding elements and text: 22.6.1. Problem (Perl Cookbook)
validating against schemas: 22.. Schemas (Perl Cookbook)
XML (Extensible Markup Language): 22.. Introduction (Perl Cookbook)
13. XML and Perl (Perl in a Nutshell)
CDATA: 22.. CDATA (Perl Cookbook)
comments: 22.. Comments (Perl Cookbook)
declaration: 22.. XML Declaration (Perl Cookbook)
documents (see XML documents)
files, larger than available memory, processing: 22.8.1. Problem (Perl Cookbook)
filtering: 22.4.1. Problem (Perl Cookbook)
namespaces: 22.. Namespaces (Perl Cookbook)
nested elements: 22.. Namespaces (Perl Cookbook)
parsing
into data structures: 22.1.1. Problem (Perl Cookbook)
into DOM tree: 22.2.1. Problem (Perl Cookbook)
into SAX events: 22.3.1. Problem (Perl Cookbook)
paths: 22.. Paths (Perl Cookbook)
Perl and, history of: 22.. History of Perl and XML (Perl Cookbook)
processing instructions: 22.. Processing Instructions (Perl Cookbook)
reasons for success of: 22.. Introduction (Perl Cookbook)
schemas: 22.. Schemas (Perl Cookbook)
SOAP, and: 14.1. What Is SOAP? (Perl in a Nutshell)
syntax: 22.. Syntax (Perl Cookbook)
transformations: 22.. Transformations (Perl Cookbook)
Unicode encodings: 22.. XML Declaration (Perl Cookbook)
validating: 22.5.1. Problem (Perl Cookbook)
documents against schemas: 22.. Schemas (Perl Cookbook)
well-formed documents: 22.. Well-Formed XML (Perl Cookbook)
writing: 22.10.1. Problem (Perl Cookbook)
XML, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
XML-RPC: 18.. Introduction (Perl Cookbook)
client: 18.12.1. Problem (Perl Cookbook)
server: 18.11.1. Problem (Perl Cookbook)
XML Schema: 22.. Schemas (Perl Cookbook)
XML Stylesheet Language for Transformations (see XSLT)
XMLDecl handler (Expat): 13.3. Expat Handlers (Perl in a Nutshell)
XMLin( ): 13.1. XML Parsing and Validation (Perl in a Nutshell)
22.1.3. Discussion (Perl Cookbook)
XML::LibXML module: 22.. History of Perl and XML (Perl Cookbook)
22.3.3. Discussion (Perl Cookbook)
finding elements and text in XML documents: 22.6.2. Solution (Perl Cookbook)
parsing XML into a DOM tree: 22.2.2. Solution (Perl Cookbook)
validating XML against DTD: 22.5.2. Solution (Perl Cookbook)
XML::LibXSLT module: 22.. Transformations (Perl Cookbook)
22.7.2. Solution (Perl Cookbook)
XMLout( ), writing XML: 22.10.2. Solution (Perl Cookbook)
XML::Parser: 13.1. XML Parsing and Validation (Perl in a Nutshell)
methods: 13.2. XML::Parser Methods (Perl in a Nutshell)
styles: 13.4. XML::Parser Styles (Perl in a Nutshell)
XML::Parser module: 22.3.3. Discussion (Perl Cookbook)
caution against using directly: 22.. History of Perl and XML (Perl Cookbook)
XML::Parser::ContentModel methods: 13.6. XML::Parser::ContentModel Methods (Perl in a Nutshell)
XMLRPC::Lite module: 18.. Introduction (Perl Cookbook)
18.12.2. Solution (Perl Cookbook)
XML::RSS module: 22.9.2. Solution (Perl Cookbook)
XML::Sablotron module, XSLT: 22.. Transformations (Perl Cookbook)
XML::SAX module: 22.3.3. Discussion (Perl Cookbook)
parsing XML into SAX events: 22.3.2. Solution (Perl Cookbook)
XML::SAX modules, parsing XML: 22.. History of Perl and XML (Perl Cookbook)
XML::SAX::Base module: 22.3.3. Discussion (Perl Cookbook)
XML::SAX::Machines module, filtering XML: 22.4.2. Solution (Perl Cookbook)
XML::SAX::ParserFactory module: 22.3.3. Discussion (Perl Cookbook)
XML::SAX::PurePerl module: 22.3.3. Discussion (Perl Cookbook)
XML::Simple: 13.1. XML Parsing and Validation (Perl in a Nutshell)
XML::Simple module: 22.1.2. Solution (Perl Cookbook)
writing XML: 22.10.2. Solution (Perl Cookbook)
XML::Twig module, processing large XML files: 22.8.2. Solution (Perl Cookbook)
XML::Xerces module, validating XML against W3C Schema: 22.5.2. Solution (Perl Cookbook)
XML::XSLT module: 22.. Transformations (Perl Cookbook)
XOR (^) operator, bitwise: 4.5.10. Bitwise Operators (Perl in a Nutshell)
xor logical operator: 3.13. Bitwise Operators (Programming Perl)
3.20. Logical and, or, not, and xor (Programming Perl)
xor operator: 10.9.3. Control Structures Using Partial-Evaluation Operators (Learning Perl)
xover( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
xpat command (NNTP): 17.1. The NNTP Protocol (Perl in a Nutshell)
xpat( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
XPath: 22.. Paths (Perl Cookbook)
expressions: 22.6.3. Discussion (Perl Cookbook)
xpath( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
Xref backend (Perl compiler): 3.4. The Perl Compiler (Perl in a Nutshell)
xrover( ) (Net::NNTP): 17.2.2. Net::NNTP Reference (Perl in a Nutshell)
XS interface: 12.9.3. Discussion (Perl Cookbook)
12.18.3. Discussion (Perl Cookbook)
XS language
code, portability of: 25.6. External Subroutines (XS) (Programming Perl)
debugging tools for: 32.1.13. Perl Language Extensions and Internals (Programming Perl)
external subroutines, wrapping: 21.3. Extending Perl (Using C from Perl) (Programming Perl)
functions, mapping between C and Perl: 21.3.1. XS and XSUBs (Programming Perl)
XS_constant function (ExtUtils::Constant module): 8.69. ExtUtils::Constant (Perl in a Nutshell)
-xscrollcommand option: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
Scrollbar widget: 21.1.2.2. The Scrollbar widget (Perl in a Nutshell)
-xscrollincrement option (Canvas): 21.12. The Canvas Widget (Perl in a Nutshell)
XSLoader module: 32.1.17. Module Installation Support (Programming Perl)
XSLT (XML Stylesheet Language for Transformations): 22.. Transformations (Perl Cookbook)
processing: 22.7.1. Problem (Perl Cookbook)
XS::Typemap module: 8.234. XS::Typemap (Perl in a Nutshell)
xsubpp compiler: 21.3.1. XS and XSUBs (Programming Perl)
XSUBs: 21.3. Extending Perl (Using C from Perl) (Programming Perl)
21.3.1. XS and XSUBs (Programming Perl)
(see also XS)
input and output: 21.3.3. XSUB Input and Output (Programming Perl)
wrapping subroutines for Perl: 21.3. Extending Perl (Using C from Perl) (Programming Perl)
xview( )
Canvas widget: 21.12.3. Canvas Methods (Perl in a Nutshell)
Entry widget: 21.8.2. Entry Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

-y option (place geometry manager): 21.2.3. The place Geometry Manager (Perl in a Nutshell)
y// pattern match operator: 4.6.1. Pattern-Matching Operators (Perl in a Nutshell)
y/// (transliteration) operator: 5.2. Pattern-Matching Operators (Programming Perl)
5.2.4. The tr/// Operator (Transliteration) (Programming Perl)
29.2.201. y// (Programming Perl)
years (see date and time values)
yield function: 17.2.1.7. Yielding the processor (Programming Perl)
yposition( ) (Menu widget): 21.15.2. Menu Methods (Perl in a Nutshell)
-yscrollcommand option: 21.3. Common Widget Configuration Options (Perl in a Nutshell)
Scrollbar widget: 21.1.2.2. The Scrollbar widget (Perl in a Nutshell)
-yscrollincrement option (Canvas): 21.12. The Canvas Widget (Perl in a Nutshell)
yview( )
Canvas widget: 21.12.3. Canvas Methods (Perl in a Nutshell)
Listbox widget: 21.10.2. Listbox Methods (Perl in a Nutshell)
Text widget: 21.11.2. Text Methods (Perl in a Nutshell)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

^Z (Control-Z) as eof: 24.5.2. Generating Perl in Other Languages (Programming Perl)
.Z extension: 2.3.1. Installing on Unix (Perl in a Nutshell)
-z file test operator: 4.5.8. File Test Operators (Perl in a Nutshell)
-z option (dprofpp): 6.5. The Perl Profiler (Perl in a Nutshell)
\z (string boundary): 5.6.2. Endings: The \z, \Z, and $ Assertions (Programming Perl)
-z (zero size) file test: 3.10. Named Unary and File Test Operators (Programming Perl)
zero-width assertions: 5.1. The Regular Expression Bestiary (Programming Perl)
5.3.1. Metasymbol Tables (Programming Perl)
5.6. Positions (Programming Perl)
quantifiers and: 5.1. The Regular Expression Bestiary (Programming Perl)
zipping, Perl modules for: 22.1. The CPAN modules Directory (Programming Perl)
zombie processes: Glossary (Programming Perl)
zombie processes, reaping: 16.1.2. Reaping Zombies (Programming Perl)
servers: 16.5.2. Networking Servers (Programming Perl)
zombies: 16.. Process Creation (Perl Cookbook)
avoiding: 16.19.1. Problem (Perl Cookbook)
Symbols & Numbers | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2004 O'Reilly & Associates, Inc. All Rights Reserved.


The Perl CD Bookshelf, v4.0

The Perl CD Bookshelf, v4.0 The Perl CD Bookshelf

Copyright © 2004 O'Reilly & Associates, Inc. All rights reserved.

The Perl CD Bookshelf, Version 4.0
By O'Reilly & Associates, Inc.
ISBN 0-596-00622-5
Published by O'Reilly & Associates, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

This CD-ROM is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this reference library available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this CD without the explicit written permission of O'Reilly & Associates, Inc. If you would like to discuss licensing for multiple users, contact service@oreilly.com.

If you have found this CD Bookshelf on the web, or it is a copy of an original, then you have an unauthorized, infringing copy. Authorized, lawful, non-infringing copies of this product can be purchased from O'Reilly & Associates, Inc.

O'Reilly & Associates books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles at safari.oreilly.com. For more information contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this CD, and O'Reilly & Associates, Inc., was aware of the trademark claim, the designations have been printed in caps or initial caps.

While every precaution has been taken in the preparation of this CD, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. External urls and hyperlinks may have changed from the time of publication.

The Perl CD Bookshelf, Version 4.0, is Copyright © 2004 by O'Reilly & Associates, Inc. All rights reserved.
Questions, comments, and suggestions to bookquestions@oreilly.com.


The Perl CD Bookshelf, v2.0

The Perl CD Bookshelf, v4.0 The Perl CD Bookshelf

The CD

Project Manager
Ellie Cutler
Technical Development and Tools
Erik Ray, Ellie Cutler
Graphics and Design
Ellie Volckhausen, Emma Colby
Production and Testing
Tony Castro, Ellie Cutler, Paul LaBrier,
Chris Olson, Becki Maisch
CD-ROM Search Engine
QuestAgent Pro version 4.0.9 from JObjects.

The Books

Perl in a Nutshell, 2nd Edition
By By Nathan Patwardhan, Ellen Siever and Stephen Spainhour
Learning Perl, 3rd Edition
By Randal L. Schwartz and Tom Phoenix
Programming Perl, 3rd Edition
By Larry Wall, Tom Christiansen, and Jon Orwant
Perl Cookbook, 2nd Edition
By Tom Christiansen and Nathan Torkington
Learning Perl Objects, References and Modules
By Randal L. Schwartz, with Tom Phoenix
Mastering Regular Expressions, 2nd Edition
by Jeffrey Friedl

The Perl CD Bookshelf, Version 4.0, is Copyright © 2004 by O'Reilly & Associates, Inc. All rights reserved.
Questions, comments, and suggestions to bookquestions@oreilly.com.